1. API
v2.1 (Sandbox)
  • v2.1 (Production)
  • v2.1 (Sandbox)
  • v2.0 (Sandbox)
  • v1.0 (Deprecated)
  • API
    • Getting Started
    • Account Setup For PSP
    • Account Setup For Direct Client
    • Idempotent Requests
    • Webhook
    • API Error Handling Guide
    • Changelog
    • Authentication
      • Create Token
    • Account Management
      • Get Balance
      • Internal Transfer
      • Get Internal Transfer
    • Merchant Management
      • Create Merchant
      • Get Merchant
      • Initiate Merchant Activation
      • Confirm Merchant Activation
      • Merchant Status Webhook
    • Fiat Payment
      • Fiat Deposit
        • Get Deposit Bank Account
        • Get Fiat Deposit Detail
        • Get Fiat Deposit History
        • Fiat Deposit Webhook
      • Fiat Account Management
        • Get Fiat Account Capabilities
        • Create Fiat Account Request
        • Submit Additional Information for Fiat Account Request
        • Get Fiat Account Application Status
        • Get Bank Accounts
        • Add Bank Account
        • Fiat Account Request Status Webhook
      • Fiat Withdrawal
        • Get Same Name Withdrawal Capabilities
        • Activate Same Name Withdrawal
        • Submit Additional Information for Activating Same Name Withdrawal
        • Activate Same Name Withdrawal Webhook
        • Create Fiat Withdrawal
        • Submit Additional Information for Fiat Withdrawal Request
        • Get Fiat Withdrawal Detail
        • Get Fiat Withdrawal History
        • Fiat Withdrawal Webhook
    • Crypto Payment
      • Crypto Deposit
        • Update Crypto Deposit Travel Rule Info
        • Get Crypto Deposit Wallet
        • Get Crypto Deposit
        • Get Crypto Deposit History
        • Crypto Deposit Webhook
      • Crypto Withdrawal
        • Register Wallet Address
        • Remove Wallet Address
        • Create Crypto Withdrawal
        • Get Wallet Address
        • Get Crypto Withdrawal
        • Get Crypto Withdrawal History
        • Crypto Withdrawal Webhook
      • Crypto Checkout v1.0
        • Create Crypto Checkout
        • Create Crypto Checkout Link
        • Crypto Checkout Wallet Connection
        • Generate POS Payment Request
        • Close Crypto Checkout
        • Get Convertible Cryptos
        • Get Supported Blockchains
        • Get Crypto Checkout
        • Get Crypto Checkout Link
        • Get Crypto Checkout Currencies
        • Crypto Checkout Webhook
      • Crypto Refund v1.0
        • Create Crypto Refund
        • Confirm Crypto Refund
        • Get Crypto Refund
        • Crypto Refund Webhook
      • Crypto Checkout v2.0
        • Create Checkout
        • Create Crypto Quotation
        • Confirm Checkout
        • Order Accept
        • Get Checkout History
        • Get Checkout
        • Close Checkout
        • Get Checkout Acceptable Cryptos
        • Checkout Status Webhook
      • Crypto Refund v2.0
        • Create Crypto Void
        • Create Crypto Risk Refund
        • Create Crypto Refund
        • Close Crypto Refund
        • Get Crypto Refund
        • Get Checkout Refundable Info
        • Refund Status Webhook
    • Conversion
      • Create Quotation
      • Create Conversion
      • Get Quotation
      • Get Conversion
      • Conversion Webhook
    • Statements
      • Create statement
      • Get statement overview
      • Get statement entries
      • Get statement transactions
    • Points
      • Get Points Balance
      • List Points Transactions
      • Get Points Transaction Detail
    • Fee Estimate
      • Fee Estimate
    • Tool
      • Upload File
      • getTnC
      • Validate Crypto Address
  1. API

Changelog

All API changes for the CAMP Connect API, consolidated from individual changelog entries.
DateKey Changes
2026-07-17Merchant Activation APIs
2026-07-07Crypto Checkout & Refund v2.0 (16 new APIs)
2026-06-16Modified APIs
2026-06-12Fee Estimate, Address Validation
2026-06-02Statements, Points APIs
2026-04-02Initial v2.0 release (73 APIs)

20260402#

Executive Summary#

StatusCountNote
New APIs0-
Deleted APIs1Fully removed
Modified APIs39With field-level changes
Unchanged APIs33No 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: POST
Summary Change:
Old: Get Token
New: Create Token
Request Body Changes:
client_id (Deleted)
Type: string
Required: True
Description: Client's ID
client_secret (Deleted)
Type: string
Required: True
Description: Client's Secret
clientId (Added)
Type: string
Required: True
Description: Client's ID
clientSecret (Added)
Type: string
Required: True
Description: Client's Secret
Response Body Changes:
access_token (Deleted)
Type: string
Required: False
Description: Access token
expires_in (Deleted)
Type: integer
Required: False
Description: Token expiry time
not-before-policy (Deleted)
Type: integer
Required: False
Description: A timestamp before which tokens are considered invalid
refresh_expires_in (Deleted)
Type: integer
Required: False
Description: Time in seconds until the token expiry is refreshed
scope (Deleted)
Type: string
Required: False
Description: Scope included in the token
token_type (Deleted)
Type: string
Required: False
Description: Token type
accessToken (Added)
Type: string
Required: False
Description: Access token
expiresIn (Added)
Type: integer
Required: False
Description: Token expiry time
tokenType (Added)
Type: string
Required: False
Description: Token type

Account Management#

Get Balance#

Path: /v1.0/ledger/account → /v2.0/ledger/account
Method: GET

Get Internal Transfer#

Path: /v1.0/payment/account/getInternalTransfer → /v2.0/payment/account/getInternalTransfer
Method: GET
Response Body Changes:
data
createdAt
Type: string -> integer
Description 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: POST
Response Body Changes:
data
createdAt
Type: string -> integer
Description Change:
Old: Transfer transaction time
New: Transfer transaction time (Unix timestamp in milliseconds)

