Pakasir Proxy

Pakasir Proxy.

API reference for integrating payments into your application.

Base URL: https://msdzul.com

Authentication

All endpoints require your per-app API key. Send it as a bearer token on every request.

Authorization Bearer <per-app-api-key> required

Transactions

Transaction endpoints for your application. All requests require your per-app API key.

Create Transaction

POST /api/v1/transactions/create 201
Authorization Bearer <per-app-api-key> required
Content-Type application/json required
Name Type Description Required
webhook_url string URL to receive webhook when payment completes required
order_id string Unique order ID from your system required
amount int Payment amount in IDR (e.g. 50000) required
payment_method string Payment method (see below) required

Payment methods

Method Description Min Max
qris QRIS (QR Code) 500 10.000.000
bri_va BRI Virtual Account 10.000 50.000.000
bni_va BNI Virtual Account 10.000 50.000.000
permata_va Permata Virtual Account 10.000 50.000.000
cimb_niaga_va CIMB Niaga Virtual Account 10.000 50.000.000
sampoerna_va Sampoerna Virtual Account 10.000 50.000.000
bnc_va Bank Neo Commerce Virtual Account 10.000 50.000.000
maybank_va Maybank Virtual Account 10.000 50.000.000
atm_bersama_va ATM Bersama Virtual Account 10.000 50.000.000
artha_graha_va Artha Graha Virtual Account 10.000 50.000.000

Amounts outside these limits are rejected with 400 before any call to Pakasir.

Example request

        curl -X POST https://msdzul.com/api/v1/transactions/create \
  -H "Authorization: Bearer <per-app-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "webhook_url": "https://your-app.com/webhook/pakasir",
    "order_id": "INV20260819-001",
    "amount": 50000,
    "payment_method": "qris"
  }'
    

Success response (201 Created)

        {
  "txn_id": "vwiqpcriq",
  "project": "my-shop",
  "order_id": "INV20260819-001",
  "amount": 50000,
  "fee": 750,
  "total_payment": 50750,
  "payment_method": "qris",
  "qr_string": "00020101021226610016ID.CO.SHOPEE.WWW0118...",
  "va_number": "",
  "expired_at": "2026-08-20T12:00:00.000Z",
  "is_sandbox": true,
  "status": "pending",
  "completed_at": null
}
    

The body is the Pakasir API v2 response, forwarded as-is. Read the payment instruction from qr_string (QRIS) or va_number (virtual account) and keep txn_id for cancel and status operations.

Error responses

Status Error Description
400 invalid request body Malformed JSON
400 webhook_url is required Missing webhook_url
400 order_id is required Missing order_id
400 amount must be greater than 0 Invalid amount
400 amount must be at least ... for payment_method ... Below the method minimum
400 amount must be at most ... for payment_method ... Above the method maximum
400 invalid payment_method Unknown payment method
401 unauthorized Invalid or missing API key
409 transaction already exists Duplicate order_id for this project
502 Pakasir error message Error from Pakasir (message forwarded)
500 failed to save transaction Database error

Creating a transaction is idempotent on Pakasir side, so retrying the same order_id with the same body returns the same txn_id.

Cancel Transaction

POST /api/v1/transactions/cancel 200
Authorization Bearer <per-app-api-key> required
Content-Type application/json required
Name Type Description Required
order_id string Order ID to cancel required
amount int Deprecated and ignored, Pakasir API v2 cancels by txn_id —

Example request

        curl -X POST https://msdzul.com/api/v1/transactions/cancel \
  -H "Authorization: Bearer <per-app-api-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "INV20260819-001"
  }'
    

Success response (200 OK)

        {
  "status": "cancelled"
}
    

Error responses

