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:

  • Referenced refunds are connected to the original payment, using a unique identifier of that payment.
  • Unreferenced refunds need to be manually reconciled, and let you return any amount to any card presented in-store. You can use this for example to issue a refund to someone who did not make the original payment, such as a gift recipient.

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.

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. In the response we return the transaction identifier of the payment. To make a referenced refund, you specify this transaction identifier in your refund request. This allows us to validate the refund 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 multiple partial refunds. These can be useful when, for example, a shopper is returning several items at different times.

The transaction identifier that you need to specify in your full or partial refund request, consists of tenderReference.pspReference. For a full refund using the same terminal that was used in the original payment, it is sufficient to specify the tenderReference, because all information is available in that terminal. In all other cases the .pspReference is required.

Make a referenced refund

Full and partial refund requests are very similar: there are a few additional parameters for a partial refund. To make a full or partial referenced refund request:

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

    • MessageHeader object: This follows the standard MessageHeader structure, explained in Terminal API fundamentals:

      • ProtocolVersion: 3.0
      • MessageCategory: Reversal. This indicates you are initiating a refund request.
      • MessageType: Request
      • SaleID: Your unique ID for the cash register.
      • ServiceID: Your unique ID for this transaction attempt. This needs to be unique within the last 48 hours.
      • POIID: Unique ID of the terminal. This indicates which terminal the payment will be routed to.

    • ReversalRequest object with:

      • OriginalPOITransaction.POITransactionID.TransactionID: Transaction identifier of the original payment that you want to refund, in one of the following formats:

        Format Example
        tenderReference.pspReference 7JLX001566393198001.851556019495143C
        0000000000000000.pspReference 0000000000000000.851556019495143C

        This has 16 zeroes instead of a tender reference.

        .pspReference

        From VOS firmware version 1.44

        .851556019495143C

        Don't forget the leading dot (.).

        tenderReference 7JLX001566393198001

        Only for a full refund using the same terminal as the original payment.

      • OriginalPOITransaction.POITransactionID.TimeStamp: Date and time of the original transaction.
      • ReversalReason: MerchantCancel

    • For a partial refund, extend the ReversalRequest object with:

      • ReversedAmount: The amount being returned to the shopper in the partial refund.
      • SaleData.SaleToAcquirerData: The currency, in the format currency=EUR. This must match the currency used to make the original payment.
      • SaleData.SaleTransactionID.TimeStamp: Date and time of the partial refund.
      • SaleData.SaleTransactionID.TransactionID: Your unique reference for the partial refund. In your Customer Area, this is the merchant reference for the transaction.

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

    Sample request for a full refund:

    {
      "SaleToPOIRequest":{  
         "MessageHeader":{  
            "ProtocolVersion":"3.0",
            "MessageCategory":"Reversal",
            "MessageType":"Request",
            "MessageClass":"Service",
            "SaleID":"POSSystemID12345",
            "ServiceID":"0207111107",
            "POIID":"V400m-324688179"
          },
         "ReversalRequest":{  
            "OriginalPOITransaction":{  
               "POITransactionID":{  
                  "TransactionID":"7JLX001566393198001.851556019495143C",
                  "TimeStamp":"2019-03-07T10:11:04+00:00"
               }
            },
            "ReversalReason":"MerchantCancel"
         }
      }
    }

    Sample request for a partial refund of 6.00 EUR:

    {
      "SaleToPOIRequest":{
         "MessageHeader":{
            "ProtocolVersion":"3.0",
            "MessageCategory":"Reversal",
            "MessageType":"Request",
            "MessageClass":"Service",
            "SaleID":"POSSystemID12345",
            "ServiceID":"0207111108",
            "POIID":"V400m-324688179"
         },
         "ReversalRequest":{
            "OriginalPOITransaction":{
               "POITransactionID":{
                  "TransactionID":"pZtU001251034513719.881566567357804C",
                  "TimeStamp":"2019-08-12T15:40:03+00:00"
               }
            },
            "ReversalReason":"MerchantCancel",
            "ReversedAmount":6.00,
            "SaleData":{
               "SaleToAcquirerData":"currency=EUR",
               "SaleTransactionID":{
                  "TimeStamp":"2019-08-15T12:00:00+00:00",
                  "TransactionID":"27911"
               }    
            }
         }
      }
    }
  2. Receive the result of the refund request.

    • If successful, the response contains a ReversalResponse body object with:

      • POIData.POITransactionID.TransactionID: The transaction identifier in the format tenderReference.pspReference for this refund request.
      • Response.Result: Succes

      Sample success response for a full or partial refund request:

      {  
         "SaleToPOIResponse":{  
            "ReversalResponse":{  
               "POIData":{  
                  "POITransactionID":{  
                     "TimeStamp":"2019-05-23T10:32:32.928Z",
                     "TransactionID":"0000001565959382003.881566557882697F"
                  }
               },
               "Response":{  
                  "Result":"Success",
                  ...
               }
            },
            ...
         }
      }
    • If unsuccessful, the response contains a ReversalResponse body object with:

      • Response.Result: Failure
      • AdditionalResponse: Contains a message explaining why the request failed.
      {  
         "SaleToPOIResponse":{  
            "ReversalResponse":{  
               "Response":{  
                  "Result":"Failure",
                  "AdditionalResponse":"tid=24687685&...&message=Original%20pspReference%20required%20for%20this%20operation&posAmountCashbackValue=0&posEntryMode=UNKNOWN&posAuthAmountValue=0",
                  "ErrorCondition":"NotAllowed"
               }
            },
            ...
            }
         }
      }

    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.

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.

Make an unreferenced refund

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

    • MessageHeader object: This follows the standard MessageHeader structure, explained in Terminal API fundamentals:

      • ProtocolVersion: 3.0
      • MessageCategory: Payment.
      • MessageType: Request
      • SaleID: Your unique ID for the cash register.
      • ServiceID: Your unique ID for this transaction attempt. This needs to be unique within the last 48 hours.
      • POIID: Unique ID of the terminal. This indicates which terminal the payment will be routed to.

    • PaymentRequest object with:

      • SaleData.SaleTransactionID.TimeStamp: Date and time of the refund.
      • SaleData.SaleTransactionID.TransactionID: Your unique reference for the refund. In your Customer Area, this is the merchant reference for the transaction.
      • PaymentTransaction.AmountsReq: The Currency and RequestedAmount being refunded to the card.
      • PaymentData.PaymentType: Refund

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

    {
      "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"
          }
        }
      }
    }

    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:
    {
        "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.

Next steps