Merchant Management#

Create Merchant#

Path: /v2.0/crm/addressBook/createMerchant
Method: POST
Request Body Changes:
merchantDetails
personalDetails
contactNumber
Description Change:
Old:
New: Phone number for contact, country code + Number. eg, +65 87654321
dateOfBirth
Description Change:
Old: Date of birth (UTC format)
New: Date of birth, format: YYYY-MM-DD, e.g., 1990-05-15
taxResidency
Description Change:
Old:
New: The country of tax residency (Country Code in ISO 3166-1 alpha-2 format)
corporationDetails
dateOfIncorporation
Description Change:
Old: Date of Incoporation
New: Date of Incoporation, format: YYYY-MM-DD, e.g., 1990-05-15
Response Body Changes:
data
merchantInfo
merchantDetails
personalDetails
contactNumber
Description Change:
Old:
New: Phone number for contact, country code + Number. eg, +65 87654321
dateOfBirth
Description Change:
Old: Date of birth (UTC format)
New: Date of birth, format: YYYY-MM-DD, e.g., 1990-05-15
taxResidency
Description Change:
Old:
New: The country of tax residency (Country Code in ISO 3166-1 alpha-2 format)
corporationDetails
dateOfIncorporation
Description Change:
Old: Date of Incoporation
New: Date of Incoporation, format: YYYY-MM-DD, e.g., 1990-05-15
status
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: GET
Response Body Changes:
data
merchantInfo
merchantDetails
personalDetails
contactNumber
Description Change:
Old:
New: Phone number for contact, country code + Number. eg, +65 87654321
dateOfBirth
Description Change:
Old: Date of birth (UTC format)
New: Date of birth, format: YYYY-MM-DD, e.g., 1990-05-15
taxResidency
Description Change:
Old:
New: The country of tax residency (Country Code in ISO 3166-1 alpha-2 format)
corporationDetails
dateOfIncorporation
Description Change:
Old: Date of Incoporation
New: Date of Incoporation, format: YYYY-MM-DD, e.g., 1990-05-15
merchantStatus
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: GET
Get Fiat Deposit Detail#
Path: /v1.0/payment/fiat/deposit/detail → /v2.0/payment/fiat/deposit/detail
Method: GET
Response Body Changes:
data
createdAt
Type: string -> integer
Description 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: GET
Response Body Changes:
data
endTime
Description Change:
Old:
New: Unix timestamp in milliseconds
startTime
Description Change:
Old:
New: Unix timestamp in milliseconds
transactions
createdAt
Type: string -> integer
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: POST
Get Bank Accounts#
Path: /v1.0/crm/addressBook/bankAccount → /v2.0/crm/addressBook/bankAccount
Method: GET
Get Fiat Account Application Status#
Path: /v2.0/crm/fiatAccount/appStatus
Method: GET
Response Body Changes:
data
status
Description Change:
Old: Status of the request
New: Status of the request Enum values: - 1: PENDING - 2: PROCESSING - 3: ACTIVE - 4: REJECTED
Submit Additional Information for Fiat Account Request#
Path: /v2.0/crm/fiatAccount/addInfo/submit
Method: POST
Response Body Changes:
data
status
Description Change:
Old: Status of the request
New: Status of the request Enum values: - 1: PENDING - 2: PROCESSING - 3: ACTIVE - 4: REJECTED
updatedAt
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: POST
Request Body Changes:
amount
Type: number -> string
withdrawalType
Description Change:
Old: First or third party withdrawal
New: First or third party withdrawal Enum values: - 1: First Party - 2: Third Party
Response Body Changes:
data
amount
Type: number -> string
estimatedAmountReceivable
Type: number -> string
fees
Type: number -> string
missingFields
Description Change:
Old: Missing fields for the withdrawal request. Ref. to {} for details
New: Missing fields
status
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
withdrawalType
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: GET
Response Body Changes:
data
amount
Type: number -> string
estimatedAmountReceivable
Type: number -> string
fees
Type: number -> string
swiftChargingCode
Description Change:
Old:
New: 1-BEN (Beneficiary Pays All Fees), 2-OUR (Sender Pays All Fees), 3-SHA (Shared Fees).
withdrawalType
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: GET
Response Body Changes:
data
endTime
Description Change:
Old: The end time
New: The end time (Unix timestamp in milliseconds)
startTime
Description Change:
Old: The start time
New: The start time (Unix timestamp in milliseconds)
transactions
amount
Type: number -> string
estimatedAmountReceivable
Type: number -> string
fees
Type: number -> string
swiftChargingCode
Description Change:
Old:
New: Swift charging code: 1-BEN (Beneficiary Pays All Fees), 2-OUR (Sender Pays All Fees), 3-SHA (Shared Fees).
withdrawalType
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: GET
Response Body Changes:
data
udpatedAt (Deleted)
Type: integer
Required: False
Description: Update time
updatedAt (Added)
Type: integer
Required: False
Description: Update time
status
Description 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
Enum Change: Add: [9]
Get Crypto Deposit History#
Path: /v1.0/payment/getCryptoDepositHistory → /v2.0/payment/getCryptoDepositHistory
Method: GET
Response Body Changes:
data
transactions
udpatedAt (Deleted)
Type: integer
Required: False
Description: Update time
updatedAt (Added)
Type: integer
Required: False
Description: Update time
status
Description 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
Enum Change: Add: [9]
Get Crypto Deposit Wallet#
Path: /v1.0/crm/deposit/wallet → /v2.0/crm/deposit/wallet
Method: GET
Update Crypto Deposit Travel Rule Info#
Path: /v1.0/payment/crypto/updateCryptoDepositTravelRuleInfo → /v2.0/payment/crypto/updateCryptoDepositTravelRuleInfo
Method: POST
Request Body Changes:
ownerInfo
Required: False -> True
Description Change:
Old: required if "isOwner" is false
New: Owner information
platformUserId
Description Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
Response Body Changes:
data
Type: object -> null
Required: True -> False

