Create Refund

5 minute read

Ping allows both full and partial refunds with a single API-call through a single endpoint, agnostics to the payment method. Since most of the refund methods are asynchronous Ping will send callbacks in a similar fashion 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

NameDescription
amountThe amount in minor currency unit which is to be refunded.
currencyISO 4217 currency code for the Refund (e.g. EUR, SEK). Must be the same as the Payment currency.
descriptionShort description to clarifying why the refund is performed
messageMessage that will be shown to the original Payer
order_itemsAn 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.
reasonEnum 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 the Tenant. See Update Tenant to learn how to configure this callback URL.

Response Parameters

NameDescription
idThe ID of the refund. This will be provided in the refund status callback.
currencyThe currency of the refund, same as in the request parameter
amountThe amount of the refund, same as in the request parameter
providerThe provider which facilitated the refund. Will be the same as the provider Payment that is being refunded.
statusThe 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 this case 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, lets 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 case we provided amount an amount less than the original payment amount. That also means a new update version of the order_items list must 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 so you can react accordingly. The possible status of a refund are PENDING, DECLINED, FAILED, COMPLETED .

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

StatusTypeDescription
PENDINGnon-terminatedIf the refund is successfully initiated the status will transition to PENDING, which indicates that the payment is ongoing.
COMPLETEDterminatedThe original payer has successfully been refunded
DECLINEDterminatedThe refund was declined by the original payment provider. See details field information of why the refund was declined.
FAILEDterminatedThe 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