All API changes for the CAMP Connect API, consolidated from individual changelog entries.| Date | Key Changes |
|---|
| 2026-07-17 | Merchant Activation APIs |
| 2026-07-07 | Crypto Checkout & Refund v2.0 (16 new APIs) |
| 2026-06-16 | Modified APIs |
| 2026-06-12 | Fee Estimate, Address Validation |
| 2026-06-02 | Statements, Points APIs |
| 2026-04-02 | Initial v2.0 release (73 APIs) |
20260402#
Executive Summary#
| Status | Count | Note |
|---|
| New APIs | 0 | - |
| Deleted APIs | 1 | Fully removed |
| Modified APIs | 39 | With field-level changes |
| Unchanged APIs | 33 | No modifications |
| Total APIs (v2.0) | 73 | |
Detailed API Changes#
The following sections detail all field-level modifications, organized by functional category.Authentication#
Create Token#
Path: /v1.0/oauth/token → /v2.0/oauth/token
Method: POSTDescription: Client's Secret
Description: Client's Secret
Description: Access token
Description: Token expiry time
not-before-policy (Deleted)Description: A timestamp before which tokens are considered invalid
refresh_expires_in (Deleted)Description: Time in seconds until the token expiry is refreshed
Description: Scope included in the token
Description: Access token
Description: Token expiry time
Account Management#
Get Balance#
Path: /v1.0/ledger/account → /v2.0/ledger/account
Method: GETGet Internal Transfer#
Path: /v1.0/payment/account/getInternalTransfer → /v2.0/payment/account/getInternalTransfer
Method: GETDescription Change:
Old: Transfer transaction time
New: Transfer transaction time (Unix timestamp in milliseconds)
Internal Transfer#
Path: /v1.0/payment/account/internalTransfer → /v2.0/payment/account/internalTransfer
Method: POSTDescription Change:
Old: Transfer transaction time
New: Transfer transaction time (Unix timestamp in milliseconds)
Merchant Management#
Create Merchant#
Path: /v2.0/crm/addressBook/createMerchant
Method: POSTDescription Change:
Old:
New: Phone number for contact, country code + Number. eg, +65 87654321
Description Change:
Old: Date of birth (UTC format)
New: Date of birth, format: YYYY-MM-DD, e.g., 1990-05-15
Description Change:
Old:
New: The country of tax residency (Country Code in ISO 3166-1 alpha-2 format)
Description Change:
Old: Date of Incoporation
New: Date of Incoporation, format: YYYY-MM-DD, e.g., 1990-05-15
Description Change:
Old:
New: Phone number for contact, country code + Number. eg, +65 87654321
Description Change:
Old: Date of birth (UTC format)
New: Date of birth, format: YYYY-MM-DD, e.g., 1990-05-15
Description Change:
Old:
New: The country of tax residency (Country Code in ISO 3166-1 alpha-2 format)
Description Change:
Old: Date of Incoporation
New: Date of Incoporation, format: YYYY-MM-DD, e.g., 1990-05-15
Description Change:
Old: Current status of the application
New: Current status of the application Enum values: - 1: PROCESSING - 2: APPROVED - 3: REJECTED
Get Merchant#
Path: /v2.0/crm/addressBook/getMerchant
Method: GETDescription Change:
Old:
New: Phone number for contact, country code + Number. eg, +65 87654321
Description Change:
Old: Date of birth (UTC format)
New: Date of birth, format: YYYY-MM-DD, e.g., 1990-05-15
Description Change:
Old:
New: The country of tax residency (Country Code in ISO 3166-1 alpha-2 format)
Description Change:
Old: Date of Incoporation
New: Date of Incoporation, format: YYYY-MM-DD, e.g., 1990-05-15
Description Change:
Old: Merchant status
New: Merchant status Enum values: - 1: PROCESSING - 2: APPROVED - 3: REJECTED
Fiat Payment#
Fiat Deposit#
Get Deposit Bank Account#
Path: /v1.0/crm/deposit/bankAccount → /v2.0/crm/deposit/bankAccount
Method: GETGet Fiat Deposit Detail#
Path: /v1.0/payment/fiat/deposit/detail → /v2.0/payment/fiat/deposit/detail
Method: GETDescription Change:
Old: Timestamp of deposit transaction, ISO-8601
New: Timestamp of deposit transaction (Unix timestamp in milliseconds)
Get Fiat Deposit History#
Path: /v1.0/payment/fiat/deposit/history → /v2.0/payment/fiat/deposit/history
Method: GETDescription Change:
Old:
New: Unix timestamp in milliseconds
Description Change:
Old:
New: Unix timestamp in milliseconds
Description Change:
Old: Timestamp of deposit transaction, ISO-8601
New: Timestamp of deposit transaction (Unix timestamp in milliseconds)
Fiat Payment#
Fiat Account Management#
Add Bank Account#
Path: /v1.0/crm/addressBook/addBankAccount → /v2.0/crm/addressBook/addBankAccount
Method: POSTGet Bank Accounts#
Path: /v1.0/crm/addressBook/bankAccount → /v2.0/crm/addressBook/bankAccount
Method: GETGet Fiat Account Application Status#
Path: /v2.0/crm/fiatAccount/appStatus
Method: GETDescription Change:
Old: Status of the request
New: Status of the request Enum values: - 1: PENDING - 2: PROCESSING - 3: ACTIVE - 4: REJECTED
Path: /v2.0/crm/fiatAccount/addInfo/submit
Method: POSTDescription Change:
Old: Status of the request
New: Status of the request Enum values: - 1: PENDING - 2: PROCESSING - 3: ACTIVE - 4: REJECTED
Description Change:
Old: Timestamp of update, UNIX timestamp in milliseconds (e.g., 1715000000000)
New: Timestamp of update, UNIX timestamp in milliseconds (e.g., 1715000000000)
Fiat Payment#
Fiat Withdrawal#
Create Fiat Withdrawal#
Path: /v2.0/payment/fiat/createWithdrawal
Method: POSTDescription Change:
Old: First or third party withdrawal
New: First or third party withdrawal Enum values: - 1: First Party - 2: Third Party
estimatedAmountReceivable Description Change:
Old: Missing fields for the withdrawal request. Ref. to {} for details
New: Missing fields
Description Change:
Old: Withdrawal status. Possible values: 1-PROCESSING, 2-COMPLETED, 3-CANCELLED, 4-FAILED, 5-PENDING.
New: Withdrawal status. Possible values: 1-PROCESSING, 2-COMPLETED, 3-CANCELLED, 4-FAILED, 5-PENDING. Enum values: - 1: PROCESSING - 2: COMPLETED - 3: CANCELLED - 4: FAILED - 5: PENDING
Description Change:
Old: First or third party withdrawal
New: First or third party withdrawal Enum values: - 1: First Party - 2: Third Party
Get Fiat Withdrawal Detail#
Path: /v2.0/payment/fiat/withdrawal/detail
Method: GETestimatedAmountReceivable Description Change:
Old:
New: 1-BEN (Beneficiary Pays All Fees), 2-OUR (Sender Pays All Fees), 3-SHA (Shared Fees).
Description Change:
Old: First or third party withdrawal
New: First or third party withdrawal Enum values: 1: First Party 2: Third Party
Get Fiat Withdrawal History#
Path: /v2.0/payment/fiat/withdrawal/history
Method: GETDescription Change:
Old: The end time
New: The end time (Unix timestamp in milliseconds)
Description Change:
Old: The start time
New: The start time (Unix timestamp in milliseconds)
estimatedAmountReceivable Description Change:
Old:
New: Swift charging code: 1-BEN (Beneficiary Pays All Fees), 2-OUR (Sender Pays All Fees), 3-SHA (Shared Fees).
Description Change:
Old: First or third party withdrawal
New: First or third party withdrawal Enum values: - 1 - 2
Crypto Payment#
Crypto Deposit#
Get Crypto Deposit#
Path: /v1.0/payment/getCryptoDeposit → /v2.0/payment/getCryptoDeposit
Method: GETDescription Change:
Old: Status
New: Status 1 DETECTED 2 CONFIRMED 3 KYT FAILED 4 PENDING TRAVELRULE 5 TRAVELRULE COMPLETED 6 REJECTED 7 COMPLETED 8 CANCELLED 9 REFUNDED
Get Crypto Deposit History#
Path: /v1.0/payment/getCryptoDepositHistory → /v2.0/payment/getCryptoDepositHistory
Method: GETDescription Change:
Old: Status
New: Status 1 DETECTED 2 CONFIRMED 3 KYT FAILED 4 PENDING TRAVELRULE 5 TRAVELRULE COMPLETED 6 REJECTED 7 COMPLETED 8 CANCELLED 9 REFUNDED
Get Crypto Deposit Wallet#
Path: /v1.0/crm/deposit/wallet → /v2.0/crm/deposit/wallet
Method: GETUpdate Crypto Deposit Travel Rule Info#
Path: /v1.0/payment/crypto/updateCryptoDepositTravelRuleInfo → /v2.0/payment/crypto/updateCryptoDepositTravelRuleInfo
Method: POSTDescription Change:
Old: required if "isOwner" is false
New: Owner information
Description Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
Crypto Payment#
Crypto Withdrawal#
Create Crypto Withdrawal#
Path: /v1.0/payment/crypto/createCryptoWithdrawal → /v2.0/payment/crypto/createCryptoWithdrawal
Method: POSTDescription Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
Get Crypto Withdrawal#
Path: /v1.0/payment/getCryptoWithdrawal → /v2.0/payment/getCryptoWithdrawal
Method: GETDescription Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
Get Crypto Withdrawal History#
Path: /v1.0/payment/getCryptoWithdrawalHistory → /v2.0/payment/getCryptoWithdrawalHistory
Method: GETDescription Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
Get Wallet Address#
Path: /v1.0/payment/crypto/getWalletAddress → /v2.0/payment/crypto/getWalletAddress
Method: GETDescription Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
Register Wallet Address#
Path: /v1.0/payment/crypto/registerWalletAddress → /v2.0/payment/crypto/registerWalletAddress
Method: POSTDescription Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
Description Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
Remove Wallet Address#
Path: /v1.0/payment/crypto/removeWalletAddress → /v2.0/payment/crypto/removeWalletAddress
Method: POSTConversion#
Create Conversion#
Path: /v1.0/trade/conversion/createConversion → /v2.0/trade/conversion/createConversion
Method: POSTCreate Quotation#
Path: /v1.0/trade/conversion/createQuotation → /v2.0/trade/conversion/createQuotation
Method: POSTclientReference (Deleted) clientReference (Deleted) Get Conversion#
Path: /v1.0/trade/conversion/getConversion → /v2.0/trade/conversion/getConversion
Method: GETGet Quotation#
Path: /v1.0/trade/conversion/getQuotation → /v2.0/trade/conversion/getQuotation
Method: GETUpload File#
Path: /v2.0/auth/tools/upload
Method: POSTDescription: The unique id of the uploaded file
Description: The size of the uploaded file (byte)
Description: Response Code
Description: Response Message
getTnC#
Path: /v2.0/tool/getTnC/{tncId}
Method: GETDescription Change:
Old: Effective date of the T&C
New: Effective date of the T&C (Unix timestamp in milliseconds)
Webhooks#
Conversion Webhook#
Type: Webhook
Name: Conversion Webhook
Method: POSTDescription Change:
Old: api_conversion_status_update
New: conversion.updated.v2
Crypto Deposit Webhook#
Type: Webhook
Name: Crypto Deposit Webhook
Method: POSTDescription Change:
Old: Status
New: Status 1 DETECTED 2 CONFIRMED 3 KYT FAILED 4 PENDING TRAVELRULE 5 TRAVELRULE COMPLETED 6 REJECTED 7 COMPLETED 8 CANCELLED 9 REFUNDED
Description Change:
Old: Webhook event type = "api_deposit_crypto_status_update"
New: crypto.deposit.updated.v2
Crypto Withdrawal Webhook#
Type: Webhook
Name: Crypto Withdrawal Webhook
Method: POSTDescription Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
Description Change:
Old: api_withdrawal_crypto_status_update
New: crypto.withdrawal.updated.v2
Fiat Account Request Status Webhook#
Type: Webhook
Name: Fiat Account Request Status Webhook
Method: POSTDescription Change:
Old: Status of the request
New: Status of the request Enum values: - 1: PENDING - 2: PROCESSING - 3: ACTIVE - 4: REJECTED
Description Change:
Old: api_fiat_account_request_status_update
New: fiat.account.request.updated.v2
Fiat Deposit Webhook#
Type: Webhook
Name: Fiat Deposit Webhook
Method: POSTDescription Change:
Old: Timestamp of deposit transaction, ISO-8601
New: Timestamp of deposit transaction (Unix timestamp in milliseconds)
Description Change:
Old: Webhook event type = "api_deposit_status_update"
New: fiat.deposit.updated.v2
Fiat Withdrawal Webhook#
Type: Webhook
Name: Fiat Withdrawal Webhook
Method: POSTestimatedAmountReceivable Description Change:
Old:
New: Swift charging code: 1-BEN (Beneficiary Pays All Fees), 2-OUR (Sender Pays All Fees), 3-SHA (Shared Fees).
Description Change:
Old: First or third party withdrawal
New: First or third party withdrawal Enum values: 1: First Party 2: Third Party
Description Change:
Old: Webhook event type = "api_withdrawal_status_update"
New: fiat.withdrawal.updated.v2
Merchant Status Webhook#
Type: Webhook
Name: Merchant Status Webhook
Method: POSTDescription: Update timestamp, UNIX timestamp in milliseconds (e.g., 1715000000000)
Description: Update timestamp, UNIX timestamp in milliseconds (e.g., 1715000000000)
Description Change:
Old:
New: Phone number for contact, country code + Number. eg, +65 87654321
Description Change:
Old: Date of birth (UTC format)
New: Date of birth, format: YYYY-MM-DD, e.g., 1990-05-15
Description Change:
Old:
New: The country of tax residency (Country Code in ISO 3166-1 alpha-2 format)
Description Change:
Old: Date of Incoporation
New: Date of Incoporation, format: YYYY-MM-DD, e.g., 1990-05-15
Description Change:
Old: Indicates the current status of the application
New: Indicates the current status of the application Enum values: - 1: PROCESSING - 2: APPROVED - 3: REJECTED
Description Change:
Old: Webhook event type = "api_merchant_status_update_v2"
New: merchant.updated.v2
Deleted APIs#
The following 2 APIs have been completely removed in v2.1:| Method | Path | Name |
|---|
| GET | /v1.0/payment/getStatement | Get Settlement Statement |
20260602#
Executive Summary#
| Status | Count | Note |
|---|
| New APIs | 4 | - |
| Deleted APIs | 0 | Fully removed |
| Modified APIs | 0 | With field-level changes |
New APIs#
| Method | Path | Name |
|---|
| POST | /v2.0/payment/statements | Create statement |
| GET | /v2.0/payment/statements/{statementId} | Get statement overview |
| GET | /v2.0/payment/statements/{statementId}/entries | Get statement entries |
| GET | /v2.0/payment/statements/{statementId}/transactions | Get statement transactions |
20260612#
Executive Summary#
| Status | Count | Note |
|---|
| New APIs | 4 | - |
| Deleted APIs | 0 | Fully removed |
| Modified APIs | 0 | With field-level changes |
New APIs#
| Method | Path | Name |
|---|
| POST | /v2.0/payment/withdrawal/feeEstimate | Fee Estimate |
| GET | /v2.0/points/balance | Get Points Balance |
| GET | /v2.0/points/transactions | List Points Transactions |
| GET | /v2.0/points/transactions/detail | Get Points Transaction Detail |
20260616#
Changelog 20260616#
Executive Summary#
| Status | Count | Note |
|---|
| New APIs | 0 | — |
| Deleted APIs | 0 | — |
| Modified APIs | 3 | Field-level changes only |
Breaking change: No. All v2.0 valid requests remain valid in 20260616. URL paths, request/response structure, and field types are unchanged.
Detailed API Changes#
1. Create Merchant#
Path: /v2.0/crm/addressBook/createMerchant (unchanged)Summary Change: Unchanged.Description Change: Updated to reflect 20260616 tier rules and new fields.Request Body Changes#
merchantDetails → additionalCorporationDetails → natureOfBusiness (Modified)| Property | Old | New |
|---|
| Type | integer | integer (unchanged) |
| Required | Yes (tier 3 only) | Yes (all tiers) |
| Enum values | 1–18 | 1–24 |
| Description | "The nature of the company's business" | Extended with full label mapping |
Enum label changes (1–18):| Value | Old Label | New Label |
|---|
| 2 | Manufacturing | Manufacturing and Industrial |
| 6 | Hospitality and Tourism | Hospitality and Travel |
| 7 | Real Estate and Construction | Real Estate and E-Commerce |
| 8 | Health Care and Pharmaceuticals | Healthcare |
| 9 | Professional and Services | Professional Services |
| 16 | Multimedia and Entertainment | Media and Entertainment |
| 17 | Cryptocurrency Mining | Cryptocurrency & Digital Assets |
Values 1, 3, 4, 5, 10, 11, 12, 13, 14, 15, 18 (Others) — labels unchanged. Integer values unchanged. No code change required for existing integrations.
| Value | Label |
|---|
| 19 | Insurance & Wealth |
| 20 | Trading & Commodities |
| 21 | Digital Products & Online Services |
| 22 | Business Support Services |
| 23 | Gaming |
| 24 | Advertising |
merchantDetails → additionalCorporationDetails → otherNatureOfBusiness (New)| Property | Value |
|---|
| Type | string |
| Required | No (optional) |
| Description | Specific business nature description. Use when natureOfBusiness = 18 (Others). |
merchantDetails → additionalCorporationDetails → sourceOfWealth (Modified)| Property | Old | New |
|---|
| Type | array[string] | array[string] (unchanged) |
| Required | No | Yes (tier 3) |
| Description | "Source of wealth (If HIGH risk and/or PEP)" | "Source of wealth. Required for tier 3 as of 20260616." |
merchantDetails → additionalPersonalDetails → sourceOfWealth (Modified)| Property | Old | New |
|---|
| Type | array[string] | array[string] (unchanged) |
| Required | No | Yes (tier 3) |
| Description | "Source of wealth" | "Source of wealth. Required for tier 3 as of 20260616." |
Tier Rule Changes#
| Tier | Old Behavior | New Behavior |
|---|
| Tier 1/2 (Corporate) | additionalCorporationDetails not available | Can submit additionalCorporationDetails with only natureOfBusiness (and optional otherNatureOfBusiness). The 8-field required constraint is waived for this case (server-side exception). |
| Tier 3 (Corporate) | additionalCorporationDetails required; sourceOfWealth optional | additionalCorporationDetails required; sourceOfWealth now required (8 fields: operatingAddress, companyType, descriptionOfBusiness, purposesOfAccountOpening, sourceOfFunds, authSignatories, directors, sourceOfWealth) |
| Tier 3 (Individual) | additionalPersonalDetails optional; sourceOfWealth optional | additionalPersonalDetails optional; sourceOfWealth now required when the block is submitted (4 fields: occupation, purposesOfAccountOpening, sourceOfFunds, sourceOfWealth) |
2. Get Merchant#
Path: /v2.0/crm/addressBook/getMerchant (unchanged)New: Get Merchant Details
Description Change: Updated to note that 20260616 response includes natureOfBusiness, otherNatureOfBusiness, and sourceOfWealth in additional details blocks.Response Body Changes#
No structural changes. The following fields may now appear in the response (returned when present on the merchant record):| Field | Location | Type |
|---|
natureOfBusiness | merchantInfo.merchantDetails.additionalCorporationDetails | integer (1–24) |
otherNatureOfBusiness | merchantInfo.merchantDetails.additionalCorporationDetails | string |
sourceOfWealth | merchantInfo.merchantDetails.additionalCorporationDetails | array[string] |
sourceOfWealth | merchantInfo.merchantDetails.additionalPersonalDetails | array[string] |
3. Merchant Status Webhook#
Path: Partner-implemented webhook endpoint (unchanged)Summary Change: Unchanged.Description Change: Updated to note 20260616 payload backward compatibility.Payload Changes#
No structural changes. The webhook payload (eventType, notificationId, data with applicationId / merchantInfo / status / statusInfo / updatedAt) is unchanged from v2.0.New fields (natureOfBusiness, otherNatureOfBusiness, sourceOfWealth) are included within merchantInfo when present on the merchant record.
Migration Guide#
No action required if:#
You already submit sourceOfWealth in tier 3 merchant creation — your existing requests remain valid.
You consume webhooks — the payload structure is unchanged.
Action required if:#
All merchants (tier 1/2/3): natureOfBusiness is now required for every corporate merchant creation. Submit it within additionalCorporationDetails.
Tier 3 merchants: sourceOfWealth is now required in both additionalCorporationDetails (CORPORATE) and additionalPersonalDetails (INDIVIDUAL).
Recommended:#
If your integration uses natureOfBusiness = 18 (Others), consider adopting the new otherNatureOfBusiness field to provide a specific business type description.
Review the updated enum labels (values 1–17) to ensure your UI or internal mappings align with the new naming.
Full natureOfBusiness Enum (20260616)#
| Value | Label | Status |
|---|
| 1 | Financial Services | Unchanged |
| 2 | Manufacturing and Industrial | Renamed |
| 3 | Information Technology | Unchanged |
| 4 | Agriculture and Farming | Unchanged |
| 5 | Retail and Wholesale | Unchanged |
| 6 | Hospitality and Travel | Renamed |
| 7 | Real Estate and E-Commerce | Renamed |
| 8 | Healthcare | Renamed |
| 9 | Professional Services | Renamed |
| 10 | Education and Training | Unchanged |
| 11 | Non Profit and Charity | Unchanged |
| 12 | Transaction and Logistics | Unchanged |
| 13 | Energy and Utilities | Unchanged |
| 14 | Telecommunications | Unchanged |
| 15 | Government and Public Sector | Unchanged |
| 16 | Media and Entertainment | Renamed |
| 17 | Cryptocurrency & Digital Assets | Renamed |
| 18 | Others | Unchanged |
| 19 | Insurance & Wealth | New |
| 20 | Trading & Commodities | New |
| 21 | Digital Products & Online Services | New |
| 22 | Business Support Services | New |
| 23 | Gaming | New |
| 24 | Advertising | New |
20260707#
Changelog 20260707#
Executive Summary#
| Status | Count | Note |
|---|
| New APIs | 17 | Crypto Checkout |
| Deleted APIs | 0 | — |
| Modified APIs | 9 | Withdrawal — amount semantics clarification (field-level only) |
Breaking change: No. All v2.0 valid requests remain valid in 20260707. Existing withdrawal integrations are backward-compatible; checkout APIs are additive.
Part A: Crypto Checkout (New APIs)#
A.1 API Summary#
Crypto Checkout#
| Method | Path | Name | Status |
|---|
| POST | /v2.0/payment/crypto/checkouts | Create Checkout | released |
| POST | /v2.0/payment/crypto/checkouts/quotations | Create Checkout Quotation | released |
| POST | /v2.0/payment/crypto/checkouts/{checkoutId}/confirm | Confirm Checkout | released |
| POST | /v2.0/payment/crypto/checkouts/{checkoutId}/accept | Accept Checkout | developing |
| GET | /v2.0/payment/crypto/checkouts/history | List Checkout History | developing |
| GET | /v2.0/payment/crypto/checkouts/{checkoutId} | Get Checkout Detail | released |
| POST | /v2.0/payment/crypto/checkouts/{checkoutId}/close | Close Checkout | released |
| GET | /v2.0/payment/crypto/checkouts/cryptos | Get Checkout Acceptable Cryptos | released |
| POST | (partner webhook) | Checkout Status Webhook | released |
Crypto Refund#
| Method | Path | Name | Status |
|---|
| POST | /v2.0/payment/crypto/refunds/refund | Create Refund | released |
| POST | /v2.0/payment/crypto/refunds/risk-refund | Create Risk Refund | released |
| POST | /v2.0/payment/crypto/refunds/void | Create Void Refund | released |
| POST | /v2.0/payment/crypto/refunds/{refundId}/close | Close Refund | released |
| GET | /v2.0/payment/crypto/refunds/{refundId} | Get Refund Detail | released |
| GET | /v2.0/payment/crypto/checkouts/{checkoutId}/refundable-info | Get Checkout Refundable Info | released |
| POST | (partner webhook) | Refund Status Webhook | released |
Address#
| Method | Path | Name | Status |
|---|
| POST | /v2.0/payment/crypto/addresses/validate | Validate Crypto Address | released |
A.2 Detailed Endpoint Descriptions#
A.2.1 Create Checkout#
POST /v2.0/payment/crypto/checkoutsCreate a new crypto checkout order. Supports individual and corporate buyers with tiered KYC requirements (threshold: 1000 USD).Request Body#
| Field | Type | Required | Description |
|---|
participantCode | string | Yes | Participant's (merchant) code |
orderAmount | string | Yes | Amount to be paid |
orderCurrency | string | Yes | Payment currency code (e.g. USD) |
expiry | integer | Yes | Order expiration timestamp in milliseconds |
buyerInfo | oneOf | Yes | IndividualBuyerInfo or CorporateBuyerInfo (see below) |
productInfo | object | Yes | {"productName" (required), "description", "productImageUrl"} |
clientCheckoutId | string | Yes | External client checkout ID (unique per merchant) |
checkoutConfiguration | object | No | UI/UX config: merchantName, merchantLogo, redirectUrl, customerSupportEmail, defaultLanguage (ENGLISH/CHINESE), checkoutLinkLogo, feeBearer (BUYER/MERCHANT) |
paymentMethod | object | No | Pre-select {"paymentCurrency", "blockchain"}. If provided, acceptableCryptos in response is null |
Individual Buyer (buyerInfo oneOf option 1):| Field | Type | Required | Description |
|---|
firstName | string | Yes | First name |
lastName | string | Yes | Last name |
middleName | string | No | Middle name |
residentialAddress | object | ≥1000 USD | Address fields: country, state, city, postcode, addressLine1, addressLine2 |
identityType | string | No | PASSPORT or NRIC |
identityNumber | string | ≥1000 USD | Identity document number |
dateOfBirth | string | ≥1000 USD | Format: YYYY-MM-DD |
placeOfBirth | string | ≥1000 USD | Place of birth |
nationality | string | No | ISO 3166-1 alpha-2 |
≥1000 USD: at least one of {residentialAddress, identityNumber, dateOfBirth + placeOfBirth} required.
Corporate Buyer (buyerInfo oneOf option 2):| Field | Type | Required | Description |
|---|
companyName | string | Yes | Company name |
registeredAddress | object | ≥1000 USD | Registered business address |
businessRegistrationNumber | string | ≥1000 USD | Business registration number |
countryOfIncorporation | string | ≥1000 USD | ISO 3166-1 alpha-2 |
dateOfRegistration | string | ≥1000 USD | Date of registration |
Response (200)#
| Field | Type | Description |
|---|
checkoutId | string | e.g. CKO_20240115_001 |
status | string | OPENING |
checkoutUrl | string (uri) | Checkout page URL |
orderAmount | string | Order amount |
orderCurrency | string | Order currency |
createdAt | integer | Creation timestamp |
acceptableCryptos | array | Accepted [{cryptoCurrency, blockchains[]}] (null if paymentMethod specified) |
checkoutConfiguration | object | Echo of config |
paymentMethod | object | Payment method details |
Errors: 400 BadRequest, 401 Unauthorized
A.2.2 Create Checkout Quotation#
POST /v2.0/payment/crypto/checkouts/quotationsCreate an exchange rate quotation for a checkout order.Request Body#
| Field | Type | Required | Description |
|---|
participantCode | string | Yes | Participant code |
orderAmount | string | Yes | Order amount |
orderCurrency | string | Yes | Order currency code |
paymentCurrency | string | Yes | Payment cryptocurrency (e.g. USDT) |
Response (200)#
| Field | Type | Description |
|---|
quotationId | string | Quotation ID |
participantCode | string | Participant code |
price | string | Exchange rate |
paymentAmount | string | Amount in cryptocurrency |
paymentCurrency | string | Payment cryptocurrency |
orderAmount | string | Order amount |
orderCurrency | string | Order currency |
quotationExpiry | integer | Expiry timestamp (ms) |
A.2.3 Confirm Checkout#
POST /v2.0/payment/crypto/checkouts/{checkoutId}/confirmConfirm a checkout with selected cryptocurrency and blockchain. Optionally reuses an existing quotation.Path Parameters#
| Parameter | Type | Required |
|---|
checkoutId | string | Yes |
Request Body#
| Field | Type | Required | Description |
|---|
paymentCurrency | string | Yes | e.g. USDT |
blockchain | string | Yes | e.g. TRC20 |
quotationId | string | No | Quotation ID to reuse |
email | string | No | Email for refund address collection |
Response (200)#
| Field | Type | Description |
|---|
quotationId | string | Quotation ID |
checkoutId | string | Checkout ID |
status | string | AWAITING_PAYMENT |
price | string | Exchange rate |
orderAmount / orderCurrency | string | Order details |
paymentAmount / paymentCurrency | string | Payment details |
payeeFeeAmount | object | Buyer-side fee {amount, feeCurrency} |
payerFeeAmount | object | Merchant-side fee {amount, feeCurrency} |
paymentBlockchain | string | Blockchain network |
checkoutWallet | string | Receiving address |
qrCode | string | Base64-encoded PNG QR |
quotationExpiry | integer | Expiry (ms) |
email | string | Refund email |
A.2.4 Accept Checkout#
POST /v2.0/payment/crypto/checkouts/{checkoutId}/acceptAccept a checkout with a settlement mode.Query Parameters#
| Parameter | Type | Required | Description |
|---|
acceptMode | string | Yes | ACCEPT — settle all; VOID_OVERPAYMENT — settle paymentAmount & void excess; VOID_ALL — void entire order |
refundAddress | string | No | Refund address for void refunds |
Response (200)#
| Field | Type | Description |
|---|
checkoutId | string | Checkout ID |
status | string | Order status |
acceptMode | string | Applied mode |
acceptedAt | string | Timestamp |
voidRefund | object | Void refund details (when applicable) |
A.2.5 List Checkout History#
GET /v2.0/payment/crypto/checkouts/historyList checkout history with time-range filtering and pagination.Query Parameters#
| Parameter | Type | Required |
|---|
participantCode | string | No |
startTime | string | No |
endTime | string | No |
offset | string | No |
Response (200)#
| Field | Type | Description |
|---|
participantCode | string | Participant code |
startTime / endTime | string | Query time range |
transactions | array[CryptoCheckoutDetail] | Checkout records (see A.2.6) |
pagination | object | {limit, offset, total, hasMore} |
A.2.6 Get Checkout Detail#
GET /v2.0/payment/crypto/checkouts/{checkoutId}Retrieve full checkout details including payments, conversions, and fees.Response (200)#
| Field | Type | Description |
|---|
checkoutId | string | Checkout ID |
participantCode | string | Participant code |
clientCheckoutId | string | External client checkout ID |
status | string | OPENING → AWAITING_PAYMENT → RECEIVED → SUCCEEDED → SETTLED / EXPIRED / CLOSED |
orderAmount / orderCurrency | string | Order amount & currency |
paymentAmount / paymentCurrency / paymentBlockchain | string | Payment details |
accumulatedAmount | string | Total received |
quotationId / quotationExpiry | string / integer | Quotation details |
checkoutExpiry | integer | Checkout expiry (ms) |
email | string | Refund email |
payeeFeeAmount / payerFeeAmount | object | {amount, currency} — buyer/merchant fees |
riskTobeRefund | boolean | true = to be refunded; false = not; null = no risk |
receivedPayments | array | See below |
conversions | array[ConversionInfo] | Conversion records |
createdAt / updatedAt | integer | Timestamps |
| Field | Type | Description |
|---|
receivedPaymentId | string | Payment ID |
paymentSequence | integer | Sequence number |
paidAmount / paidCurrency | string | Paid amount & currency |
blockchain | string | Blockchain network |
fromAddress | string | Sender wallet |
txHash | string | Transaction hash |
status | string | PAYMENT_DETECTED / PAYMENT_ACCEPTED / PAYMENT_REJECTED / PAYMENT_ERROR |
| Field | Type | Description |
|---|
conversionId | string | Conversion ID |
quotationId / participantCode / price | string | Related quotation |
sourceCurrency / sourceAmount | string | Source |
destinationCurrency / destinationAmount | string | Destination |
status | string | INITIATED / COMPLETED / CANCELLED |
createdAt | integer | Timestamp |
A.2.7 Close Checkout#
POST /v2.0/payment/crypto/checkouts/{checkoutId}/closeClose or settle a checkout order.Request Body#
| Field | Type | Required | Description |
|---|
processingResult | integer | Yes | 1 = To be settled; 2 = To be closed |
Response (200)#
| Field | Type | Description |
|---|
checkoutId | string | Checkout ID |
success | boolean | Operation result |
closedAt | integer | Closed timestamp |
A.2.8 Get Checkout Acceptable Cryptos#
GET /v2.0/payment/crypto/checkouts/cryptosQuery accepted cryptocurrencies and blockchains for a participant and currency pair.Query Parameters#
| Parameter | Type | Required |
|---|
participantCode | string | Yes |
orderCurrency | string | Yes |
Response (200)#
| Field | Type | Description |
|---|
participantCode | string | Participant code |
orderCurrency | string | Order currency |
acceptableCryptos | array | [{cryptoCurrency, blockchains[]}] |
A.2.9 Checkout Status Webhook#
Event type: crypto.checkout.updated.v2. Payload: {eventType, notificationId, data: CryptoCheckoutDetail}. Respond with HTTP 200.
A.2.10 Create Refund#
POST /v2.0/payment/crypto/refunds/refundStandard post-settlement refund with configurable fee bearer.Request Body#
| Field | Type | Required | Description |
|---|
originalTransactionType | string | Yes | CHECKOUT or COLLECTION |
originalTransactionId | string | Yes | Original transaction ID |
amount | string | Yes | Refund amount in order currency |
refundCurrency | string | Yes | Order currency (e.g. USD) |
feeBearer | string | Yes | BUYER or MERCHANT |
clientRefundId | string | Yes | External refund ID (unique) |
refundInfo | oneOf | Yes | {"email"} or {"refundAddress"} |
Response (200)#
| Field | Type | Description |
|---|
refundId | string | e.g. REF_20240115_001 |
refundType | string | REFUND |
originalTransactionId | string | Original transaction ID |
clientRefundId | string | External refund ID |
amount / currency | string | Refund amount & currency |
blockchain | string | Blockchain network |
feeAmount / feeCurrency | string | Transaction fee |
netAmount / netAmountCurrency | string | Net received amount |
status | string | INITIATED → PROCESSING → COMPLETED / REJECTED / CLOSED |
email / refundAddress | string | Refund destination |
A.2.11 Create Risk Refund#
POST /v2.0/payment/crypto/refunds/risk-refundKYT-triggered risk refund. Supports CHECKOUT, COLLECTION, and DEPOSIT original transaction types.Request Body#
| Field | Type | Required | Description |
|---|
originalTransactionType | string | Yes | CHECKOUT, COLLECTION, or DEPOSIT |
originalTransactionId | string | Yes | Original transaction ID |
clientRefundId | string | Yes | External refund ID (unique) |
refundCurrency | string | No | Refund cryptocurrency |
blockchain | string | No | Blockchain network |
refundInfo | oneOf | Yes | {"email"} or {"refundAddress"} |
Response (200)#
Same as Create Refund, with refundType = RISK_REFUND.
A.2.12 Create Void Refund#
POST /v2.0/payment/crypto/refunds/voidPre-settlement void. Used for overpayment, incomplete order, and wrong-currency refunds.Request Body#
| Field | Type | Required | Description |
|---|
originalTransactionType | string | Yes | CHECKOUT or COLLECTION |
originalTransactionId | string | Yes | Original transaction ID |
clientRefundId | string | Yes | External refund ID (unique) |
refundCurrency | string | No | Refund cryptocurrency |
blockchain | string | No | Blockchain network |
refundInfo | oneOf | Yes | {"email"} or {"refundAddress"} |
Response (200)#
Same as Create Refund, with refundType = VOID.
A.2.13 Close Refund#
POST /v2.0/payment/crypto/refunds/{refundId}/closeConfirm and close a refund order. Empty request body {}.Response (200)#
| Field | Type | Description |
|---|
refundId | string | Refund ID |
success | boolean | Operation result |
closedAt | integer | Closed timestamp |
A.2.14 Get Refund Detail#
GET /v2.0/payment/crypto/refunds/{refundId}Retrieve full refund details including on-chain transaction info.Response (200)#
| Field | Type | Description |
|---|
refundId | string | Refund ID |
refundType | string | VOID, RISK_REFUND, or REFUND |
originalTransactionId | string | Original transaction ID |
participantCode | string | Merchant code |
clientRefundId | string | External refund ID |
status | string | INITIATED / PROCESSING / COMPLETED / REJECTED / CLOSED |
reason | string | Failure reason (when applicable) |
blockchain | string | Blockchain network |
currency / amount | string | Refund currency & amount |
email / refundAddress | string | Refund destination |
feeCurrency / feeAmount | string | Fee details |
netAmount / netAmountCurrency | string | Net received |
txHash | string | On-chain transaction hash |
createdAt / updatedAt | integer | Timestamps |
A.2.15 Get Checkout Refundable Info#
GET /v2.0/payment/crypto/checkouts/{checkoutId}/refundable-infoQuery refundable (settled), voidable, and KYT risk-refundable amounts. Categories with no data are null. An order with nothing refundable still returns 200.Query Parameters#
| Parameter | Type | Required |
|---|
participantCode | string | Yes |
Response (200)#
| Field | Type | Description |
|---|
checkoutId | string | Checkout ID |
refundableItem | object | null | Settled refundable balance |
voidableItems | array | null | VOID amounts |
riskRefundableItems | array | null | Risk-refundable amounts |
Each line item: {amount: {amount, currency}, chainCode}.
A.2.16 Refund Status Webhook#
Event type: crypto.refund.updated.v2. Payload: {eventType, notificationId, data: CryptoRefundDetail}. Respond with HTTP 200.
A.2.17 Validate Crypto Address#
POST /v2.0/payment/crypto/addresses/validateValidate on-chain address format for a given blockchain. HTTP 200 whenever the check ran; outcome is in data.valid.Request Body#
| Field | Type | Required | Description |
|---|
blockchain | string | Yes | e.g. ETH |
address | string | Yes | On-chain address |
Response (200)#
| Field | Type | Description |
|---|
blockchain | string | Echo of request |
address | string | Echo of request |
valid | boolean | true = valid format; false = invalid |
Failure codes (valid: false):| failureCode | Meaning |
|---|
INVALID_ADDRESS | Address format incorrect for blockchain |
VALIDATION_UNAVAILABLE | Validation query failed; retry later |
Part B: Withdrawal Amount Semantics (Modified APIs)#
B.1 Motivation#
The withdrawal API (both crypto and fiat) previously relied on implicit conventions to determine whether amount represented a gross debit amount (total deducted from account, including fees) or a net received amount (amount the payee receives, excluding fees). This convention was derived from withdrawalType (for fiat) or beneficiaryWallet ownership (for crypto), which created ambiguity and integration complexity.This update introduces explicit amount semantics via amountType, adds fee bearer declaration via feeBearer, and formally separates debit / received amounts in the response via dedicated fields (debitAmount, receivedAmount). For fiat withdrawals, feeAmount and feeCurrency are added to the response (crypto withdrawal already had these fields). Legacy response fields (fees, estimatedAmountReceivable) are retained as aliases.
B.2 Detailed API Changes#
B.2.1 Create Crypto Withdrawal#
Path: /v2.0/payment/crypto/createCryptoWithdrawal (unchanged)Summary Change: Added amountType and feeBearer request fields; amount semantics clarified.Request Body Changes#
| Property | Value |
|---|
| Type | integer |
| Required | Yes (for new integrations) |
| Enum values | 1 = Debit (gross debit amount), 2 = Receive (net received amount) |
| Default (backward compat) | Falls back on beneficiaryWallet ownership: first-party wallet → Debit, third-party wallet → Receive |
| Description | Explicitly declares the meaning of amount. New integrations must provide this field. |
| Property | Value |
|---|
| Type | integer |
| Required | No (optional) |
| Enum values | 1 = Customer (borne by trading party), 2 = Partner (borne by platform partner) |
| Default | 1 (Customer) |
| Description | Which participant account bears the platform fee. Default behavior is unchanged from v2.0. |
| Property | Old | New |
|---|
| Type | string | string (unchanged) |
| Required | Yes | Yes (unchanged) |
| Meaning | Implicitly derived from withdrawalType | Explicitly declared by amountType |
When amountType is not provided, the backend falls back on the existing beneficiaryWallet logic. Existing integrations do not need to change.
Response Body Changes#
| Field | Type | Description |
|---|
amountType | integer | Echoed from request. 1=Debit, 2=Receive. |
feeBearer | integer | Echoed from request. 1=Customer, 2=Partner. |
debitAmount | string | Gross debit amount. The relationship debitAmount = receivedAmount + feeAmount always holds. feeBearer=1: full amount from trading party account; feeBearer=2: fee portion from partner account instead. |
receivedAmount | string | Net amount received by payee (excluding platform fees). |
Legacy fields unchanged. The above fields are additional — existing response fields remain.
B.2.2 Get Crypto Withdrawal#
Path: /v2.0/payment/getCryptoWithdrawal (unchanged)Summary Change: Response now includes amountType, feeBearer, debitAmount, receivedAmount.Response Body Changes#
| Field | Type | Description |
|---|
amountType | integer | 1=Debit, 2=Receive. Echoed from creation-time value. |
feeBearer | integer | 1=Customer, 2=Partner. Echoed from creation-time value. |
debitAmount | string | Gross debit amount. |
receivedAmount | string | Net amount received by payee. |
All existing response fields unchanged. New fields are additive only.
B.2.3 Get Crypto Withdrawal History#
Path: /v2.0/payment/getCryptoWithdrawalHistory (unchanged)Summary Change: Each history item now includes amountType, feeBearer, debitAmount, receivedAmount.Same field additions as Get Crypto Withdrawal — each object in the history list gains the four fields above.
B.2.4 Crypto Withdrawal Webhook#
Path: Partner-implemented webhook endpoint (unchanged)Summary Change: Webhook payload now includes amountType, feeBearer, debitAmount, receivedAmount.Payload Changes#
| Field | Type | Description |
|---|
amountType | integer | 1=Debit, 2=Receive |
feeBearer | integer | 1=Customer, 2=Partner |
debitAmount | string | Gross debit amount |
receivedAmount | string | Net amount received by payee |
Existing payload fields unchanged. Webhook signature verification, retry policy, and security model are unchanged.
B.2.5 Create Fiat Withdrawal#
Path: /v2.0/payment/fiat/createWithdrawal (unchanged)Summary Change: Added amountType and feeBearer request fields; amount semantics clarified.Request Body Changes#
| Property | Value |
|---|
| Type | integer |
| Required | Yes (for new integrations) |
| Enum values | 1 = Debit (gross debit amount), 2 = Receive (net received amount) |
| Default (backward compat) | Falls back on withdrawalType: withdrawalType=1 (First Party) → Debit, withdrawalType=2 (Third Party) → Receive |
| Description | Explicitly declares the meaning of amount. New integrations must provide this field. |
| Property | Value |
|---|
| Type | integer |
| Required | No (optional) |
| Enum values | 1 = Customer (borne by trading party), 2 = Partner (borne by platform partner) |
| Default | 1 (Customer) |
| Description | Which participant account bears the platform fee. Default behavior is unchanged. |
| Property | Old | New |
|---|
| Meaning | Implicitly derived from withdrawalType | Explicitly declared by amountType |
Response Body Changes#
| Field | Type | Description |
|---|
amountType | integer | Echoed from request. 1=Debit, 2=Receive. |
feeBearer | integer | Echoed from request. 1=Customer, 2=Partner. |
debitAmount | string | Gross debit amount — total actually debited from the trading party account. |
feeAmount | string | Platform fee amount. Alias for legacy field fees. |
feeCurrency | string | Fee currency (uppercase ISO 4217). Typically same as currency. |
receivedAmount | string | Net amount received by payee. Alias for legacy field estimatedAmountReceivable. |
Legacy Fields Retained as Aliases:| Legacy Field | Equivalent |
|---|
fees | feeAmount |
estimatedAmountReceivable | receivedAmount |
Both legacy and new field names are returned. No removal of existing fields.
B.2.6 Get Fiat Withdrawal Detail#
Path: /v2.0/payment/fiat/withdrawal/detail (unchanged)Summary Change: Response now includes the six new fields plus legacy aliases.Same field additions as Create Fiat Withdrawal response. Fields echoed from creation-time values. Legacy fees and estimatedAmountReceivable retained as aliases.
B.2.7 Get Fiat Withdrawal History#
Path: /v2.0/payment/fiat/withdrawal/history (unchanged)Summary Change: Each history item now includes the six new fields plus legacy aliases.Same as Get Fiat Withdrawal Detail — each object in the history list gains the new fields.
B.2.8 Fiat Withdrawal Webhook#
Path: Partner-implemented webhook endpoint (unchanged)Summary Change: Webhook payload now includes all six new fields plus legacy aliases.Payload Changes#
| Field | Type | Description |
|---|
amountType | integer | 1=Debit, 2=Receive |
feeBearer | integer | 1=Customer, 2=Partner |
debitAmount | string | Gross debit amount |
feeAmount | string | Platform fee (alias for legacy fees) |
feeCurrency | string | Fee currency |
receivedAmount | string | Net amount received (alias for legacy estimatedAmountReceivable) |
Legacy fields fees and estimatedAmountReceivable are retained as aliases in the webhook payload.
B.2.9 Fee Estimate (Withdrawal)#
Path: /v2.0/payment/withdrawal/feeEstimate (unchanged)Summary Change: Field renames for naming consistency (non-breaking; pre-production); added feeBearer to request and response.Non-breaking: The totalAmount → debitAmount and receiveAmount → receivedAmount renames occurred before production release. No client code is affected.
Request Body Changes#
| Property | Value |
|---|
| Type | string |
| Required | No (optional) |
| Enum values | CUSTOMER (default), PARTNER |
| Description | Which participant account bears the platform fee. |
debitAmount (Renamed from totalAmount, pre-production)| Property | Old | New |
|---|
| Name | totalAmount | debitAmount |
| Type | string | string (unchanged) |
| Description | Gross debit amount (FIRST_PARTY only). Mutually exclusive with receivedAmount. | |
receivedAmount (Renamed from receiveAmount, pre-production)| Property | Old | New |
|---|
| Name | receiveAmount | receivedAmount |
| Type | string | string (unchanged) |
| Description | Net received amount (THIRD_PARTY only). Mutually exclusive with debitAmount. | |
Response Body Changes#
feeBearer (New, top-level): CUSTOMER or PARTNER. Echoed from request.Field Renames (within withPoints and withoutPoints, pre-production):| Old Name | New Name |
|---|
totalAmount | debitAmount |
B.3 Amount Semantics: Debit vs Receive#
| amountType | Meaning of amount | Account is debited | Payee receives |
|---|
| 1 = Debit | Gross debit amount (including fees) | amount | amount - feeAmount |
| 2 = Receive | Net received amount (excluding fees) | amount + feeAmount | amount |
B.4 Fee Bearer: Customer vs Partner#
The relationship debitAmount = receivedAmount + feeAmount always holds, regardless of feeBearer. The feeBearer only determines whose account the fee portion is deducted from.| feeBearer | Fee deducted from | Effect |
|---|
| 1 = Customer (default) | Trading party participant account | Full debitAmount from trading party account |
| 2 = Partner | Platform partner participant account (fee portion only) | feeAmount portion from partner account; remaining from trading party account |
Part C: Cross-Cutting Concerns#
C.1 Authentication#
All APIs use API Key authentication via the X-API-Key header.C.2 Common Error Responses#
| Code | Type | Schema |
|---|
| 400 | BadRequest | {"code": "INVALID_REQUEST", "message": "...", "data": null} |
| 401 | Unauthorized | {"code": "UNAUTHORIZED", "message": "Invalid or missing API key"} |
| 404 | NotFound | {"code": "NOT_FOUND", "message": "Resource not found"} |
| 500 | InternalServerError | {"code": "INTERNAL_ERROR", "message": "An unexpected error occurred"} |
C.3 Checkout Status Lifecycle#
OPENING → AWAITING_PAYMENT → RECEIVED → SUCCEEDED → SETTLED
↓ ↓\n EXPIRED CLOSED
C.4 Refund Status Lifecycle#
INITIATED → PROCESSING → COMPLETED
↓\n REJECTED
↓\n CLOSED
C.5 Refund Types#
| Type | Use Case | Endpoint |
|---|
REFUND | Standard post-settlement refund | /refunds/refund |
RISK_REFUND | KYT-triggered risk refund | /refunds/risk-refund |
VOID | Pre-settlement void (overpayment, incomplete order, wrong currency) | /refunds/void |
Part D: Migration Guide#
Withdrawal APIs#
No action required if:#
You do not call the withdrawal APIs — this update does not affect other endpoints.
You already call withdrawal APIs — your existing v2.0 requests remain valid. The backend applies backward-compatible fallback logic when amountType is absent.
You consume withdrawal webhooks — new fields are purely additive; existing payload fields remain.
Recommended:#
New integrations: Always provide amountType in Create Withdrawal requests. This is mandatory for new integrations.
Existing integrations: Consider adopting amountType to make amount semantics explicit in your integration. The fallback logic preserves your current behavior, but explicit declaration improves auditability.
Fee Estimate users: The totalAmount → debitAmount and receiveAmount → receivedAmount renames are pre-production; no migration needed.
Response parsing: If your integration reads fees or estimatedAmountReceivable, you may optionally switch to feeAmount and receivedAmount. Both sets are returned during the transition period.
Field Reference Mapping#
| Context | Old Field | New Field | Status |
|---|
| Request (Create Withdrawal) | amount (ambiguous) | amount + amountType | Old format still accepted |
| Response | fees | feeAmount | Alias (both returned) |
| Response | estimatedAmountReceivable | receivedAmount | Alias (both returned) |
| Fee Estimate request | totalAmount | debitAmount | Renamed (pre-production) |
| Fee Estimate request | receiveAmount | receivedAmount | Renamed (pre-production) |
| Fee Estimate response | totalAmount | debitAmount | Renamed (pre-production) |
Checkout APIs#
The checkout API surface is additive — no existing integrations are affected.
Summary of All New Fields (20260707)#
Checkout#
| Field | APIs Where Added | Type | Notes |
|---|
acceptableCryptos | Create Checkout response; GET /cryptos response | array | Acceptable crypto+blockchain pairs |
refundableItem / voidableItems / riskRefundableItems | GET /refundable-info response | object/array/null | Refundability breakdown |
valid / failureCode | POST /addresses/validate response | boolean/string | Address validation result |
Withdrawal (field-level)#
| Field | APIs Where Added | Type | Enum |
|---|
amountType | Create Crypto/Fiat Withdrawal (request), All queries & webhooks (response) | integer | 1=Debit, 2=Receive |
feeBearer | Create Crypto/Fiat Withdrawal, Fee Estimate (request), All queries & webhooks (response) | integer (withdrawal) / string (feeEstimate) | 1/CUSTOMER, 2/PARTNER |
debitAmount | All query & webhook responses | string | — |
feeAmount | Fiat query & webhook responses | string | — |
feeCurrency | Fiat query & webhook responses | string | — |
receivedAmount | All query & webhook responses | string | — |
20260717#
Changelog 20260717#
Executive Summary#
| Status | Count | Note |
|---|
| New APIs | 2 | Merchant Activation (Non-FI partners) |
| Deleted APIs | 0 | — |
| Modified APIs | 3 | Merchant — activationStatus added (field-level) |
Breaking change: No. Existing integrations remain compatible — the two activation endpoints are additive; activationStatus is an additive field on existing merchant responses/payloads; request bodies of existing endpoints are unchanged.
Part A: Non-FI Merchant Activation (New)#
CAMP partners fall into two types — FI (licensed financial institutions) and Non-FI (non-financial businesses / individuals) — assigned by CAMP when the partner is onboarded. This release introduces merchant activation for Non-FI partners: a merchant created by a Non-FI partner must complete a one-time email OTP activation before it can call fund-write APIs. FI partners require no activation; their API behaviour is unchanged.A.1 Who Needs to Activate#
| FI Partner | Non-FI Partner |
|---|
| After creating a merchant | Ready to use | Activation required |
| Calling activation endpoints | Returns 400, not needed | Normal |
internalTransfer | ✅ Available | ❌ Not available |
activationStatus value | Always NO_NEED_ACTIVATION | Follows the state machine |
A.2 Integration Flow#
Main call chain: createMerchant → getMerchant → initiateActivation → confirmActivation. getTnC is not part of this chain — it is an auxiliary call used to fetch the agreement link, which the partner places on the OTP entry page for the merchant to review.
A.3 Activation State Machine#
| Value | Meaning | Fund-write APIs available? |
|---|
NOT_ACTIVATED | Merchant created, activation not yet started | ❌ |
PENDING_ACTIVATION | OTP sent to merchant email, awaiting confirmation | ❌ |
EXPIRED | OTP expired unused | ❌ |
LOCKED | 5 wrong OTP attempts, locked for 30 min | ❌ |
ACTIVATED | Activated (terminal) | ✅ (except internalTransfer) |
NO_NEED_ACTIVATION | FI-partner merchant (terminal) | ✅ (all) |
A.4 Step-by-Step#
Main call chain (4 steps): createMerchant → getMerchant → initiateActivation → confirmActivation. getTnC is an auxiliary call for displaying the agreement (see the note under A.4.3).A.4.1 Create Merchant · POST /v2.0/crm/addressBook/createMerchant#
The merchant enters KYC review after creation, with initial activationStatus = NOT_ACTIVATED. The response does not include activationStatus; query it via Get Merchant.A.4.2 Get Merchant · GET /v2.0/crm/addressBook/getMerchant#
Query by participantCode or clientReference.| Field | Description |
|---|
merchantStatus | KYC status: 1=PROCESSING, 2=APPROVED, 3=REJECTED |
activationStatus | Activation state, initially NOT_ACTIVATED |
Activation can only be initiated after the merchant's KYC is approved (merchantStatus = 2).
A.4.3 Initiate Activation · POST /v2.0/crm/merchant/initiateActivation#
| Field | Type | Required | Description |
|---|
participantCode | string | Yes | Target merchant |
clientReference | string | No | Idempotency key, ≤100 chars |
{
"code": 200,
"msg": "success",
"data": {
"participantCode": "B0100106",
"activationStatus": "PENDING_ACTIVATION",
"otpSentToMaskedEmail": "j***@e***.com",
"otpExpiresAt": 1768636800000,
"tncId": "N001"
}
}
| Response field | Description |
|---|
otpSentToMaskedEmail | Masked email the OTP was sent to |
otpExpiresAt | OTP expiry, UNIX timestamp (ms); valid for 10 minutes |
tncId | Agreement code for this activation; used to fetch the agreement link (below) and as acceptedTnC in A.4.4 |
The OTP is sent only to the merchant's registered email; the OTP itself is never returned.
Re-calling for an already-activated merchant → idempotent ACTIVATED; re-calling in PENDING_ACTIVATION/EXPIRED → the previous OTP is invalidated and a new one sent.
Auxiliary — Get Agreement Link · GET /v2.0/tool/getTnC/{tncId}This call is not part of the main chain. Use the tncId from the response above as the path parameter to fetch the agreement link, then place tncContent (agreement PDF) on the OTP entry page for the merchant to review.{
"code": 200,
"msg": "success",
"data": {
"tncId": "N001",
"name": "Partner_Program_Agreement_EndUser_Authorization",
"version": "V1.0",
"tncContent": "https://.../Partner_Program_Agreement_EndUser_Authorization.pdf",
"effectiveFrom": "2026-07-15"
}
}
A.4.4 Confirm Activation · POST /v2.0/crm/merchant/confirmActivation#
After the merchant reviews the agreement and submits the OTP on the entry page, the partner calls this endpoint.| Field | Type | Required | Description |
|---|
participantCode | string | Yes | Target merchant |
otp | string | Yes | 6-digit OTP submitted by the merchant |
acceptedTnC | string[] | Yes | Agreement code(s); must match the tncId returned by initiateActivation, e.g. ["N001"] |
{
"code": 200,
"msg": "success",
"data": {
"participantCode": "B0100106",
"activationStatus": "ACTIVATED",
"activatedAt": 1768637100000
}
}
The activation result is returned synchronously. Once the merchant reaches ACTIVATED, fund-write APIs are unlocked.A.5 Fund APIs Gated by Activation#
The following endpoints cannot be called before the merchant is activated (activationStatus other than ACTIVATED / NO_NEED_ACTIVATION):| Endpoint | Path | Meaning |
|---|
| Create Crypto Withdrawal | POST /v2.0/payment/crypto/createCryptoWithdrawal | Crypto withdrawal |
| Create Fiat Withdrawal | POST /v2.0/payment/fiat/createWithdrawal | Fiat withdrawal |
| Activate Same Name Withdrawal | POST /v2.0/payment/fiat/sameNameWithdrawal/activate | Same-name withdrawal activation |
| Create Conversion | POST /v2.0/trade/conversion/createConversion | Conversion |
Internal Transfer (POST /v2.0/payment/account/internalTransfer) is not available to Non-FI partners.
Part B: Modified APIs#
All changes are additive and field-level; request bodies are unchanged.B.1 Get Merchant · GET /v2.0/crm/addressBook/getMerchant#
Response data adds activationStatus (read-only, enum in A.3). Existing merchantStatus and merchantInfo are unchanged.B.2 Create Merchant · POST /v2.0/crm/addressBook/createMerchant#
Request/response structure unchanged. A Non-FI merchant is created as NOT_ACTIVATED with fund operations disabled by default until activated. activationStatus is not returned in this response — query it via Get Merchant.B.3 Merchant Status Webhook · POST /webhooks/merchant-status/v2#
Payload data adds activationStatus. Activation itself does not trigger this webhook (confirmActivation returns the result synchronously); the webhook continues to fire on existing merchant KYC-status changes, now additionally carrying activationStatus.Impact on existing integrations: Get Merchant and the webhook consumers must tolerate the new field and not reject payloads with unrecognised fields.
Appendix: Endpoint List#
| Endpoint | Path | Type |
|---|
| Create Merchant | POST /v2.0/crm/addressBook/createMerchant | Existing |
| Get Merchant | GET /v2.0/crm/addressBook/getMerchant | Existing (added activationStatus) |
| Initiate Activation | POST /v2.0/crm/merchant/initiateActivation | New |
| Confirm Activation | POST /v2.0/crm/merchant/confirmActivation | New |
| Get TnC | GET /v2.0/tool/getTnC/{tncId} | Existing (auxiliary, for displaying the agreement) |
| Merchant Status Webhook | POST /webhooks/merchant-status/v2 | Existing (added activationStatus) |
Modified at 2026-07-22 08:20:37