Deposit promo bonuses
PayIn deposit promo bonuses: a sponsored bonus on top of the merchant's regular net, and the fee_breakdown object (merchant-side picture only) in the deal.completed webhook
Deposit promo bonuses (PayIn)
A promo bonus is a deposit marketing mechanic: when a PayIn deal completes, the platform or the campaign sponsor (the merchant or the provider) credits a bonus on top of the merchant's regular net. The bonus is fully subsidized by the campaign sponsor — for the merchant, the deal economics can only improve:
- the merchant commission does not change — it is calculated from the actual payment amount, and the promo does not affect it;
- the bonus arrives with the same designation as the net — there is no separate payment or bonus claim;
- the bonus may not apply (for example, the campaign budget is exhausted) — the payment then goes through the regular path, with no promo fields in the breakdown (see below).
What the merchant sees
The final breakdown arrives in the deal.completed webhook (V2 only):
the payload carries a fee_breakdown object with your merchant-side
picture only: the amount, your commission, your net (+ a bonus line when a
promo applies); the platform's internal costs are not disclosed (the Stripe
Connect / Adyen canon: gross, the client's commission, and their net go out;
the platform's cost stays internal). For the webhook itself (signature,
delivery, retries), see Callbacks.
fee_breakdown object fields
All amounts are int64 in USDT cents and are passed in JSON as
strings (the same proto3 JSON rule as for the webhook's other int64
values):
| Field | Type | Presence | Description |
|---|---|---|---|
gross_usdt_cents | int64 | Always | The total USDT equivalent of the payment. |
merchant_commission_usdt_cents | int64 | Always | Your commission on the deal (gross − merchant_cut); calculated from the actual payment amount. |
merchant_cut_usdt_cents | int64 | Always | Your net before the promo bonus. |
promo_bonus_usdt_cents | int64 | Only when a promo is applied | The bonus in USDT cents credited on top of the net. |
promo_id | string(UUID) | Only when a promo is applied | The identifier of the applied campaign rule. |
promo_sponsor_type | string | Only when a promo is applied | The bonus sponsor: PLATFORM / MERCHANT / PROVIDER. |
The platform's internal costs (the provider's cost, team and agent shares, the platform's take) are not disclosed in the object: only the merchant-side picture goes out — the amount, their commission, their net.
The promo line and when it is missing
The promo fields (promo_bonus_usdt_cents, promo_id,
promo_sponsor_type) are present in the object only when a promo is
applied. In every other case, the fee_breakdown object still arrives —
with the merchant-side picture but without the promo fields:
- the campaign does not match the payment (amount, method, active window) — the rule did not match;
- the promo was skipped — the rule matched, but the bonus was not paid out (for example, the campaign budget is exhausted). The payment goes through the regular path, and the deal completes normally.
Amount reconciliation
promo_bonusis part of the total credit to the merchant's balance, with the same designation as the net, and is reflected separately in the breakdown — reconcile the credit asmerchant_cut_usdt_cents + promo_bonus_usdt_cents(when a promo is applied);- the promo bonus arrives on top, funded by the sponsor, rather than
redistributing the payment: it changes neither
gross_usdt_cents, nor your commission, nor the net — the platform's internal cost structure stays undisclosed; - the merchant commission (
merchant_commission_usdt_cents) does not depend on the promo — reconcile it against the rate for the actual payment amount as before.
Payload examples
deal.completed (PayIn, V2) — with a promo applied (the promo_* line
in fee_breakdown):
{
"event": "deal.completed",
"deal_id": "7ac148fe-19a3-45bb-b992-019fac55b721",
"merchant_id": "8f870a31-b88d-4cb0-a882-628d08cbda88",
"tenant_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": "150000",
"currency": "RUB",
"status": "COMPLETED",
"timestamp": "2026-09-17T10:00:00Z",
"received_amount": "150000",
"amount_match_status": "full",
"fee_breakdown": {
"gross_usdt_cents": "150000",
"merchant_commission_usdt_cents": "2500",
"merchant_cut_usdt_cents": "147500",
"promo_bonus_usdt_cents": "750",
"promo_id": "0f0e0d0c-0b0a-4909-9807-060504030201",
"promo_sponsor_type": "PLATFORM"
}
}The same completion without a promo — the object is present, the promo fields are not:
{
"event": "deal.completed",
"deal_id": "7ac148fe-19a3-45bb-b992-019fac55b721",
"merchant_id": "8f870a31-b88d-4cb0-a882-628d08cbda88",
"tenant_id": "550e8400-e29b-41d4-a716-446655440000",
"amount": "150000",
"currency": "RUB",
"status": "COMPLETED",
"timestamp": "2026-09-17T10:00:00Z",
"received_amount": "150000",
"amount_match_status": "full",
"fee_breakdown": {
"gross_usdt_cents": "150000",
"merchant_commission_usdt_cents": "2500",
"merchant_cut_usdt_cents": "147500"
}
}API versions
The fee_breakdown object and the promo line are available to V2
merchants only: the legacy V1 envelope does not receive the new fields
(gated by api_version), and the V1 notification payload stays unchanged.
Migrating merchants should see Notification types in the adapter (V1
compatibility).
The fee_breakdown field exists only in deal.completed of V2
merchants' PayIn deals; other events and API versions are unaffected.
The platform's internal costs are not disclosed in the object: only the
merchant-side picture goes out (a change dated 2026-09-17 — see the
Changelog). Handlers that do not read this object keep
working unchanged.