References and attribution
Which reference identifies which order, per leg — and why neither leg needs you to attribute a payment any more.
Neither leg has an attribution problem to solve. The buy leg debits your own KES balance directly. The sell leg takes the USDT from your own USDT balance (or collects it from your own wallet) at the moment you create the order, so there is no deposit of yours to match to an order.
| Reference | Whose | Where it comes from | Used for |
|---|---|---|---|
partnerReference | Yours | You choose it. | Idempotent order creation, on both legs. |
partnerReference makes creation idempotent — reusing it on create returns the
existing order rather than a second one. It never attributes money; there is no
partner-supplied payment left to attribute on either leg.
Buying — nothing to attribute
POST /v1/orders/buy debits your own KES VA balance directly, the instant
the order is created. There is no payer, no rail, and no incoming payment for a
reference to identify — so there is no attribution problem on this leg at all.
kesDebit.status on the order tells you where that debit stands; see
Buy USDT with KES.
Selling — nothing to attribute either
POST /v1/orders/sell takes your USDT the instant the order is created: it is
debited from your USDT balance, or collected from your own wallet, depending on
how your account is configured. You never send USDT for a specific order, so
there is no deposit to link to one — see
Sell USDT, receive KES.
Your Tron deposit address is long-lived and the same for every one of your
orders. It tops up your USDT balance generally, so it cannot tell two of your
orders apart and is not meant to: a deposit to it announces itself with
usdt_credit.received, not against an order.
The transaction hash
PATCH /v1/orders/{id} still exists. It accepts the Tron transaction hash of a
USDT send for a sell order that is still awaiting_usdt, and it is not part of
the current sell flow — see
Sell USDT, receive KES.
A hash is normalised before comparison — case and a leading 0x are ignored,
because those are the same on-chain transaction. One hash attributes exactly one
order.
GET /v1/orders/{id} carries the hash attached to an order, once there is one:
{
"status": "usdt_received",
"txHash": "5d6a3c7b1e4f2a908c6d5b4a3928170f6e5d4c3b2a1908f7e6d5c4b3a2918070"
}txHash is null until one is attached.
Everything else that identifies a resource
partnerReference and the transaction hash are the only references THIS page
is about. Three other identifiers are easy to confuse with them:
orderId/transferId/sendId— the resource's own id, minted by us and returned on creation. Read the resource back with it (GET /v1/orders/:id,GET /v1/transfers/:id,GET /v1/usdt/sends/:id); every webhook about it carries the same id.idempotencyKey— required on transfers and USDT sends (an order usespartnerReferencefor this same role instead): a retried create with the same key returns the original resource rather than a second one. See Idempotency.- A collection's
reference— unlike everything above, this one is ours, not yours: we mint it (a short prefix, a hyphen, and 6 characters drawn from23456789ABCDEFGHJKMNPQRSTUVWXYZ— no0,1,I,LorO, the characters most easily misread off a screen or a bank statement). It is the handle you and we use for this collection — it is not what your contributor quotes. What they quote isdepositMessage, fromdepositInstructions, which is a different code. Treatreferenceas a value you receive and display, never one you generate.
Rules of thumb
partnerReferenceis for creation, not attribution. Reusing it on create returns the original order, which is what makes retries safe — it does nothing for attributing money.- One transaction hash funds one order. A hash already attributed to another
order is refused (
409); attaching a different hash to an order that already has one is refused the same way, never an overwrite. - Neither leg needs you to attribute a payment. The debit is yours, from your own balance, the moment you create the order.