Refund Payments
To issue a full or partial refund, you need the id of a succeeded payment. Create one with Accept Card Payments. You can also cancel a refund before it settles.
Before you start
Secret Key- Authenticates requests from your server. Never send it to the browser.
Issue a Refund
We will need to reference the payment's id from the previously processed payment to create a refund.
For example, given you have a payment:
{
"id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "succeeded",
"transaction_id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"amount": 1000,
"amount_capturable": 0,
"amount_charged": 1000,
"amount_refunded": 0,
"refunded": false,
...
}
Create the Refund
We need to make a call to Create Refund endpoint:
curl 'https://api.publicsquare.com/refunds' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'IDEMPOTENCY-KEY: 09ec2c87-7fb8-44ca-bb18-5c71a76974da' \
-H 'Content-Type: application/json' \
-d '{
"amount": 1000,
"currency": "USD",
"payment_id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"reason": "Customer returned the item"
}'
Refund Response
Given the above examples, you should see a refund result similar to:
{
"id": "rfd_2YKewBonG4tgk12MheY3PiHDy",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "succeeded",
"transaction_id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"payment_id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"amount": 1000,
"currency": "USD",
"reason": "Customer returned the item",
"transaction": {
"id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "succeeded",
"amount": -1000,
"fee_amount": 0,
"net_amount": -1000,
"currency": "USD",
"type_id": "rfd_2YKewBonG4tgk12MheY3PiHDy",
"type": "refund",
"processor": "nuvei",
"processor_id": "7110000000010554769",
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
},
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
}
View Refunded Payment
Now if you retrieve the payment, you will see the payment info has updated:
curl 'https://api.publicsquare.com/payments/pmt_2YKewBonG4tgk12MheY3PiHDy' \
-H 'Accept: application/json' \
-H 'X-API-KEY: <SECRET_API_KEY>'
Given the above examples, you should see a payment result similar to:
{
"id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
...
"status": "succeeded",
"amount": 0,
"amount_capturable": 0,
"amount_charged": 1000,
"amount_refunded": 1000,
"refunded": true,
...
}
Payment Cancellation
Credova will attempt to cancel a payment first if it has not been settled and the refund amount matches the payment amount. In that situation, a succeeded refund will still be created, but the associated payment will be cancelled.
Refund Response
You should see a refund result similar to:
{
"id": "rfd_2YKewBonG4tgk12MheY3PiHDy",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "succeeded",
"transaction_id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"payment_id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"amount": 1000,
"currency": "USD",
"reason": "Cancelling payment",
"transaction": {
"id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "succeeded",
"amount": -1000,
"fee_amount": 0,
"net_amount": -1000,
"currency": "USD",
"type_id": "rfd_2YKewBonG4tgk12MheY3PiHDy",
"type": "refund",
"processor": "nuvei",
"processor_id": "7110000000010554769",
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
},
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
}
View Cancelled Payment
Now if you retrieve the payment, you will see the payment info has updated:
curl 'https://api.publicsquare.com/payments/pmt_2YKewBonG4tgk12MheY3PiHDy' \
-H 'Accept: application/json' \
-H 'X-API-KEY: <SECRET_API_KEY>'
You should see a payment result similar to:
{
"id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
...
"status": "cancelled",
"amount": 1000,
"amount_capturable": 0,
"amount_charged": 1000,
"amount_refunded": 0,
"refunded": false,
...
}
Refunding a Specific Capture
If a payment was captured using multiple partial captures, it has more than one entry in its payment_captures array. In that case, pass payment_capture_id on the refund request to specify which capture to refund:
curl 'https://api.publicsquare.com/refunds' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'IDEMPOTENCY-KEY: 09ec2c87-7fb8-44ca-bb18-5c71a76974da' \
-H 'Content-Type: application/json' \
-d '{
"amount": 400,
"currency": "USD",
"payment_id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"payment_capture_id": "cpt_3fRkT8bcdefghijklmnop",
"reason": "Customer returned the item"
}'
{
"id": "rfd_2YKewBonG4tgk12MheY3PiHDy",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "succeeded",
"transaction_id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"payment_id": "pmt_2YKewBonG4tgk12MheY3PiHDy",
"payment_capture_id": "cpt_3fRkT8bcdefghijklmnop",
"amount": 400,
"currency": "USD",
"reason": "Customer returned the item",
"created_at": "2024-06-30T01:02:29.212Z",
"modified_at": "2024-06-30T01:02:29.212Z"
}
payment_capture_id is required when the payment has more than one capture: payment_capture_id is required when the payment has multiple captures. If the payment has a single capture, it is resolved automatically and can be omitted.
The refund amount is validated against that capture's settled amount minus any prior refunds against it, rather than against the payment's total.
Cancel a Refund
There may be scenarios in which you need to cancel a refund, such as a refund issued in error or a customer decides to keep a product or service.
Credova API offers the ability to cancel a refund before it is settled.
Cancel the Refund
In order to cancel a refund, we will need the ID of a refund. Assuming you have a refund similar to:
{
"id": "rfd_2YKewBonG4tgk12MheY3PiHDy",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "succeeded",
...
}
We need to make a call to Cancel Refund endpoint:
curl 'https://api.publicsquare.com/refunds/cancel' \
-X 'POST' \
-H 'X-API-KEY: <SECRET_API_KEY>' \
-H 'Content-Type: application/json' \
-d '{
"refund_id": "rfd_2YKewBonG4tgk12MheY3PiHDy"
}'
Cancelled Refund Response
Given the above examples, you should see a cancelled refund result similar to:
{
"id": "rfd_2YKewBonG4tgk12MheY3PiHDy",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "cancelled",
"transaction_id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"amount": 1000,
...
"transaction": {
"id": "trx_95rvMJvAVeG68W4NtLdfkN3LG",
"account_id": "acc_B518niGwGYKzig6vtrRVZGGGV",
"environment": "test",
"status": "cancelled",
"amount": -1000,
"fee_amount": 0,
"net_amount": -1000,
...
},
...
}
Handling Cancellation Failures
If a refund cannot be cancelled because the refund has already been settled, an error response will be returned:
{
"title": "Error",
"status": 400,
"detail": "refund cancellation failed."
}
Conclusion
This guide showed you how to issue a refund for a payment and how to cancel a refund before it is settled. You can issue multiple refunds towards the original payment as long as the total refunded amount does not exceed the original payment amount. To learn more, see Search and View Transactions.