Crypto Payment#

Crypto Withdrawal#

Create Crypto Withdrawal#
Path: /v1.0/payment/crypto/createCryptoWithdrawal → /v2.0/payment/crypto/createCryptoWithdrawal
Method: POST
Request Body Changes:
amount
Type: number -> string
Response Body Changes:
data
amount
Type: number -> string
beneficiaryWallet
platformUserId
Description Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
feeAmount
Type: number -> string
Get Crypto Withdrawal#
Path: /v1.0/payment/getCryptoWithdrawal → /v2.0/payment/getCryptoWithdrawal
Method: GET
Response Body Changes:
data
amount
Type: number -> string
beneficiaryWallet
platformUserId
Description Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
feeAmount
Type: number -> string
Get Crypto Withdrawal History#
Path: /v1.0/payment/getCryptoWithdrawalHistory → /v2.0/payment/getCryptoWithdrawalHistory
Method: GET
Response Body Changes:
data
transactions
amount
Type: number -> string
beneficiaryWallet
platformUserId
Description Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
feeAmount
Type: number -> string
Get Wallet Address#
Path: /v1.0/payment/crypto/getWalletAddress → /v2.0/payment/crypto/getWalletAddress
Method: GET
Response Body Changes:
data
platformUserId
Description 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: POST
Request Body Changes:
platformUserId
Description Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
Response Body Changes:
data
platformUserId
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: POST

Conversion#

Create Conversion#

Path: /v1.0/trade/conversion/createConversion → /v2.0/trade/conversion/createConversion
Method: POST

Create Quotation#

Path: /v1.0/trade/conversion/createQuotation → /v2.0/trade/conversion/createQuotation
Method: POST
Request Body Changes:
clientReference (Deleted)
Type: string
Required: False
Response Body Changes:
data
clientReference (Deleted)
Type: string
Required: False

Get Conversion#

Path: /v1.0/trade/conversion/getConversion → /v2.0/trade/conversion/getConversion
Method: GET

Get Quotation#

Path: /v1.0/trade/conversion/getQuotation → /v2.0/trade/conversion/getQuotation
Method: GET

Tool#

Upload File#

Path: /v2.0/auth/tools/upload
Method: POST
Response Body Changes:
fileId (Deleted)
Type: string
Required: False
Description: The unique id of the uploaded file
fileSize (Deleted)
Type: integer
Required: False
Description: The size of the uploaded file (byte)
code (Added)
Type: string
Required: True
Description: Response Code
data (Added)
Type: object
Required: True
msg (Added)
Type: string
Required: False
Description: Response Message

getTnC#

Path: /v2.0/tool/getTnC/{tncId}
Method: GET
Response Body Changes:
data
effectiveFrom
Type: string -> integer
Description 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: POST
Request Body Changes:
eventType
Description Change:
Old: api_conversion_status_update
New: conversion.updated.v2

Crypto Deposit Webhook#

Type: Webhook
Name: Crypto Deposit Webhook
Method: POST
Request Body Changes:
data
udpatedAt (Deleted)
Type: integer
Required: False
Description: Update time
updatedAt (Added)
Type: integer
Required: False
Description: Update time
status
Description 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
Enum Change: 新增: [9]
eventType
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: POST
Request Body Changes:
data
amount
Type: number -> string
beneficiaryWallet
platformUserId
Description Change:
Old: Platform user id
New: required if "walletType" is "Platform Wallet"
feeAmount
Type: number -> string
eventType
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: POST
Request Body Changes:
data
status
Description Change:
Old: Status of the request
New: Status of the request Enum values: - 1: PENDING - 2: PROCESSING - 3: ACTIVE - 4: REJECTED
eventType
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: POST
Request Body Changes:
data
createdAt
Type: string -> integer
Description Change:
Old: Timestamp of deposit transaction, ISO-8601
New: Timestamp of deposit transaction (Unix timestamp in milliseconds)
eventType
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: POST
Request Body Changes:
data
amount
Type: number -> string
estimatedAmountReceivable
Type: number -> string
fees
Type: number -> string
swiftChargingCode
Description Change:
Old:
New: Swift charging code: 1-BEN (Beneficiary Pays All Fees), 2-OUR (Sender Pays All Fees), 3-SHA (Shared Fees).
withdrawalType
Description Change:
Old: First or third party withdrawal
New: First or third party withdrawal Enum values: 1: First Party 2: Third Party
eventType
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: POST
Request Body Changes:
data
updateAt (Deleted)
Type: integer
Required: True
Description: Update timestamp, UNIX timestamp in milliseconds (e.g., 1715000000000)
updatedAt (Added)
Type: integer
Required: True
Description: Update timestamp, UNIX timestamp in milliseconds (e.g., 1715000000000)
merchantInfo
merchantDetails
personalDetails
contactNumber
Description Change:
Old:
New: Phone number for contact, country code + Number. eg, +65 87654321
dateOfBirth
Description Change:
Old: Date of birth (UTC format)
New: Date of birth, format: YYYY-MM-DD, e.g., 1990-05-15
taxResidency
Description Change:
Old:
New: The country of tax residency (Country Code in ISO 3166-1 alpha-2 format)
corporationDetails
dateOfIncorporation
Description Change:
Old: Date of Incoporation
New: Date of Incoporation, format: YYYY-MM-DD, e.g., 1990-05-15
status
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
eventType
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:
MethodPathName
GET/v1.0/payment/getStatementGet Settlement Statement


20260602#

Executive Summary#

StatusCountNote
New APIs4-
Deleted APIs0Fully removed
Modified APIs0With field-level changes

New APIs#

MethodPathName
POST/v2.0/payment/statementsCreate statement
GET/v2.0/payment/statements/{statementId}Get statement overview
GET/v2.0/payment/statements/{statementId}/entriesGet statement entries
GET/v2.0/payment/statements/{statementId}/transactionsGet statement transactions


