How to Reverse or Refund a Transaction
Once you've charged a payment method, you might want to cancel the transaction or refund the customer their money later. This guide provides instructions for the various ways you can "undo" a charge.
To attempt to completely reverse a transaction, regardless of its present settlement status, you may use the reverseTransaction
mutation. When using this mutation, we will either void the transaction or issue a refund for the full amount of the transaction.
Voiding the transaction cancels it, preventing funds from being debited from the customer's account. A refund occurs when you have received or are in the process of receiving funds from a transaction already, and you would like to debit the full or partial amount of money from your own account to send back to the customer.
Reversing a Transaction
To reverse a transaction, you only need the ID of the Transaction
. Depending on the settlement status at the time of the attempted reversal, the result of the reverseTransaction
mutation will either be a Transaction
updated to the VOIDED
status, or a new Refund
linked to the original transaction. If you are interested in only partially refunding a transaction or wish to provide an orderId
, use the refundTransaction
mutation directly instead.
mutation
mutation ExampleReverse($input: ReverseTransactionInput!) {reverseTransaction(input: $input) {reversal {... on Transaction {idstatusstatusHistory {statusterminal}}... on Refund {idamount {value}orderIdstatusrefundedTransaction {idamount {value}orderIdstatus}}}}}
variables
{"input": {"transactionId": "TRANSACTION_ID"}}
response
"data": {"reverseTransaction": {"reversal": {"id": "TRANSACTION_ID","status": "VOIDED","statusHistory": [{"status": "VOIDED","terminal": true,},{"status": "SUBMITTED_FOR_SETTLEMENT","terminal": false,},{"status": "AUTHORIZED","terminal": false,}]}}}
or
response
"data": {"reverseTransaction": {"reversal": {"id": "REFUND_ID","amount": {"value": "10.00"},"orderId": "original-charge-order-id-123","status": "SUBMITTED_FOR_SETTLEMENT","refundedTransaction": {"id": "TRANSACTION_ID","amount": {"value": "10.00"},"orderId": "original-charge-order-id-123","status": "SETTLED"}}}}
Refunding a Transaction
If you already know the transaction has been SETTLED
, or you want to partially refund it, or you need to provide a refund order ID, you can use the refundTransaction
mutation.
You'll need the ID for the Transaction
that needs to be refunded. It must meet the following criteria to be refundable:
- in either the
SETTLING
orSETTLED
status - has not already been fully refunded
By default, refundTransaction
will fully refund a transaction. You can pass in an amount
less than the original amount in order to partially refund it. You can also optionally specify an orderId
to give the refund its own unique order ID, instead of the default behavior, which is inheriting the order ID from the original transaction.
mutation
mutation ExampleRefund($input: RefundTransactionInput!) {refundTransaction(input: $input) {refund {idamount {value}orderIdstatusrefundedTransaction {idamount {value}orderIdstatus}}}}
variables
{"input": {"transactionId": "SETTLED_TRANSACTION_ID","refund": {"amount": "7.00","orderId": "refund-order-id-456"}}}
A successful refund results in a new Refund
object:
response
{"data": {"refundTransction": {"refund": {"id": "REFUND_ID","amount": {"value": "7.00"},"orderId": "refund-order-id-456","status": "SUBMITTED_FOR_SETTLEMENT","refundedTransaction": {"id": "TRANSACTION_ID","amount": {"value": "10.00"},"orderId": "original-charge-order-id-123","status": "SETTLED"}}}}}
Or, a refund can fail because the original transaction wasn't ready to refund or had already been refunded. For example:
errors
{"data": null,"errors": [{"message": "Transaction has already been completely refunded.","locations": [{"line": 2, "column": 3}],"path": ["refundTransaction"],"extensions": {"errorType": "user_error","errorClass": "VALIDATION","legacyCode": "91512","inputPath": ["input", "transactionId"]}}]}