Skip to main content
POST
/
api
/
v2.0
/
disbursement
/
transfer
Disburse Transfer
curl --request POST \
  --url https://sandbox-payment-b2b.singapay.id/api/v2.0/disbursement/transfer \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --header 'X-PARTNER-ID: <api-key>' \
  --header 'X-Signature: <x-signature>' \
  --header 'X-Timestamp: <x-timestamp>' \
  --data '
{
  "account_id": "01K946KF851RK7FX075GJHBVKF",
  "reference_number": "REF-20260610-001",
  "bank_code": "002",
  "bank_account_number": "1234567890000",
  "amount": 50000,
  "notes": "Transfer payment"
}
'
{
  "response_code": "SP000",
  "response_message": "Successfully",
  "data": {
    "transaction_id": "101222025122910292195055674",
    "reference_number": "11111111118",
    "transaction_status": {
      "code": "00",
      "desc": "Success"
    },
    "post_timestamp": "1766978961000",
    "processed_timestamp": "1766978962000",
    "bank": {
      "code": "002",
      "name": "BRI",
      "account_name": "Dummy Test Account Internal",
      "account_number": "11111111118"
    },
    "gross_amount": {
      "currency": "IDR",
      "value": "12504.00"
    },
    "fee": {
      "currency": "IDR",
      "value": "2500"
    },
    "net_amount": {
      "currency": "IDR",
      "value": "10004.00"
    },
    "balance_after": {
      "currency": "IDR",
      "value": "829988"
    },
    "notes": "test transfer"
  }
}

Authorizations

Authorization
string
header
required

JWT issued by POST /api/v1.1/access-token/b2b. Send Authorization: Bearer <token>.

X-PARTNER-ID
string
header
required

Merchant API key (Credential.api_key). Required on every request.

Headers

X-Signature
string
required

HMAC-SHA512 hex signature, computed as HMAC_SHA512(clientSecret, "{HTTP_METHOD}:{REQUEST_URI}:{ACCESS_TOKEN}:{SHA256_HEX(MINIFIED_BODY)}:{X_TIMESTAMP}"). MINIFIED_BODY is the request body with object keys recursively sorted alphabetically and re-serialised with no whitespace (an empty/missing body hashes the empty string). ACCESS_TOKEN is the bearer token without the Bearer prefix. Missing header returns 400 (response_code=4019900); signature mismatch returns 401 (response_code=4019900).

X-Timestamp
string<date-time>
required

ISO-8601 timestamp of the request; used as part of the signed string. Missing header returns 400 (response_code=4019900).

Body

application/json

Request body for submitting a bank disbursement (API v2.0 transfer).

account_id
string
required

Unique identifier (ULID) of the merchant account to debit. Specified in the request body, not in the URL path.

Example:

"01K946KF851RK7FX075GJHBVKF"

reference_number
string
required

Unique merchant reference for this transfer within the account. Used for idempotency; a duplicate reference returns HTTP 400 with response code SP004.

Maximum string length: 64
Example:

"REF-20260610-001"

bank_code
string
required

Destination bank identifier: a three-digit national bank code or a bank SWIFT code.

Example:

"002"

bank_account_number
string
required

Beneficiary account number. Numeric digits only, between 6 and 30 characters.

Example:

"1234567890000"

amount
number
required

Net amount to be credited to the beneficiary, in IDR. Must be within merchant-specific minimum and maximum disbursement limits. The transfer fee is added to compute the gross debit from the merchant account.

Example:

50000

notes
string | null

Optional note attached to the transaction for merchant reference.

Maximum string length: 100
Example:

"Transfer payment"

Response

SP000 Successfully — transfer accepted (often pending in data.transaction_status). Merchant action: check inquiry status.

Custom v2 envelope for disbursement transfer. Success uses SP000 (HTTP 200).

response_code
string
required

SingaPay custom business response code.

Example:

"SP000"

response_message
string
required

Human-readable label paired with response_code.

Example:

"Successfully"

data
object
required

data on successful disbursement v2 transfer or v2 inquiry status (HTTP 200, response_code SP000).