> For the complete documentation index, see [llms.txt](https://developers.doku.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://developers.doku.com/wallet-as-a-service/sub-account/sub-account-v2/integration-guide.md).

# Integration Guide

{% hint style="info" %}
All new integrations should use V2 for the latest capabilities and best experience.
{% endhint %}

## Register Sub Account

> Creates a new sub-account for each party that will receive payments on your platform.\
> \
> Once created, the sub-account receives:\
> \- A unique \*\*Profile ID\*\*\
> \- One or more \*\*Account Numbers\*\* (IDR, Pending IDR, Points)\
> \
> A webhook notification is sent to your callback URL when registration is complete (see Webhook: Register Sub Account below).<br>

```json
{"openapi":"3.1.0","info":{"title":"Sub-Account API","version":"2.0.0"},"tags":[{"name":"Account Management","description":"Create and manage sub-accounts"}],"servers":[{"url":"https://api-sandbox.doku.com","description":"Sandbox"},{"url":"https://api.doku.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"B2B Token obtained from Get B2B Token API"}},"parameters":{"X-PARTNER-ID":{"name":"X-PARTNER-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Your Partner ID (DOKU's Client ID)"},"X-TIMESTAMP":{"name":"X-TIMESTAMP","in":"header","required":true,"schema":{"type":"string","format":"date-time"},"description":"Client's current local time in ISO 8601 format, with timezone offset"},"X-SIGNATURE":{"name":"X-SIGNATURE","in":"header","required":true,"schema":{"type":"string"},"description":"Request signature generated using HMAC_SHA512(clientSecret, stringToSign). The stringToSign is constructed from request components to ensure integrity and prevent tampering."},"X-EXTERNAL-ID":{"name":"X-EXTERNAL-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Numeric string used as a request reference. Must be unique within the same day (resets daily). Used by DOKU to detect and reject duplicate requests."}},"schemas":{"AccountInfo":{"type":"object","properties":{"type":{"type":"string","maxLength":32,"description":"Account type: DOKU_MERCHANT_IDR (withdrawable IDR), DOKU_MERCHANT_PENDING_IDR (held/reserved), DOKU_MERCHANT_POINT (non-cash points), DOKU_SYSTEM_POINT (funding source for point top-ups; merchant profile only, carries a negative balance)"},"currency":{"type":"string","minLength":3,"maxLength":3,"description":"ISO 4217 currency code (IDR) or POINT for non-cash accounts"},"accountNo":{"type":"string","maxLength":10,"description":"Unique account number assigned by DOKU. Use this in transaction APIs (transfers, debits, balance inquiries)."}}},"ErrorResponse":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128}}}}},"paths":{"/sub-account/v2.0/register":{"post":{"operationId":"registerSubAccount","tags":["Account Management"],"summary":"Register Sub Account","description":"Creates a new sub-account for each party that will receive payments on your platform.\n\nOnce created, the sub-account receives:\n- A unique **Profile ID**\n- One or more **Account Numbers** (IDR, Pending IDR, Points)\n\nA webhook notification is sent to your callback URL when registration is complete (see Webhook: Register Sub Account below).\n","parameters":[{"$ref":"#/components/parameters/X-PARTNER-ID"},{"$ref":"#/components/parameters/X-TIMESTAMP"},{"$ref":"#/components/parameters/X-SIGNATURE"},{"$ref":"#/components/parameters/X-EXTERNAL-ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["partnerReferenceNo","type","name","email"],"properties":{"partnerReferenceNo":{"type":"string","maxLength":64,"description":"Your merchant-assigned reference number"},"parentProfileId":{"type":"string","maxLength":128,"description":"Parent Profile ID for hierarchical accounts"},"referralCode":{"type":"string","maxLength":64,"description":"Referral code. DOKU auto-generates if omitted"},"type":{"type":"string","maxLength":10,"description":"Sub-account type. Use DEFAULT for standard sub-accounts."},"email":{"type":"string","maxLength":25,"format":"email","description":"Email address of the account holder. Email address of the account holder."},"name":{"type":"string","maxLength":128,"description":"Name of the account holder"},"phoneNo":{"type":"string","maxLength":15,"description":"Phone number of the account holder (e.g., 081234567890)"},"countryCode":{"type":"string","maxLength":3,"description":"ISO 3166-1 alpha-2 country code (e.g., ID for Indonesia)"}}}}}},"responses":{"200":{"description":"Sub-account registered successfully","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128},"parentProfileId":{"description":"Profile ID of the parent sub-account, if the account is nested","type":"string","maxLength":128},"profileId":{"type":"string","maxLength":128,"description":"Newly created Profile ID. Use this to reference the sub-account in future API calls (e.g., Balance Inquiries)."},"accounts":{"type":"array","description":"List of accounts created for this sub-account. Each sub-account can have up to 3 account types: DOKU_MERCHANT_IDR (withdrawable), DOKU_MERCHANT_PENDING_IDR (held), DOKU_MERCHANT_POINT (non-cash).","items":{"$ref":"#/components/schemas/AccountInfo"}}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate partnerReferenceNo","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Transfer Inquiry

> Validate and retrieve beneficiary details before executing a transfer. This ensures the destination account is valid and the details are correct.\
> \
> The response includes a \`referenceNo\` that \*\*must be used\*\* in the \[Transfer Payment]\(/api-reference/transfer-payment) request.\
> \
> Supports four transfer types:\
> \- \`BANK\_ACCOUNT\` — To any of 100+ Indonesian banks\
> \- \`DOKU\_SUB\_ACCOUNT\` — Between sub-accounts on your platform (set \`currency: POINT\` for a point P2P transfer)\
> \- \`DOKU\_WALLET\` — To a DOKU e-wallet\
> \- \`DOKU\_NON\_FIAT\` — Point top-up. Issues new points from your \`DOKU\_SYSTEM\_POINT\` account; \`fromAccount\` is selected automatically and any supplied value is overridden<br>

```json
{"openapi":"3.1.0","info":{"title":"Sub-Account API","version":"2.0.0"},"tags":[{"name":"Fund Transfers","description":"Validate and execute fund transfers"}],"servers":[{"url":"https://api-sandbox.doku.com","description":"Sandbox"},{"url":"https://api.doku.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"B2B Token obtained from Get B2B Token API"}},"parameters":{"X-PARTNER-ID":{"name":"X-PARTNER-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Your Partner ID (DOKU's Client ID)"},"X-TIMESTAMP":{"name":"X-TIMESTAMP","in":"header","required":true,"schema":{"type":"string","format":"date-time"},"description":"Client's current local time in ISO 8601 format, with timezone offset"},"X-SIGNATURE":{"name":"X-SIGNATURE","in":"header","required":true,"schema":{"type":"string"},"description":"Request signature generated using HMAC_SHA512(clientSecret, stringToSign). The stringToSign is constructed from request components to ensure integrity and prevent tampering."},"X-EXTERNAL-ID":{"name":"X-EXTERNAL-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Numeric string used as a request reference. Must be unique within the same day (resets daily). Used by DOKU to detect and reject duplicate requests."}},"schemas":{"Amount":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"string","description":"Amount as a string with 2 decimal places (e.g., \"500000.00\")"},"currency":{"type":"string","minLength":3,"maxLength":3,"description":"ISO 4217 currency code (IDR), or POINT for non-cash point accounts"}}},"ErrorResponse":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128}}}}},"paths":{"/sub-account/v2.0/transfer-inquiry":{"post":{"operationId":"transferInquiry","tags":["Fund Transfers"],"summary":"Transfer Inquiry","description":"Validate and retrieve beneficiary details before executing a transfer. This ensures the destination account is valid and the details are correct.\n\nThe response includes a `referenceNo` that **must be used** in the [Transfer Payment](/api-reference/transfer-payment) request.\n\nSupports four transfer types:\n- `BANK_ACCOUNT` — To any of 100+ Indonesian banks\n- `DOKU_SUB_ACCOUNT` — Between sub-accounts on your platform (set `currency: POINT` for a point P2P transfer)\n- `DOKU_WALLET` — To a DOKU e-wallet\n- `DOKU_NON_FIAT` — Point top-up. Issues new points from your `DOKU_SYSTEM_POINT` account; `fromAccount` is selected automatically and any supplied value is overridden\n","parameters":[{"$ref":"#/components/parameters/X-PARTNER-ID"},{"$ref":"#/components/parameters/X-TIMESTAMP"},{"$ref":"#/components/parameters/X-SIGNATURE"},{"$ref":"#/components/parameters/X-EXTERNAL-ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["partnerReferenceNo","type","amount","fromAccount","beneficiaryAccountNumber"],"properties":{"partnerReferenceNo":{"type":"string","maxLength":64,"description":"Unique transaction identifier. Must be unique per request"},"type":{"type":"string","maxLength":20,"enum":["BANK_ACCOUNT","DOKU_SUB_ACCOUNT","DOKU_WALLET","DOKU_NON_FIAT"],"description":"Transfer destination type: BANK_ACCOUNT (external bank), DOKU_SUB_ACCOUNT (between sub-accounts), DOKU_WALLET (e-wallet), DOKU_NON_FIAT (point top-up from DOKU_SYSTEM_POINT)"},"amount":{"$ref":"#/components/schemas/Amount"},"channel":{"type":"string","maxLength":22,"enum":["BI_FAST","ONLINE"],"description":"Transfer channel. Defaults to BI_FAST"},"fromAccount":{"type":"string","maxLength":22,"description":"Source sub-account number"},"beneficiaryBankCode":{"type":"string","maxLength":16,"description":"Destination bank SWIFT/BIC code. Required for BANK_ACCOUNT type. Not needed for DOKU_SUB_ACCOUNT or DOKU_NON_FIAT. Full list: https://developers.doku.com/payout/kirim-doku#list-of-supported-banks"},"beneficiaryAccountNumber":{"type":"string","maxLength":22,"description":"Destination account number"},"remark":{"type":"string","maxLength":256,"description":"Transfer remarks"}}}}}},"responses":{"200":{"description":"Inquiry successful","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128},"referenceNo":{"type":"string","maxLength":64,"description":"DOKU-generated reference number. You MUST pass this value as referenceNo in the Transfer Payment request to execute this transfer."},"partnerReferenceNo":{"description":"Your reference number, echoed back from the request","type":"string","maxLength":64},"type":{"description":"Transfer destination type — BANK_ACCOUNT, DOKU_SUB_ACCOUNT, DOKU_WALLET or DOKU_NON_FIAT","type":"string","maxLength":20},"channel":{"type":"string","maxLength":22,"description":"Transfer channel (BI_FAST or ONLINE)"},"fromAccount":{"type":"string","maxLength":22,"description":"Source sub-account number"},"beneficiaryAccountNumber":{"description":"Destination account number","type":"string","maxLength":22},"beneficiaryAccountName":{"type":"string","maxLength":256,"description":"Account holder name as registered at the destination bank. Display this to the user for confirmation before calling Transfer Payment."},"beneficiaryBankCode":{"type":"string","maxLength":16,"description":"Bank SWIFT/BIC code. Full list: https://developers.doku.com/payout/kirim-doku#list-of-supported-banks"},"amount":{"$ref":"#/components/schemas/Amount"}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Account not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Transfer Payment

> Execute a fund transfer after a successful \[Transfer Inquiry]\(/api-reference/transfer-inquiry).\
> \
> Requires the \`referenceNo\` from the inquiry response. Once processed:\
> \- Funds are deducted from the source sub-account\
> \- Funds are delivered to the destination\
> \- A webhook notification is sent to your callback URL (see Webhook: Transfer Payment below)<br>

```json
{"openapi":"3.1.0","info":{"title":"Sub-Account API","version":"2.0.0"},"tags":[{"name":"Fund Transfers","description":"Validate and execute fund transfers"}],"servers":[{"url":"https://api-sandbox.doku.com","description":"Sandbox"},{"url":"https://api.doku.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"B2B Token obtained from Get B2B Token API"}},"parameters":{"X-PARTNER-ID":{"name":"X-PARTNER-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Your Partner ID (DOKU's Client ID)"},"X-TIMESTAMP":{"name":"X-TIMESTAMP","in":"header","required":true,"schema":{"type":"string","format":"date-time"},"description":"Client's current local time in ISO 8601 format, with timezone offset"},"X-SIGNATURE":{"name":"X-SIGNATURE","in":"header","required":true,"schema":{"type":"string"},"description":"Request signature generated using HMAC_SHA512(clientSecret, stringToSign). The stringToSign is constructed from request components to ensure integrity and prevent tampering."},"X-EXTERNAL-ID":{"name":"X-EXTERNAL-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Numeric string used as a request reference. Must be unique within the same day (resets daily). Used by DOKU to detect and reject duplicate requests."}},"schemas":{"Amount":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"string","description":"Amount as a string with 2 decimal places (e.g., \"500000.00\")"},"currency":{"type":"string","minLength":3,"maxLength":3,"description":"ISO 4217 currency code (IDR), or POINT for non-cash point accounts"}}},"ErrorResponse":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128}}}}},"paths":{"/sub-account/v2.0/transfer-payment":{"post":{"operationId":"transferPayment","tags":["Fund Transfers"],"summary":"Transfer Payment","description":"Execute a fund transfer after a successful [Transfer Inquiry](/api-reference/transfer-inquiry).\n\nRequires the `referenceNo` from the inquiry response. Once processed:\n- Funds are deducted from the source sub-account\n- Funds are delivered to the destination\n- A webhook notification is sent to your callback URL (see Webhook: Transfer Payment below)\n","parameters":[{"$ref":"#/components/parameters/X-PARTNER-ID"},{"$ref":"#/components/parameters/X-TIMESTAMP"},{"$ref":"#/components/parameters/X-SIGNATURE"},{"$ref":"#/components/parameters/X-EXTERNAL-ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["partnerReferenceNo","referenceNo","type","amount","fromAccount","beneficiaryBankCode","beneficiaryAccountNumber","beneficiaryAccountName"],"properties":{"partnerReferenceNo":{"type":"string","maxLength":64,"description":"Unique transaction identifier. Must be unique per request"},"referenceNo":{"type":"string","maxLength":64,"description":"DOKU reference number from Transfer Inquiry"},"type":{"description":"Transfer destination type — BANK_ACCOUNT, DOKU_SUB_ACCOUNT, DOKU_WALLET or DOKU_NON_FIAT","type":"string","maxLength":20,"enum":["BANK_ACCOUNT","DOKU_SUB_ACCOUNT","DOKU_WALLET","DOKU_NON_FIAT"]},"channel":{"type":"string","maxLength":22,"enum":["BI_FAST","ONLINE"],"description":"Transfer channel. BI_FAST = real-time national payment rail, ONLINE = standard bank transfer. Defaults to BI_FAST if omitted."},"amount":{"$ref":"#/components/schemas/Amount"},"fromAccount":{"type":"string","maxLength":22,"description":"Source sub-account number"},"beneficiaryBankCode":{"type":"string","maxLength":16,"description":"Destination bank SWIFT/BIC code. Full list: https://developers.doku.com/payout/kirim-doku#list-of-supported-banks"},"beneficiaryAccountNumber":{"type":"string","maxLength":22,"description":"Destination account number"},"beneficiaryAccountName":{"type":"string","maxLength":256,"description":"Destination account holder name. Required. Use the name returned by Transfer Inquiry"}}}}}},"responses":{"200":{"description":"Transfer executed successfully","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":256},"referenceNo":{"description":"DOKU-generated reference number for this transaction","type":"string","maxLength":64},"partnerReferenceNo":{"description":"Your reference number, echoed back from the request","type":"string","maxLength":64},"type":{"description":"Transfer destination type — BANK_ACCOUNT, DOKU_SUB_ACCOUNT, DOKU_WALLET or DOKU_NON_FIAT","type":"string","maxLength":20},"channel":{"type":"string","maxLength":22,"description":"Transfer channel (BI_FAST or ONLINE)"},"amount":{"$ref":"#/components/schemas/Amount"},"referenceNumber":{"type":"string","maxLength":64,"description":"Bank reference number"},"transactionDate":{"description":"Timestamp when the transaction was processed, ISO 8601","type":"string","format":"date-time"},"beneficiaryBankCode":{"type":"string","maxLength":16,"description":"Bank SWIFT/BIC code. Full list: https://developers.doku.com/payout/kirim-doku#list-of-supported-banks"},"beneficiaryAccountNumber":{"description":"Destination account number","type":"string","maxLength":10},"beneficiaryAccountName":{"description":"Destination account holder name","type":"string","maxLength":22},"fromAccount":{"description":"Source account number","type":"string","maxLength":22}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Exceeds transaction amount limit","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate partnerReferenceNo","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Create Split Rules

> Create automated fund distribution rules for transactions. Once active, the rule applies automatically to all matching transactions — no batch, no manual intervention.\
> \
> Supports two rule types:\
> \- \*\*PERCENTAGE\*\* — each party gets a percentage of the total\
> \- \*\*FLAT\*\* — each party gets a fixed amount<br>

```json
{"openapi":"3.1.0","info":{"title":"Sub-Account API","version":"2.0.0"},"tags":[{"name":"Split Rules","description":"Configure automated fund distribution"}],"servers":[{"url":"https://api-sandbox.doku.com","description":"Sandbox"},{"url":"https://api.doku.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"B2B Token obtained from Get B2B Token API"}},"parameters":{"X-PARTNER-ID":{"name":"X-PARTNER-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Your Partner ID (DOKU's Client ID)"},"X-TIMESTAMP":{"name":"X-TIMESTAMP","in":"header","required":true,"schema":{"type":"string","format":"date-time"},"description":"Client's current local time in ISO 8601 format, with timezone offset"},"X-SIGNATURE":{"name":"X-SIGNATURE","in":"header","required":true,"schema":{"type":"string"},"description":"Request signature generated using HMAC_SHA512(clientSecret, stringToSign). The stringToSign is constructed from request components to ensure integrity and prevent tampering."},"X-EXTERNAL-ID":{"name":"X-EXTERNAL-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Numeric string used as a request reference. Must be unique within the same day (resets daily). Used by DOKU to detect and reject duplicate requests."}},"schemas":{"SplitRuleItem":{"type":"object","required":["type","value","accountNumber"],"properties":{"type":{"type":"string","maxLength":20,"enum":["PERCENTAGE","FLAT"],"description":"PERCENTAGE = distribute a percentage of the transaction amount. FLAT = distribute a fixed amount regardless of transaction size."},"value":{"type":"number","description":"When type is PERCENTAGE, this is the percentage (e.g., 70 = 70%). When type is FLAT, this is the fixed amount in the specified currency (e.g., 5000 = IDR 5,000). Only numbers and decimal point (.) are allowed — no commas, spaces, or other characters."},"currency":{"type":"string","maxLength":6,"description":"ISO 4217 currency code. Required when type is FLAT to specify the currency of the flat amount. Ignored for PERCENTAGE type."},"accountNumber":{"type":"number","description":"The sub-account number that will receive this portion of the split. Must be an existing sub-account under your merchant."}}},"ErrorResponse":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128}}}}},"paths":{"/sub-account/v2.0/split-rules":{"post":{"operationId":"createSplitRules","tags":["Split Rules"],"summary":"Create Split Rules","description":"Create automated fund distribution rules for transactions. Once active, the rule applies automatically to all matching transactions — no batch, no manual intervention.\n\nSupports two rule types:\n- **PERCENTAGE** — each party gets a percentage of the total\n- **FLAT** — each party gets a fixed amount\n","parameters":[{"$ref":"#/components/parameters/X-PARTNER-ID"},{"$ref":"#/components/parameters/X-TIMESTAMP"},{"$ref":"#/components/parameters/X-SIGNATURE"},{"$ref":"#/components/parameters/X-EXTERNAL-ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["transactionType","rules"],"properties":{"transactionType":{"type":"string","maxLength":64,"description":"The transaction type this rule will match against. Use PAYMENT for split rules applied to incoming payments."},"rules":{"description":"The distribution rules that make up this split","type":"array","items":{"$ref":"#/components/schemas/SplitRuleItem"}}}}}}},"responses":{"200":{"description":"Split rule created","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string"},"responseMessage":{"description":"Human-readable status message","type":"string"},"splitRuleId":{"type":"string","maxLength":36,"description":"Unique ID for this split rule"},"transactionType":{"description":"Transaction type","type":"string","maxLength":64},"rules":{"description":"The distribution rules that make up this split","type":"array","items":{"$ref":"#/components/schemas/SplitRuleItem"}}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Balance Inquiries

> Retrieve the current balance information for a sub-account.\
> \
> Returns \*\*available\*\* and \*\*reserved\*\* balances for each account type (IDR, Pending IDR, Points).<br>

```json
{"openapi":"3.1.0","info":{"title":"Sub-Account API","version":"2.0.0"},"tags":[{"name":"Monitoring","description":"Check balances, transaction status, and history"}],"servers":[{"url":"https://api-sandbox.doku.com","description":"Sandbox"},{"url":"https://api.doku.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"B2B Token obtained from Get B2B Token API"}},"parameters":{"X-PARTNER-ID":{"name":"X-PARTNER-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Your Partner ID (DOKU's Client ID)"},"X-TIMESTAMP":{"name":"X-TIMESTAMP","in":"header","required":true,"schema":{"type":"string","format":"date-time"},"description":"Client's current local time in ISO 8601 format, with timezone offset"},"X-SIGNATURE":{"name":"X-SIGNATURE","in":"header","required":true,"schema":{"type":"string"},"description":"Request signature generated using HMAC_SHA512(clientSecret, stringToSign). The stringToSign is constructed from request components to ensure integrity and prevent tampering."},"X-EXTERNAL-ID":{"name":"X-EXTERNAL-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Numeric string used as a request reference. Must be unique within the same day (resets daily). Used by DOKU to detect and reject duplicate requests."}},"schemas":{"Balance":{"type":"object","properties":{"available":{"type":"string","description":"Available balance (can be spent or transferred)"},"reserved":{"type":"string","description":"Reserved balance (held for pending transactions)"}}},"ErrorResponse":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128}}}}},"paths":{"/sub-account/v2.0/balance-inquiries":{"post":{"operationId":"balanceInquiries","tags":["Monitoring"],"summary":"Balance Inquiries","description":"Retrieve the current balance information for a sub-account.\n\nReturns **available** and **reserved** balances for each account type (IDR, Pending IDR, Points).\n","parameters":[{"$ref":"#/components/parameters/X-PARTNER-ID"},{"$ref":"#/components/parameters/X-TIMESTAMP"},{"$ref":"#/components/parameters/X-SIGNATURE"},{"$ref":"#/components/parameters/X-EXTERNAL-ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["profileId"],"properties":{"profileId":{"type":"string","maxLength":22,"description":"Profile ID of the sub-account"},"accounts":{"type":"array","maxItems":10,"items":{"type":"string"},"description":"Specific account numbers to query. Omit to get all"}}}}}},"responses":{"200":{"description":"Balance retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128},"name":{"type":"string","maxLength":128,"description":"Account holder name"},"profileId":{"description":"Profile ID of the sub-account","type":"string","maxLength":128},"accounts":{"type":"array","items":{"type":"object","properties":{"type":{"description":"Account type, e.g. DOKU_MERCHANT_IDR","type":"string","maxLength":32},"currency":{"description":"Currency of this account — IDR, or POINT for a non-cash account","type":"string","maxLength":3},"accountNo":{"description":"Account number. Use this in transfers, debits and balance inquiries","type":"string","maxLength":10},"balance":{"$ref":"#/components/schemas/Balance"}}}}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Transaction Status

> Check the real-time status of any Sub-Account transaction.\
> \
> Returns the current status and, for cancelled debit transactions, the complete debit cancel history.\
> \
> \*\*Status codes:\*\*\
> \| Code | Status |\
> \|------|--------|\
> \| \`00\` | Success |\
> \| \`03\` | Pending |\
> \| \`04\` | Refunded |\
> \| \`06\` | Failed |<br>

```json
{"openapi":"3.1.0","info":{"title":"Sub-Account API","version":"2.0.0"},"tags":[{"name":"Monitoring","description":"Check balances, transaction status, and history"}],"servers":[{"url":"https://api-sandbox.doku.com","description":"Sandbox"},{"url":"https://api.doku.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"B2B Token obtained from Get B2B Token API"}},"parameters":{"X-PARTNER-ID":{"name":"X-PARTNER-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Your Partner ID (DOKU's Client ID)"},"X-TIMESTAMP":{"name":"X-TIMESTAMP","in":"header","required":true,"schema":{"type":"string","format":"date-time"},"description":"Client's current local time in ISO 8601 format, with timezone offset"},"X-SIGNATURE":{"name":"X-SIGNATURE","in":"header","required":true,"schema":{"type":"string"},"description":"Request signature generated using HMAC_SHA512(clientSecret, stringToSign). The stringToSign is constructed from request components to ensure integrity and prevent tampering."},"X-EXTERNAL-ID":{"name":"X-EXTERNAL-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Numeric string used as a request reference. Must be unique within the same day (resets daily). Used by DOKU to detect and reject duplicate requests."}},"schemas":{"Amount":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"string","description":"Amount as a string with 2 decimal places (e.g., \"500000.00\")"},"currency":{"type":"string","minLength":3,"maxLength":3,"description":"ISO 4217 currency code (IDR), or POINT for non-cash point accounts"}}},"RefundHistoryItem":{"type":"object","properties":{"refundNo":{"type":"string","maxLength":64,"description":"DOKU-assigned debit cancel number"},"refundStatus":{"type":"string","maxLength":4,"description":"Debit cancel status code"},"transactionDate":{"type":"string","format":"date-time","description":"Debit cancel datetime"},"reason":{"type":"string","maxLength":128,"description":"Debit cancel reason"},"refundAmount":{"$ref":"#/components/schemas/Amount"}}},"ErrorResponse":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128}}}}},"paths":{"/sub-account/v2.0/transactions-status":{"post":{"operationId":"transactionStatus","tags":["Monitoring"],"summary":"Transaction Status","description":"Check the real-time status of any Sub-Account transaction.\n\nReturns the current status and, for cancelled debit transactions, the complete debit cancel history.\n\n**Status codes:**\n| Code | Status |\n|------|--------|\n| `00` | Success |\n| `03` | Pending |\n| `04` | Refunded |\n| `06` | Failed |\n","parameters":[{"$ref":"#/components/parameters/X-PARTNER-ID"},{"$ref":"#/components/parameters/X-TIMESTAMP"},{"$ref":"#/components/parameters/X-SIGNATURE"},{"$ref":"#/components/parameters/X-EXTERNAL-ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["partnerReferenceNo"],"properties":{"partnerReferenceNo":{"type":"string","maxLength":64,"description":"Your unique transaction identifier"}}}}}},"responses":{"200":{"description":"Status retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128},"partnerReferenceNo":{"description":"Your reference number, echoed back from the request","type":"string","maxLength":64},"transactionType":{"description":"Transaction type","type":"string","maxLength":16},"latestTransactionStatus":{"type":"string","description":"00 = Success, 03 = Pending, 04 = Refunded, 05 = Canceled (Void Topup only), 06 = Failed. May be absent for voided transactions."},"latestTransactionDesc":{"type":"string","maxLength":32,"description":"Status description (e.g., success, void, pending)"},"transactionDate":{"description":"Timestamp when the transaction was processed, ISO 8601","type":"string","format":"date-time"},"amount":{"$ref":"#/components/schemas/Amount"},"refundHistory":{"description":"One entry per cancellation against this transaction","type":"array","items":{"$ref":"#/components/schemas/RefundHistoryItem"}}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Transaction not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Transaction History

> Retrieve a paginated list of transactions for a sub-account within a date range.\
> \
> Use this for reconciliation, generating statements, and compliance reporting.<br>

```json
{"openapi":"3.1.0","info":{"title":"Sub-Account API","version":"2.0.0"},"tags":[{"name":"Monitoring","description":"Check balances, transaction status, and history"}],"servers":[{"url":"https://api-sandbox.doku.com","description":"Sandbox"},{"url":"https://api.doku.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"B2B Token obtained from Get B2B Token API"}},"parameters":{"X-PARTNER-ID":{"name":"X-PARTNER-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Your Partner ID (DOKU's Client ID)"},"X-TIMESTAMP":{"name":"X-TIMESTAMP","in":"header","required":true,"schema":{"type":"string","format":"date-time"},"description":"Client's current local time in ISO 8601 format, with timezone offset"},"X-SIGNATURE":{"name":"X-SIGNATURE","in":"header","required":true,"schema":{"type":"string"},"description":"Request signature generated using HMAC_SHA512(clientSecret, stringToSign). The stringToSign is constructed from request components to ensure integrity and prevent tampering."},"X-EXTERNAL-ID":{"name":"X-EXTERNAL-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Numeric string used as a request reference. Must be unique within the same day (resets daily). Used by DOKU to detect and reject duplicate requests."}},"schemas":{"TransactionHistoryItem":{"type":"object","properties":{"mutationType":{"type":"string","enum":["CREDIT","DEBIT"],"description":"CREDIT = money in, DEBIT = money out"},"transactionType":{"type":"string","maxLength":32,"description":"Transaction type: PAYMENT, TOPUP, TOPUP_FEE, PURCHASE, TRANSFER_P2P, PAYOUT, PAYOUT_CHARGE, SETTLEMENT, SETTLEMENT_FEE, SPLIT_TRANSACTION, REFUND_PURCHASE, REFUND_PAYMENT, VOID_PAYMENT, ADJUSTMENT_CREDIT, ADJUSTMENT_DEBIT"},"amount":{"type":"number","description":"Transaction amount"},"currency":{"type":"string","maxLength":3,"description":"Currency code (IDR or POINT)"},"status":{"type":"string","maxLength":16,"description":"Transaction status: SUCCESS, PENDING, FAILED, or VOID. VOID rows remain in history as an audit trail but are excluded from balance-inquiries, so balance = sum of rows where status != VOID"},"dateTime":{"type":"string","format":"date-time","description":"Transaction datetime"},"remark":{"type":"string","maxLength":256,"description":"Transaction remarks"},"partnerReferenceNo":{"type":"string","maxLength":64,"description":"Your merchant reference"},"referenceNo":{"type":"string","maxLength":64,"description":"DOKU reference number"},"channel":{"type":"string","maxLength":64,"description":"Payment channel (e.g., VIRTUAL_ACCOUNT_BRI, CREDIT_CARD, BI_FAST, ONLINE, SAC_TRANSFER). May be empty for BRI VA top-ups and P2P transfers."}}},"ErrorResponse":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128}}}}},"paths":{"/sub-account/v2.0/transaction-history-list":{"post":{"operationId":"transactionHistory","tags":["Monitoring"],"summary":"Transaction History","description":"Retrieve a paginated list of transactions for a sub-account within a date range.\n\nUse this for reconciliation, generating statements, and compliance reporting.\n","parameters":[{"$ref":"#/components/parameters/X-PARTNER-ID"},{"$ref":"#/components/parameters/X-TIMESTAMP"},{"$ref":"#/components/parameters/X-SIGNATURE"},{"$ref":"#/components/parameters/X-EXTERNAL-ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["accountNo","fromDateTime","toDateTime","pageSize","pageNumber"],"properties":{"accountNo":{"type":"string","maxLength":10,"description":"Sub-account number"},"fromDateTime":{"type":"string","maxLength":25,"description":"Start date in ISO 8601 format"},"toDateTime":{"type":"string","maxLength":25,"description":"End date in ISO 8601 format"},"pageSize":{"type":"string","maxLength":3,"description":"Items per page"},"pageNumber":{"type":"string","maxLength":3,"description":"Page number (starts from 0). Use 0 for the first page."}}}}}},"responses":{"200":{"description":"History retrieved","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128},"detailData":{"description":"The transactions matching your query, newest first","type":"array","items":{"$ref":"#/components/schemas/TransactionHistoryItem"}}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Debit

> Process a debit transaction on a sub-account.\
> \
> A webhook notification is sent to your callback URL when the transaction status updates (see Webhook: Debit below).<br>

```json
{"openapi":"3.1.0","info":{"title":"Sub-Account API","version":"2.0.0"},"tags":[{"name":"Debits","description":"Process debits and debit cancellations"}],"servers":[{"url":"https://api-sandbox.doku.com","description":"Sandbox"},{"url":"https://api.doku.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"B2B Token obtained from Get B2B Token API"}},"parameters":{"X-PARTNER-ID":{"name":"X-PARTNER-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Your Partner ID (DOKU's Client ID)"},"X-TIMESTAMP":{"name":"X-TIMESTAMP","in":"header","required":true,"schema":{"type":"string","format":"date-time"},"description":"Client's current local time in ISO 8601 format, with timezone offset"},"X-SIGNATURE":{"name":"X-SIGNATURE","in":"header","required":true,"schema":{"type":"string"},"description":"Request signature generated using HMAC_SHA512(clientSecret, stringToSign). The stringToSign is constructed from request components to ensure integrity and prevent tampering."},"X-EXTERNAL-ID":{"name":"X-EXTERNAL-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Numeric string used as a request reference. Must be unique within the same day (resets daily). Used by DOKU to detect and reject duplicate requests."}},"schemas":{"Amount":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"string","description":"Amount as a string with 2 decimal places (e.g., \"500000.00\")"},"currency":{"type":"string","minLength":3,"maxLength":3,"description":"ISO 4217 currency code (IDR), or POINT for non-cash point accounts"}}},"ErrorResponse":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128}}}}},"paths":{"/sub-account/v2.0/debit":{"post":{"operationId":"purchase","tags":["Debits"],"summary":"Debit","description":"Process a debit transaction on a sub-account.\n\nA webhook notification is sent to your callback URL when the transaction status updates (see Webhook: Debit below).\n","parameters":[{"$ref":"#/components/parameters/X-PARTNER-ID"},{"$ref":"#/components/parameters/X-TIMESTAMP"},{"$ref":"#/components/parameters/X-SIGNATURE"},{"$ref":"#/components/parameters/X-EXTERNAL-ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["partnerReferenceNo","fromAccount","transactionType","amount"],"properties":{"partnerReferenceNo":{"type":"string","maxLength":64,"description":"Unique transaction identifier. Must be unique per request"},"fromAccount":{"type":"string","maxLength":10,"description":"Sub-account number to debit"},"transactionType":{"type":"string","maxLength":16,"description":"Transaction type for debit. Only PURCHASE is supported.","enum":["PURCHASE"]},"amount":{"$ref":"#/components/schemas/Amount"},"description":{"type":"string","maxLength":128,"description":"Transaction description"}}}}}},"responses":{"200":{"description":"Debit processed","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128},"partnerReferenceNo":{"description":"Your reference number, echoed back from the request","type":"string","maxLength":64},"referenceNo":{"description":"DOKU-generated reference number for this transaction","type":"string","maxLength":64},"transactionType":{"description":"Transaction type","type":"string","maxLength":16},"fromAccount":{"description":"Source account number","type":"string","maxLength":10},"amount":{"$ref":"#/components/schemas/Amount"},"description":{"description":"Transaction description, echoed back from the request","type":"string","maxLength":128},"latestTransactionStatus":{"type":"string","description":"00 = Success, 03 = Pending, 04 = Refunded, 06 = Failed"},"transactionStatusDesc":{"description":"Human-readable description of `latestTransactionStatus`","type":"string","maxLength":128},"transactionDate":{"description":"Timestamp when the transaction was processed, ISO 8601","type":"string","format":"date-time"}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Duplicate partnerReferenceNo","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Debit Cancel

> Process a full or partial cancellation for a previous debit transaction.\
> \
> References the original debit by \`originalPartnerReferenceNo\`. The cancellation amount can be equal to or less than the original debit amount.\
> \
> A webhook notification is sent to your callback URL when the debit cancellation is processed (see Webhook: Debit Cancel below).<br>

```json
{"openapi":"3.1.0","info":{"title":"Sub-Account API","version":"2.0.0"},"tags":[{"name":"Debits","description":"Process debits and debit cancellations"}],"servers":[{"url":"https://api-sandbox.doku.com","description":"Sandbox"},{"url":"https://api.doku.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"B2B Token obtained from Get B2B Token API"}},"parameters":{"X-PARTNER-ID":{"name":"X-PARTNER-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Your Partner ID (DOKU's Client ID)"},"X-TIMESTAMP":{"name":"X-TIMESTAMP","in":"header","required":true,"schema":{"type":"string","format":"date-time"},"description":"Client's current local time in ISO 8601 format, with timezone offset"},"X-SIGNATURE":{"name":"X-SIGNATURE","in":"header","required":true,"schema":{"type":"string"},"description":"Request signature generated using HMAC_SHA512(clientSecret, stringToSign). The stringToSign is constructed from request components to ensure integrity and prevent tampering."},"X-EXTERNAL-ID":{"name":"X-EXTERNAL-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Numeric string used as a request reference. Must be unique within the same day (resets daily). Used by DOKU to detect and reject duplicate requests."}},"schemas":{"Amount":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"string","description":"Amount as a string with 2 decimal places (e.g., \"500000.00\")"},"currency":{"type":"string","minLength":3,"maxLength":3,"description":"ISO 4217 currency code (IDR), or POINT for non-cash point accounts"}}},"ErrorResponse":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128}}}}},"paths":{"/sub-account/v2.0/debit/cancel":{"post":{"operationId":"refundPurchase","tags":["Debits"],"summary":"Debit Cancel","description":"Process a full or partial cancellation for a previous debit transaction.\n\nReferences the original debit by `originalPartnerReferenceNo`. The cancellation amount can be equal to or less than the original debit amount.\n\nA webhook notification is sent to your callback URL when the debit cancellation is processed (see Webhook: Debit Cancel below).\n","parameters":[{"$ref":"#/components/parameters/X-PARTNER-ID"},{"$ref":"#/components/parameters/X-TIMESTAMP"},{"$ref":"#/components/parameters/X-SIGNATURE"},{"$ref":"#/components/parameters/X-EXTERNAL-ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["partnerReferenceNo","originalPartnerReferenceNo","transactionType","refundAmount"],"properties":{"partnerReferenceNo":{"type":"string","maxLength":64,"description":"Unique identifier for this debit cancel request"},"originalPartnerReferenceNo":{"type":"string","maxLength":64,"description":"partnerReferenceNo from the original debit"},"originalReferenceNo":{"type":"string","maxLength":64,"description":"referenceNo from the original debit"},"transactionType":{"type":"string","maxLength":16,"description":"Use REFUND_PURCHASE for cancelling a debit transaction."},"refundAmount":{"$ref":"#/components/schemas/Amount"},"reason":{"type":"string","maxLength":128,"description":"Reason for the debit cancellation"}}}}}},"responses":{"200":{"description":"Debit cancellation processed","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128},"partnerReferenceNo":{"description":"Your reference number, echoed back from the request","type":"string","maxLength":64},"originalPartnerReferenceNo":{"description":"Your reference number from the original transaction","type":"string","maxLength":64},"originalReferenceNo":{"description":"DOKU reference number from the original transaction","type":"string","maxLength":64},"transactionType":{"description":"Transaction type","type":"string","maxLength":16},"refundNo":{"type":"string","maxLength":64,"description":"DOKU-assigned debit cancel number"},"refundAmount":{"$ref":"#/components/schemas/Amount"},"reason":{"description":"Reason supplied on the request, echoed back","type":"string","maxLength":128},"latestTransactionStatus":{"type":"string","description":"00 = Success, 03 = Pending, 04 = Refunded, 06 = Failed"},"transactionStatusDesc":{"description":"Human-readable description of `latestTransactionStatus`","type":"string","maxLength":128},"transactionDate":{"description":"Timestamp when the transaction was processed, ISO 8601","type":"string","format":"date-time"}}}}}},"400":{"description":"Bad Request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Original transaction not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}
```

## Void Topup

> Reverse a point top-up in full. The original top-up is marked as cancelled and the points are removed from the destination sub-account.\
> \
> Only point top-ups (\`type: DOKU\_NON\_FIAT\`) can be voided. To reverse a point purchase, use Debit Cancel instead.\
> \
> A void does \*\*not\*\* create new transaction history rows — the original \`TOPUP\` rows change \`status\` from \`SUCCESS\` to \`VOID\` on both the destination account and \`DOKU\_SYSTEM\_POINT\`, and remain in history as an audit trail. \`VOID\` rows are excluded from balance inquiries.\
> \
> Partial voids are not supported: \`voidAmount.value\` must equal the original top-up amount exactly. Voids are not idempotent — voiding an already-voided top-up returns \`4034415\`.\
> \
> \### Errors\
> \
> \| responseCode | HTTP | responseMessage | Cause |\
> \|---|---|---|---|\
> \| \`4004402\` | 400 | \`Invalid Mandatory Field voidAmount\` | \`voidAmount\` missing from the request |\
> \| \`4034415\` | 403 | \`Transaction is already voided\` | The top-up has already been voided. Voids are not idempotent — a repeat returns this error rather than succeeding again |\
> \| \`4034415\` | 403 | \`Void amount does not match original transaction amount\` | \`voidAmount.value\` differs from the original top-up amount. Partial voids are not supported |\
> \
> \`4034415\` covers both 403 cases — branch on \`responseMessage\`, not on the code alone.<br>

```json
{"openapi":"3.1.0","info":{"title":"Sub-Account API","version":"2.0.0"},"tags":[{"name":"Fund Transfers","description":"Validate and execute fund transfers"}],"servers":[{"url":"https://api-sandbox.doku.com","description":"Sandbox"},{"url":"https://api.doku.com","description":"Production"}],"security":[{"BearerAuth":[]}],"components":{"securitySchemes":{"BearerAuth":{"type":"http","scheme":"bearer","description":"B2B Token obtained from Get B2B Token API"}},"parameters":{"X-PARTNER-ID":{"name":"X-PARTNER-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Your Partner ID (DOKU's Client ID)"},"X-TIMESTAMP":{"name":"X-TIMESTAMP","in":"header","required":true,"schema":{"type":"string","format":"date-time"},"description":"Client's current local time in ISO 8601 format, with timezone offset"},"X-SIGNATURE":{"name":"X-SIGNATURE","in":"header","required":true,"schema":{"type":"string"},"description":"Request signature generated using HMAC_SHA512(clientSecret, stringToSign). The stringToSign is constructed from request components to ensure integrity and prevent tampering."},"X-EXTERNAL-ID":{"name":"X-EXTERNAL-ID","in":"header","required":true,"schema":{"type":"string"},"description":"Numeric string used as a request reference. Must be unique within the same day (resets daily). Used by DOKU to detect and reject duplicate requests."}},"schemas":{"ErrorResponse":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128}}},"Amount":{"type":"object","required":["value","currency"],"properties":{"value":{"type":"string","description":"Amount as a string with 2 decimal places (e.g., \"500000.00\")"},"currency":{"type":"string","minLength":3,"maxLength":3,"description":"ISO 4217 currency code (IDR), or POINT for non-cash point accounts"}}}}},"paths":{"/sub-account/v2.0/topup/void":{"post":{"operationId":"voidTopup","tags":["Fund Transfers"],"summary":"Void Topup","description":"Reverse a point top-up in full. The original top-up is marked as cancelled and the points are removed from the destination sub-account.\n\nOnly point top-ups (`type: DOKU_NON_FIAT`) can be voided. To reverse a point purchase, use Debit Cancel instead.\n\nA void does **not** create new transaction history rows — the original `TOPUP` rows change `status` from `SUCCESS` to `VOID` on both the destination account and `DOKU_SYSTEM_POINT`, and remain in history as an audit trail. `VOID` rows are excluded from balance inquiries.\n\nPartial voids are not supported: `voidAmount.value` must equal the original top-up amount exactly. Voids are not idempotent — voiding an already-voided top-up returns `4034415`.\n\n### Errors\n\n| responseCode | HTTP | responseMessage | Cause |\n|---|---|---|---|\n| `4004402` | 400 | `Invalid Mandatory Field voidAmount` | `voidAmount` missing from the request |\n| `4034415` | 403 | `Transaction is already voided` | The top-up has already been voided. Voids are not idempotent — a repeat returns this error rather than succeeding again |\n| `4034415` | 403 | `Void amount does not match original transaction amount` | `voidAmount.value` differs from the original top-up amount. Partial voids are not supported |\n\n`4034415` covers both 403 cases — branch on `responseMessage`, not on the code alone.\n","parameters":[{"$ref":"#/components/parameters/X-PARTNER-ID"},{"$ref":"#/components/parameters/X-TIMESTAMP"},{"$ref":"#/components/parameters/X-SIGNATURE"},{"$ref":"#/components/parameters/X-EXTERNAL-ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["partnerReferenceNo","originalPartnerReferenceNo","transactionType","voidAmount"],"properties":{"partnerReferenceNo":{"type":"string","maxLength":64,"description":"Unique identifier for this void request"},"originalPartnerReferenceNo":{"type":"string","maxLength":64,"description":"`partnerReferenceNo` of the top-up being voided"},"originalReferenceNo":{"type":"string","maxLength":64,"description":"`referenceNo` of the top-up being voided"},"transactionType":{"description":"Transaction type","type":"string","maxLength":16,"enum":["VOID_TOPUP"]},"voidAmount":{"type":"object","description":"Amount to void. Must equal the original top-up amount exactly — partial voids are rejected with 4034415","properties":{"value":{"description":"Amount voided, matching the original top-up exactly","type":"string"},"currency":{"description":"`POINT`","type":"string","minLength":3,"maxLength":3}}},"reason":{"type":"string","maxLength":128,"description":"Reason for the void. Accepted but not returned in the response"}}}}}},"responses":{"200":{"description":"Void processed","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string","maxLength":7},"responseMessage":{"description":"Human-readable status message","type":"string","maxLength":128},"partnerReferenceNo":{"description":"Your reference number, echoed back from the request","type":"string","maxLength":64},"originalPartnerReferenceNo":{"description":"Your reference number from the original transaction","type":"string","maxLength":64},"referenceNo":{"type":"string","maxLength":64,"description":"DOKU reference of the original top-up. Voiding does not mint a new reference"},"transactionType":{"description":"Transaction type","type":"string","maxLength":16},"voidAmount":{"type":"object","properties":{"value":{"description":"Amount voided, matching the original top-up exactly","type":"string"},"currency":{"description":"`POINT`","type":"string"}}},"latestTransactionStatus":{"type":"string","description":"05 = Canceled. Specific to this endpoint; other endpoints return 00, 03, 04 or 06"},"transactionStatusDesc":{"description":"Human-readable description of `latestTransactionStatus`","type":"string","maxLength":128},"transactionDate":{"type":"string","format":"date-time","description":"ISO 8601 datetime, with microsecond precision"}}}}}},"400":{"description":"Bad Request — a mandatory field is missing or malformed","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Forbidden. `4034415` covers both cases below — branch on `responseMessage`, not on the code alone.\n","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Original transaction not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}},"callbacks":{"voidTopupNotification":{"https://your-company.example.com/your-callback-path":{"post":{"summary":"Void Topup notification (sent to your server)","description":"After a successful void, DOKU posts this to the notification URL you registered at\nmerchant setup. It is **not** a DOKU endpoint — the URL above is a placeholder for\nyour own server (any host, any path, maximum 64 characters).\n\nThe payload is **smaller than the top-up notification**: it omits `referenceNo`,\n`transactionType`, `toAccount` and `remarks`. `trxDateTime` carries the timestamp of\nthe **original top-up**, not of the void, and the amount is in `amount` (not\n`voidAmount` as in the request above).\n\nDelivery is not instant (~75s observed). Anything other than `200` is retried at\nroughly +30 minutes, +6 hours and +12 hours.\n","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"partnerReferenceNo":{"type":"string","description":"The `partnerReferenceNo` of the void request, not of the original top-up"},"fromAccount":{"type":"string","description":"The sub-account the points are taken back from"},"amount":{"$ref":"#/components/schemas/Amount"},"latestTransactionStatus":{"type":"string","description":"05 = Canceled"},"transactionStatusDesc":{"description":"Human-readable description of `latestTransactionStatus`","type":"string"},"trxDateTime":{"type":"string","format":"date-time","description":"Timestamp of the original top-up, not of the void"}}}}}},"responses":{"200":{"description":"Your server must acknowledge with this response","content":{"application/json":{"schema":{"type":"object","properties":{"responseCode":{"description":"Response status code. `2xxxxxx` indicates success","type":"string"},"responseMessage":{"description":"Human-readable status message","type":"string"}}}}}}}}}}}}}}}
```

{% openapi-webhook spec="sac-v2-all-api" name="topupNotification" method="post" %}
[sac-v2-all-api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/4d18d7817e188a1403b4df9884970c24e6a6f07a4296ee5b65304e11d88534a4.yaml?X-Amz-Algorithm=AWS4-HMAC-SHA256\&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD\&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260918%2Fauto%2Fs3%2Faws4_request\&X-Amz-Date=20260918T170132Z\&X-Amz-Expires=172800\&X-Amz-Signature=63bbbde88252d1f79e6b0158326d7432baacf957c88f319fe1b63cb2991050d5\&X-Amz-SignedHeaders=host\&x-amz-checksum-mode=ENABLED\&x-id=GetObject)
{% endopenapi-webhook %}

{% openapi-webhook spec="sac-v2-all-api" name="registerNotification" method="post" %}
[sac-v2-all-api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/4d18d7817e188a1403b4df9884970c24e6a6f07a4296ee5b65304e11d88534a4.yaml?X-Amz-Algorithm=AWS4-HMAC-SHA256\&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD\&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260918%2Fauto%2Fs3%2Faws4_request\&X-Amz-Date=20260918T170132Z\&X-Amz-Expires=172800\&X-Amz-Signature=63bbbde88252d1f79e6b0158326d7432baacf957c88f319fe1b63cb2991050d5\&X-Amz-SignedHeaders=host\&x-amz-checksum-mode=ENABLED\&x-id=GetObject)
{% endopenapi-webhook %}

{% openapi-webhook spec="sac-v2-all-api" name="transferNotification" method="post" %}
[sac-v2-all-api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/4d18d7817e188a1403b4df9884970c24e6a6f07a4296ee5b65304e11d88534a4.yaml?X-Amz-Algorithm=AWS4-HMAC-SHA256\&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD\&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260918%2Fauto%2Fs3%2Faws4_request\&X-Amz-Date=20260918T170132Z\&X-Amz-Expires=172800\&X-Amz-Signature=63bbbde88252d1f79e6b0158326d7432baacf957c88f319fe1b63cb2991050d5\&X-Amz-SignedHeaders=host\&x-amz-checksum-mode=ENABLED\&x-id=GetObject)
{% endopenapi-webhook %}

{% openapi-webhook spec="sac-v2-all-api" name="debitNotification" method="post" %}
[sac-v2-all-api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/4d18d7817e188a1403b4df9884970c24e6a6f07a4296ee5b65304e11d88534a4.yaml?X-Amz-Algorithm=AWS4-HMAC-SHA256\&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD\&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260918%2Fauto%2Fs3%2Faws4_request\&X-Amz-Date=20260918T170132Z\&X-Amz-Expires=172800\&X-Amz-Signature=63bbbde88252d1f79e6b0158326d7432baacf957c88f319fe1b63cb2991050d5\&X-Amz-SignedHeaders=host\&x-amz-checksum-mode=ENABLED\&x-id=GetObject)
{% endopenapi-webhook %}

{% openapi-webhook spec="sac-v2-all-api" name="debitCancelNotification" method="post" %}
[sac-v2-all-api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/4d18d7817e188a1403b4df9884970c24e6a6f07a4296ee5b65304e11d88534a4.yaml?X-Amz-Algorithm=AWS4-HMAC-SHA256\&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD\&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260918%2Fauto%2Fs3%2Faws4_request\&X-Amz-Date=20260918T170132Z\&X-Amz-Expires=172800\&X-Amz-Signature=63bbbde88252d1f79e6b0158326d7432baacf957c88f319fe1b63cb2991050d5\&X-Amz-SignedHeaders=host\&x-amz-checksum-mode=ENABLED\&x-id=GetObject)
{% endopenapi-webhook %}

{% openapi-webhook spec="sac-v2-all-api" name="voidTopupNotification" method="post" %}
[sac-v2-all-api](https://4401d86825a13bf607936cc3a9f3897a.r2.cloudflarestorage.com/gitbook-x-prod-openapi/raw/4d18d7817e188a1403b4df9884970c24e6a6f07a4296ee5b65304e11d88534a4.yaml?X-Amz-Algorithm=AWS4-HMAC-SHA256\&X-Amz-Content-Sha256=UNSIGNED-PAYLOAD\&X-Amz-Credential=dce48141f43c0191a2ad043a6888781c%2F20260918%2Fauto%2Fs3%2Faws4_request\&X-Amz-Date=20260918T170132Z\&X-Amz-Expires=172800\&X-Amz-Signature=63bbbde88252d1f79e6b0158326d7432baacf957c88f319fe1b63cb2991050d5\&X-Amz-SignedHeaders=host\&x-amz-checksum-mode=ENABLED\&x-id=GetObject)
{% endopenapi-webhook %}
