Dime Bridge splits one customer payment across several merchants in your marketplace, and lets you keep a platform fee from each of them. The buyer pays once. Dime works out each merchant's share from the items they sold, takes off processing fees and your fee, and pays each merchant the rest.
Use Bridge whenever a single checkout includes items from more than one seller.
- One payment, many merchants. A single checkout pays several child merchants at once.
- Payouts worked out for you. You don't calculate or send payout amounts. Dime derives each merchant's share from the line items tagged with it.
- A platform fee per merchant. You set the fee you keep from each merchant's payout, in major units (for example
10= 10.00). - Works on every way of taking a payment: hosted checkout orders (
POST /orders), the hosted payment page (POST /payments/hosted-page), direct charges (POST /payments/sale) and authorisations (POST /payments/auth). - A full breakdown on every payment. Payment webhooks include each merchant's gross, fee and net amount, so you can reconcile in your system.
- Single-merchant carts work too. With one merchant, Bridge behaves like a normal payment with one platform fee.
- Bridge must be enabled on your account. Ask Dime support. Until it is, any request containing
splitis rejected with400onsplit. - Not available on the bank processor model.
- You need each child merchant's token (
m…). Your own merchant is never a row insplit: what you keep is expressed as thefee.
You send a normal order or charge, plus two things:
items[].merchant_id: which merchant sells each line item.split[]: one row per merchant, with itsmerchant_idand thefeeyou keep from it.
Dime checks that every item is tagged, that every merchant in the items has a
splitrow (and the other way round), and that the items add up to the total.When the buyer pays, for each merchant Dime:
- adds up the merchant's items to get its gross,
- deducts the merchant's processing fees from that gross,
- deducts your platform fee,
- credits the remainder (net) to the merchant's balance.
You keep the platform fees.
Webhooks deliver the per-merchant breakdown.
A 2,000.00 USD order with two merchants:
| Merchant | Items | Gross | Your fee | Merchant receives |
|---|---|---|---|---|
m4D8mQ1wMrdTUIg | Hardcover Book (500.00) | 500.00 | 10.00 | 500.00 − processing fees − 10.00 |
m7UarSiV9zWxN6v | Online Course (1,500.00) | 1,500.00 | 30.00 | 1,500.00 − processing fees − 30.00 |
Processing fees depend on each merchant's rates, so they aren't shown as fixed numbers here. The actual amounts arrive in the payment webhook.
All requests use your client key in the client_key header. Examples target sandbox: swap the host for production when you go live.
https://sandbox.api.dimepay.app/dapi/v2curl https://sandbox.api.dimepay.app/dapi/v2/orders \
-H "client_key: ck_your_sandbox_key" \
-H "Content-Type: application/json" \
-d '{
"id": "ORDER-10001",
"currency": "USD",
"subtotal": 2000,
"tax": 0,
"total": 2000,
"email": "buyer@example.com",
"items": [
{ "id": "SKU-BOOK-1", "name": "Hardcover Book", "price": 500, "quantity": 1, "merchant_id": "m4D8mQ1wMrdTUIg" },
{ "id": "SKU-COURSE-1", "name": "Online Course Access", "price": 1500, "quantity": 1, "merchant_id": "m7UarSiV9zWxN6v" }
],
"split": [
{ "merchant_id": "m4D8mQ1wMrdTUIg", "fee": 10 },
{ "merchant_id": "m7UarSiV9zWxN6v", "fee": 30 }
]
}'The response includes the order's checkout_url. Send the buyer there to pay.
Add the same items and split to POST /payments/sale (or POST /payments/auth), along with the saved card's token:
{
"token": "card_Xk3m9QpL2vR7tYw",
"id": "9d2b7c54-1e8f-4a36-b7c1-5f0e2d8a4c13",
"currency": "USD",
"subtotal": 2000,
"tax": 0,
"total": 2000,
"email": "buyer@example.com",
"ipAddress": "198.51.100.10",
"referenceTransactionId": "sale-10001",
"items": [
{ "id": "SKU-BOOK-1", "name": "Hardcover Book", "price": 500, "quantity": 1, "merchant_id": "m4D8mQ1wMrdTUIg" },
{ "id": "SKU-COURSE-1", "name": "Online Course Access", "price": 1500, "quantity": 1, "merchant_id": "m7UarSiV9zWxN6v" }
],
"split": [
{ "merchant_id": "m4D8mQ1wMrdTUIg", "fee": 10 },
{ "merchant_id": "m7UarSiV9zWxN6v", "fee": 30 }
]
}// Group the cart by merchant and attach your fee for each one.
function buildSplit(items, feeByMerchant) {
const merchants = [...new Set(items.map((item) => item.merchant_id))];
return merchants.map((merchant_id) => ({
merchant_id,
fee: feeByMerchant[merchant_id] ?? 0,
}));
}
const items = [
{ id: 'SKU-BOOK-1', name: 'Hardcover Book', price: 500, quantity: 1, merchant_id: 'm4D8mQ1wMrdTUIg' },
{ id: 'SKU-COURSE-1', name: 'Online Course Access', price: 1500, quantity: 1, merchant_id: 'm7UarSiV9zWxN6v' },
];
const total = items.reduce((sum, item) => sum + item.price * item.quantity, 0);
const order = {
id: 'ORDER-10001',
currency: 'USD',
subtotal: total,
tax: 0,
total,
email: 'buyer@example.com',
items,
split: buildSplit(items, { m4D8mQ1wMrdTUIg: 10, m7UarSiV9zWxN6v: 30 }),
};
const res = await fetch('https://sandbox.api.dimepay.app/dapi/v2/orders', {
method: 'POST',
headers: { client_key: process.env.DIME_CLIENT_KEY, 'Content-Type': 'application/json' },
body: JSON.stringify(order),
});
console.log((await res.json()).checkout_url);| Rule | What happens if it's broken |
|---|---|
Every line item has a merchant_id. | 400: "Bridge split orders require item-level merchant_id…" |
Every merchant in the items has a split row, every split row matches at least one item, and there are no duplicate rows. | 400 on split |
Every merchant_id is a real Dime merchant, and not your own. | 400: "split contains an invalid Dime merchant token…" |
items[].price × quantity adds up to total, to the cent. | 400: "Order line totals must equal the transaction charge…" |
| A merchant's payout can't go below zero after processing fees and your fee. | 400 on split |
| Bridge is enabled on your account. | 400: "Bridge split settlements are not enabled for this merchant…" |
feeis in major units,0or more.- Don't send a payout amount (
split[].amount). Dime always derives it from the items. - Amounts are rounded down to two decimal places.
Payment events (for example payment.succeeded) include the breakdown on payload.transaction.split[]. Each row has:
| Field | Meaning |
|---|---|
merchant_id | The child merchant. |
gross_amount | Total of that merchant's items. |
fee | The platform fee you kept. |
net_amount | What the merchant was credited after processing fees and your fee. |
The transaction also carries settlement_override and metadata.fee_breakdown, which list the processing fees applied.
- A Bridge payment is refunded in full, once. One refund reverses the payment for every merchant in the split.
- Partial refunds aren't supported. Don't send
amountwhen refunding a Bridge payment: the whole payment is refunded either way. - Once a Bridge payment has been refunded, any further refund on it returns
409("One or more transactions have already been refunded").
- Orders:
POST /ordersand thesplitanditems[].merchant_idfields. - Payments:
POST /payments/sale,/auth,/hosted-pageand/refund. - Transactions: look up a Bridge payment and its split.
- API v2 overview: webhooks, authentication and errors.
- Test cards: cards for trying Bridge in sandbox.