Create Refund
5 minute read
Ping Payments supports both full and partial Refunds through a single, unified API endpoint — regardless of the original Payment method. Most Refunds are processed asynchronously. Once a Refund is initiated, Ping will send callback notifications to your system, following the same pattern as with the InitiatePayment endpoint.
Refund Flow Overview
This sequence diagram shows the basic API calls and responses for Refunds. Later sections cover each step in depth, with full schemas, examples, and callback details.
API Parameters
Request Parameters
Name | Description |
---|---|
amount | The amount in Minor Currency Unit which is to be refunded. |
currency | ISO 4217 currency code for the Refund (e.g. EUR, SEK). Must be the same as the Payment currency. |
description | Short description to clarifying why the Refund is performed |
message | Message that will be shown to the original Payer |
order_items | An updated version of how the order_item list will look after that the Refund has been created. It is important that the sum of the order_items and the provided amount sums to the full Payment amount. This parameter is crucial to perform partial Refunds and is how we can refund certain order_items or part of order_items . |
reason | Enum which describes the reason for refund. |
Note: Unlike from the InitiatePayment, the callback URL is not set when creating the Refund. Instead it's configured on Tenant level. See Update Tenant to learn how to configure this callback URL.
Response Parameters
Name | Description |
---|---|
id | The ID of the Refund. This will be provided in the Refund status callback. |
currency | The currency of the Refund, same as in the request parameter |
amount | The amount of the Refund, same as in the request parameter |
provider | The provider which facilitated the Refund. Will be the same as the provider Payment that is being refunded. |
status | The initial status of the Refund. |
Example - Full Refund
Minimal example displaying how to perform a full Refund.
In this example, lets assume that the full Payment amount is 299.00 SEK.
Request
curl --location 'https://sandbox.pingpayments.com/payments/api/v1/payment_orders/<YOUR-PAYMENT-ORDER-ID>/payments/<YOUR-PAYMENT-ID>/refund' \
--header 'tenant_id: <YOUR-TENANT-ID>' \
--header 'x-api-secret: <YOUR-API-SECRET>' \
--header 'Content-Type: application/json' \
--data '{
"amount": 29900,
"currency": "SEK",
"description": "Test refund",
"reason": "requested_by_customer",
"order_items": []
}'
In example order_items
is an empty list and the amount is the full Payment amount, which is indicating that we are performing a full Refund.
Response
{
"id": "e2fbcec8-4858-40f0-ba7f-7fcf82653f58",
"status": "PENDING",
"currency": "SEK",
"provider": "swish",
"amount": 29900
}
Example - Partial Refund
Minimal example displaying how to perform a partial Refund.
In this example, let's assume that the full Payment amount is 299.00 SEK and only want to refund 100.00 SEK.
Request
curl --location 'https://sandbox.pingpayments.com/payments/api/v1/payment_orders/<YOUR-PAYMENT-ORDER-ID>/payments/<YOUR-PAYMENT-ID>/refund' \
--header 'tenant_id: <YOUR-TENANT-ID>' \
--header 'x-api-secret: <YOUR-API-SECRET>' \
--header 'Content-Type: application/json' \
--data '{
"amount": 10000,
"currency": "SEK",
"description": "Test refund",
"reason": "requested_by_customer",
"order_items": [
{
"amount": 19900,
"metadata": {},
"name": "Test Purchase",
"merchant_id": <YOU-MERCHANT-ID>,
"vat_rate": "0",
"tags": []
}
]
}'
In this example, an amount less than the original Payment amount was provided. This requires a new set of order_items
to be provided.
Notice that the Refund amount and
order_items
amount sum to the original Payment amount.
Once this PaymentOrder is Settled, only 199.00 SEK will be allocated to the Merchant instead of the original 299.00 SEK.
Response
{
"id": "e2fbcec8-4858-40f0-ba7f-7fcf82653f58",
"status": "PENDING",
"currency": "SEK",
"provider": "swish",
"amount": 10000
}
Status callback
Ping will post callbacks regarding the Refund status to the configured callback URL to let you now the exact state of the refund enabling you to react accordingly.
Note: To ensure robust callbacks ping will make up to 20 attempts with exponential back off to make sure the callback is allays delivered.
Possible refund statuses
Status | Type | Description |
---|---|---|
PENDING | non-terminated | If the refund is successfully initiated the status will transition to PENDING, which indicates that the Payment is ongoing. |
COMPLETED | terminated | The original payer has successfully been refunded |
DECLINED | terminated | The refund was declined by the original Payment provider. See details field information of why the Refund was declined. |
FAILED | terminated | The original Payment provider failed to perform the Refund. See details field information of why the Refund was failed. |
Note: Once a Refund is terminated, no more status-callbacks will be sent regarding that Refund
Updated 16 days ago