# Sandbox invoice remains PAID after the full payment refund is COMPLETED

**URL:** <https://developer.squareup.com/forums/t/sandbox-invoice-remains-paid-after-the-full-payment-refund-is-completed/27863>\
**Category:** Questions\
**Tags:** sandbox, invoices-api\
**Created:** [September 16, 2026, 9:20pm UTC](https://developer.squareup.com/forums/t/sandbox-invoice-remains-paid-after-the-full-payment-refund-is-completed/27863 "2026-09-16T21:20:36Z")\
**Posts on this page:** 2\
**Page:** 1

<div class="post-metadata">

**Author:** ![MBSM](https://avatars.discourse-cdn.com/v4/letter/m/9d8465/32.png) [@MBSM](https://developer.squareup.com/forums/u/MBSM)\
**Post date:** [September 16, 2026, 9:20pm UTC](https://developer.squareup.com/forums/t/sandbox-invoice-remains-paid-after-the-full-payment-refund-is-completed/27863/1 "2026-09-16T21:20:36Z")

</div>

We reproduced an invoice/refund status disagreement in the Square Sandbox with two entirely synthetic test invoices.

1. Create an order and invoice, then publish with SHARE\_MANUALLY.
2. Pay the invoice on Square’s hosted sandbox payment page using the official test card.
3. Retrieve the payment ID from the order and call RefundPayment once for the full amount.
4. Independently retrieve the invoice, payment and refund after processing.

Both PaymentRefund objects are COMPLETED, and each Payment.refunded\_money equals the full original payment. However, both Invoice objects remain PAID at version 2, with unchanged updated\_at. All readbacks return HTTP 200. The same result occurs with API versions 2026-08-19 and 2026-09-16, including repeat reads at 15:49, 16:09 and 19:56 UTC on September 16.

The Pay or Refund Invoices guide says a full refund changes the invoice to REFUNDED and updates its version/timestamp. Is there a known sandbox propagation limitation? What supported readback should establish invoice closure before a corrected replacement is created?

We have held replacements and have not attempted another refund or an invoice-status override. No production transaction or customer data is involved. We can provide the exact sandbox resource IDs through a supported private channel if needed.

Reference: [Pay or Refund Invoices](https://developer.squareup.com/docs/invoices-api/pay-refund-invoices)

---

<div class="post-metadata">

**Author:** ![jseok](https://avatars.discourse-cdn.com/v4/letter/j/f475e1/32.png) [@jseok](https://developer.squareup.com/forums/u/jseok)\
**Post date:** [September 17, 2026, 5:23pm UTC](https://developer.squareup.com/forums/t/sandbox-invoice-remains-paid-after-the-full-payment-refund-is-completed/27863/3 "2026-09-17T17:23:59Z")

</div>

@MBSM - This is a known sandbox parity gap. The [Pay or Refund Invoices](https://developer.squareup.com/docs/invoices-api/pay-refund-invoices) docs are correct that a full refund should transition the invoice to `REFUNDED` with an updated `version` and `updated_at` for production-level invoices. The `PaymentRefund` objects completing correctly while the invoice stays `PAID` is consistent with the sandbox’s known divergence from production behavior.

Square’s standing guidance is to use a **separate free production account** for end-to-end testing of flows like invoice lifecycle transitions. To simulate payment activity without moving real money, use `CASH` or `EXTERNAL` tender types.
