Chains API (Marketplace)
The Chains API enables marketplace and platform businesses to split payments between platform and merchants. Build multi-party payment flows with automated commission handling.
Available Endpointsโ
- Create Charge Chain - POST /charges (with destination)
- Create Transfer Chain - POST /transfers (with merchant_id)
- List Chains - GET /chains
- Retrieve Chain Transfer - GET /chains/:id/transfer
Overviewโ
Chains (also called Omise Link) enable:
- Split payments - Automatically split between platform and merchants
- Commission handling - Deduct platform fees before merchant payout
- Multi-merchant charges - Charge customer and distribute to multiple recipients
- Marketplace flows - Build Uber, Airbnb, Shopify-style payment flows
- Transparent tracking - Track entire payment chain from charge to transfer
How Chains Workโ
- Customer pays - Charge created with destination (recipient)
- Platform receives - Full amount goes to platform account
- Commission deducted - Platform fee is automatically calculated
- Merchant receives - Remaining amount transferred to recipient
- Chain tracked - Entire flow linked via chain ID
Prerequisitesโ
- Chain-enabled account - Contact Omise to enable marketplace features
- Verified recipients - Recipients must be verified before receiving transfers
- KYC compliance - Recipients complete identity verification
Authenticationโ
All Chains API endpoints require authentication using your secret key.
Commission Calculationโ
Platform fees can be specified as fixed amounts and/or percentages:
Fixed Commissionโ
{
"platform_fee": {
"fixed": 50000
}
}
Deducts เธฟ500.00 (50,000 satang) from merchant payout.
Percentage Commissionโ
{
"platform_fee": {
"percentage": 10.5
}
}
Deducts 10.5% from merchant payout.
Combined Commissionโ
{
"platform_fee": {
"fixed": 10000,
"percentage": 5
}
}
Deducts เธฟ100 + 5% from merchant payout.
Calculation Exampleโ
Charge Amount: เธฟ10,000 (1,000,000 satang) Platform Fee: เธฟ100 fixed + 5% = เธฟ100 + เธฟ500 = เธฟ600 Merchant Receives: เธฟ10,000 - เธฟ600 = เธฟ9,400
Implementation Exampleโ
Creating a Chain Chargeโ
// Node.js example
const charge = await omise.charges.create({
amount: 1000000, // เธฟ10,000
currency: 'thb',
card: 'tokn_test_123',
description: 'Order #1234 - Platform Marketplace',
// Destination merchant
destination: {
amount: 950000, // เธฟ9,500 (after เธฟ500 platform fee)
recipient: 'recp_test_merchant_456'
},
// Platform fee
platform_fee: {
fixed: 50000 // เธฟ500
},
metadata: {
order_id: '1234',
merchant_id: 'merchant_456',
customer_email: 'customer@example.com'
}
});
console.log('Chain ID:', charge.id);
console.log('Status:', charge.status);
Important Notesโ
- destination.amount must be less than or equal to charge amount minus platform fee
- Total of destination amounts cannot exceed charge amount
- Platform fee is deducted from the destination amount
- Funds are held in platform account until transfer is initiated
Chain Status Lifecycleโ
Chains progress through these stages:
- Charge Created - Customer payment processed
- Charge Successful - Payment confirmed
- Transfer Pending - Waiting for transfer schedule
- Transfer Created - Transfer to merchant initiated
- Transfer Sent - Funds sent to recipient's bank
- Transfer Paid - Merchant received funds
Multiple Recipientsโ
You can split payments to multiple merchants:
{
amount: 1000000, // เธฟ10,000
destinations: [
{
amount: 400000, // เธฟ4,000 to merchant A
recipient: 'recp_test_merchant_a'
},
{
amount: 350000, // เธฟ3,500 to merchant B
recipient: 'recp_test_merchant_b'
}
],
platform_fee: {
fixed: 250000 // เธฟ2,500 platform keeps
}
}
Webhook Eventsโ
Monitor chain progress with webhooks:
charge.complete- Customer payment successfultransfer.create- Merchant transfer initiatedtransfer.sent- Funds sent to merchanttransfer.paid- Merchant received funds
Error Handlingโ
| Error | Description | Solution |
|---|---|---|
chain_not_enabled | Account not enabled for chains | Contact support to enable |
invalid_destination | Recipient not found or inactive | Verify recipient exists and is active |
destination_amount_exceeds_charge | Destination sum > charge amount | Reduce destination amounts |
insufficient_balance | Not enough balance for transfer | Charge must complete before transfer |
Best Practicesโ
1. Verify Recipients Firstโ
Ensure all recipients are verified before creating chain charges:
const recipient = await omise.recipients.retrieve('recp_test_123');
if (recipient.verified === false) {
throw new Error('Recipient not verified');
}
2. Use Metadata for Trackingโ
Store order and merchant details:
{
"metadata": {
"order_id": "ord_123",
"merchant_id": "merch_456",
"commission_rate": "5%"
}
}
3. Handle Failed Transfersโ
Not all transfers will succeed. Monitor webhooks and retry if needed:
if (transfer.status === 'failed') {
// Log failure reason
console.error('Transfer failed:', transfer.failure_code);
// Notify merchant
await notifyMerchant(transfer.recipient, transfer.failure_message);
}
4. Reconcile Dailyโ
Match charges to transfers daily for accurate accounting:
- List all chains for a date range
- Verify each charge has corresponding transfer
- Track commission totals
Limitationsโ
- Minimum transfer amount: เธฟ20 (2,000 satang)
- Maximum recipients per charge: 10
- Platform fee cannot exceed charge amount
- Recipients must have verified bank accounts
- Transfers follow standard settlement schedule (7 days Thailand, 21 days Japan)
Related Resourcesโ
- Recipients API - Create and manage merchant recipients
- Transfers API - Manual transfer operations