Download OpenAPI specification:
This API allows merchants to manage users, virtual accounts, deposits, and withdrawals through the CACI Clearing Gateway API.
Key Features:
API Key Authentication:
X-Api-Key headerX-Signature headerX-Timestamp headerTo access the API, your server's outbound IP address must be whitelisted by the CACI team.
401 UnauthorizedTo generate the HMAC-SHA512 signature:
"METHOD|PATH|BODY|TIMESTAMP"import hmac
import hashlib
import json
def generate_signature(method, path, raw_body, timestamp, client_secret):
"""
Generate HMAC-SHA512 signature for CACI API authentication
Args:
method: HTTP method (e.g., 'POST', 'GET')
path: API endpoint path (e.g., '/v1/transactions/fiat')
raw_body: Raw request body JSON string (empty string for GET/DELETE)
timestamp: Unix timestamp in milliseconds
client_secret: Your API secret key
Returns:
Hexadecimal signature string
"""
# Create canonical JSON with sorted keys
if raw_body:
try:
# Parse and re-sort JSON to ensure canonical ordering
body_dict = json.loads(raw_body)
canonical_body = json.dumps(body_dict, sort_keys=True, separators=(',', ':'))
except json.JSONDecodeError:
canonical_body = raw_body
else:
canonical_body = ""
# Build payload
payload = f"{method}|{path}|{canonical_body}|{timestamp}"
# Generate HMAC-SHA512 signature
signature = hmac.new(
client_secret.encode("utf-8"),
payload.encode("utf-8"),
hashlib.sha512
).hexdigest()
return signature
# Example usage
if __name__ == "__main__":
# Sample request data
method = "POST"
path = "/d/v1/users"
timestamp = 1763474667930
client_secret = "your_api_secret_here"
# Sample request body
request_data = {
"requestId": str(uuid.uuid4()),
"userId": str(uuid.uuid4())[:8],
"kycName": "Jhon Doe",
"phone": "+6281234567891",
"email": "jhon.doe@icex.id",
"type": "retail",
"nationality": "ID",
"whitelistedKycNames": [
"Jhon",
"Pg"
]
}
# Convert to canonical JSON
raw_body = json.dumps(request_data, sort_keys=True, separators=(',', ':'))
# Generate signature
signature = generate_signature(method, path, raw_body, timestamp, client_secret)
print(f"Payload: {method}|{path}|{raw_body}|{timestamp}")
print(f"Signature: {signature}")
# Headers to include in request
headers = {
"X-Api-Key": "your_api_key_here",
"X-Signature": signature,
"X-Timestamp": str(timestamp)
}
Create a new merchant user with KYC information and optional whitelisted accounts.
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
| requestId required | string Idempotency key for this request |
| userId required | string Merchant user identifier |
| kycName required | string Legal/KYC name |
| phone | string User phone number with country code |
string User email | |
| type required | string Enum: "institutional" "retail" "other" User type |
| nationality | string ISO country code (2 chars) |
| idType | string Identity document type (optional) |
| idNumber | string Identity document number (optional) |
| whitelistedKycNames | Array of strings Alternate KYC names for verification |
Array of objects (WhitelistedWithdrawalAccount) Whitelisted beneficiary accounts |
{- "requestId": "2dd96e87-4f8f-460e-a04d-040370505552",
- "userId": "567890",
- "kycName": "Jhon Doe",
- "phone": "6281234567890",
- "email": "john.doe@example.com",
- "type": "retail",
- "nationality": "ID",
- "idType": "ktp",
- "idNumber": "1234567890",
- "whitelistedKycNames": [
- "Jhon Doe",
- "Johnny Doe"
], - "whitelistedWithdrawalAccounts": [
- {
- "accountId": "f9f06d65-6bf1-4ded-934a-4dcf0f8f95db",
- "bankCode": "002",
- "accountNumber": "888801000003301",
- "accountHolderName": "Jhon Doe"
}
]
}{- "timestamp": "1772590502",
- "code": 201,
- "message": "success",
- "data": {
- "userId": "567890",
- "createdAt": "2026-03-04T10:00:00Z"
}
}Retrieve detailed information of a specific merchant user.
| userId required | string Example: 1ff159d3 Merchant user identifier |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
{- "code": 200,
- "message": "SUCCESS",
- "timestamp": 1774573934924,
- "data": {
- "userId": "1ff159d3",
- "kycName": "Kucing",
- "phone": "+6281234567810",
- "email": "kucing@example.com",
- "type": "retail",
- "nationality": "ID",
- "idType": "ktp",
- "idNumber": "1234567810",
- "whitelistedKycNames": [
- "Kucing",
- "Liar"
], - "whitelistedWithdrawalAccounts": [
- {
- "accountHolderName": "Jhon Doe",
- "accountId": "f9f06d65-6bf1-4ded-934a-db4dcf0f8f95",
- "accountNumber": "888801000003301",
- "bankCode": "002"
}
], - "createdAt": "2026-03-26T22:13:23.971714Z",
- "updatedAt": "2026-03-26T22:13:23.971714Z"
}
}Update an existing merchant user. The userId path parameter must match the user being updated.
whitelistedWithdrawalAccounts is updated through this endpoint.
| userId required | string Example: 567890 Merchant user identifier |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
| requestId required | string Idempotency key |
| kycName | string |
| phone | string |
string | |
| type | string Enum: "institutional" "retail" "other" |
| nationality | string |
| idType | string |
| idNumber | string |
| whitelistedKycNames | Array of strings |
Array of objects (WhitelistedWithdrawalAccount) |
{- "requestId": "3eeb5958-a2f5-4934-9d8b-26197d104abb",
- "kycName": "Jhon Doe Updated",
- "phone": "6281234567890",
- "email": "john.updated@example.com",
- "type": "retail",
- "nationality": "ID",
- "idType": "ktp",
- "idNumber": "1234567890",
- "whitelistedKycNames": [
- "Jhon Doe",
- "Johnny Doe"
], - "whitelistedWithdrawalAccounts": [
- {
- "accountId": "f9f06d65-6bf1-4ded-934a-4dcf0f8f95db",
- "bankCode": "002",
- "accountNumber": "888801000003301",
- "accountHolderName": "Jhon Doe"
}
]
}{- "code": 200,
- "message": "SUCCESS",
- "reason": "User updated successfully",
- "requestId": "c4b3fa1a-9720-455d-aa23-6a0822b34193",
- "timestamp": 1774573970513
}Soft delete a merchant user.
| userId required | string Example: 567890 Merchant user identifier |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
| requestId required | string Idempotency key |
{- "requestId": "6b0b4af8-07e4-44fe-b4b3-32a410bbfd67"
}{- "code": 200,
- "message": "SUCCESS",
- "reason": "User deleted successfully",
- "timestamp": 1774573995972
}Retrieve all virtual accounts associated with a specific merchant user.
| userId required | string Example: USER001 Merchant user identifier |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
{- "code": 200,
- "message": "SUCCESS",
- "timestamp": 1774563064105,
- "data": [
- {
- "paymentInstrumentId": "019d2c0f-4746-78da-bf6e-9ab6e9bdd53f",
- "userId": "USER001",
- "bankCode": "DURIANPAY",
- "virtualAccountNo": "8808012345678901",
- "virtualAccountName": "Jhon Doe",
- "status": "active",
- "expiredDate": "2027-03-26T21:31:32.034955Z",
- "createdAt": "2026-03-26T21:31:32.034955Z",
- "updatedAt": "2026-03-26T21:31:32.034955Z"
}
]
}Returns payment instruments enabled for the authenticated merchant. Data is grouped by upstream provider so merchants can see provider-specific channel/bank availability.
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
{- "timestamp": 1780908709325,
- "code": 200,
- "message": "SUCCESS",
- "data": [
- {
- "providerCode": "BCA",
- "providerName": "BCA Direct",
- "paymentInstruments": [
- {
- "instrumentType": "virtual_account",
- "bankCode": "014",
- "bankName": "BCA",
- "status": "active"
}
]
}, - {
- "providerCode": "DURIANPAY",
- "providerName": "DurianPay",
- "paymentInstruments": [
- {
- "instrumentType": "bank_transfer",
- "bankCode": "014",
- "bankName": "BCA",
- "status": "active"
}, - {
- "instrumentType": "bank_transfer",
- "bankCode": "008",
- "bankName": "MANDIRI",
- "status": "active"
}
]
}
]
}Create a new virtual account for a merchant user. This operation is synchronous.
Currently supported banks:
002: BRI (Bank Rakyat Indonesia)014: BCA (Bank Central Asia)503: NOBU (Bank Nationalnobu)| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
| requestId required | string Idempotency key |
| userId required | string User to bind VA to |
| bankCode required | string Destination VA bank/channel code (BI SNAP) |
{- "requestId": "5520ef9c-e671-4c50-821d-9c9d787a5578",
- "userId": "c28f03f8",
- "bankCode": "503"
}{- "code": 200,
- "message": "SUCCESS",
- "requestId": "5520ef9c-e671-4c50-821d-9c9d787a5578",
- "timestamp": 1774723700223,
- "data": {
- "paymentInstrumentId": "019d35af-3233-7218-9135-170365519896",
- "userId": "c28f03f8",
- "bankCode": "NOBU",
- "virtualAccountNo": "662312136281234",
- "virtualAccountName": "Jhon Doe",
- "customerNo": "6281234",
- "status": "active",
- "createdAt": "2026-03-28T18:22:47.347088Z",
- "updatedAt": "2026-03-28T18:22:47.347088Z"
}
}Retrieve details of a specific virtual account by its payment instrument ID.
| paymentInstrumentId required | string <uuid> Example: 019d35af-3233-7218-9135-170365519896 Payment instrument identifier |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
{- "code": 200,
- "message": "SUCCESS",
- "timestamp": 1774726455840,
- "data": {
- "paymentInstrumentId": "019d35af-3233-7218-9135-170365519896",
- "merchantId": "019d2c0f-472e-755e-8c27-f2971ea622f6",
- "userId": "c28f03f8",
- "bankCode": "NOBU",
- "virtualAccountNo": "662312136281234",
- "virtualAccountName": "Jhon Doe",
- "status": "active",
- "expiresAt": "2099-12-31T23:59:59Z",
- "createdAt": "2026-03-28T18:22:47.347088Z",
- "updatedAt": "2026-03-28T18:22:47.347088Z"
}
}Update an existing virtual account. This operation is synchronous.
| paymentInstrumentId required | string <uuid> Example: 019d35af-3233-7218-9135-170365519896 Payment instrument identifier |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
| requestId required | string Idempotency key |
| virtualAccountName | string New display name |
| expiredDate | string <date-time> New expiration timestamp |
{- "requestId": "60a59117-5138-4cc0-ae39-babb832021ec",
- "virtualAccountName": "Jhon Doe Updated",
- "expiredDate": "2099-12-31T23:59:59Z"
}{- "code": 200,
- "message": "SUCCESS",
- "requestId": "0c2d5982-ea8c-482d-99f9-b8929fec479d",
- "timestamp": 1774755401625,
- "data": {
- "paymentInstrumentId": "019d35af-3233-7218-9135-170365519896",
- "status": "active"
}
}Create a new withdrawal request. This operation is asynchronous.
Use GET /v1/withdrawals/{transactionId} or merchant webhook to track final status.
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
| requestId required | string Idempotency key |
| userId required | string Merchant user identifier |
| merchantReference required | string Merchant transaction reference |
| beneficiaryBankCode required | string Beneficiary bank code (BI SNAP) |
| beneficiaryAccountNo required | string Beneficiary account number |
| beneficiaryAccountName | string Beneficiary account holder name |
| amount required | string Transfer amount (decimal string) |
| merchantFee | string Merchant fee override/echo for reporting to clearing |
{- "requestId": "2dd96e87-4f8f-460e-a04d-040370505552",
- "userId": "567890",
- "merchantReference": "111111111",
- "beneficiaryBankCode": "002",
- "beneficiaryAccountNo": "888801000003301",
- "beneficiaryAccountName": "Jhon Doe",
- "amount": "20000.00",
- "merchantFee": "5000.00"
}{- "timestamp": "1772590502",
- "code": 201,
- "message": "success",
- "data": {
- "transactionId": "2f1cf3d6-65db-447e-b68c-434efbf72479",
- "requestId": "2dd96e87-4f8f-460e-a04d-040370505552",
- "merchantReference": "111111111",
- "status": "pending"
}
}List withdrawal transactions with optional filters and pagination.
| userId | string Filter by merchant user |
| status | string Filter by transaction status |
| startDate | string <date-time> Lower bound for requested_at (RFC3339). Max range 90 days. Defaults to 90 days before now. |
| endDate | string <date-time> Upper bound for requested_at (RFC3339). Max range 90 days. Defaults to current time. |
| trxDateTimeStart | string <date-time> Lower bound for trx_date_time (RFC3339) |
| trxDateTimeEnd | string <date-time> Upper bound for trx_date_time (RFC3339) |
| limit | integer Default: 100 Page size for pagination |
| offset | integer Default: 0 Offset for pagination |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
{- "code": 200,
- "message": "SUCCESS",
- "timestamp": 1777024486560,
- "data": {
- "items": [
- {
- "transactionId": "a1b2c3d4-1111-7000-aaaa-000000000001",
- "transactionType": "withdrawal",
- "userId": "usr00001",
- "merchantId": "d4e5f6a7-4444-7000-dddd-000000000001",
- "merchantReference": "wd-ref-20260424-001",
- "bankReference": "bri",
- "paymentInstrumentId": "e5f6a7b8-5555-7000-eeee-000000000001",
- "amount": "20000.00",
- "currency": "IDR",
- "merchantBankFee": "0",
- "merchantFee": "3000.00",
- "merchantFeeCalcMethod": "inclusive",
- "transactionFee": "3000.00",
- "netAmount": "17000.00",
- "status": "pending",
- "details": {
- "beneficiaryAccountName": "Jane Doe",
- "beneficiaryAccountNo": "888801000009001",
- "beneficiaryBankCode": "002"
}, - "requestedAt": "2026-04-24T09:00:00Z",
- "createdAt": "2026-04-24T09:00:00Z",
- "updatedAt": "2026-04-24T09:00:00Z"
}, - {
- "transactionId": "a1b2c3d4-1111-7000-aaaa-000000000002",
- "transactionType": "withdrawal",
- "userId": "usr00001",
- "merchantId": "d4e5f6a7-4444-7000-dddd-000000000001",
- "merchantReference": "wd-ref-20260424-002",
- "bankReference": "bri",
- "paymentInstrumentId": "e5f6a7b8-5555-7000-eeee-000000000001",
- "amount": "50000.00",
- "currency": "IDR",
- "merchantBankFee": "0",
- "merchantFee": "3000.00",
- "merchantFeeCalcMethod": "inclusive",
- "transactionFee": "3000.00",
- "netAmount": "47000.00",
- "status": "completed",
- "details": {
- "beneficiaryAccountName": "Jane Doe",
- "beneficiaryAccountNo": "888801000009001",
- "beneficiaryBankCode": "002"
}, - "requestedAt": "2026-04-24T08:00:00Z",
- "processedAt": "2026-04-24T08:01:30Z",
- "createdAt": "2026-04-24T08:00:00Z",
- "updatedAt": "2026-04-24T08:01:30Z"
}
], - "limit": 10,
- "offset": 0,
- "totalItems": 2
}
}Retrieve details of a specific withdrawal transaction.
| transactionId required | string <uuid> Example: 019d6638-6b62-7130-b90c-e4d1583f9597 Transaction identifier |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
{- "code": 200,
- "message": "SUCCESS",
- "timestamp": 1777025165108,
- "data": {
- "amount": "50000.00",
- "bankReference": "bri",
- "createdAt": "2026-04-24T08:00:00Z",
- "currency": "IDR",
- "details": {
- "beneficiaryAccountName": "Jane Doe",
- "beneficiaryAccountNo": "888801000009001",
- "beneficiaryBankCode": "002"
}, - "merchantBankFee": "0",
- "merchantFee": "3000.00",
- "merchantFeeCalcMethod": "inclusive",
- "merchantId": "d4e5f6a7-4444-7000-dddd-000000000001",
- "merchantReference": "wd-ref-20260424-002",
- "netAmount": "47000.00",
- "paymentInstrumentId": "e5f6a7b8-5555-7000-eeee-000000000001",
- "requestId": "c3d4e5f6-3333-7000-cccc-000000000002",
- "requestedAt": "2026-04-24T08:00:00Z",
- "status": "completed",
- "transactionFee": "3000.00",
- "transactionId": "a1b2c3d4-1111-7000-aaaa-000000000002",
- "transactionType": "withdrawal",
- "processedAt": "2026-04-24T08:01:30Z",
- "updatedAt": "2026-04-24T08:01:30Z",
- "userId": "usr00001"
}
}List deposit transactions with optional filters and pagination.
| status | string Filter by transaction status |
| userId | string Filter by merchant user |
| startDate | string <date-time> Lower bound for requested_at (RFC3339). Max range 90 days. Defaults to 90 days before now. |
| endDate | string <date-time> Upper bound for requested_at (RFC3339). Max range 90 days. Defaults to current time. |
| trxDateTimeStart | string <date-time> Lower bound for trx_date_time (RFC3339) |
| trxDateTimeEnd | string <date-time> Upper bound for trx_date_time (RFC3339) |
| limit | integer Default: 100 Page size for pagination |
| offset | integer Default: 0 Offset for pagination |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
{- "code": 200,
- "message": "SUCCESS",
- "timestamp": 1777025342784,
- "data": {
- "items": [
- {
- "amount": "40000.00",
- "bankReference": "d1d0fe7e-9ef0-4c9d-9b82-000000000001",
- "createdAt": "2026-04-24T08:00:00Z",
- "currency": "IDR",
- "details": {
- "beneficiaryAccountName": "Jane Doe",
- "beneficiaryAccountNo": "88082676740001",
- "beneficiaryBankCode": "014"
}, - "merchantBankFee": "0",
- "merchantFee": "0",
- "merchantFeeCalcMethod": "inclusive",
- "merchantId": "d4e5f6a7-4444-7000-dddd-000000000001",
- "merchantReference": "dep-ref-20260424-001",
- "netAmount": "40000.00",
- "paymentInstrumentId": "e5f6a7b8-5555-7000-eeee-000000000001",
- "processedAt": "2026-04-24T08:00:02Z",
- "requestedAt": "2026-04-24T08:00:00Z",
- "status": "completed",
- "transactionFee": "0",
- "transactionId": "a1b2c3d4-1111-7000-aaaa-000000000001",
- "transactionType": "deposit",
- "updatedAt": "2026-04-24T08:00:02Z",
- "userId": "usr00002"
}, - {
- "amount": "12000.00",
- "bankReference": "e9b7803f-415f-48ea-a507-000000000002",
- "createdAt": "2026-04-24T07:30:00Z",
- "currency": "IDR",
- "details": {
- "beneficiaryAccountName": "John Smith",
- "beneficiaryAccountNo": "123617001460000001",
- "beneficiaryBankCode": "002"
}, - "merchantBankFee": "0",
- "merchantFee": "0",
- "merchantFeeCalcMethod": "inclusive",
- "merchantId": "d4e5f6a7-4444-7000-dddd-000000000001",
- "merchantReference": "dep-ref-20260424-002",
- "netAmount": "12000.00",
- "paymentInstrumentId": "e5f6a7b8-5555-7000-eeee-000000000002",
- "processedAt": "2026-04-24T07:30:02Z",
- "requestedAt": "2026-04-24T07:30:00Z",
- "status": "completed",
- "transactionFee": "0",
- "transactionId": "a1b2c3d4-1111-7000-aaaa-000000000002",
- "transactionType": "deposit",
- "updatedAt": "2026-04-24T07:30:02Z",
- "userId": "usr00003"
}
], - "limit": 10,
- "offset": 0,
- "totalItems": 2
}
}Retrieve details of a specific deposit transaction by its CACI transaction ID (transactionId / caciTxId).
| transactionId required | string <uuid> Example: 019d6638-6b62-7130-b90c-e4d1583f9597 Transaction identifier |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
{- "code": 200,
- "message": "SUCCESS",
- "timestamp": 1777025342784,
- "data": {
- "amount": "40000.00",
- "bankReference": "d1d0fe7e-9ef0-4c9d-9b82-000000000001",
- "createdAt": "2026-04-24T08:00:00Z",
- "currency": "IDR",
- "details": {
- "beneficiaryAccountName": "Jane Doe",
- "beneficiaryAccountNo": "88082676740001",
- "beneficiaryBankCode": "014"
}, - "merchantBankFee": "0",
- "merchantFee": "0",
- "merchantFeeCalcMethod": "inclusive",
- "merchantId": "d4e5f6a7-4444-7000-dddd-000000000001",
- "merchantReference": "dep-ref-20260424-001",
- "netAmount": "40000.00",
- "paymentInstrumentId": "e5f6a7b8-5555-7000-eeee-000000000001",
- "processedAt": "2026-04-24T08:00:02Z",
- "requestedAt": "2026-04-24T08:00:00Z",
- "status": "completed",
- "transactionFee": "0",
- "transactionId": "a1b2c3d4-1111-7000-aaaa-000000000001",
- "transactionType": "deposit",
- "updatedAt": "2026-04-24T08:00:02Z",
- "userId": "usr00002"
}
}Retrieve the merchant's current balances grouped by provider and vault type.
Each provider entry contains one or more balance records — typically a deposit vault
and a withdrawal vault — representing the available funds for each operation type.
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
{- "code": 200,
- "message": "SUCCESS",
- "timestamp": 1779722046088,
- "requestId": "006b6c7b-f11d-4a6e-ab26-cadc9b53c942",
- "data": [
- {
- "providerName": "DurianPay",
- "providerType": "payment_gateway",
- "balances": [
- {
- "balance": "9999",
- "vaultType": "deposit"
}, - {
- "balance": "19995",
- "vaultType": "withdrawal"
}
]
}
]
}After a transaction is processed, the platform asynchronously POSTs a JSON payload to all webhook URLs the merchant has configured for that event type. Delivery runs in a background goroutine and never blocks the transaction response.
Transaction Processed
│
▼
Payload enriched from DB (VA info, user info)
│
▼
POST to each configured webhook URL
│
▼
WebhookLog stored in Redis
key: webhook:log:<transactionId> | TTL: 24h
| Event Type | Triggered When |
|---|---|
va_payment |
A deposit is successfully processed |
transfer |
A withdrawal status is updated |
Treat every webhook as a signal, not as proof. A webhook payload is delivered to your URL and must not be trusted on its own. After receiving a notification, your server must call the corresponding read API to confirm the transaction's authoritative status before crediting funds, releasing goods, or settling:
| Event | Confirm with | Lookup key |
|---|---|---|
va_payment (deposit) |
GET /v1/deposits/{transactionId} |
additionalInfo.caciTxId |
transfer (withdrawal) |
GET /v1/withdrawals/{transactionId} |
additionalInfo.caciTxId |
Act only on the status returned by these endpoints — not on the webhook body. This protects you against
forged or replayed notifications, since the read API is authenticated and returns CACI's source-of-truth record.
Always dedupe on caciTxId or paymentRequestId so a repeated notification never credits the same transaction twice.
POSTapplication/jsonCACI-PG-Webhook/1.0200 or 201 response from the merchant endpoint.Webhook requests will originate from the following IPs. Whitelist these on your server to ensure delivery:
| Environment | IP Address |
|---|---|
| Production | 15.233.128.42 |
| Staging | 16.78.217.189 |
va_payment{
"partnerServiceId": "merchant-uuid",
"customerNo": "merchant-user-id",
"virtualAccountNo": "1234567890",
"trxId": "tx-uuid",
"paymentRequestId": "tx-uuid",
"paidAmount": {
"value": "100000",
"currency": "IDR"
},
"trxDateTime": "2025-01-01T10:00:00Z",
"virtualAccountName": "John Doe",
"virtualAccountType": "01",
"virtualAccountPhone": "+62812345678",
"virtualAccountEmail": "john@example.com",
"additionalInfo": {
"minAmount": 0,
"maxAmount": 10000000,
"bankCode": "BCA",
"customerInfo": {
"customer_id": "internal-user-uuid",
"customer_ref_id": "merchant-user-ref",
"given_name": "John Doe",
"email": "john@example.com",
"mobile": "+62812345678"
},
"expiredDate": "2025-01-02T00:00:00Z",
"failureReason": null,
"merchantUserId": "merchant-user-ref",
"caciTxId": "tx-uuid"
}
}
| Field | Description |
|---|---|
partnerServiceId |
Merchant UUID (falls back to merchant ID) |
customerNo |
Merchant-side user reference |
virtualAccountNo |
VA number that received the payment |
trxId |
Internal transaction ID |
paymentRequestId |
Unique identifier for this specific payment from upstream bank or provider. |
paidAmount.value |
Amount as a string |
paidAmount.currency |
e.g. IDR |
trxDateTime |
Timestamp from the provider; falls back to processedAt |
additionalInfo.bankCode |
Bank code of the VA (e.g. BCA, BNI) |
additionalInfo.caciTxId |
Unique identifier for this specific transaction from CACI. Use this for deduplication / idempotency and to verify notifications |
additionalInfo.merchantUserId |
Merchant's user reference |
additionalInfo.customerInfo |
KYC/user details resolved from the user record |
additionalInfo.failureReason |
Populated on failed payments; null on success |
transfer{
"originalReferenceNo": "provider-reference-number",
"originalPartnerReferenceNo": "merchant-reference",
"responseCode": "00",
"responseMessage": "Success",
"amount": {
"value": "500000",
"currency": "IDR"
},
"paymentInstrumentId": "pi-uuid",
"beneficiaryAccountNo": "0987654321",
"beneficiaryBankCode": "BNI",
"sourceAccountNo": "source-account-number",
"additionalInfo": {
"merchantUserId": "merchant-user-ref",
"caciTxId": "tx-uuid"
}
}
| Field | Description |
|---|---|
originalReferenceNo |
Provider's reference number for the transfer |
originalPartnerReferenceNo |
Merchant's own reference number |
responseCode |
Provider response code |
responseMessage |
Provider response message |
amount.value |
Transfer amount as a string |
beneficiaryAccountNo |
Destination account number |
beneficiaryBankCode |
Destination bank code |
paymentInstrumentId |
Payment instrument UUID |
additionalInfo.caciTxId |
Unique identifier for this specific transaction from CACI. Use this for deduplication / idempotency and to verify notifications |
additionalInfo.merchantUserId |
Merchant's user reference |
Merchants register endpoint URLs via the endpoints below. A merchant may register multiple URLs for the same event type — the platform delivers to all of them.
Register a new merchant webhook for a specific event type.
Event types:
va_payment: Triggered on deposit (virtual account payment) eventstransfer: Triggered on withdrawal events| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
| requestId required | string Idempotency key for this request |
| eventType required | string Enum: "va_payment" "transfer" "qr_payment" "debit_notify" Event type to subscribe to |
| url required | string Valid HTTPS webhook destination URL |
| headers | object Custom headers sent with every delivery |
| isActive | boolean Whether the webhook should be active. Defaults to |
| description | string Free-text label for this webhook |
{- "requestId": "2dd96e87-4f8f-460e-a04d-040370505552",
- "eventType": "va_payment",
- "headers": {
- "X-Api-Key": "your-secret"
}, - "isActive": true,
- "description": "Production deposit handler"
}{- "timestamp": 1776758146948,
- "code": 201,
- "message": "SUCCESS",
- "data": {
- "id": "754cdea6-2acd-4f11-b986-dc4276525940",
- "merchantId": "019d85d9-58e9-7995-869b-d2b0f4a016e8",
- "eventType": "va_payment",
- "headers": { },
- "isActive": true,
- "description": "",
- "createdAt": "2026-04-21T07:55:46.949308Z",
- "updatedAt": "2026-04-21T07:55:46.949308Z"
}
}Retrieve all webhooks configured for the authenticated merchant.
Event types:
va_payment: Triggered on deposit (virtual account payment) eventstransfer: Triggered on withdrawal events| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
{- "timestamp": 1776758536186,
- "code": 200,
- "message": "SUCCESS",
- "data": [
- {
- "id": "717bf9b3-e8f2-4bf7-82fa-00a6bdaa7514",
- "merchantId": "019d85d9-58e9-7995-869b-d2b0f4a016e8",
- "eventType": "transfer",
- "headers": { },
- "isActive": true,
- "description": "",
- "createdAt": "2026-04-21T08:01:32.080907Z",
- "updatedAt": "2026-04-21T08:01:32.080907Z"
}, - {
- "id": "754cdea6-2acd-4f11-b986-dc4276525940",
- "merchantId": "019d85d9-58e9-7995-869b-d2b0f4a016e8",
- "eventType": "va_payment",
- "headers": { },
- "isActive": true,
- "description": "",
- "createdAt": "2026-04-21T07:55:46.949308Z",
- "updatedAt": "2026-04-21T07:55:46.949308Z"
}
]
}Update an existing merchant webhook configuration.
Note:
eventTypecannot be changed after creation.
| webhookId required | string <uuid> Example: 717bf9b3-e8f2-4bf7-82fa-00a6bdaa7514 Webhook identifier |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
| requestId required | string Idempotency key |
| url | string New webhook destination URL |
| headers | object Custom headers sent with every delivery |
| isActive | boolean Whether the webhook should be active |
| description | string Free-text label |
{- "requestId": "3eeb5958-a2f5-4934-9d8b-26197d104abb",
- "headers": { },
- "isActive": false,
- "description": "Disabled"
}{- "timestamp": 1776759221472,
- "code": 200,
- "message": "SUCCESS",
- "data": {
- "id": "717bf9b3-e8f2-4bf7-82fa-00a6bdaa7514",
- "merchantId": "019d85d9-58e9-7995-869b-d2b0f4a016e8",
- "eventType": "transfer",
- "headers": { },
- "isActive": true,
- "description": "Testing. . . .",
- "createdAt": "2026-04-21T08:01:32.080907Z",
- "updatedAt": "2026-04-21T08:13:41.47397Z"
}
}Delete an existing merchant webhook.
Event types:
va_payment: Triggered on deposit (virtual account payment) eventstransfer: Triggered on withdrawal events| webhookId required | string <uuid> Example: 717bf9b3-e8f2-4bf7-82fa-00a6bdaa7514 Webhook identifier |
| X-Api-Key required | string Example: your-api-key Merchant API key |
| X-Signature required | string Example: a1b2c3d4e5f6... HMAC-SHA512 signature of METHOD|PATH|BODY|TIMESTAMP |
| X-Timestamp required | string Example: 1774723700223 Unix timestamp in milliseconds |
| requestId required | string Idempotency key |
{- "requestId": "6b0b4af8-07e4-44fe-b4b3-32a410bbfd67"
}{- "timestamp": 1776759320167,
- "code": 200,
- "message": "SUCCESS"
}Retry webhook delivery for a specific transaction.
| requestId required | string Idempotency key |
| transactionId required | string Transaction identifier to retry webhook for |
{- "requestId": "df4d98f2-243f-4fba-8146-7102f0d21312",
- "transactionId": "019db014-af95-7294-8116-dee5285086e3"
}{- "timestamp": 1776775674878,
- "requestId": "df4d98f2-243f-4fba-8146-7102f0d21312",
- "code": 200,
- "message": "SUCCESS",
- "data": {
- "transactionId": "019db014-af95-7294-8116-dee5285086e3",
- "status": "success",
- "attempts": 1
}
}Payment simulation endpoints for non-production environments only.
Prerequisites: Before simulating a deposit, you must complete the following steps:
POST /v1/usersPOST /v1/virtual-accountsYou can also test deposits via the UI at: https://sandbox-simulator.caci.id
Looks up a virtual account by account number and bank code, returning the VA details. Used to verify a VA exists before simulating a payment.
Non-production environments only. This endpoint is disabled in production.
| virtualAccountNo required | string Virtual account number to look up |
| bankCode required | string VA bank code — accepts BI SNAP numeric codes or provider codes |
{- "virtualAccountNo": "662312136281234",
- "bankCode": "503"
}{- "timestamp": 1774723700223,
- "code": 200,
- "message": "SUCCESS",
- "data": {
- "bankCode": "503",
- "virtualAccountNo": "662312136281234",
- "virtualAccountName": "John Doe"
}
}Simulates an inbound deposit payment to a virtual account. Creates a completed deposit transaction and triggers the configured merchant webhook.
Non-production environments only. This endpoint is disabled in production.
| virtualAccountNo required | string Virtual account number to receive the payment |
| bankCode required | string VA bank code — accepts BI SNAP numeric codes (e.g. "014" for BCA, "503" for NOBU) or provider codes (e.g. "BCA", "NOBU") |
required | object |
{- "virtualAccountNo": "662312136281234",
- "bankCode": "503",
- "payment": {
- "amount": "20000.00",
- "currency": "IDR"
}
}{- "timestamp": 1774723700223,
- "code": 201,
- "message": "SUCCESS",
- "transactionId": "2f1cf3d6-65db-447e-b68c-434efbf72479"
}GET /v1/deposits/{transactionId} endpoint to retrieve a single deposit by its CACI transaction IDpaymentRequestId and additionalInfo.caciTxId field descriptions; caciTxId is the recommended key for deduplication / idempotency and notification verificationGET /v1/balances endpoint to retrieve merchant balances per provider and vault type15.233.128.42, Staging 16.78.217.189Create Virtual Account and Update Virtual Account endpoint summaries