Refunds

All of a payment, or part of it, as many times as you need.
ts
// everything that is left
await sp.refunds.create({ payment_intent: intent.id });

// or part of it
await sp.refunds.create({
  payment_intent: intent.id,
  amount: 2000,
  reason: "requested_by_customer",
});

Our fee comes back with it

When you refund, our fee is returned in proportion. A fully refunded sale costs you what it would have cost if it had never happened, and a sequence of partial refunds returns the fee exactly once in total rather than once per refund.

Reversals happen automatically

A full refund of a payment that has not settled yet is sent to the bank as a reversal, which is faster and often never appears on the cardholder’s statement at all. Everything else is an ordinary refund. You do not choose — we use whichever the bank will accept.

A refund does not change the payment’s status. It stays succeeded, and amount_refunded goes up. That is deliberate: a payment you refunded half of is not the same thing as one that never succeeded, and treating them alike makes your own reporting wrong.

Refunds made at the bank

If someone issues a refund inside the bank’s own portal rather than through us, we find it — every settled payment is re-read periodically — and record it with origin: "bank_portal". You get a refund.succeeded webhook for it like any other, so your records and the bank’s do not silently diverge.