Partial Refunds Start With the Basket, Not the Button
A partial refund needs a commercial allocation and a reliable payment balance. A successful API call cannot decide which discount or shipping charge belongs to a returned item.
In this essay
A customer returns one item from a discounted basket. The support screen shows the original item price and a refund field. Which amount should the operator enter: the list price, the price after discount, or a share of the total payment?
The payment provider can check a permitted refund amount against its payment record. It cannot supply every commercial decision the retailer failed to record. A useful design preserves the accepted basket, its allocations and the disposition of earlier refunds before another instruction is submitted.
The example below uses fictional currency units. It assumes a documented proportional basket discount, no later repricing, no separate tax recalculation and a shipping charge that remains non-refundable for these particular returns under the assumed applicable terms. Those are example inputs, not legal advice or a universal returns policy.

Preserve the allocation accepted at purchase
The basket contains three items priced at 120, 80 and 40 units. A 30-unit discount applies proportionally to their combined 240-unit price. The customer also pays 12 units for shipping. The payment captured is therefore 222 units.
| Item | Before discount | Allocated discount | Paid amount |
|---|---|---|---|
| Jacket | 120 | 15 | 105 |
| Bag | 80 | 10 | 70 |
| Scarf | 40 | 5 | 35 |
| Merchandise total | 240 | 30 | 210 |
| Shipping | 12 | 0 | 12 |
| Captured total | 252 | 30 | 222 |
The bag's allocation is 80 ÷ 240 × 30 = 10 units of discount. Its paid amount is 70. Refunding its undiscounted price would return 10 units more than the recorded allocation. That may be a separately authorized goodwill decision, but it should not happen accidentally because the support screen chose the wrong field.
Save the allocation when the order is accepted. Recalculating against today's catalog price, a changed promotion or the remaining items can produce a different result. Where an actual promotion requires repricing after a return, represent that rule and obtain the applicable commercial decision explicitly.
Amounts that do not divide cleanly need a deterministic rounding rule in the currency's supported unit. Allocate any residual so that the saved lines add back to the accepted total. Record the rule; do not let each service round independently and leave finance to reconcile the difference.
Track two returns against one payment
The customer first returns the bag. The retailer approves 70 units and creates a refund operation. Later, the customer returns the scarf for another approved 35 units.
After both refunds are confirmed under the provider's relevant semantics, their combined amount is 105. Subtracting that from the 222 captured payment leaves 117: the kept jacket's 105 plus the assumed retained shipping charge of 12. This is arithmetic under the scenario, not a declaration that every remaining unit is commercially owed to the customer.
Stripe permits multiple partial refunds subject to the original payment's refundable amount. Adyen also requires checking whether the payment method supports partial and multiple partial refunds. Confirm the actual integration rather than assuming every method behaves like cards. Stripe refunds Adyen partial refunds
There are two different ceilings. The provider has a financial limit. The retailer has a commercial entitlement for each line and decision. A remaining provider balance of 117 does not authorize an operator to refund 117 for a scarf that was already refunded.
Reserve pending work without calling it complete
Suppose the bag refund has been submitted but its result is still unresolved when a second operator opens the case. The merchant needs to prevent a second 70-unit instruction while remaining truthful about the first one's status.
In a proposed internal model, track confirmed refunds and reserved unresolved operations separately. Before submitting new work, account for both, along with other relevant provider adjustments such as disputes. That internal calculation must be checked against the provider's current record; it is not a replacement for it.
| Point in the example | Confirmed refunds | Reserved unresolved work | Internal amount not yet allocated |
|---|---|---|---|
| Before either return | 0 | 0 | 222 |
| Bag refund submitted, result unknown | 0 | 70 | 152 |
| Bag confirmed; scarf submitted | 70 | 35 | 117 |
| Both confirmed | 105 | 0 | 117 |
The last column is a control calculation, not an instruction to refund that amount. A pending reservation does not prove that money left the provider or reached the customer. It prevents another operator from treating unresolved work as unused capacity.
If an operation fails or is reversed, investigate the event and current balance before releasing its reservation or authorizing another payment. A delayed event must not restore capacity after a later successful resolution. Preserve the sequence and the reason for each change.
Follow the amount through the decision
Read the accepted quantity, discount allocation and applicable return decision.
Keep shipping and any additional adjustment as explicit decisions.
Match the line, return case and operation identity; check the provider record.
Do not create another refund because another operator opened the case.
Resolve the commercial or financial discrepancy before submission.
Protect the business operation against concurrent work; retain the provider refund reference.
Confirmed, unresolved and failed work remain distinguishable. Communicate only the stage supported by evidence.
An API idempotency key protects its documented request scope. The merchant must also protect line-level entitlement and concurrent case handling.
Test the arithmetic and the exception together
Use the merchant launch checklist for the broader retry and concurrency cases. Add basket-specific assertions to those tests: two operators selecting the same returned line, a discount residual, a shipping exception and a failed refund whose event arrives after a later update.
A test should verify the commercial record as well as the provider result. One financial refund can still be allocated to the wrong line. Two correctly calculated refunds can still exceed what the customer returned. The case history should show why the amount was approved and which operation carried it out.
Keep currency conversion outside this simplified example. Where the original payment and customer display currencies differ, use the FX quote-to-refund guide and the provider's actual contract. Do not reuse this basket's numbers as an exchange-rate rule.
When finance, support and the customer read the case, they should find the same accepted basket, the same approved amount and a traceable result for each refund. That is the control the refund button needs behind it.
Primary provider documentation checked on 25 October 2026. The basket, allocations and internal reservation model are illustrative design examples, not observed business results.
Closing thought and further reading
A partial refund needs a commercial allocation and a reliable payment balance. A successful API call cannot decide which discount or shipping charge belongs to a returned item.
Need help applying this to your business?
Explore practical support for payment operations, product decisions, program delivery and AI automation, grounded in the challenges behind this essay.


