Payments
Refunds
Give money back to a client through Stripe from the app, or record a refund you made yourself, with a credit note on record.
A refund sends money back to a client for a payment they made. If the payment came through Stripe, you can refund it from the app and Stripe returns the money to the client's card. If the payment came by bank transfer or another route we cannot reach, you pay the client back yourself and record the refund, so your records stay correct. Either way, a credit note usually explains why, and every refund is audited.
Two ways to refund
| The payment came through | How the refund works |
|---|---|
| Stripe | Refunded through the Stripe rail, on your connected Stripe account. It is recorded when Stripe confirms it. |
| Bank transfer, QR rails, cash or anything recorded manually | You return the money yourself (for example by bank transfer), then record the refund manually with an audit entry. |
The difference comes from what each rail can do. Stripe supports refunds; instruction rails such as bank transfer only show your details and cannot move money. If you ask a rail without refunds to refund, the API answers rail_capability_missing so you know to record it manually.
Refund with a credit note
The usual path is a credit note, because it keeps your documents and numbering clean: the invoice stays as it was, and the credit note (with its own number, for example CN-2027-0004) shows what was given back.
Open the paid invoice
Open the invoice you want to refund, fully or in part.
Create a credit note
Create a full credit note, or a partial one by picking lines or entering an amount.
Choose Refund
Because the invoice was paid, you choose what happens to the money: refund or keep as client credit. Choose refund.
Confirm
Refunds move money, so you confirm before anything happens. For a Stripe payment the refund is sent to Stripe; for other payments you record the refund you made.
If you would rather not pay the money back, choose keep as client credit instead. See Client credit.
Refund a payment directly
You can also refund a single payment from the payment itself, for example after a duplicate card payment. The same rules apply: through Stripe when the payment came from Stripe, recorded manually otherwise.
What happens after a Stripe refund
- The refund is created on your connected Stripe account.
- Stripe processes it and sends a refund event.
- When that event is verified, the refund is recorded against the original payment, and the webhook event
payment.refundedis sent to your endpoints. - The client sees the money back on their card on Stripe's normal timeline.
A refund is never recorded just because a request was sent: as with payments, we wait for Stripe's verified confirmation. We charge nothing for refunds; any fees are those of your own Stripe account.
Payment states
| Payment status | Meaning |
|---|---|
succeeded | Paid, nothing refunded |
partially_refunded | Part of the payment was refunded |
refunded | The whole payment was refunded |
Each payment keeps the total refunded so far, so you can refund in several steps up to the original amount.
Through the API
| Action | REST | MCP tool | Permission |
|---|---|---|---|
Create a credit note with settlement: "refund" | POST /v1/documents/{id}/credit-notes | create_credit_note | documents.credit |
| Refund a payment | POST /v1/payments/{id}/refunds | none | payments.refund |
| Get a payment | GET /v1/payments/{id} | none | payments.view |
Both actions are destructive: they need "confirm": true, or they return confirmation_required with a preview. They also need an Idempotency-Key, so a retry never refunds twice.
curl -X POST "https://api.freeinvoiceautomation.com/v1/documents/0193f2b4-5a6b-7c8d-9e0f-1a2b3c4d5e6f/credit-notes" \
-H "Authorization: Bearer $FIA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: cn-inv-0042-refund" \
-d '{
"amount_minor": "30000",
"settlement": "refund",
"confirm": true
}'Over MCP, create_credit_note is a destructive tool: your assistant shows a preview and waits for your confirmation, even if its key is allowed to send documents automatically.
What the client sees
- The credit note, as a document with its own number and a "CREDIT NOTE" PDF, linked to the original invoice.
- The original invoice's pay page shows the credit note and the reduced balance.
- From January 2027, both appear in the client portal.
- For a Stripe refund, the money back on their card.
Store refunds
When a refund happens in your Shopify store (from February 2027) or WooCommerce store (from the week of 25 January 2027), the connector creates the credit note automatically, because the refund already happened in the store. It is recorded as refunded outside our system and audited with the store connection as the actor.
Rules and edge cases
- You cannot refund more than was paid. Refunds and credit notes are limited to what can be credited (
credit_exceeds_balance). - Voiding is not refunding. An invoice with payments cannot be voided; issue a credit note.
- Disputes (chargebacks) are handled in Stripe. Stripe tells us about them, but you respond to a dispute in your Stripe account.
- Manual refunds do not move money. Record them only after you paid the client back.
Permissions
| Key | Needed for | Default roles |
|---|---|---|
payments.refund | Refunding a payment | Owner, Admin |
documents.credit | Creating a credit note with a refund | Owner, Admin |
payments.view | Seeing refunds | Owner, Admin, Editor, Viewer, Accountant |
Errors
| Code | When |
|---|---|
confirmation_required | The call did not include "confirm": true; the response has a preview |
rail_capability_missing | The rail cannot refund; record the refund manually |
credit_exceeds_balance | The amount is more than can be refunded or credited |
upstream_error | Stripe returned an error; nothing was recorded |
permission_denied | Your role lacks payments.refund or documents.credit |
idempotency_key_reused | The same key was sent with a different body |