Status Error Description
400 invalid request body Malformed JSON
400 order_id is required Missing order_id
400 transaction is already cancelled Already cancelled
400 transaction is already completed Already completed
400 transaction is expired Payment window expired
401 unauthorized Invalid or missing API key
404 transaction not found Transaction not in database
409 transaction was created before the API v2 migration ... No txn_id stored, cancel it in the Pakasir dashboard
409 transaction status changed during cancel A webhook completed the transaction meanwhile
502 Pakasir error message Error from Pakasir (message forwarded)
500 failed to update transaction status Database error

Get Transaction Status

GET /api/v1/transactions/{order_id} 200
Authorization Bearer <per-app-api-key> required
Parameter Description
order_id The order ID to look up

Example request

        curl https://msdzul.com/api/v1/transactions/INV20260819-001 \
  -H "Authorization: Bearer <per-app-api-key>"
    

Success response (200 OK)

        {
  "id": "507f1f77bcf86cd799439011",
  "app": "my_app",
  "webhook_url": "https://your-app.com/webhook/pakasir",
  "project": "my-shop",
  "order_id": "INV20260819-001",
  "amount": 50000,
  "fee": 750,
  "total_payment": 50750,
  "payment_method": "qris",
  "txn_id": "vwiqpcriq",
  "qr_string": "00020101021226610016ID.CO.SHOPEE.WWW0118...",
  "va_number": "",
  "status": "completed",
  "expired_at": "2026-08-20T12:00:00.000Z",
  "completed_at": "2026-08-19T15:30:00.000Z",
  "created_at": "2026-08-19T15:00:00.000Z",
  "updated_at": "2026-08-19T15:30:00.000Z"
}
    

Transaction statuses

Status Description
pending Waiting for payment
completed Payment received
cancelled Transaction cancelled
expired Payment window expired

Error responses

Status Error Description
400 order_id is required Missing order_id parameter
401 unauthorized Invalid or missing API key
404 transaction not found Transaction not found in database

Webhook Receiver

This endpoint receives webhooks from Pakasir. It does not require the app API key. Once a payment is verified, the proxy forwards the payload straight to the webhook_url you registered.

POST /webhook/pakasir 200

Proxy behavior

  1. Verifies the payment status with Pakasir before forwarding
  2. Updates the stored transaction status
  3. Forwards the webhook payload to your webhook_url

Response

        200 OK
    

The proxy always returns 200 OK to Pakasir to prevent retries. Errors are logged but don't affect the response.

Webhook Payload

The payload delivered to your application keeps every field of the Pakasir v2 webhook and adds project and payment_method, resolved from the stored transaction.

        {
  "txn_id": "vwiqpcriq",
  "order_id": "INV20260819-001",
  "project": "my-shop",
  "amount": 50000,
  "payment_method": "qris",
  "is_sandbox": true,
  "status": "completed",
  "completed_at": "2026-08-19T15:30:00+07:00"
}
    

Your application should handle this payload and process the payment accordingly. If you verify project and payment_method only, no change is needed. If you read the transaction reference, use txn_id instead of project + order_id.

Schemas

Request and response payloads used by the App API.

CreateTransactionRequest

        {
  "webhook_url": "string",
  "order_id": "string",
  "amount": "int",
  "payment_method": "string"
}
    

CancelTransactionRequest

        {
  "order_id": "string",
  "amount": "int (deprecated, ignored)"
}
    

CreateTransactionResponse

        {
  "txn_id": "string",
  "project": "string",
  "order_id": "string",
  "amount": "int",
  "fee": "int",
  "total_payment": "int",
  "payment_method": "string",
  "qr_string": "string",
  "va_number": "string",
  "expired_at": "string",
  "is_sandbox": "boolean",
  "status": "string",
  "completed_at": "string|null"
}
    

WebhookPayload

        {
  "txn_id": "string",
  "order_id": "string",
  "amount": "int",
  "is_sandbox": "boolean",
  "status": "string",
  "completed_at": "string"
}
    

ErrorResponse

        {
  "error": "string"
}
    

For Pakasir API errors (status 502), the error message contains the raw response from Pakasir. For validation errors (status 400), the message describes the specific field issue.

Pakasir Proxy — API Reference