Token Transaction for Surcharge

Card readers are not required for token transaction in CSDK. To comply with PCI rules, CSDK introduces a callback method requireSurchargeDecision on interface ECLTransactionProcessingListener, which allows integrating POS application to prompt consumer for surcharge confirmation.

After consumers make the decision, integrating POS system can set the decision on the active transaction object and call transaction processor to continue the transaction.

CWS

When surcharge confirmation is needed for a token transaction, CWS set requiredInformation to "RequireSurchargeDecision" in the response for getPaymentTransactionStatus

Response

{
  "requestId" : "2101936246",
  "statusDetails" : "REQUEST_ACCEPTED",
  "data" : {
    "paymentGatewayCommand" : {
      "completed" : false,
      "eventQueue" : [ ],
      "chanId" : "eb5fcc9f-07db-40a6-9711-6c2bda9a26b9",
      "requiredInformation" : [ "RequireSurchargeDecision" ]
    }
  }
}

Request

After getting surcharge decision from consumer, integrating POS system can make continuePaymentTransaction request with decision Accept or Decline. If Decline is set or the field is empty, the transaction will be canceled.

{
  "method" : "continuePaymentTransaction",
  "requestId" : "2101936247",
  "targetType" : "paymentGatewayConverge",
  "version" : "1.0",
  "parameters" : {
    "RequireSurchargeDecision" : "Accept", 
    "paymentGatewayId" : "4c45c792-0513-4218-8b6d-c5ff7039a22e",
    "chanId" : "eb5fcc9f-07db-40a6-9711-6c2bda9a26b9"
  }
}

Java

// Suppose there is an instance of interface ECLTransactionProcessingListener
ECLTransactionProcessingListener theListener = new ECLTransactionProcessingListener() { /* implementation of the inteface *? };

// And start a transaction with the listener passed in.
...

// later on CSDK recognizes the card used for the transaction is credit card and calls requireSurchargeDecision on theListener

public void requireSurchargeDecision(ECLTransactionInterface eclTransactionInterface,
                                                 ECLTenderInterface eclTenderInterface,
                                                 ECLBinLookupOutcome eclBinLookupOutcome)
{
    // POS application should prompt consumer for surcharge confirmation with a UI element
    // object eclBinLookupOutcome contains attribute the total amount, surcharge amount and surcharge percentage
    // One example of the message to be displayed can be the following:
    // --------------------------------------------------------------------------------
    // Total Amount: formatted_version_of binLookupOutcome.getTotalAmount()
    // You will be assessed a binLookupOutcome.getCreditSurchargePercent()
    // surcharge amount of formatted_version_of binLookupOutcome.getCreditSurchargeAmount()
    // for using a credit card.
    // ---------------------------------------------------------------------------------
    //
    // The UI element should allow consumer to either accept or decline the surcharge
    // Assume boolean variable accepted records the decision from consumers
    eclTransactionInterface.setSurchargeDecision(
        accepted? ECLTransactionProcessingListener.SurchargeDecision.ACCEPT : ECLTransactionProcessingListener.SurchargeDecision.DECLINE,
        eclBinLookupOutcome);

    // call transaction processor to continue the transaction
    // if the decision is set to decline, the transaction will be terminated.
}

Objective-C (iOS)

// Implementation of [ECLTransactionProcessingDelegate shouldProvideSurchargeDecision:tender:binLookupOutcome:]
// This will get called when surcharge decision must be made by the consumer
+ (void)shouldProvideSurchargeDecision:(id<ECLCurrencyTransactionProtocol>)transaction tender:(id<ECLTenderProtocol>)tender binLookupOutcome:(ECLBinLookupOutcome *)binLookupOutcome {

    // POS application should prompt consumer for surcharge confirmation with a UI element
    // object binLookupOutcome contains properties for the surcharge amount, surcharge percentage, and total amount.
    // One example of the message to be displayed can be the following (see sample app for more details):
    // --------------------------------------------------------------------------------
    // [NSString stringWithFormat:@"Total Amount: %@ \n\nYou will be assessed a %.02f%% surcharge amount of %@ for using a credit card. Accept?",
    // [MainViewController formatWithCurrencySymbol:binLookupOutcome.totalAmount], binLookupOutcome.creditSurchargePercent,
    // [MainViewController formatWithCurrencySymbol:binLookupOutcome.creditSurchargeAmount]];
    // ---------------------------------------------------------------------------------
    //
    // The UI element should allow consumer to either accept or decline the surcharge
    // Assume BOOL variable "accepted" records the decision from consumers

    ((id<ECLCurrencyTransactionProtocol>)transaction).surchargeDecision = accepted ? ECLSurchargeDecisionAccept : ECLSurchargeDecisionDecline;
    dispatch_async(dispatch_get_main_queue(), ^() {
        // use dispatch_async and call continueProcessingTransaction using your account reference (see sample app for more details)
        [[_account transactionProcessor] continueProcessingTransaction:_transaction using:_tender delegate:self];
    });
}

C#

// Assume a CWS object cws is created and we have a delegate MyPaymentComplete to receive transaction update.
cws.StartPaymentTransaction(bea, MyNotifyCWSEvent, MyPaymentComplete);

// The following code demonstrates how to handle surcharge confirmation
public void MyPaymentComplete(PaymentTransactionResults paymentResults)
{
    // get required information
    String[] req = paymentResults.GetRequiredInformation();
    if (null != req)
    {
        for (int i = 0; i < req.Length; i++)
        {
            // if required information string is 'RequireSurchargeDecision'
            // surcharge confirmation should be prompted
            Dictionary<string, string> info = new Dictionary<string, string>();
            info["RequireSurchargeDecision"] = "Decline";
            if (String.Compare(req[i], "RequireSurchargeDecision", true ) == 0)
            {
                var binLookupOutcome = paymentResults.GetBinLookupOutcome();
                if (binLookupOutcome != null && binLookupOutcome.allowCreditSurcharge)
                {
                    // Display surcharge confirmation
                    // This is only an example for displaying surcharge confirmation message
                    string caption = "Surcharge Confirmation";
                    double totalAmount = ((double)binLookupOutcome.totalAmount.getAmountInMinorUnits()) / 100;
                    double surchargeAmount = ((double)binLookupOutcome.creditSurchargeAmount.getAmountInMinorUnits()) / 100;
                    string message = "Total Amount: $" + totalAmount + "\n\n"
                        + "You will be assessed a " + binLookupOutcome.creditSurchargePercent
                        + "% surcharge amount of $" + surchargeAmount
                        + " for using a credit card";
                    MessageBoxButton buttons = MessageBoxButton.OKCancel;
                    MessageBoxResult result = MessageBox.Show(message, caption, buttons);

                    //update attribute 'RequireSurchargeDecision' with either Accept or Decline (case insensitive)
                    info["RequireSurchargeDecision"] = result == MessageBoxResult.OK ? "Accept" : "Decline";
                }
                // Continue the transaction
                cws.StartContinuePaymentTransaction(m_PaymentGatewayId, chanId, info, MyNotifyCWSEvent, MyPaymentComplete); 
            }
        }   
    }
}