RefundsOverview

Refunds

SaySwitch refunds let merchants return all or part of a successful card payment to a customer. Refunds are asynchronous: an accepted request reserves the required funds, then moves through funding and processing before it is complete.

Current Availability

  • Refunds currently support successful USD card transactions.
  • Full and partial refunds are supported.
  • Each accepted refund includes a processing fee based on the merchant’s agreement with SaySwitch. The USD 1.00 fee used below is only an example.
  • The processing fee becomes non-refundable after the refund completes successfully.
  • Automatic virtual-account and payment-difference refunds use a separate workflow.

How Refund Funding Works

SaySwitch determines the funding split automatically. Merchants do not choose whether available or pending balance is used.

  1. Available wallet balance is reserved first.
  2. Any remaining requirement is held from eligible pending balance.
  3. The refund fee is included in the total amount that must be reserved.

For a USD card refund:

total_reserved = refund amount + USD refund fee

Funding Example

ItemAmount
Refund amountUSD 100.00
Refund fee (example)USD 1.00
Total requiredUSD 101.00
Available balanceUSD 40.00
Eligible pending balanceUSD 100.00

SaySwitch reserves USD 40.00 from available balance and holds USD 61.00 from eligible pending balance. The refund is accepted with the awaiting_settlement status.

The gross pending balance is not reduced immediately. Instead, the held amount is excluded from pending_available, which represents pending funds that remain spendable.

If available balance plus eligible pending balance cannot cover the refund amount and fee, the request is rejected with HTTP 422. No funds are deducted or reserved.

Settlement Lifecycle

  1. The merchant requests a refund.
  2. SaySwitch reserves available balance first.
  3. Any remaining requirement is held from eligible pending balance.
  4. The refund returns awaiting_settlement when pending funding is needed.
  5. As settlements occur, settled money funds the refund hold before any remainder is added to available balance.
  6. Once completely funded, the refund automatically changes to pending.
  7. The refund then proceeds through normal processing.
  8. SaySwitch sends webhook notifications as the status changes.

Merchants do not need to resubmit a refund after settlement and cannot manually change its status.

Refund Statuses

awaiting_settlement -> pending -> processing -> success
pending -> processing -> success

Alternative paths include:

awaiting_settlement -> rejected
pending -> rejected
processing -> failed
failed -> processing
failed -> rejected
StatusMeaning
awaiting_settlementWaiting for reserved pending funds to settle.
pendingFully funded and waiting for processing.
processingRefund processing has started.
successRefund completed successfully.
failedA processing attempt failed and may be retried.
rejectedThe refund was rejected and reserved funds were released.

Funding Status

Refund status and funding.status describe different parts of the process. Refund status tracks processing, while funding status shows whether the reserved money is ready.

FieldDescription
funding.statusawaiting_settlement, funded, or released.
funding.available_reservedAmount reserved immediately from available balance.
funding.pending_reservedAmount reserved from eligible pending balance.
funding.pending_funded_amountPending reservation already funded through settlement.
funding.pending_remainingPending reservation still awaiting settlement.
funding.funded_atTime the refund became fully funded, or null while waiting.

Wallet Balance Fields

Use GET /api/v1/wallet_balance/{currency} to review the balances involved in refund funding.

FieldDescription
balanceAvailable wallet balance.
pendingGross pending settlement balance.
pending_availablePending balance not already reserved for refunds.
refund_pendingTotal money reserved for active refunds.
refund_pending_unsettledRefund reservation still waiting to be funded by settlement.

Use pending_available, not gross pending, when showing spendable pending funds. See Get Wallet Balance for the complete response.

Integration Flow

  1. Check the USD wallet balance and use pending_available when showing spendable pending funds.
  2. Initiate the refund with a unique Idempotency-Key.
  3. Store the returned refund_reference, refund status, and funding status.
  4. If the refund is awaiting_settlement, wait for status updates instead of submitting it again.
  5. Verify refund webhook signatures and process each event idempotently.
  6. Verify the refund status before treating it as complete.

Only success is final confirmation that the refund completed. HTTP 202, awaiting_settlement, pending, processing, and failed do not mean that money has been returned successfully.

Safety Rules

  • Wallet balances cannot become negative because of a refund request.
  • No funds change when combined eligible funds are insufficient.
  • Existing pending refund holds cannot fund another refund.
  • An awaiting_settlement refund is accepted but is not ready for processing.
  • Rejected refunds release their reserved funds.
  • Refund fees are included in required wallet funding.
  • Idempotency prevents retries from reserving the wallet twice.

API Reference

TaskEndpointDocumentation
Initiate a refundPOST /api/v1/refundInitiate a Refund
List refundsGET /api/v1/refundGet Refunds
Verify a refundGET /api/v1/refund/status/{refund_reference}Get Refund Details
Check wallet balanceGET /api/v1/wallet_balance/{currency}Get Wallet Balance
Receive status updatesConfigured webhook URLRefund Webhooks

Refund API requests use secret-key authentication and must be made from a secure server. Keep secret keys out of frontend code.