20260612#

Executive Summary#

StatusCountNote
New APIs4-
Deleted APIs0Fully removed
Modified APIs0With field-level changes

New APIs#

MethodPathName
POST/v2.0/payment/withdrawal/feeEstimateFee Estimate
GET/v2.0/points/balanceGet Points Balance
GET/v2.0/points/transactionsList Points Transactions
GET/v2.0/points/transactions/detailGet Points Transaction Detail


20260616#

Changelog 20260616#

Executive Summary#

StatusCountNote
New APIs0—
Deleted APIs0—
Modified APIs3Field-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)
Method: POST
Summary Change: Unchanged.
Description Change: Updated to reflect 20260616 tier rules and new fields.

Request Body Changes#

merchantDetails → additionalCorporationDetails → natureOfBusiness (Modified)
PropertyOldNew
Typeintegerinteger (unchanged)
RequiredYes (tier 3 only)Yes (all tiers)
Enum values1–181–24
Description"The nature of the company's business"Extended with full label mapping
Enum label changes (1–18):
ValueOld LabelNew Label
2ManufacturingManufacturing and Industrial
6Hospitality and TourismHospitality and Travel
7Real Estate and ConstructionReal Estate and E-Commerce
8Health Care and PharmaceuticalsHealthcare
9Professional and ServicesProfessional Services
16Multimedia and EntertainmentMedia and Entertainment
17Cryptocurrency MiningCryptocurrency & 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.
New enum values (19–24):
ValueLabel
19Insurance & Wealth
20Trading & Commodities
21Digital Products & Online Services
22Business Support Services
23Gaming
24Advertising
merchantDetails → additionalCorporationDetails → otherNatureOfBusiness (New)
PropertyValue
Typestring
RequiredNo (optional)
DescriptionSpecific business nature description. Use when natureOfBusiness = 18 (Others).
merchantDetails → additionalCorporationDetails → sourceOfWealth (Modified)
PropertyOldNew
Typearray[string]array[string] (unchanged)
RequiredNoYes (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)
PropertyOldNew
Typearray[string]array[string] (unchanged)
RequiredNoYes (tier 3)
Description"Source of wealth""Source of wealth. Required for tier 3 as of 20260616."

Tier Rule Changes#

TierOld BehaviorNew Behavior
Tier 1/2 (Corporate)additionalCorporationDetails not availableCan 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 optionaladditionalCorporationDetails required; sourceOfWealth now required (8 fields: operatingAddress, companyType, descriptionOfBusiness, purposesOfAccountOpening, sourceOfFunds, authSignatories, directors, sourceOfWealth)
Tier 3 (Individual)additionalPersonalDetails optional; sourceOfWealth optionaladditionalPersonalDetails 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)
Method: GET
Summary Change:
Old: Get Merchant
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):
FieldLocationType
natureOfBusinessmerchantInfo.merchantDetails.additionalCorporationDetailsinteger (1–24)
otherNatureOfBusinessmerchantInfo.merchantDetails.additionalCorporationDetailsstring
sourceOfWealthmerchantInfo.merchantDetails.additionalCorporationDetailsarray[string]
sourceOfWealthmerchantInfo.merchantDetails.additionalPersonalDetailsarray[string]

3. Merchant Status Webhook#

Path: Partner-implemented webhook endpoint (unchanged)
Method: POST
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)#

ValueLabelStatus
1Financial ServicesUnchanged
2Manufacturing and IndustrialRenamed
3Information TechnologyUnchanged
4Agriculture and FarmingUnchanged
5Retail and WholesaleUnchanged
6Hospitality and TravelRenamed
7Real Estate and E-CommerceRenamed
8HealthcareRenamed
9Professional ServicesRenamed
10Education and TrainingUnchanged
11Non Profit and CharityUnchanged
12Transaction and LogisticsUnchanged
13Energy and UtilitiesUnchanged
14TelecommunicationsUnchanged
15Government and Public SectorUnchanged
16Media and EntertainmentRenamed
17Cryptocurrency & Digital AssetsRenamed
18OthersUnchanged
19Insurance & WealthNew
20Trading & CommoditiesNew
21Digital Products & Online ServicesNew
22Business Support ServicesNew
23GamingNew
24AdvertisingNew

20260707#

Changelog 20260707#

Executive Summary#

StatusCountNote
New APIs17Crypto Checkout
Deleted APIs0—
Modified APIs9Withdrawal — 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#

MethodPathNameStatus
POST/v2.0/payment/crypto/checkoutsCreate Checkoutreleased
POST/v2.0/payment/crypto/checkouts/quotationsCreate Checkout Quotationreleased
POST/v2.0/payment/crypto/checkouts/{checkoutId}/confirmConfirm Checkoutreleased
POST/v2.0/payment/crypto/checkouts/{checkoutId}/acceptAccept Checkoutdeveloping
GET/v2.0/payment/crypto/checkouts/historyList Checkout Historydeveloping
GET/v2.0/payment/crypto/checkouts/{checkoutId}Get Checkout Detailreleased
POST/v2.0/payment/crypto/checkouts/{checkoutId}/closeClose Checkoutreleased
GET/v2.0/payment/crypto/checkouts/cryptosGet Checkout Acceptable Cryptosreleased
POST(partner webhook)Checkout Status Webhookreleased

Crypto Refund#

MethodPathNameStatus
POST/v2.0/payment/crypto/refunds/refundCreate Refundreleased
POST/v2.0/payment/crypto/refunds/risk-refundCreate Risk Refundreleased
POST/v2.0/payment/crypto/refunds/voidCreate Void Refundreleased
POST/v2.0/payment/crypto/refunds/{refundId}/closeClose Refundreleased
GET/v2.0/payment/crypto/refunds/{refundId}Get Refund Detailreleased
GET/v2.0/payment/crypto/checkouts/{checkoutId}/refundable-infoGet Checkout Refundable Inforeleased
POST(partner webhook)Refund Status Webhookreleased

