Skip to main content

CHIP Send API

The CHIP Send API enables merchants to send funds programmatically via a REST API and to register recipient bank accounts for payouts. All endpoints share a single base URL and a single authentication scheme. This page covers everything required to make a successful request.

Endpoints

The base URL must match the merchant’s environment:
EnvironmentBase URL
Staginghttps://staging-api.chip-in.asia/api/v1
Productionhttps://api.chip-in.asia/api/v1
The operation path from the API reference (for example /send/accounts or /send/send_instructions) is appended to the base URL.

Prerequisites

Before integration begins, a CHIP Send account must be created for the merchant by the CHIP admin team. To obtain credentials, the merchant’s CHIP Account Manager must be contacted with the following information:
  1. A primary email address.
  2. The email addresses of every required approver. If two approvals are required, both email addresses must be provided.

Credentials

Two pieces of information are issued to the merchant:
CredentialWhere it goesWhat it does
API KeyAuthorization: Bearer <API Key> headerIdentifies the merchant’s account. Sent on every request.
API SecretNever sent over the network. Used only for signing.Used to compute the per-request checksum. Must be stored securely, like a password.
The API Key and the api_key value used inside the checksum string are the same value. The API Secret is never transmitted in any request. It only ever lives on the merchant’s server and is used to compute the checksum described below. Both the API Key and the API Secret are available to the merchant in the CHIP Control → Settings → Applications page of the merchant portal.

How authentication works

Every request to the CHIP Send API must include three headers:
HeaderValue
AuthorizationBearer <API Key>
epochThe current Unix timestamp in seconds (for example, 1689826456)
checksumHex-encoded HMAC-SHA512 of the signing string, computed with the API Secret
The epoch value must be within 30 seconds of the server’s clock. If it is too old or too far in the future, the request is rejected as Unauthorized. The merchant’s server clock must therefore be synchronised (for example via NTP).

How to compute the checksum

The signing string is formed by concatenating the epoch value and the API Key with no separator, in that order:
signing_string = <epoch> + <API Key>
For example, with epoch = 1689826456 and API Key = e0645c9e-fcf2-4f29-a327-202f7ed3d969:
1689826456e0645c9e-fcf2-4f29-a327-202f7ed3d969
The checksum is then computed as:
checksum = HEX( HMAC_SHA512( key = API Secret, message = signing_string ) )
Given API Secret = a118729e-4243-4145-83b3-0b8cb213fe8e, the checksum for the example signing string above is:
45bee62dba8087ab1e7e767d92f8d6e26f8bd19ee5fd2fef6386bb9425976498a86ffdbddb7a49919998e993c20626196ea652320f438a9528d2b8c9d19ec266
This expected value can be used to verify the implementation before any real request is sent.

A complete request

The following curl example computes the epoch and checksum, then sends a request end-to-end:
# 1. Compute the epoch and checksum (must be recomputed for every request)
EPOCH=$(date +%s)
API_KEY="e0645c9e-fcf2-4f29-a327-202f7ed3d969"
API_SECRET="a118729e-4243-4145-83b3-0b8cb213fe8e"
CHECKSUM=$(printf '%s%s' "$EPOCH" "$API_KEY" | openssl dgst -sha512 -hmac "$API_SECRET" -hex | sed 's/^.*= //')

# 2. Send the request
curl -X POST "https://staging-api.chip-in.asia/api/v1/send/bank_accounts" \
  -H "Authorization: Bearer $API_KEY" \
  -H "epoch: $EPOCH" \
  -H "checksum: $CHECKSUM" \
  -H "Content-Type: application/json" \
  -d '{
    "account_number": "157380112229",
    "bank_code": "MBBEMYKL",
    "name": "Ahmad Razali",
    "reference": "VENDOR-EMP-001"
  }'
A 200 OK response confirms that authentication is working correctly. For other responses, see Troubleshooting below.

Language examples

The same computation in four common languages:
const crypto = require('crypto');

const epoch = Math.floor(Date.now() / 1000).toString();
const apiKey = process.env.CHIP_API_KEY;
const apiSecret = process.env.CHIP_API_SECRET;

const signingString = epoch + apiKey;
const checksum = crypto
  .createHmac('sha512', apiSecret)
  .update(signingString)
  .digest('hex');

// Then send the request with headers:
//   Authorization: Bearer <apiKey>
//   epoch: <epoch>
//   checksum: <checksum>

Troubleshooting

SymptomMost likely cause
401 Unauthorized with no further detailThe epoch value is more than 30 seconds off the server clock, or the merchant’s server clock is incorrect. NTP synchronisation should be verified.
401 Unauthorized with a checksum-related errorThe signing string is wrong. The following should be verified: (a) it is <epoch> + <apiKey> with no separator, (b) the message is the string (not a JSON object), (c) the output is hex-encoded (not base64), (d) SHA-512 is used (not SHA-256).
401 Unauthorized with an Authorization-related errorThe Authorization: Bearer <API Key> header is missing, malformed, or the API Key is invalid.
400 Bad Request on a syntactically valid payloadThe epoch or checksum header is missing, or one of the values contains an unexpected character.
A request works in Postman but fails from the merchant’s codeThe checksum is being computed once and reused across requests. The checksum must be recomputed for every request with a fresh epoch.

Basic integration flow

A complete payout consists of four steps:
  1. The Accounts API is called to check the convertible balance.
  2. The Increase Send Limit API is called to allocate balance for payouts.
  3. The Add Bank Account API is called to register a recipient.
  4. The Create Send Instruction API is called to send funds.
A walkthrough is provided in Test Integration.

Approving CHIP Send Budget Allocation requests

Every approver receives an email when a budget-allocation request requires approval. Approval is performed by clicking the Approve button in the email. Once all required approvers have approved, the new balance is reflected in the Accounts API response. The token used in the Authorization header is the API Key mentioned in the Credentials section above.