Refund Payments
After completing the Process Payments guide, you may need to issue a full or partial refund to the customer.
Getting Started
To get started, you will need a Credova Account.
Get your Secret Key
Next you will need your Secret Key. Go to your Developers section and click Reveal for your Secret Key and copy the value.
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 'IDEMPONTENCY-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.
Conclusion
This guide showed you how to issue a refund for a payment. You can issue multiple refunds towards the original payment as long as the total refunded amount does not exceed the original payment amount.