Address#

MethodPathNameStatus
POST/v2.0/payment/crypto/addresses/validateValidate Crypto Addressreleased

A.2 Detailed Endpoint Descriptions#

A.2.1 Create Checkout#

POST /v2.0/payment/crypto/checkouts
Create a new crypto checkout order. Supports individual and corporate buyers with tiered KYC requirements (threshold: 1000 USD).

Request Body#

FieldTypeRequiredDescription
participantCodestringYesParticipant's (merchant) code
orderAmountstringYesAmount to be paid
orderCurrencystringYesPayment currency code (e.g. USD)
expiryintegerYesOrder expiration timestamp in milliseconds
buyerInfooneOfYesIndividualBuyerInfo or CorporateBuyerInfo (see below)
productInfoobjectYes{"productName" (required), "description", "productImageUrl"}
clientCheckoutIdstringYesExternal client checkout ID (unique per merchant)
checkoutConfigurationobjectNoUI/UX config: merchantName, merchantLogo, redirectUrl, customerSupportEmail, defaultLanguage (ENGLISH/CHINESE), checkoutLinkLogo, feeBearer (BUYER/MERCHANT)
paymentMethodobjectNoPre-select {"paymentCurrency", "blockchain"}. If provided, acceptableCryptos in response is null
Individual Buyer (buyerInfo oneOf option 1):
FieldTypeRequiredDescription
firstNamestringYesFirst name
lastNamestringYesLast name
middleNamestringNoMiddle name
residentialAddressobject≥1000 USDAddress fields: country, state, city, postcode, addressLine1, addressLine2
identityTypestringNoPASSPORT or NRIC
identityNumberstring≥1000 USDIdentity document number
dateOfBirthstring≥1000 USDFormat: YYYY-MM-DD
placeOfBirthstring≥1000 USDPlace of birth
nationalitystringNoISO 3166-1 alpha-2
≥1000 USD: at least one of {residentialAddress, identityNumber, dateOfBirth + placeOfBirth} required.
Corporate Buyer (buyerInfo oneOf option 2):
FieldTypeRequiredDescription
companyNamestringYesCompany name
registeredAddressobject≥1000 USDRegistered business address
businessRegistrationNumberstring≥1000 USDBusiness registration number
countryOfIncorporationstring≥1000 USDISO 3166-1 alpha-2
dateOfRegistrationstring≥1000 USDDate of registration

Response (200)#

FieldTypeDescription
checkoutIdstringe.g. CKO_20240115_001
statusstringOPENING
checkoutUrlstring (uri)Checkout page URL
orderAmountstringOrder amount
orderCurrencystringOrder currency
createdAtintegerCreation timestamp
acceptableCryptosarrayAccepted [{cryptoCurrency, blockchains[]}] (null if paymentMethod specified)
checkoutConfigurationobjectEcho of config
paymentMethodobjectPayment method details
Errors: 400 BadRequest, 401 Unauthorized

A.2.2 Create Checkout Quotation#

POST /v2.0/payment/crypto/checkouts/quotations
Create an exchange rate quotation for a checkout order.

Request Body#

FieldTypeRequiredDescription
participantCodestringYesParticipant code
orderAmountstringYesOrder amount
orderCurrencystringYesOrder currency code
paymentCurrencystringYesPayment cryptocurrency (e.g. USDT)

Response (200)#

FieldTypeDescription
quotationIdstringQuotation ID
participantCodestringParticipant code
pricestringExchange rate
paymentAmountstringAmount in cryptocurrency
paymentCurrencystringPayment cryptocurrency
orderAmountstringOrder amount
orderCurrencystringOrder currency
quotationExpiryintegerExpiry timestamp (ms)
Errors: 400 BadRequest

A.2.3 Confirm Checkout#

POST /v2.0/payment/crypto/checkouts/{checkoutId}/confirm
Confirm a checkout with selected cryptocurrency and blockchain. Optionally reuses an existing quotation.

Path Parameters#

ParameterTypeRequired
checkoutIdstringYes

Request Body#

FieldTypeRequiredDescription
paymentCurrencystringYese.g. USDT
blockchainstringYese.g. TRC20
quotationIdstringNoQuotation ID to reuse
emailstringNoEmail for refund address collection

Response (200)#

FieldTypeDescription
quotationIdstringQuotation ID
checkoutIdstringCheckout ID
statusstringAWAITING_PAYMENT
pricestringExchange rate
orderAmount / orderCurrencystringOrder details
paymentAmount / paymentCurrencystringPayment details
payeeFeeAmountobjectBuyer-side fee {amount, feeCurrency}
payerFeeAmountobjectMerchant-side fee {amount, feeCurrency}
paymentBlockchainstringBlockchain network
checkoutWalletstringReceiving address
qrCodestringBase64-encoded PNG QR
quotationExpiryintegerExpiry (ms)
emailstringRefund email
Errors: 400 BadRequest

A.2.4 Accept Checkout#

POST /v2.0/payment/crypto/checkouts/{checkoutId}/accept
Status: developing
Accept a checkout with a settlement mode.

Query Parameters#

ParameterTypeRequiredDescription
acceptModestringYesACCEPT — settle all; VOID_OVERPAYMENT — settle paymentAmount & void excess; VOID_ALL — void entire order
refundAddressstringNoRefund address for void refunds

Response (200)#

FieldTypeDescription
checkoutIdstringCheckout ID
statusstringOrder status
acceptModestringApplied mode
acceptedAtstringTimestamp
voidRefundobjectVoid refund details (when applicable)

A.2.5 List Checkout History#

GET /v2.0/payment/crypto/checkouts/history
Status: developing
List checkout history with time-range filtering and pagination.

Query Parameters#

ParameterTypeRequired
participantCodestringNo
startTimestringNo
endTimestringNo
offsetstringNo

Response (200)#

