Skip to main content
Here’s every event we send for checkout sessions, what’s in each one, and how to handle them.

checkout.pending

Sent once, as soon as we see the payment arrive. It isn’t a confirmation. It’s an early signal so your customer isn’t left staring at a blank screen while we convert or move the money.
string
required
Always checkout.pending.
string
The network the payment came in on.
string
The blockchain transaction ID of the payment.
string
USDC or USDT, whichever your customer paid with.
string
required
Always deposit_received.
This is not checkout.completed. The payment could still fail. Tell your customer “we’ve seen it, hang on”, but don’t hand over goods on this alone.

checkout.completed

You’ve been paid and the money is yours, either as local currency in your account or as USDC in your Minisend wallet.
string
required
Always checkout.completed.
string
required
Use it together with event to spot repeats. See best practices.
string
Your reference, if you set one.
number
required
The amount you asked for. This isn’t always what arrived. See amount_received_usdc.
number
required
The amount you asked for. Same as amount_usdc. Compare it with amount_received_usdc.
number
What your customer actually sent. Use this one in your books, not amount_usdc.If a customer sends a little more or less than you asked for, we still pay you out for what they sent, so their money isn’t stuck. That means a completed payment can show an amount_usdc you never received.
boolean
false when the amount received was more than $0.01 away from what you asked for. Take a look at these: the payout is real, but it isn’t the amount you quoted.
string
The network the payment came in on.
string
The blockchain transaction ID of the payment.
string
USDC or USDT, whichever your customer paid with.
string
required
fiat or usdc. Always present. A usdc message has fee_usdc, amount_usdc_net, settlement_chain, and forward_required instead of amount_local and exchange_rate.
number
USDC only. The platform fee taken from the payment.
number
USDC only. What you actually got: the amount received minus the fee.
string
USDC only. The network your USDC is on, or is being moved to.
boolean
USDC only. true when your USDC still has to be moved to settlement_chain.We send checkout.completed before that move starts, so you hear about the payment as soon as possible. When this is true, wait for checkout.forwarded before treating the money as arrived on your chosen network.
number
Local currency only. What you received after the platform fee.
string
required
KES, NGN, GHS, or UGX for local currency payouts. USDC if you keep USDC.
number
Local currency only. How much local currency 1 USDC was worth at payout.
string
required
For local currency, the payout receipt (an M-Pesa code, for example). For USDC, the transaction ID of your customer’s payment.
string
required
Always completed.
string
required
Date and time, ISO 8601.
string
required
Date and time, ISO 8601.

When this arrives

It depends on how you get paid: Whichever applies, by the time you get this event the payment can’t be reversed, and it’s safe to treat as final.

checkout.failed

The payment arrived but we couldn’t finish paying you out. This is rare.
string
required
Always checkout.failed.
string
required
string
number
required
The amount you asked for. If we’d already matched a payment to this session, amount_received_usdc shows what was actually sent.
string
required
string
required
Always failed.
string
required
Send the session_id to support and we’ll sort it out. Your customer’s money is not lost.

checkout.expired

Nobody paid within 30 minutes. Use this to mark the order as abandoned.
string
required
Always checkout.expired.
string
required
string
Use this to mark the matching order as abandoned.
number
required
The amount that was never paid.
string
required
string
required
Always expired.
string
required
Expired sessions cost you nothing. We only charge a fee on completed payments.

checkout.forwarded

Only if you keep USDC on a network other than Base. Your USDC has arrived on the network you chose.
string
required
Always checkout.forwarded.
string
required
string
string
required
The network your USDC arrived on.
string
required
The transaction ID on that network.
If the move fails, you get settlement.forward_failed below instead. Your USDC is safe on Base either way. To check without waiting for an event, look at forward.status on the checkout session.

settlement.forward_failed

Only if you keep USDC. Your money didn’t make it to the network you chose, and it needs our help to get there. Your customer’s payment isn’t affected: they paid and you were credited. This is only about moving your own USDC between networks.
string
required
Always settlement.forward_failed.
string
required
Where the money was meant to go.
string
required
Where it is right now. Always Base, because the money never left.
We only send this once we’re sure the move won’t finish by itself, never on a first hiccup. Until then, treat it as still on its way. Send the session_id to support and we’ll get it moving again.

settlement.swap_failed

Only if you keep USDC, and only when your customer paid in USDT. We couldn’t convert their USDT to USDC, so for now you’re holding USDT on the network they paid on, instead of the USDC you expected.
string
required
Always settlement.swap_failed.
string
required
The network your customer paid on. That’s where the money is now.
string
required
The coin you’re holding: USDT, not the USDC you expected.
This always comes after checkout.completed, because your customer’s payment did go through. If you’re paid in local currency instead, you won’t get this event. We keep trying the conversion for you, since we can’t pay out local currency from unconverted USDT. Send the session_id to support.

Best practices

Reply first, then do the work

Avoid handling the same event twice

We can occasionally send the same news more than once, and each copy can have a different X-Minisend-Event-Id. So check for repeats using session_id and event from the message body:

Check settlement_mode before reading amounts

amount_local and exchange_rate only appear when you’re paid in local currency. When you keep USDC, you get fee_usdc, amount_usdc_net, and forward_required instead, so check which one you’re dealing with first:

Record what arrived, not what you asked for

amount_usdc is the amount you created the session with. If you record your sales from it, an underpayment shows up as money you never got.

Match payments to your orders with external_id