Search

Are you looking for test card numbers?

Would you like to contact support?

Refund a payment

Learn how to issue a point of sale refund.

If you want to return funds to a shopper after a payment has been Approved you need to refund the payment.

We offer two types of refund:

You may want to support one type of refund, or both.

For most use cases, we recommend using referenced refunds, because they offer the following advantages over unreferenced refunds:

  • Simpler reconciliation: A refund can be matched against a payment, using the pspReference.
  • Lower risk of return fraud: A payment can't be refunded multiple times, or for an amount exceeding 100% of the payment value.
  • Support for non-card payment methods, such as Alipay and WeChat Pay.
  • Cross-channel refunds: Refunds can be issued in-store, from your call center, or your fulfillment center.

If you need to issue a refund to someone that did not make the original payment, such as a gift recipient, you will need to make an unreferenced refund. These let you to refund any amount to any card presented in-store.

When a refund has been processed it is deducted from your in-process funds, and will appear in your shopper's account within a few days.

You can also issue refunds from your Customer Area. You may wish to do this if you're not refunding point of sale payments often.

Referenced refunds

When you make a point of sale payment, we connect the shopper's payment details to the payment, and return a unique reference (pspReference) in the response.

To make a referenced refund, you specify this pspReference in the refund request. We validate your refund request against the original payment, to ensure that it hasn't already been refunded.

Depending on what the shopper is returning, you can either make a:

  • Full refund: Returns the total value of the purchase to the shopper.
  • Partial refund: Returns part of the purchase to the shopper. For example, when a shopper wishes to return one of the items they purchased.

    You can also make mutiple partial refunds. These can be useful when, for example, a shopper is returning several items at different times.

Make full referenced refund

To make a full referenced refund request:

  • Make a POST request to a Terminal API endpoint, specifying:

    • content-type: application/json
    • x-api-key: Your API key. This is only required if you're using cloud-based communications.
    • ProtocolVersion: 3.0
    • MessageCategory: Reversal
    • MessageType: Request
    • MessageClass: Service
    • SaleID: Your unique ID for the cash register.
    • ServiceID: Your unique ID generated by the cash register for this refund request.
    • POIID: Unique ID of the terminal that made the payment.

      The POIID = [Terminal model]-[Serial number], for example: P400Plus-123456789

    • TransactionID: The pspReference of the payment being refunded.
    • TimeStamp: Date and time of the transaction being refunded.
    • ReversalReason: MerchantCancel

    The example below shows how you would refund a payment with the TransactionID 851556019495143C.

    The integration in this example uses synchronous, cloud-based communication.

    curl -H "content-type:application/json" -H "x-api-key:YOUR_API_KEY" -X POST --data-binary '{
      "SaleToPOIRequest":{
        "MessageHeader":{
          "ProtocolVersion":"3.0",
          "MessageCategory":"Reversal",
          "MessageType":"Request",
          "MessageClass":"Service",
          "SaleID":"POSSystemID12345",
          "ServiceID":"0207111107",
          "POIID":"V400m-324688179"
        },
        "ReversalRequest":{
          "OriginalPOITransaction":{
            "POITransactionID":{
              "TransactionID":"851556019495143C",
              "TimeStamp":"2019-03-07T10:11:04+00:00"
            }
          },
          "ReversalReason":"MerchantCancel"
        }
      }
    }' --url https://terminal-api-test.adyen.com/sync

    For a complete list of fields you can pass when making a referenced refund, see the ReversalRequest API reference.

If your refund request was successfully received the response contains:

  • result: Success
  • TransactionID: Our unique identifier for this refund request.
{
  "SaleToPOIResponse": {
    "ReversalResponse": {
      "POIData": {
        "POITransactionID": {
          "TimeStamp": "2019-05-23T10:32:32.928Z",
          "TransactionID": "851556019495143C"
        }
      },
      "Response": {
        "Result": "Success",
        ...
      }
    },
    ...
  }
}

For a complete list of fields you can receive in a referenced refund response, see the ReversalResponse API reference.

We attempt to issue the refund asynchronously, and inform you whether this is successful with a webhook notification. If successful, the refund is issued to the shopper's account.

Make partial referenced refund

If you only need to refund part of a purchase you can make a partial referenced refund. This is similar to making a full refund request, but you additionally specify:

  • ReversedAmount: The amount being refunded to the shopper.
  • SaleData: Must include the following:

    • SaleToAcquirerData: The currency, in the format currency=EUR. This must match the currency used to make the payment.
    • SaleTransactionID: The TimeStamp and your TransactionID of the payment.

The example below shows how you would partially refund 6.00 EUR of a payment with the TransactionID 851556019495143C.

The integration in this example uses synchronous, cloud-based communication.

curl -H "content-type:application/json" -H "x-api-key:YOUR_API_KEY" -X POST --data-binary '{
  "SaleToPOIRequest":{
    "MessageHeader":{
      "ProtocolVersion":"3.0",
      "MessageCategory":"Reversal",
      "MessageType":"Request",
      "MessageClass":"Service",
      "SaleID":"POSSystemID12345",
      "ServiceID":"0207111108",
      "POIID":"V400m-324688179"
    },
    "ReversalRequest":{
      "OriginalPOITransaction":{
        "POITransactionID":{
          "TransactionID":"851556019495143C",
          "TimeStamp":"2019-03-07T10:11:04+00:00"
        }
      },
      "ReversalReason":"MerchantCancel",
      "ReversedAmount":6.00,
      "SaleData":{
        "SaleToAcquirerData":"currency=EUR",
        "SaleTransactionID":{
          "TimeStamp":"2019-04-23T12:00:00+00:00",
          "TransactionID":"27911"
        }    
      }
    }
  }
}' --url https://terminal-api-test.adyen.com/sync

