KintsugiKintsugi
API Guides

4. Handling Refund Transactions

Refunds change what you owe, so they need to reach Kintsugi as deliberately as the sales they reverse. A credit note records a refund against the original transaction, keeping your filings anchored to net sales rather than gross. This guide covers when to create credit notes, how to shape them, and how full and partial refunds behave.

Understanding Credit Notes

A credit note in Kintsugi represents a refund, return, or adjustment against an original sale. Each credit note:

  • Is created against the original transaction, which Kintsugi records on the credit note's related_to field
  • Carries the amount being credited on total_amount and on each line item
  • Updates the original transaction's refund status
  • Offsets the original sale in compliance calculations

The outcome is filings that reflect what you actually kept.

Credit notes are transactions: Credit notes are transaction records with their own endpoint. Create them with POST /v1/transactions/{original_transaction_id}/credit_notes, and Kintsugi records them with a type of FULL_CREDIT_NOTE or PARTIAL_CREDIT_NOTE.

When to Create Credit Notes

Create a credit note whenever you refund, accept a return, or adjust a completed sale:

  • Product returns: The customer sends items back
  • Service cancellations: The customer cancels and is refunded
  • Billing adjustments: You correct an overcharge or an error
  • Partial refunds: You refund specific line items rather than the whole order

Which sales can be credited: A sale can carry a credit note while its status is PENDING, COMMITTED, or PARTIALLY_REFUNDED. A CANCELLED sale, an already FULLY_REFUNDED one, or a record Kintsugi has set aside is rejected with 400. A cancelled order needs no credit note in the first place.

Creating Credit Notes

Create credit notes with POST /v1/transactions/{original_transaction_id}/credit_notes. The path parameter is the original transaction's Kintsugi transaction ID, not your external_id.

Required Fields

  • external_id: Your unique identifier for the credit note (for example, "CN-2026-001")
  • date: Credit note date, normally the refund date, in ISO 8601 format
  • status: PENDING, COMMITTED, or CANCELLED
  • total_amount: The amount being credited
  • currency: ISO 4217 currency code, for example USD
  • transaction_items: The line items being credited

Optional Fields

  • description: The reason for the refund, which is worth sending on every credit note
  • addresses: Addresses for the credit note, where they differ from the original
  • taxable_amount, tax_amount_imported, tax_rate_imported: Tax figures you already calculated elsewhere

Credit Note Line Items

Each item mirrors a line from the original sale and requires:

  • external_id: Your identifier for the credit note line
  • date: Item date
  • external_product_id: The same product identifier used on the original line
  • quantity: Units being credited
  • amount: Value being credited for that line

Either sign works: Send total_amount and item amount positive or negative as you prefer. Kintsugi normalizes credit note amounts to negative on write, so the stored record is consistent either way. Quantities stay positive. The Create Credit Note reference carries a complete worked example.

Credit Note Workflow

You never edit the original sale. You attach a credit note to it, and Kintsugi adjusts your liability from there.

Find the original transaction
GET/v1/transactions/external/{external_id}Look it up by your own id
The credit note endpoint takes Kintsugi's transaction id, not your external_id, so you need this unless you stored the id when you synced the sale.
Check the sale can be credited
A sale can carry a credit note while it is pending, committed, or already partially refunded.
REJECTED →A cancelled sale, an already fully refunded one, or anything Kintsugi has set aside comes back 400. A cancelled sale needs no refund in the first place.
Build the credit note
Match the line items you are crediting to the items on the original sale, then total them.
CHECKTwo independent caps apply, and both are the remaining balance rather than the original figure. Validate before sending: an over-refund is rejected, not trimmed to fit.
Create the credit note
POST/v1/transactions/{transaction_id}/credit_notesReturns the credit note
Non-2xx? Same retry policy as product and customer creation: back off on 5xx and 429, fix the payload on 4xx.
Refund recorded
Once the credit note is COMMITTED, the original sale's refund_status updates itself and your liability drops by the credited tax.

Full Versus Partial Refunds

Kintsugi reads the amounts and classifies the refund for you.

Full Refunds

When the credit note covers the full original amount, Kintsugi records:

  • Credit note type: "FULL_CREDIT_NOTE"
  • Original transaction refund_status: "FULLY_REFUNDED"

The original sale is fully offset for compliance purposes.

The two fields are derived differently: type is decided per credit note, by comparing that note's taxable_amount against the sale's. refund_status is cumulative, comparing every committed credit note's total against the sale's total_amount. On a single full refund they agree; across several partial refunds they can differ, so read refund_status when you need the sale's overall position.

Partial Refunds

When the credit note covers less than the original amount, Kintsugi records:

  • Credit note type: "PARTIAL_CREDIT_NOTE"
  • Original transaction refund_status: "PARTIALLY_REFUNDED"

The sale is reduced, not erased. You can add further partial credit notes against the same transaction until the credited total reaches the original amount.

Two caps apply, both against the remaining balance: Kintsugi checks the credit note total against what is still creditable on the sale, and separately checks each line against what is still creditable on the matching original line. Either one over is a 400 and nothing is written, so an over-refund is rejected rather than trimmed to fit.

The transaction-level cap is the sale's total_amount plus any total_tax_amount_imported, minus everything already credited by committed credit notes. A PENDING credit note does not consume the balance, so two pending notes can each pass validation and then fail when you commit the second.

