Refunds

Refunds enable your merchants to transfer the full or partial amount of a previous charge transaction back to the shopper.
Linked Refunds
For refunds implemented as Linked Refunds, you must provide the
transactionIdentifier
of the previous charge transaction in order to perform the refund. The shopper is not required to present the card again for you to process a Linked Refund. The refund will be paid to the same card used for the charge transaction.
To run a full or partial Linked Refund, create the
TransactionParameters
with the
transactionIdentifier
of the previous charge transaction you want to refund. For partial refunds, you also must specify the amount that should be refunded.
To start the refund process, you then call the
AmendTransaction
on the
ITransactionModule
with the created
TransactionParameters
:
var refundParameters = new TransactionParameters.Builder() .Refund("<transactionIdentifier>") // For partial refunds, also specify refund amount and currency // .AmountAndCurrency(10.00m, Currency.EUR) .Build(); // delegate methods are similar to start transaction var process = PosClient.GetTransactionModule().AmendTransaction(refundParameters, (transaction, transactionProcessDetails, abortable) => { // transaction update information }, (transaction, transactionStateDetails, error) => { // check for error if (error != null) { // error indicates that there was a problem refunding the transaction // check error.Type and error.Message for more information } else { // Let the merchant know that they can return the goods to the shopper // You can access details of the refund in transaction.RefundDetails Console.WriteLine("Refund successful"); // Provide a refund receipt: // Get all refundTransactions from the CHARGE transaction List<Payworks.PayClient.Transactions.RefundTransaction> refundTransactions = transaction.RefundDetails.RefundTransactions; // Access the last refund transaction (usually there is only one) RefundTransaction lastRefund = refundTransactions.Last(); if(lastRefund != null && lastRefund.Status == TransactionStatus.APPROVED) { // Get REFUND transaction includung receipt data PosClient.GetTransactionModule().GetTransaction(lastRefund.Identifier, (refundTransaction, err) => { if(err == null) { // Provide a printed REFUND receipt to the merchant and shopper // refundTransaction.MerchantReceipt // refundTransaction.CustomerReceipt } }); } } });
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 enables the merchant to perform a refund without reference to the previous charge transaction. The shopper is required to present the card again to process this type of refund.
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, contact your account manager before implementing this type of refund to ensure that 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 enable the ability to pay out merchant money without limitations and that only authorized store personal must be allowed to use them.
  • Your POS system protects the use of the Standalone Refund feature, i.e., your POS system make sure that only authorized store personal (like the store owner or supervisor) can use it and that usage is protected by a password or PIN. Note that before enabling you to go live with Standalone Refunds, we will verify this requirement has been met as part of our Testing.
Once enabled, Standalone Refunds are run very similar to charge transactions, meaning a card reader
Device
needs to be provided to
StartTransaction
.
Standalone Refund with Transaction Parameters:
var transactionParameters = new TransactionParameters.Builder() .Refund(10.00m, Currency.EUR) .Subject("Refund of previous charge") .CustomIdentifier("yourReferenceForTheTransaction") .Build(); var transactionProcessParameters = new TransactionProcessParameters.Builder().Build(); InteractiveProcess = PosClient.GetTransactionModule().StartTransaction(Device, transactionParameters, transactionProcessParameters, (transaction, transactionProcessDetails, abortable) => { // transaction update information // abortable indicates if the transaction can be aborted in the current state // transactionProcessDetails.Information array indicates human-readable the state information: // always show those two status lines in your merchant-facing UI // transactionProcessDetails.Information[0] // transactionProcessDetails.Information[1] }, (actionType) => { // Can be left empty, refunds will not raise an action }, (transaction, transactionProcessDetails, error) => { // check for error if (error != null) { // error indicates that there was a error with the transaction processing // check error.Type and error.Message for more information } else { // Inspect the transaction.Status to get the overall result / transaction completed if (transaction.Status == TransactionStatus.APPROVED) // DECLINED / ABORTED { Console.WriteLine("APPROVED: " + transaction.Identifier); // Provide printed refund receipts to the merchant and shopper // transaction.MerchantReceipt // transaction.CustomerReceipt } } } );