To return funds to a shopper after a payment is Approved, you need to refund the payment. Referenced refunds are connected to the original payment, using the unique identifier of that payment.
When you make a POS payment, the Terminal API response returns the transaction identifier of the payment in the format tenderReference.pspReference
. To make a referenced refund, you specify this transaction identifier in your refund request. This lets us validate the refund against the original payment, to ensure that it hasn't already been refunded.
You can make a:
- Full refund to return the total value of the purchase to the shopper.
- Partial refund to return part of the purchase to the shopper. For example, when a shopper returns one of the items they purchased. You can also make multiple partial refunds. For example, when a shopper returns several items at different times.
Make a referenced refund
Select a tab to see the parameters that you need to specify for a full referenced refund, or a partial referenced refund.
Here we describe the basic referenced refund request for the full amount. To refund an offline payment or to refund an ecommerce payment, the request is a little different.
-
Get the
TransactionID
and theTimeStamp
of the original payment. You received these values in the payment response, in thePOIData.POITransactionID
object. -
Make a POST request to a Terminal API endpoint, specifying:
-
MessageHeader
: the standardSaleToPOIRequest.MessageHeader
object. Specify:Parameter Required Description ProtocolVersion
3.0 MessageClass
Service MessageCategory
Reversal MessageType
Request ServiceID
Your unique ID for this request, consisting of 1-10 alphanumeric characters. Must be unique within the last 48 hours for the terminal ( POIID
) being used.SaleID
Your unique ID for the POS system component to send this request from. POIID
The unique ID of the terminal to send this request to. Format: [device model]-[serial number]. -
ReversalRequest
: the request body. Specify:Parameter Required Description OriginalPOITransaction.POITransactionID
An object with: TransactionID
: Transaction identifier of the original payment in the formattenderReference.pspReference
. For example, BV0q001643892070000.VK9DRSLLRCQ2WN82TimeStamp
: Date and time in UTC format of the original payment. For example, 2000-01-01T00:00:00.000Z
ReversalReason
MerchantCancel
The following example shows how to make a full referenced refund.
Expand viewCopy link to code blockCopy code{ "SaleToPOIRequest":{ "MessageHeader":{ "ProtocolVersion":"3.0", "MessageClass":"Service", "MessageCategory":"Reversal", "MessageType":"Request", "SaleID":"POSSystemID12345", "ServiceID":"0207111105", "POIID":"V400m-324688179" }, "ReversalRequest":{ "OriginalPOITransaction":{ "POITransactionID":{ "TransactionID":"BV0q001643892070000.VK9DRSLLRCQ2WN82", "TimeStamp":"2022-01-31T12:08:45.004Z" } }, "ReversalReason":"MerchantCancel" } } } The payment terminal shows a waiting screen until you receive the response.
-
-
When you receive the
ReversalResponse
, check if we received your request. Note the following:Response.Result
: Success. This means we received your request. The refund itself will be processed asynchronously.POIData.POITransactionID.TransactionID
: the PSP reference for this refund request.PaymentReceipt
: the generated receipt data. This includes REFUND REQUESTED.Response.AdditionalResponse
with:posOriginalAmountValue
: the amount (in minor units) of the original payment.posAuthAmountValue
: the refund amount (in minor units) that we will try to get authorized.-
pspReference
: the PSP reference for this refund request.
Response when we received your full reversal requestExpand viewCopy link to code blockCopy code{ "SaleToPOIResponse": { "MessageHeader": { "MessageCategory": "Reversal", "MessageClass": "Service", "MessageType": "Response", "POIID": "V400m-324688179", "ProtocolVersion": "3.0", "SaleID": "POSSystemID12345", "ServiceID": "207111107" }, "ReversalResponse": { "POIData": { "POITransactionID": { "TimeStamp": "2022-02-03T15:04:15.004Z", "TransactionID": "TF995R5G6L2GWR82" } }, "PaymentReceipt": [...], "Response": { "AdditionalResponse": "tid=47069832&transactionType=GOODS_SERVICES&posadditionalamounts.originalAmountValue=1025&giftcardIndicator=false&posAmountGratuityValue=0&pspReference=TF995R5G6L2GWR82&store=YOUR_STOREL&iso8601TxDate=2022-02-03T15%3a04%3a13.0000000%2b0000&posOriginalAmountValue=1025&txtime=16%3a04%3a13&paymentMethod=mc&txdate=03-02-2022&merchantReference=2022-02-03%2016%3a04%3a13&posadditionalamounts.originalAmountCurrency=EUR&transactionReferenceNumber=TF995R5G6L2GWR82&posAuthAmountCurrency=EUR&posAmountCashbackValue=0&posEntryMode=CLESS_CHIP&posAuthAmountValue=1025", "Result": "Success" } } } } If your request failed, the
ReversalResponse
contains:Response.Result
: FailureAdditionalResponse
: this includes amessage
explaining why the request failed. For example:- Original pspReference required for this operation: messages like this tell you how to fix the request so you can try again.
- Transaction is already voided: this message tells you that we already received a full reversal request for the original transaction.
-
Wait for the CANCEL_OR_REFUND webhook to learn the outcome. Refunds are always processed asynchronously.
For a complete list of fields you can pass and receive for a referenced refund, see the ReversalRequest API reference and the ReversalResponse API reference.
Refund an offline payment when back online
When there is a temporary loss of internet connectivity, you can continue making point-of-sale payments. This is referred to as offline payments. If you need to refund such a payment when your integration is back online, you need to accommodate the fact that the PSP reference of the offline payment is missing.
An offline point-of-sale payment does have a tender reference, because the tender reference is generated by the terminal. However, the PSP reference is missing because PSP references are generated on the Adyen payments platform, and that could not be reached due to the loss of internet connectivity.
To refund an offline point-of-sale payment, you need to know the tender reference and the date of the original payment. In most cases you also need to know the unique identifier of the terminal that processed the original payment.
Compared to a basic full referenced refund, note the following request parameters:
Parameter | Required | Description |
---|---|---|
OriginalPOITransaction.POITransactionID |
An object with TransactionID : the tender reference of the original payment. For example, BV0q001643892070000 |
|
OriginalPOITransaction.POIID |
If using a different terminal than for the original payment. | The unique ID of the terminal that processed the original payment. With the POIID, we can find the missing information. |
{ "SaleToPOIRequest":{ "MessageHeader":{ "ProtocolVersion":"3.0", "MessageClass":"Service", "MessageCategory":"Reversal", "MessageType":"Request", "SaleID":"POSSystemID12345", "ServiceID":"207111108", "POIID":"V400m-324688179" }, "ReversalRequest":{ "OriginalPOITransaction":{ "POITransactionID":{ "TransactionID":"BV0q001643892070000", "TimeStamp":"2022-01-31T12:08:45.004Z" }, "POIID":"P400Plus-275008565" }, "ReversalReason":"MerchantCancel" } } }
Refund an ecommerce payment
An ecommerce payment does have a PSP reference, but the tender reference is missing because it is generated by the terminal. To refund an ecommerce payment, you need to know the PSP reference, the date, and the currency of the original payment.
Compared to a basic full referenced refund, note the following request parameters:
Parameter | Required | Description |
---|---|---|
OriginalPOITransaction.POITransactionID |
An object with TransactionID : the PSP reference of the original payment, in the format .pspReference . Do not forget the leading dot (.). For example: .VK9DRSLLRCQ2WN82 |
|
SaleData.SaleToAcquirerData |
The currency of the refund, in the format currency=ABC where ABC is the three-letter currency code. This must match the currency of the original payment. |
|
SaleData.SaleTransactionID |
An object with:
|
{ "SaleToPOIRequest":{ "MessageHeader":{ "ProtocolVersion":"3.0", "MessageClass":"Service", "MessageCategory":"Reversal", "MessageType":"Request", "SaleID":"POSSystemID12345", "ServiceID":"207111108", "POIID":"V400m-324688179" }, "ReversalRequest":{ "OriginalPOITransaction":{ "POITransactionID":{ "TransactionID":".VK9DRSLLRCQ2WN82", "TimeStamp":"2022-01-31T12:08:45.004Z" } }, "ReversalReason":"MerchantCancel", "SaleData":{ "SaleToAcquirerData":"currency=EUR", "SaleTransactionID":{ "TimeStamp":"2022-02-03T15:04:14.004Z", "TransactionID":"rev-708" } } } } }
When you receive the ReversalResponse
, note that the Response.AdditionalResponse
includes:
posOriginalAmountValue
: 0 (zero)posAuthAmountValue
: 0 (zero)
That is because at this moment we do not know the original amount of the ecommerce payment, and thus also do not know the refund amount that we will try to get authorized.