Archive topic

Ledger API 2026-09-01

Refund headroom reservation, pending refund total, and refund events.

This is a release-history archive topic. For current integration guidance, see the Ledger API package page.

Changes in 2026-09-01

Overview

Ledger API 2026-09-01 makes refunds that are still processing count against a payment's refund headroom, adds the fields and events needed to track those refunds, and corrects the status returned for a missing If-Match header. This release changes refund behavior. Review the compatibility information before you pin to it.

New Features

  • Pending refund total: Payment.amount_refund_pending carries the total of refunds that are still processing. The remaining refund headroom on a payment is amount - amount_refunded - amount_refund_pending.
  • Refund retrieval and events: GET /v1/refunds/{refund_id} returns a single refund, and the refund.succeeded and refund.failed webhooks report when a refund reaches a terminal state. An integration that waits for one refund to finish before it issues the next can now observe that directly.
  • Refund settlement time: Refund.settled_at records when a refund reached a terminal state, separately from created_at, so reconciliation can align each refund to the period in which it completed.

Enhancements

  • Refund headroom reservation: A refund that is still processing reserves its amount against the payment. A new refund is accepted only if it fits in the remaining headroom, and the check and the reservation are a single atomic step. A request that does not fit returns 422 refund_amount_exceeded. Previously, only succeeded refunds counted, so two concurrent ₹600 refunds against a ₹1,000 payment were both accepted and the payer received ₹1,200.
  • Refunded amount: Payment.amount_refunded counts only succeeded refunds, which is the money actually returned to the payer. It previously also counted refunds that were still processing, so the field showed a pending refund as spent while the refund check ignored it.

Fixes

  • Missing If-Match header: When a PATCH /v1/invoices/{invoice_id} request has no If-Match header, the API returns 428 precondition_required. It previously returned 412 precondition_failed, the status for a stale value, so a client could not tell the two conditions apart. This fix applies to every release.

Compatibility

The refund headroom and amount_refunded changes apply only to requests pinned to 2026-09-01 or later. Accounts created before this date keep their existing pin until they send Ledger-Version: 2026-09-01. amount_refund_pending is returned only from this release, because on earlier releases amount_refunded still includes pending refunds and returning both would count them twice. GET /v1/refunds/{refund_id}, the two refund webhooks, and settled_at are available on every release.

Review every read of amount_refunded, and every code path that can issue more than one refund against a payment, before you pin to this release. Refer to Migrating to 2026-09-01 for the full procedure, including a sandbox test.

Known Issues

  • Several earlier SDK versions apply the Ledger-Version value set when the client is created and ignore a per-call override. Confirm the header on the outgoing request when you test this release.
← Back to Portfolio