FieldTypeDescription
participantCodestringParticipant code
startTime / endTimestringQuery time range
transactionsarray[CryptoCheckoutDetail]Checkout records (see A.2.6)
paginationobject{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)#

FieldTypeDescription
checkoutIdstringCheckout ID
participantCodestringParticipant code
clientCheckoutIdstringExternal client checkout ID
statusstringOPENING → AWAITING_PAYMENT → RECEIVED → SUCCEEDED → SETTLED / EXPIRED / CLOSED
orderAmount / orderCurrencystringOrder amount & currency
paymentAmount / paymentCurrency / paymentBlockchainstringPayment details
accumulatedAmountstringTotal received
quotationId / quotationExpirystring / integerQuotation details
checkoutExpiryintegerCheckout expiry (ms)
emailstringRefund email
payeeFeeAmount / payerFeeAmountobject{amount, currency} — buyer/merchant fees
riskTobeRefundbooleantrue = to be refunded; false = not; null = no risk
receivedPaymentsarraySee below
conversionsarray[ConversionInfo]Conversion records
createdAt / updatedAtintegerTimestamps
Received Payment item:
FieldTypeDescription
receivedPaymentIdstringPayment ID
paymentSequenceintegerSequence number
paidAmount / paidCurrencystringPaid amount & currency
blockchainstringBlockchain network
fromAddressstringSender wallet
txHashstringTransaction hash
statusstringPAYMENT_DETECTED / PAYMENT_ACCEPTED / PAYMENT_REJECTED / PAYMENT_ERROR
Conversion item:
FieldTypeDescription
conversionIdstringConversion ID
quotationId / participantCode / pricestringRelated quotation
sourceCurrency / sourceAmountstringSource
destinationCurrency / destinationAmountstringDestination
statusstringINITIATED / COMPLETED / CANCELLED
createdAtintegerTimestamp
Errors: 404 NotFound

A.2.7 Close Checkout#

POST /v2.0/payment/crypto/checkouts/{checkoutId}/close
Close or settle a checkout order.

Request Body#

FieldTypeRequiredDescription
processingResultintegerYes1 = To be settled; 2 = To be closed

Response (200)#

FieldTypeDescription
checkoutIdstringCheckout ID
successbooleanOperation result
closedAtintegerClosed timestamp
Errors: 400 BadRequest

A.2.8 Get Checkout Acceptable Cryptos#

GET /v2.0/payment/crypto/checkouts/cryptos
Query accepted cryptocurrencies and blockchains for a participant and currency pair.

Query Parameters#

ParameterTypeRequired
participantCodestringYes
orderCurrencystringYes

Response (200)#

FieldTypeDescription
participantCodestringParticipant code
orderCurrencystringOrder currency
acceptableCryptosarray[{cryptoCurrency, blockchains[]}]
Errors: 404 NotFound

A.2.9 Checkout Status Webhook#

POST (partner 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/refund
Standard post-settlement refund with configurable fee bearer.

Request Body#

FieldTypeRequiredDescription
originalTransactionTypestringYesCHECKOUT or COLLECTION
originalTransactionIdstringYesOriginal transaction ID
amountstringYesRefund amount in order currency
refundCurrencystringYesOrder currency (e.g. USD)
feeBearerstringYesBUYER or MERCHANT
clientRefundIdstringYesExternal refund ID (unique)
refundInfooneOfYes{"email"} or {"refundAddress"}

Response (200)#

FieldTypeDescription
refundIdstringe.g. REF_20240115_001
refundTypestringREFUND
originalTransactionIdstringOriginal transaction ID
clientRefundIdstringExternal refund ID
amount / currencystringRefund amount & currency
blockchainstringBlockchain network
feeAmount / feeCurrencystringTransaction fee
netAmount / netAmountCurrencystringNet received amount
statusstringINITIATED → PROCESSING → COMPLETED / REJECTED / CLOSED
email / refundAddressstringRefund destination
Errors: 400 BadRequest

A.2.11 Create Risk Refund#

POST /v2.0/payment/crypto/refunds/risk-refund
KYT-triggered risk refund. Supports CHECKOUT, COLLECTION, and DEPOSIT original transaction types.

Request Body#

FieldTypeRequiredDescription
originalTransactionTypestringYesCHECKOUT, COLLECTION, or DEPOSIT
originalTransactionIdstringYesOriginal transaction ID
clientRefundIdstringYesExternal refund ID (unique)
refundCurrencystringNoRefund cryptocurrency
blockchainstringNoBlockchain network
refundInfooneOfYes{"email"} or {"refundAddress"}

Response (200)#

Same as Create Refund, with refundType = RISK_REFUND.
Errors: 400 BadRequest

A.2.12 Create Void Refund#

POST /v2.0/payment/crypto/refunds/void
Pre-settlement void. Used for overpayment, incomplete order, and wrong-currency refunds.

Request Body#

FieldTypeRequiredDescription
originalTransactionTypestringYesCHECKOUT or COLLECTION
originalTransactionIdstringYesOriginal transaction ID
clientRefundIdstringYesExternal refund ID (unique)
refundCurrencystringNoRefund cryptocurrency
blockchainstringNoBlockchain network
refundInfooneOfYes{"email"} or {"refundAddress"}

Response (200)#

Same as Create Refund, with refundType = VOID.
Errors: 400 BadRequest

A.2.13 Close Refund#

POST /v2.0/payment/crypto/refunds/{refundId}/close
Confirm and close a refund order. Empty request body {}.

Response (200)#

FieldTypeDescription
refundIdstringRefund ID
successbooleanOperation result
closedAtintegerClosed timestamp
Errors: 400 BadRequest

A.2.14 Get Refund Detail#

GET /v2.0/payment/crypto/refunds/{refundId}
Retrieve full refund details including on-chain transaction info.

Response (200)#

FieldTypeDescription
refundIdstringRefund ID
refundTypestringVOID, RISK_REFUND, or REFUND
originalTransactionIdstringOriginal transaction ID
participantCodestringMerchant code
clientRefundIdstringExternal refund ID
statusstringINITIATED / PROCESSING / COMPLETED / REJECTED / CLOSED
reasonstringFailure reason (when applicable)
blockchainstringBlockchain network
currency / amountstringRefund currency & amount
email / refundAddressstringRefund destination
feeCurrency / feeAmountstringFee details
netAmount / netAmountCurrencystringNet received
txHashstringOn-chain transaction hash
createdAt / updatedAtintegerTimestamps
Errors: 404 NotFound

A.2.15 Get Checkout Refundable Info#

GET /v2.0/payment/crypto/checkouts/{checkoutId}/refundable-info
Query refundable (settled), voidable, and KYT risk-refundable amounts. Categories with no data are null. An order with nothing refundable still returns 200.

Query Parameters#

ParameterTypeRequired
participantCodestringYes

Response (200)#

FieldTypeDescription
checkoutIdstringCheckout ID
refundableItemobject | nullSettled refundable balance
voidableItemsarray | nullVOID amounts
riskRefundableItemsarray | nullRisk-refundable amounts
Each line item: {amount: {amount, currency}, chainCode}.
Errors: 404 NotFound

A.2.16 Refund Status Webhook#

POST (partner 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/validate
Validate on-chain address format for a given blockchain. HTTP 200 whenever the check ran; outcome is in data.valid.

Request Body#

FieldTypeRequiredDescription
blockchainstringYese.g. ETH
addressstringYesOn-chain address

Response (200)#

FieldTypeDescription
blockchainstringEcho of request
addressstringEcho of request
validbooleantrue = valid format; false = invalid
Failure codes (valid: false):
failureCodeMeaning
INVALID_ADDRESSAddress format incorrect for blockchain
VALIDATION_UNAVAILABLEValidation query failed; retry later
Errors: 400 BadRequest

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)
Method: POST
Summary Change: Added amountType and feeBearer request fields; amount semantics clarified.

Request Body Changes#

amountType (New)
PropertyValue
Typeinteger
RequiredYes (for new integrations)
Enum values1 = 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
DescriptionExplicitly declares the meaning of amount. New integrations must provide this field.
feeBearer (New)
PropertyValue
Typeinteger
RequiredNo (optional)
Enum values1 = Customer (borne by trading party), 2 = Partner (borne by platform partner)
Default1 (Customer)
DescriptionWhich participant account bears the platform fee. Default behavior is unchanged from v2.0.
amount (Modified)
PropertyOldNew
Typestringstring (unchanged)
RequiredYesYes (unchanged)
MeaningImplicitly derived from withdrawalTypeExplicitly 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#

FieldTypeDescription
amountTypeintegerEchoed from request. 1=Debit, 2=Receive.
feeBearerintegerEchoed from request. 1=Customer, 2=Partner.
debitAmountstringGross 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.
receivedAmountstringNet 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)
Method: GET
Summary Change: Response now includes amountType, feeBearer, debitAmount, receivedAmount.