For a complete list of fields you can pass when making a partial referenced refund, see the ReversalRequest API reference.

We attempt to issue the refund asynchronously, and inform you whether this is successful with a webhook notification. If successful, the partial refund is issued to the shopper's account.

Unreferenced refunds

If you are using unreferenced refunds, we highly recommend that your cash register system is able to reconcile a refund against an original purchase. This reduces your risk of return fraud (a payment being refunded multiple times), and human error (store staff enter the wrong refund amount).

It's not possible to make an unreferenced refund to a QR code payment method, such as Alipay and WeChat Pay. To refund these payment methods you must make a referenced refund.

Before you can make unreferenced refunds, you need to contact our POS Support Team team. They will need to enable unreferenced refunds for your merchant account.

To make an unreferenced refund request:

  1. Make a POST request to a Terminal API endpoint, specifying:

    • content-type: application/json
    • x-api-key: Your API key. This is only required if you're using cloud-based communications.
    • ProtocolVersion: 3.0
    • MessageCategory: Payment
    • MessageType: Request
    • MessageClass: Service
    • SaleID: Your unique ID for the cash register.
    • ServiceID: Your unique ID generated by the cash register for this transaction. This needs to be unique within the last 48 hours.
    • POIID: Unique ID of the terminal.

      The POIID = [Terminal model]-[Serial number], for example: P400Plus-123456789.

    • TransactionID: Your unique reference for this transaction.
    • TimeStamp: Date and time of the refund.
    • AmountsReq: The Currency and RequestedAmount being refunded to the card.
    • PaymentType: Refund

    The example below shows how you would refund 10.99 EUR to a card.

    The integration in this example uses synchronous, cloud-based communication.

    curl -H "content-type:application/json" -H "x-api-key:YOUR_API_KEY" -X POST --data-binary '{
      "SaleToPOIRequest":{
        "MessageHeader":{
          "ProtocolVersion":"3.0",
          "MessageCategory":"Payment",
          "MessageType":"Request",
          "MessageClass":"Service",
          "SaleID":"POSSystemID12345",
          "ServiceID":"12392",
          "POIID":"V400m-324688179"
        },
        "PaymentRequest":{
          "SaleData":{
            "SaleTransactionID":{
              "TimeStamp":"2019-04-23T12:15:01+00:00",
              "TransactionID":"YOUR_REFUND_REFERENCE"
            }
          },
          "PaymentTransaction":{
            "AmountsReq":{
              "Currency":"EUR",
              "RequestedAmount":10.99
            }
          },
          "PaymentData":{
            "PaymentType":"Refund"
          }
        }
      }
    }' --url https://terminal-api-test.adyen.com/sync

    For a complete list of fields you can pass when making a unreferenced refund, see the PaymentRequest API reference.

    The refund request is routed to the terminal.

  2. Present the card to the terminal, and follow the instructions on the terminal screen.

If your refund request is successfully received:

  • Approved is displayed on the terminal screen.
  • You receive a JSON response with:

    • Result: Success
    • POIData.POITransactionID.TransactionID: Our unique identifier for this refund request.
    {
        "SaleToPOIResponse": {
            "PaymentResponse": {
                "POIData": {
                    "POITransactionID": {
                        "TimeStamp": "2019-06-03T15:49:36.000Z",
                        "TransactionID": "4rVu001559576976000.881559576981487A"
                    },
                    ...
                },
                ...
                "Response": {
                    "Result": "Success",
                    ...
                }
            },
            ...
        }
    }

    For a complete list of fields you can receive in a unreferenced refund response, see the PaymentResponse API reference.

We attempt to issue the refund asynchronously, and inform you whether this is successful with a webhook notification. If successful, the refund is issued to the card presented to the terminal.

Refund notifications

When we receive your refund request, we send you a webhook notification to inform you whether this request was processed. This notification contains:

  • eventCode: REFUND
  • pspReference: Matches the TransactionID of the refund request.
  • success: Indicates whether the refund request was processed:

    • true: We processed your refund request. This usually results in the refund being issued.
    • false: We did not process your refund request. This means you do not have sufficient in-process funds to issue the refund. You should increase your in-process funds, and request the refund again.

In rare cases, after your refund request is processed you can receive a notification indicating that this refund:

An overview of failed and reversed refunds is available in your payment accounting report.

Refund failed

If there was a technical issue when we attempt to issue a refund, we send you a notification that contains:

  • eventCode: REFUND_FAILED
  • originalReference: The pspReference of the payment you are refunding.
  • pspReference: Our unique identifier for the refund that failed.

When a refund fails we will try to fix the issue, then attempt the refund again.

Refunded reversed

If we try and refund a payment, and the shopper's account is no longer valid (for example, they have closed their account), we send you a notification that contains:

  • eventCode: REFUNDED_REVERSED
  • originalReference: The pspReference of the failed refund request.
  • success: true

This means that the funds have been returned to Adyen, and are back in your merchant account.

Terminal API endpoints

For test transactions, use the endpoint below that corresponds to your integration architecture.

For more information on these architectures, see our Terminal API overview.

Local

Endpoints for local communications with the Terminal API use the format:

  • https://[TERMINAL]:8443/nexo/ on port 8443 (https).
    Replace [TERMINAL] with the IP or resolvable hostname of the terminal.

Cloud

For cloud-based communications with the Terminal API use either:

Next steps