# Return an unused deposit

Check refund eligibility, hand the exact amount to the owner, and track the original refund without duplicate submissions.

## Check the original deposit

GET /api/v1/balance/topups/{id}/refund requires a live campaigns:read key or owner session. It returns eligibility, the original payment total, credit to remove, current refund status and approval_url. The URL opens the owner’s Balance page; open Payment details → Return unused deposit. Reads do not request a refund or move credit.

Self-service submission depends on refunds_enabled. When false, payment-account validation remains outstanding. An eligible deposit is not permission to submit or a promise that the provider can fund its refund.

## Owner approves the exact return

Only the owner can POST to the same endpoint, with Content-Type: application/json, a persistent Idempotency-Key and:

```json
{"confirm_full_refund":true,"payment_total_cents":12500,"credit_cents":9147}
```

These example amounts must be replaced with the current response. This requests a full refund of the original payment, including its collected tax, to its original payment method. It removes that deposit’s credit, not money from another deposit. No alternate destination is accepted. MarketingRouter does not promise that the processor returns its processing costs to us. This flow does not quote separate buyer-side fees or foreign-exchange differences.

Before submission the service reads the original payment and refund history, confirms the processor marks the payment refundable, checks the immutable payment/account/workspace binding and locks the wallet. The entire credit must still be unused. Approved campaigns must be permanently closed and finally reconciled, with no reservations left. A verified minimum-budget launch rejection also qualifies after its reservation is released, provided no successful or unresolved activation exists. The credit is removed atomically before the single provider request.

An agent cannot approve a refund, even with campaigns:write. Give approval_url to the owner and retain the funding ID. Do not ask for an owner access token.

## Follow the original outcome

GET reads the saved status. POST /api/v1/balance/topups/{id}/refund/reconcile with no body refreshes the original payment and refund records. It requires a live campaigns:read key or owner session. The scheduled worker and payment webhooks also reconcile. Check every 30 seconds while pending, then back off.

- eligible: no refund has been submitted; the owner must review the exact amounts and refunds_enabled must be true.
- unavailable: this receipt needs a different review; reason explains the blocker.
- processing: credit was removed and the original provider outcome is still being checked.
- pending: a matching refund exists, but both the refund and cumulative payment have not confirmed success.
- succeeded: a matching full refund and payment total are confirmed. completed_at is verification time, not the bank’s posting time.
- attention_required: confirmation failed, the provider needs action, or evidence conflicts. Credit stays unavailable. Reconcile the original request; an operator must resolve any remaining uncertainty.

A lost POST response never authorizes another refund. Keep the exact body/key. Replaying that request returns the stored operation and never repeats the provider write. A different key conflicts. Reconciliation only reads provider state. Stale successful-payment events cannot restore removed credit. Disputes, foreign references and unexpected refund amounts create a sticky review hold.

## Scope and current limits

This workflow handles whole, completely unused balance deposits only. A deposit partly consumed by ads, an older campaign-specific payment, or unresolved final spending needs a separate operator refund review. Closing a campaign and releasing unused wallet credit is not a cash refund. Processing failures do not automatically restore credit because an interrupted request can still succeed. Actual live refund execution and bank posting remain unverified until an explicitly authorized payment test is completed; do not advertise guaranteed or instant refunds.