Response Body Changes#

FieldTypeDescription
amountTypeinteger1=Debit, 2=Receive. Echoed from creation-time value.
feeBearerinteger1=Customer, 2=Partner. Echoed from creation-time value.
debitAmountstringGross debit amount.
receivedAmountstringNet 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)
Method: GET
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)
Method: POST
Summary Change: Webhook payload now includes amountType, feeBearer, debitAmount, receivedAmount.

Payload Changes#

FieldTypeDescription
amountTypeinteger1=Debit, 2=Receive
feeBearerinteger1=Customer, 2=Partner
debitAmountstringGross debit amount
receivedAmountstringNet 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)
Method: POST
Summary Change: Added amountType and feeBearer request fields; amount semantics clarified.

Request Body Changes#

amountType (New)
PropertyValue
Typeinteger
RequiredYes (for new integrations)
Enum values1 = 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
DescriptionExplicitly declares the meaning of amount. New integrations must provide this field.
feeBearer (New)
PropertyValue
Typeinteger
RequiredNo (optional)
Enum values1 = Customer (borne by trading party), 2 = Partner (borne by platform partner)
Default1 (Customer)
DescriptionWhich participant account bears the platform fee. Default behavior is unchanged.
amount (Modified)
PropertyOldNew
MeaningImplicitly derived from withdrawalTypeExplicitly declared by amountType

Response Body Changes#

FieldTypeDescription
amountTypeintegerEchoed from request. 1=Debit, 2=Receive.
feeBearerintegerEchoed from request. 1=Customer, 2=Partner.
debitAmountstringGross debit amount — total actually debited from the trading party account.
feeAmountstringPlatform fee amount. Alias for legacy field fees.
feeCurrencystringFee currency (uppercase ISO 4217). Typically same as currency.
receivedAmountstringNet amount received by payee. Alias for legacy field estimatedAmountReceivable.
Legacy Fields Retained as Aliases:
Legacy FieldEquivalent
feesfeeAmount
estimatedAmountReceivablereceivedAmount
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)
Method: GET
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)
Method: GET
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)
Method: POST
Summary Change: Webhook payload now includes all six new fields plus legacy aliases.

Payload Changes#

FieldTypeDescription
amountTypeinteger1=Debit, 2=Receive
feeBearerinteger1=Customer, 2=Partner
debitAmountstringGross debit amount
feeAmountstringPlatform fee (alias for legacy fees)
feeCurrencystringFee currency
receivedAmountstringNet 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)
Method: POST
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#

feeBearer (New)
PropertyValue
Typestring
RequiredNo (optional)
Enum valuesCUSTOMER (default), PARTNER
DescriptionWhich participant account bears the platform fee.
debitAmount (Renamed from totalAmount, pre-production)
PropertyOldNew
NametotalAmountdebitAmount
Typestringstring (unchanged)
DescriptionGross debit amount (FIRST_PARTY only). Mutually exclusive with receivedAmount.
receivedAmount (Renamed from receiveAmount, pre-production)
PropertyOldNew
NamereceiveAmountreceivedAmount
Typestringstring (unchanged)
DescriptionNet 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 NameNew Name
totalAmountdebitAmount

