rfd.XXXX.YYYYYYYYYYYYYYYYYYYYYYYY.
At a glance
Lifecycle
Creating a refund records it and submits it to the provider in the same request, so the response is normallyprocessing rather than
pending.
You do not need to poll. Kwugwo follows the refund with the provider
and sends a webhook as soon as it resolves. If a
refund is still
processing after a couple of weeks, contact support
with its uid.
What a refund does to the payment
A refund is counted against the activity as soon as it is created, before the provider confirms it, so that a second request cannot over-refund a payment while the first is still in flight:- On create, the activity’s
refunded_amountrises and the activity becomespartially_refunded, orrefundedonce the full amount is covered. - If the refund fails,
refunded_amountis given back and the activity returns topartially_refundedorsuccessful.
partially_refunded while some of the
money is still yours, refunded once all of it has gone back. See
the ugwo status table.
How much you can refund
Leaveamount out and Kwugwo refunds everything still refundable on
the activity: what the provider collected (charged_amount, falling
back to the activity’s amount) less anything already refunded.
Pass amount for a partial refund. It must be at least the currency
minimum (20000 kobo for NGN), and it cannot take the total past
what the activity collected.
Providers
A refund goes back through the same provider that took the payment. By default Kwugwo uses the connection the activity used; passnzube_psp to use a different connection for the same provider.
Not every provider supports refunds. When one does not, the refund
comes back failed with an error.code of system_error. Check
with support before building a flow on top of a provider you have not
refunded through before.
Refunds for bank transfer and USSD payments
Some PSPs cannot send money back to the account that paid by bank transfer or USSD, because they never saw it. For these, pass the customer’s bank account asdestination when you create the
refund:
failed with an error.message
like nzube.psp.paystack.error.missing_destination. Sending it for
other mediums is harmless.
Refunds created outside the API
A refund can also start at the provider, for example when someone issues it from the provider’s own dashboard. Kwugwo records it and reports it exactly like any other refund, so:- A
refund.createdwebhook can arrive for a refund you never requested. Do not treat unknown refund IDs as an error. - Its
refisnull, since there was no API request to carry one. - Its
amountcan be below the currency minimum.
Idempotency
ref is unique per workspace, which makes it an idempotency key.
Send one on every refund and a duplicate request is rejected with
409 instead of refunding twice.
If a create call times out, retry it with the same ref. Either the
first attempt never landed and you get a refund back, or it did and
you get 409.
The Refund object
Every field is documented on The Refund object.Partial refunds in practice
A customer paid ₦5,000.00 (500000 kobo) and returns two items worth
₦3,000.00.
- Create a refund for
200000with"ref": "order_4719_refund_1". The activity becomespartially_refundedwithrefunded_amount: 200000. - Create a second for
100000with a newref.refunded_amountbecomes300000; the activity stayspartially_refunded. - Each refund resolves on its own and its webhooks can arrive in any
order, so match on
data.uidrather than arrival order. - To return the rest later, omit
amount. The activity and the ugwo both becomerefunded.