Matching the Original Transaction

Credit note line items should mirror the sale they reverse:

  • Use the same external_product_id values
  • Keep credited quantities at or below the original quantities
  • Keep credited amounts at or below the original amounts

That discipline gives you clean reporting on which products were returned, and an audit trail that holds up under review.

Where an amount has to be spread across lines rather than itemized, Kintsugi allocates it in proportion to each line's remaining creditable balance, skipping lines that are already fully credited and giving the last eligible line the rounding remainder. Tax and quantity follow the same split, so a partial refund's tax reconciles against the lines it credited.

Credit Note Statuses

Credit notes use the same status values as transactions:

  • PENDING: Created, refund not yet finalized
  • COMMITTED: Refund complete and included in compliance calculations
  • CANCELLED: Credit note voided, for example a reversed refund

Move credit notes to COMMITTED once the refund has actually been processed so your compliance figures track reality.

Updating Credit Notes

Update with PUT /v1/transactions/{original_transaction_id}/credit_notes/{credit_note_id}. Typical cases:

  • Status changes: Moving PENDING to COMMITTED after the refund settles
  • Amount corrections: Fixing an incorrect refund figure
  • Item adjustments: Revising which lines were credited

Filed records lock: Once the original transaction is included in a filing, its credit notes are locked and can no longer be updated. Make corrections before the filing period closes.

Best Practices

Creating Credit Notes

  • Mirror the original: Same products, same address treatment, amounts that reconcile
  • Validate before you post: Check the remaining creditable balance so the request is not rejected
  • Use descriptive external IDs: Tie the credit note back to the sale, for example CN-\{original_id\}
  • Always send a description: The refund reason is the first thing anyone asks about months later
  • Set status to match reality: PENDING while the refund is in flight, COMMITTED once it clears

Finding Original Transactions

  • Store Kintsugi transaction IDs: The credit note path parameter needs the Kintsugi ID, so save it when you create the transaction
  • Fall back to external lookup: Without the Kintsugi ID, resolve it with GET /v1/transactions/external/{external_id}
  • Handle not-found cleanly: The original transaction must exist before a credit note can reference it

Error Handling

Common failures when creating credit notes:

  • Original transaction not found: Confirm you are passing the Kintsugi transaction ID, not your external_id
  • Amount exceeds creditable balance: Subtract already-committed credit notes from the sale total plus imported tax before you post, and check the line-level balances too
  • Sale cannot be credited: The sale must be PENDING, COMMITTED, or PARTIALLY_REFUNDED; cancelled and fully refunded sales are rejected
  • Product mismatch: Reference the same products as the original line items
  • Missing required fields: currency and status are required alongside external_id, date, total_amount, and transaction_items

See the Error Handling guide for detailed strategies.

Refund Scenarios

Single Item Return

A customer returns one item from a multi-item order:

  1. Find the original transaction
  2. Create a credit note containing only the returned line item
  3. Credit that item's share of the order
  4. Kintsugi marks the original transaction PARTIALLY_REFUNDED

Full Order Refund

The entire order is refunded:

  1. Find the original transaction
  2. Create a credit note containing every line item
  3. Credit the full original amount
  4. Kintsugi marks the original transaction FULLY_REFUNDED

Multiple Partial Refunds

Refunds arrive over time:

  1. Create a credit note for the first refund
  2. Add further credit notes as later refunds are issued
  3. Kintsugi tracks the cumulative credited total
  4. The original stays PARTIALLY_REFUNDED until the credited total reaches the original amount

Refund Status Tracking

Credit notes are cumulative. Each one reduces the remaining balance, and the refund status follows the total.

Worked exampleBar shows the amount still refundable
Original transaction$100.00
Committed, nothing credited yet$100.00 remaining
CREDIT NOTE 1Partial refund−$30.00
PARTIALLY_REFUNDED$70.00 remaining
CREDIT NOTE 2Refunds the rest−$70.00
FULLY_REFUNDED$0.00 remaining
Two credit notes of $70.00 against a $100.00 sale is rejected, not clamped: the second comes back 400 and nothing is written. Check the remaining balance before every credit note, not just the first.

Refund Status on the Original

Kintsugi derives refund_status on the sale from the credit notes committed against it. Until one is committed the field is absent rather than carrying a "not refunded" value, and only committed credit notes count: a PENDING credit note neither consumes the balance nor moves the status.

PARTIALLY_REFUNDED
Committed credit notes total less than the sale. The uncredited remainder still counts toward nexus, and the sale can carry further credit notes.
FULLY_REFUNDED
Committed credit notes reach the sale total. The sale nets to zero, the record stays for audit, and further credit notes are rejected.

You can also set it directly: refund_status is writable on POST /v1/transactions and on update, which is how a historical import lands a sale that was already refunded before you integrated. Kintsugi recomputes it from committed credit notes whenever one is attached. See Transaction Statuses.

Next Steps

With refund handling in place:

  1. Verify credit notes: Read them back with GET /v1/transactions/{transaction_id} and filter the transaction list by transaction_type to review credit notes on their own. See the Get Transactions API reference.

  2. Monitor refund status: Track refund_status across your transactions so compliance figures stay accurate.

  3. Plan for edge cases: Decide up front how you handle reversed refunds and refunds that span filing periods.

For endpoint-level detail, see: