Token Transaction for Service Fee

Card readers are not used for token transactions. To comply with PCI rules, Commerce SDK will notify the Integrator’s POS system through API callbacks for service fee confirmation.

The POS system can send one of the following decisions to Commerce SDK:

  • Accept - accept the service fee and send the transaction for authorization
  • Decline - decline the service fee and cancel the transaction

The following documents the API changes for different platforms:

CWS

When service fee confirmation is needed from the POS application, CWS sets property requiredInformation to either “RequireServiceFeePercentageConfirmation” (for percentage based service fee) or “RequireServiceFeeAmountConfirmation” (for fixed amount service fee) in the response to getPaymentTransactionStatus. CWS also sets property extraChargeLookupOutcome with the service fee details.

Response (Percentage Based)

{
    "requestId": "1895323088",
    "statusDetails": "REQUEST_ACCEPTED",
    "data": {
        "paymentGatewayCommand": {
            "completed": false,
            "eventQueue": [],
            "chanId": "7b935b30-acec-4ca7-8879-303ca7719cc0",
            "requiredInformation": ["RequireServiceFeePercentageConfirmation"],
            "extraChargeLookupOutcome": {
                "allowExtraCharge": true,
                "extraChargeType": "SERVICE_FEE_P",
                "extraChargePercent": 3.0,
                "extraChargeAmount": {
                    "currencyCode": "USD",
                    "amount": 30
                },
                "totalAmount": {
                    "currencyCode": "USD",
                    "amount": 1030
                },
                "baseAmount": {
                    "currencyCode": "USD",
                    "amount": 1000
                },
                "extraChargeConfirmationOption": null
            }
        }
    }
}

Response (Fixed Amount)

{
    "requestId": "2101936246",
    "statusDetails": "REQUEST_ACCEPTED",
    "data": {
        "paymentGatewayCommand": {
            "completed": false,
            "eventQueue": [],
            "chanId": "1d5f66cf-9d90-43ff-9f35-c74429b91679",
            "requiredInformation": ["RequireServiceFeeAmountConfirmation"],
            "extraChargeLookupOutcome": {
                "allowExtraCharge": true,
                "extraChargeType": "SERVICE_FEE_A",
                "extraChargePercent": 0.0,
                "extraChargeAmount": {
                    "currencyCode": "USD",
                    "amount": 100
                },
                "totalAmount": {
                    "currencyCode": "USD",
                    "amount": 1100
                },
                "baseAmount": {
                    "currencyCode": "USD",
                    "amount": 1000
                },
                "extraChargeConfirmationOption": null
            }
        }
    }
}

The 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.

Request (Percentage Based)

{
    "method": "continuePaymentTransaction",
    "requestId": "1895323089",
    "targetType": "paymentGatewayConverge",
    "version": "1.0",
    "parameters": {
        "RequireServiceFeePercentageConfirmation": "Accept",
        "chanId": "7b935b30-acec-4ca7-8879-303ca7719cc0",
        "paymentGatewayId": "419b27d4-aeed-46e4-a443-24ec4c8deae4"
    }
}

Request (Fixed Amount)

{
    "method": "continuePaymentTransaction",
    "requestId": "2101936247",
    "targetType": "paymentGatewayConverge",
    "version": "1.0",
    "parameters": {
        "RequireServiceFeeAmountConfirmation": "Accept",
        "paymentGatewayId": "fd4d63b6-a60f-4a15-b8bc-7ac16fb935de",
        "chanId": "1d5f66cf-9d90-43ff-9f35-c74429b91679"
    }
}

Java

// Suppose there is an instance of interface ECLTransactionProcessingListener
ECLTransactionProcessingListener theListener = new ECLTransactionProcessingListener() { /* implementation of the interface */ };
 
// And start a transaction with the listener passed in.
...
 
// later on CSDK needs the service fee decision and calls requireExtraChargeDecision on theListener
  
public void requireExtraChargeDecision(ECLTransactionInterface transaction,
                                       ECLTenderInterface tender,
                                       ECLExtraChargeLookupOutcome extraChargeLookupOutcome,
                                       ECLTransactionProcessingCallbackListener transactionProcessingCallbackListener)
{
    // POS application should prompt consumer for service fee confirmation with a UI element
    // object extraChargeLookupOutcome contains attributes such as service fee amount and total amount
    //
    // Assume boolean variable "accepted" records the decision from consumer
    ECLExtraChargeDecision extraChargeDecision = accepted ? ECLExtraChargeDecision.ACCEPT : ECLExtraChargeDecision.DECLINE;
    transactionProcessingCallbackListener.setExtraChargeDecision(transaction, tender, extraChargeLookupOutcome, extraChargeDecision)
}

Objective-C (iOS)

// Implementation of [ECLTransactionProcessingDelegate shouldProvideExtraChargeDecision:tender:extraChargeLookupOutcome:]
// This will get called when service fee decision must be made by the consumer
- (void)shouldProvideExtraChargeDecision:(id<ECLCurrencyTransactionProtocol>)transaction tender:(id<ECLTenderProtocol>)tender extraChargeLookupOutcome:(ECLExtraChargeLookupOutcome *)extraChargeLookupOutcome {
     
    // POS application should prompt consumer for service fee confirmation with a UI element
    // object extraChargeLookupOutcome contains attributes such as service fee amount and total amount
    //
    // Assume BOOL variable "accepted" records the decision from consumer
    transaction.extraChargeDecision = accepted ? ECLExtraChargeDecisionAccept : ECLExtraChargeDecisionDecline;
    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 service fee confirmation
public void MyPaymentComplete(PaymentTransactionResults paymentResults)
{
    // get required information
    String[] req = paymentResults.GetRequiredInformation();
    if (null != req)
    {
        Dictionary<string, string> info = new Dictionary<string, string>();
        for (int i = 0; i < req.Length; i++)
        {
            if (String.Compare(req[i], "RequireServiceFeePercentageConfirmation", true) == 0)
            {
                info["RequireServiceFeePercentageConfirmation"] = "Accept"; // can also set to "Decline"
            }
            else if (String.Compare(req[i], "RequireServiceFeeAmountConfirmation", true) == 0)
            {
                info["RequireServiceFeeAmountConfirmation"] = "Accept"; // can also set to "Decline"
            }
        }
    
        if (info.Count != 0)
        {
            // Continue the transaction
            cws.StartContinuePaymentTransaction(m_PaymentGatewayId, chanId, info, MyNotifyCWSEvent, MyPaymentComplete);
        }
    }
}