Refunds

The following PayProtocol (P3) refund messages are supported by the PayServer. Also see, Message Specification as a starting point.
Refunds allow your merchants to transfer the full or partial amount of a previous charge transaction back to the shopper.
Linked Refunds
Refunds are implemented as Linked Refunds, meaning you need to provide the
transactionIdentifier
of the previous charge transaction in order to perform the refund. For Linked Refunds it is not required for the shopper to present their card again and the refund will be paid out on the exact same card as used for the charge.
To run a full or partial Linked Refund, you need to implement the
AMEND_TRANSACTION
messages. Those messages are part of a long running operation but do not require a card reader device.
Then sending the
AMEND_TRANSACTION_REQUEST
message, you need to specify
REFUND
as the
type
and provide the
transactionIdentifier
of the previous charge transaction as the
referencedTransactionIdentifier
. For partial refunds, you also need to specify the
amount
and
currency
that should be refunded:
Request Data
{ "tag": "abc123", "type": "AMEND_TRANSACTION_REQUEST", "resource": null, "amendTransactionRequest": { "mode" : "ONLINE | OFFLINE", "transactionParameters": { "type": "REFUND", "referencedTransactionIdentifier": "97a293ca3b804d639d8552962e0e3522", "amount": 5.00, "currency": <Currency>, "subject": "My Refund Subject", "customIdentifier": "my-custom-identifier", } } }
Update Data
Since amending transactions is a long running operation, the server provides the client with update messages which inform about the current state of the process.
{ "tag": "abc123", "type": "AMEND_TRANSACTION_UPDATE", "resource": null, "amendTransactionUpdate": { "state": <TransactionProcessDetailsState>, "stateDetails": <TransactionProcessDetailsStateDetails>, "information": ["Processing", "payment..."], "abortable": false, } }
The field
information
is an array of exactly two strings which contain localized, human readable information about the state of the transaction. You can use them straight in your POS UI.
Response Data
Receiving an amend transaction response means that the long running operation is over and there will be no more related updates.
{ "tag": "abc123", "type": "AMEND_TRANSACTION_RESPONSE", "resource": null, "amendTransactionResponse": { "state": <TransactionProcessDetailsState>, "stateDetails": <TransactionProcessDetailsStateDetails>, "transaction": { "amount": 10.00, "currency": <Currency>, "type": "CHARGE", "subject": "My Charge Subject", "statementDescriptor": "My Statement Descriptor", "status": <TransactionStatus>, "identifier": "97a293ca3b804d639d8552962e0e3522", "createdTimestamp": 1464009191, "customIdentifier": "my-custom-identifier", "refundDetails": { "status": <RefundDetailsStatus>, "process": [<RefundDetailsProcess>], "refundTransactions": [ { "identifier": "c735ec8ed1794e83882fba8c99ccd7d2", "createdTimestamp": 1464609191, "amount": 5.00, "currency": <Currency>, "subject": "My Refund Subject", "customIdentifier": "my-custom-identifier", "type": "REFUND", "code": <RefundTransactionCode>, "status": <TransactionStatus>, "statusDetails": { "code": <TransactionStatusDetailsCodes>, "description": "A description", "developerDescription": "A developer description", } } ] } } } }
The returned transaction object is the one from the original charge transaction, but in case of a successful refund, the
refundDetails
now contains the refund transactions.
In case the refund failed (i.e., the
refundDetails
are empty), make sure to notify the merchant accordingly
.
In order to create the required refund receipts you need to take the last
$refundDetails.refundTransactions.identifier
from the array (e.g.
c735ec8ed1794e83882fba8c99ccd7d2
in the sample above) and use it to retrieve the
merchantReceipt
and
customerReceipt
data via the
GET_TRANSACTION_REQUEST
message.
Further details on the
GET_TRANSACTION_REQUEST
message can be found in the overall message specification.
Standalone Refunds
There might be the rare occasion when the
transactionIdentifier
of the previous charge is not available, e.g. should your POS system not allow the merchant to retrieve the original invoice containing the
transactionIdentifier
.
In this scenario Standalone Refunds allow the merchant to perform a refund without reference to the previous charge transaction. The shopper must present their card again.
Standalone Refunds have a high risk profile, i.e. merchant money can be paid out without limitations. Only consider offering them after you are absolutely sure that Linked Refunds are not possible in your setup.
Should your merchants require Standalone Refunds, please talk to your account manager beforehand to ensure all prerequisites are met. Specifically you need to ensure that:
  • Each merchant provides you with a written confirmation that they understand that Standalone Refunds potentially allow to pay out merchant money without limitations and that only authorized store personal must be allowed to use them.
  • Your POS system protects usage of the Standalone Refund feature, i.e., your POS system make sure that only authorized store personal (like store owner or supervisor) can use it and that usage is protected by a password or PIN. Note that before allowing you to go LIVE with Standalone Refunds, we will verify this requirements as part of our Testing.
Stand Alone Refunds are run via the
EXECUTE_TRANSACTION_REQUEST
message, similar to charge transactions, but using
REFUND
as
type
(instead of
CHARGE
).
Standalone Refunds with Transaction Parameters
{ "tag": "abc123", "type": "EXECUTE_TRANSACTION_REQUEST", "resource": "devices/usbReader", "executeTransactionRequest": { "transactionParameters": { "amount": 5.00, "currency": "EUR", "type": "REFUND", "subject": "Refund of previous charge" } } }