B.3 Amount Semantics: Debit vs Receive#

amountTypeMeaning of amountAccount is debitedPayee receives
1 = DebitGross debit amount (including fees)amountamount - feeAmount
2 = ReceiveNet received amount (excluding fees)amount + feeAmountamount

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.
feeBearerFee deducted fromEffect
1 = Customer (default)Trading party participant accountFull debitAmount from trading party account
2 = PartnerPlatform 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#

CodeTypeSchema
400BadRequest{"code": "INVALID_REQUEST", "message": "...", "data": null}
401Unauthorized{"code": "UNAUTHORIZED", "message": "Invalid or missing API key"}
404NotFound{"code": "NOT_FOUND", "message": "Resource not found"}
500InternalServerError{"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#

TypeUse CaseEndpoint
REFUNDStandard post-settlement refund/refunds/refund
RISK_REFUNDKYT-triggered risk refund/refunds/risk-refund
VOIDPre-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#

ContextOld FieldNew FieldStatus
Request (Create Withdrawal)amount (ambiguous)amount + amountTypeOld format still accepted
ResponsefeesfeeAmountAlias (both returned)
ResponseestimatedAmountReceivablereceivedAmountAlias (both returned)
Fee Estimate requesttotalAmountdebitAmountRenamed (pre-production)
Fee Estimate requestreceiveAmountreceivedAmountRenamed (pre-production)
Fee Estimate responsetotalAmountdebitAmountRenamed (pre-production)

Checkout APIs#

The checkout API surface is additive — no existing integrations are affected.

Summary of All New Fields (20260707)#

Checkout#

FieldAPIs Where AddedTypeNotes
acceptableCryptosCreate Checkout response; GET /cryptos responsearrayAcceptable crypto+blockchain pairs
refundableItem / voidableItems / riskRefundableItemsGET /refundable-info responseobject/array/nullRefundability breakdown
valid / failureCodePOST /addresses/validate responseboolean/stringAddress validation result

Withdrawal (field-level)#

FieldAPIs Where AddedTypeEnum
amountTypeCreate Crypto/Fiat Withdrawal (request), All queries & webhooks (response)integer1=Debit, 2=Receive
feeBearerCreate Crypto/Fiat Withdrawal, Fee Estimate (request), All queries & webhooks (response)integer (withdrawal) / string (feeEstimate)1/CUSTOMER, 2/PARTNER
debitAmountAll query & webhook responsesstring—
feeAmountFiat query & webhook responsesstring—
feeCurrencyFiat query & webhook responsesstring—
receivedAmountAll query & webhook responsesstring—

20260717#

Changelog 20260717#

Executive Summary#

StatusCountNote
New APIs2Merchant Activation (Non-FI partners)
Deleted APIs0—
Modified APIs3Merchant — 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 PartnerNon-FI Partner
After creating a merchantReady to useActivation required
Calling activation endpointsReturns 400, not neededNormal
internalTransfer✅ Available❌ Not available
activationStatus valueAlways NO_NEED_ACTIVATIONFollows 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#

ValueMeaningFund-write APIs available?
NOT_ACTIVATEDMerchant created, activation not yet started❌
PENDING_ACTIVATIONOTP sent to merchant email, awaiting confirmation❌
EXPIREDOTP expired unused❌
LOCKED5 wrong OTP attempts, locked for 30 min❌
ACTIVATEDActivated (terminal)✅ (except internalTransfer)
NO_NEED_ACTIVATIONFI-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.
FieldDescription
merchantStatusKYC status: 1=PROCESSING, 2=APPROVED, 3=REJECTED
activationStatusActivation 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#

Request
FieldTypeRequiredDescription
participantCodestringYesTarget merchant
clientReferencestringNoIdempotency key, ≤100 chars
Response (200)
{
  "code": 200,
  "msg": "success",
  "data": {
    "participantCode": "B0100106",
    "activationStatus": "PENDING_ACTIVATION",
    "otpSentToMaskedEmail": "j***@e***.com",
    "otpExpiresAt": 1768636800000,
    "tncId": "N001"
  }
}
Response fieldDescription
otpSentToMaskedEmailMasked email the OTP was sent to
otpExpiresAtOTP expiry, UNIX timestamp (ms); valid for 10 minutes
tncIdAgreement 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.
Request
FieldTypeRequiredDescription
participantCodestringYesTarget merchant
otpstringYes6-digit OTP submitted by the merchant
acceptedTnCstring[]YesAgreement code(s); must match the tncId returned by initiateActivation, e.g. ["N001"]
Response (200)
{
  "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):
EndpointPathMeaning
Create Crypto WithdrawalPOST /v2.0/payment/crypto/createCryptoWithdrawalCrypto withdrawal
Create Fiat WithdrawalPOST /v2.0/payment/fiat/createWithdrawalFiat withdrawal
Activate Same Name WithdrawalPOST /v2.0/payment/fiat/sameNameWithdrawal/activateSame-name withdrawal activation
Create ConversionPOST /v2.0/trade/conversion/createConversionConversion
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#

EndpointPathType
Create MerchantPOST /v2.0/crm/addressBook/createMerchantExisting
Get MerchantGET /v2.0/crm/addressBook/getMerchantExisting (added activationStatus)
Initiate ActivationPOST /v2.0/crm/merchant/initiateActivationNew
Confirm ActivationPOST /v2.0/crm/merchant/confirmActivationNew
Get TnCGET /v2.0/tool/getTnC/{tncId}Existing (auxiliary, for displaying the agreement)
Merchant Status WebhookPOST /webhooks/merchant-status/v2Existing (added activationStatus)

Modified at 2026-07-22 08:20:37
Previous
API Error Handling Guide
Next
Create Token
Built with