Search

Are you looking for test card numbers?

Would you like to contact support?

Point-of-sale icon

NFC-enabled passes

Learn how to process transactions with NFC-enabled passes.

Shoppers can link their credit and debit cards to a mobile wallet app and then make in-store payments with the mobile wallet using a service like Apple Pay. The payment terminal interfaces with the mobile wallet through near field communication (NFC) between the terminal and the shopper's phone or smartwatch.

Apart from credit and debit cards, shoppers can also keep other passes in their mobile wallet, such as loyalty cards, vouchers, gift cards, boarding passes, and tickets. With these NFC-enabled passes, they can for example redeem a voucher or collect points on a loyalty card.

As a merchant, you can create your own NFC-enabled passes, and tie them in with your loyalty program. With a Terminal API integration you are then able to check if the shopper has your pass in their mobile wallet, and use the pass for their transaction.

At the moment, we support this for:

  • Apple Wallet passes

How it works

There are various ways to implement NFC-enabled passes with a payment, depending on what makes sense for your pass and loyalty program:

  • Payment flow: You check for the passes after the payment, and update the shopper's account later.
  • Redeem flow: You check for the passes before the payment through a card acquisition request. If there are discounts or other advantages related to the pass, you can apply these to the payment beforehand. If the shopper doesn't have your pass yet, you can create one on the spot and add this information to your payment request. The shopper then receives a message that lets them add the pass to their wallet.

    There are two variations of the redeem flow: single-tap redeem flow and double-tap redeem flow. Apart from a configuration setting, the implementation is the same. The difference is that in the double-tap flow the terminal asks the shopper a second time to present their card. This allows the shopper to redeem the NFC pass the first time that the terminal asks for their card, and then switch to another payment method the second time that the terminal asks for their card.

Select the tabs below to learn more. Before you configure your NFC pass in the Customer Area, you need to understand how these flows work and which flow you want to implement.

You make a payment request. If the shopper pays with an NFC-enabled mobile wallet, you are informed in the payment response whether the shopper has your pass in their mobile wallet. If they do, the payment response includes the unique ID of the shopper's pass so that you can update the shopper's account.

You first make a card acquisition request with an amount. The terminal asks the shopper to present their card. When the shopper taps their NFC-enabled mobile device to the payment terminal, the terminal polls the mobile wallet on the device for:

  • Your passes.
  • The details of the payment method (the credit or debit card that is linked to the wallet).

If the shopper has your pass, the card acquisition response includes the unique ID of the shopper's pass so that you can look up the shopper's account. You can then for example:

  • Make an input request to ask the shopper whether they want to redeem loyalty points.
  • Add or recalculate loyalty points.
  • Apply a discount.

If the shopper doesn't have your pass, you can check if they already have a loyalty account and issue a pass.

Then you make a payment request for the final amount. This must be equal to or lower than the card acquisition amount.

In this flow, the shopper taps their mobile device to the terminal only once, because the card acquisition polls for the pass details and the payment method details at the same time.

You first make a card acquisition request with or without an amount. The terminal asks the shopper to present their card. When the shopper taps their NFC-enabled mobile device to the payment terminal, the terminal polls the mobile wallet on the device for your passes. If the shopper has your pass, the card acquisition response includes the unique ID of the shopper's pass so that you can look up the shopper's account. You can then for example:

  • Make an input request to ask the shopper whether they want to redeem loyalty points.
  • Add or recalculate loyalty points.
  • Apply a discount.

If the shopper doesn't have your pass, you can check if they already have a loyalty account and issue a pass.

Then you make a payment request for the final amount. The terminal asks the shopper again to present their card. The shopper can then choose to pay with their mobile wallet and tap their mobile device to the terminal a second time, or use a different payment method.

Shopper enrollment

To enroll shoppers in your loyalty program and let them add your NFC-enabled pass to their mobile wallet, you can inform them through email, social media, your web site, and so on.

In the redeem flow, it's possible to enroll the shopper and/or issue a pass on the spot, and add this information to your payment request. The shopper then receives a notification on their device that lets them add the pass to their wallet. See Case 2: The shopper doesn't have your pass.

Create NFC-enabled passes

  1. Set up a server for your NFC-enabled passes. On this pass server, you need to make a URL available where shoppers can enroll with the loyalty program tied to your NFC-enabled pass and add the pass to their mobile wallet.

    You need to specify this URL when you configure the pass in your Customer Area.

  2. Create one or more NFC-enabled passes. See for example the Wallet Developer Guide, which explains how to create an Apple Wallet pass for your loyalty program.

    While creating your pass, a pass type ID and private key are generated. You will need these later, when you configure the pass in your Customer Area.

  3. Make sure that you have built a Terminal API integration that can make a payment.
  4. Tie in your loyalty program with your NFC-enabled passes. To learn more about how to link a customer in your loyalty program to a transaction, refer to Shopper recognition and tokenization.

Configure NFC-enabled passes in your Customer Area

To enable us to get the unique ID of the shopper's pass, you need to inform us about your NFC-enabled pass and the flow you want to use:

  1. Log in to your Customer Area and select the account level where you want to use your NFC-enabled pass.
  2. Go to Point of sale > Terminal settings > Payment features.
  3. Scroll to NFC wallet passes and select Switch to decrypted mode.
  4. At Choose your setup, select an option for the flow you want to use. This setting determines what the terminal tries to do when you make a card acquisition request and the shopper taps a device with an NFC wallet to the payment terminal.

    • Single-tap redeem flow: Collect both the NFC pass details and the NFC payment method details when you make a card acquisition request.
    • Payment flow: Collect both the NFC pass details and the NFC payment method details when you make a payment request.
    • Double-tap redeem flow: Collect only the NFC pass details when you make a card acquisition request.

  5. Enter the Name of your pass.
  6. Enter the Pass type ID that was generated when you created your NFC pass.
    We use this to poll only for your pass and not for passes from other organizations that the shopper may have in their mobile wallet. For an Apple Wallet pass, this has the format pass.com.company.pass-name.
  7. At Protocol select the company responsible for the protocol that your NFC pass is based on. For example, Apple.
  8. Optional. Enter the URL where people can add the pass to their mobile wallet.
    We use this when the shopper doesn't have your pass in their wallet yet, to send an NFC signal so that the shopper receives a message that lets them add the pass to their wallet..
  9. In the Private key box, select the slot where you will provide your private key. For example, Private key 1.
  10. Under Private key slots, go to the slot that you selected in the previous step and enter the private key for your NFC pass.
    This key was generated when you created the pass. We will protect and encrypt it in our back end. The terminal uses this key to decrypt the NFC message and return the unique ID of the shopper's pass in the response.
  11. To add more NFC-enabled passes, select Add another pass and repeat the steps to complete the settings.
  12. Select Save.

After you have finished the configuration, you are ready to accept your NFC-enabled pass with a payment, using either the payment flow or the redeem flow.

Use the payment flow

To make a payment request and afterwards update the shopper's NFC pass account:

  1. Make a payment request with:

    Payment request in the payment flow
    {
        "SaleToPOIRequest": {
            "MessageHeader": {
                "ProtocolVersion": "3.0",
                "MessageClass": "Service",
                "MessageCategory": "Payment",
                "MessageType": "Request",
                "ServiceID": "s9wrxa",
                "SaleID": "POSSystemID12345",
                "POIID": "V400m-324689265"
            },
            "PaymentRequest": {
                "SaleData": {
                    "SaleTransactionID": {
                        "TransactionID": "a1b2c3",
                        "TimeStamp": "2020-06-16T16:13:16"
                    }
                },
                "PaymentTransaction": {
                    "AmountsReq": {
                        "Currency": "EUR",
                        "RequestedAmount": 10.99
                    }
                }
            }
        }
    }
  2. Check the payment response for the following:

    • LoyaltyResult: An array with your NFC enabled passes that are in the shopper's digital wallet. For each pass, there is a LoyaltyAccount object with:
      Property Description
      LoyaltyAccountID.IdentificationType AccountNumber. The type of ID of the shopper's pass.
      LoyaltyAccountID.EntryMode Contactless. Indicates how the NFC pass details were obtained.
      LoyaltyAccountID.LoyaltyID The unique ID of the shopper's pass.
      LoyaltyBrand The vendor protocol that the NFC pass is based on.

    If the response doesn't include a LoyaltyResult, the shopper hasn't yet added your NFC-enabled pass to their mobile wallet.

    Payment response including LoyaltyResult
    {
        "SaleToPOIResponse": {
            "PaymentResponse": {
                "POIData": {
                    "POITransactionID": {
                        "TimeStamp": "2020-06-15T16:13:16.000Z",
                        "TransactionID": "fanx001580400796015.8515658977098900"
                    },
                    "POIReconciliationID": "1000"
                },
                "SaleData": {
                    "SaleTransactionID": {
                        "TimeStamp": "2020-06-15T16:13:16.000Z",
                        "TransactionID": "a1b2c3"
                    }
                },
                "PaymentReceipt": [...],
                "PaymentResult": {
                    "AuthenticationMethod": [
                        "SecuredChannel"
                    ],
                    "OnlineFlag": true,
                    "PaymentAcquirerData": {...},
                        "MerchantID": "YOUR_MERCHANT_ACCOUNT"
                    },
                    "PaymentInstrumentData": {
                        "CardData": {
                            "EntryMode": [
                                "Contactless"
                            ],
                            "PaymentToken": {
                                "TokenRequestedType": "Customer",
                                "TokenValue": "G526627978654924"
                            },
                            "PaymentBrand": "visa",
                            "MaskedPan": "481749 **** 1108",
                            "CardCountryCode": "076",
                            "SensitiveCardData": {
                                "CardSeqNumb": "00",
                                "ExpiryDate": "1223"
                            }
                        },
                        "PaymentInstrumentType": "Card"
                    },
                    "AmountsResp": {
                        "AuthorizedAmount": 10.99,
                        "Currency": "EUR"
                    }
                },
                "LoyaltyResult": [
                    {
                        "LoyaltyAccount": {
                            "LoyaltyAccountID": {
                                "IdentificationType": "AccountNumber",
                                "EntryMode": [
                                    "Contactless"
                                ],
                                "LoyaltyID": "rEqQFLnckxJ3jCvmQoLmBh"
                            },
                            "LoyaltyBrand": "AppleVAS"
                        }
                    }
                ],
                "Response": {
                    "Result": "Success",
                    "AdditionalResponse": "..."
                }
            },
            "MessageHeader": {...}
        }
    }
  3. Using the LoyaltyID and card alias returned in the response, look up the shopper in your pass server and loyalty program, and update the shopper's data. For example, the loyalty points accrued.

Use the redeem flow

In this flow you check whether the shopper has your NFC-enabled pass in their wallet app before you start a payment. If the shopper already has your pass, you can apply a discount or other advantages related to the pass. If the shopper doesn't have your pass, you can issue a pass and add this data to your payment request. The shopper will receive a message that lets them add the pass to their wallet.

Get the shopper's pass details

  1. Make a card acquisition request with:

    Parameter Description
    CardAcquisitionTransaction In the single-tap redeem flow, this object must contain:
    • TotalAmount: The transaction amount.

    In the double-tap redeem flow, you can omit TotalAmount when you don't know the amount yet. Or you can also change the transaction amount later, in the payment request.

    Card acquisition in the redeem flow
    {
        "SaleToPOIRequest":{
            "MessageHeader":{
                "ProtocolVersion":"3.0",
                "MessageClass":"Service",
                "MessageCategory":"CardAcquisition",
                "MessageType":"Request",
                "ServiceID":"0305Acq",
                "SaleID":"POSSystemID12345",
                "POIID":"V400m-346403161"
            },
            "CardAcquisitionRequest":{
                "SaleData":{
                    "SaleTransactionID":{
                        "TransactionID":"422024",
                        "TimeStamp":"2020-06-19T12:18:04"
                    }
                },
                "CardAcquisitionTransaction":{
                    "TotalAmount": 14.98
                }
            }
        }
    }
  2. When you receive the card acquisition response, keep the TimeStamp and TransactionID from the POIData.POITransactionID. You need these details later in your payment request.

  3. Check the card acquisition response for the following:

    • LoyaltyResult: An array with your NFC enabled passes that are in the shopper's digital wallet. For each pass, there is a LoyaltyAccount object with:
      Property Description
      LoyaltyAccountID.IdentificationType AccountNumber. The type of ID of the shopper's pass.
      LoyaltyAccountID.EntryMode Contactless. Indicates how the NFC pass details were obtained.
      LoyaltyAccountID.LoyaltyID The unique ID of the shopper's pass.
      LoyaltyBrand The vendor protocol that the NFC pass is based on.

    If the response doesn't include a LoyaltyResult, the shopper hasn't yet added your NFC-enabled pass to their mobile wallet.

    Card acquisition response including LoyaltyResult
    {
        "SaleToPOIResponse": {
            "CardAcquisitionResponse": {
                "POIData": {
                    "POITransactionID": {
                        "TimeStamp": "2020-06-19T10:18:48.000Z",
                        "TransactionID": "8ha5001592561928000"
                    },
                    "POIReconciliationID": "1000"
                },
                "SaleData": {
                    "SaleTransactionID": {
                        "TimeStamp": "2020-06-19T12:18:04.000Z",
                        "TransactionID": "422024"
                    }
                },
                "PaymentInstrumentData": {
                    "CardData": {
                        "PaymentBrand": "mc",
                        "MaskedPan": "541333 **** 9999",
                        "CardCountryCode": "528",
                        "SensitiveCardData": {
                            "ExpiryDate": "0228"
                        }
                    },
                    "PaymentInstrumentType": "Card"
                },
                "Response": {
                    "Result": "Success",
                    "AdditionalResponse": "..."
                },
                "LoyaltyResult": [
                    {
                        "LoyaltyAccount": {
                            "LoyaltyAccountID": {
                                "IdentificationType": "AccountNumber",
                                "EntryMode": [
                                    "Contactless"
                                ],
                                "LoyaltyID": "rEqQFLnckxJ3jCvmQoLmBh"
                            },
                            "LoyaltyBrand": "AppleVAS"
                        }
                    }
                ]
            },
            "MessageHeader": {...}
        }
    }
  4. Go to the next step, depending on the case:
    • Case 1: The shopper already added your pass to their wallet.
    • Case 2: The shopper doesn't have your pass in their wallet yet.

Case 1: The shopper has your pass

  1. Using the LoyaltyID returned in the card acquisition response, look up the shopper in your pass server and loyalty program, and apply your business logic.
    For example:

    • Make a confirmation input request to ask the shopper whether they want to redeem loyalty points.
    • Add or recalculate loyalty points.
    • Apply a discount.
    • Recalculate the transaction amount.

  2. Make a payment request with:

    Parameter Description
    PaymentTransaction.AmountsReq An object with:
    • Currency: The transaction currency.
    • RequestedAmount: The final transaction amount.
    PaymentData.CardAcquisitionReference An object referencing the card acquisition:
    • TimeStamp: The timestamp returned in the POIData.POITransactionID of the card acquisition response.
    • TransactionID: The transaction ID returned in the POIData.POITransactionID of the card acquisition response.
    Payment request in the redeem flow
    {
        "SaleToPOIRequest":{
            "MessageHeader":{
                "ProtocolVersion":"3.0",
                "MessageClass":"Service",
                "MessageCategory":"Payment",
                "MessageType":"Request",
                "ServiceID":"0305p",
                "SaleID":"POSSystemID12345",
                "POIID":"V400m-346403161"
            },
            "PaymentRequest":{
                "SaleData":{
                    "SaleTransactionID":{
                        "TimeStamp": "2020-06-19T12:23:04.000Z",
                        "TransactionID": "042208"
                    }
                },
                "PaymentTransaction":{
                    "AmountsReq":{
                        "Currency":"EUR",
                        "RequestedAmount":14.48
                    }
                },
                "PaymentData":{
                    "CardAcquisitionReference":{
                        "TimeStamp": "2020-06-19T10:21:27.000Z",
                        "TransactionID": "8ha5001592562087001"
                    }
                }
            }
        }
    }

    In the payment response, note that you receive the same LoyaltyResult as in the card acquisition response.

    Payment response including LoyaltyResult
    {
        "SaleToPOIResponse": {
            "PaymentResponse": {
                "POIData": {
                    "POITransactionID": {
                        "TimeStamp": "2020-06-19T10:24:03.000Z",
                        "TransactionID": "8ha5001592562087001.8815658961765250"
                    },
                    "POIReconciliationID": "1000"
                },
                "SaleData": {
                    "SaleTransactionID": {
                        "TimeStamp": "2020-06-19T12:23:04.000Z",
                        "TransactionID": "042208"
                    }
                },
                "PaymentReceipt": [...],
                "PaymentResult": {
                    "OnlineFlag": true,
                    "PaymentAcquirerData": {...},
                        "MerchantID": "YOUR_MERCHANT_ACCOUNT"
                    },
                    "PaymentInstrumentData": {
                        "CardData": {
                            "EntryMode": [
                                "Contactless"
                            ],
                            "PaymentBrand": "mc",
                            "MaskedPan": "541333 **** 9999",
                            "CardCountryCode": "056",
                            "SensitiveCardData": {
                                "CardSeqNumb": "83",
                                "ExpiryDate": "0228"
                            }
                        },
                        "PaymentInstrumentType": "Card"
                    },
                    "AmountsResp": {
                        "AuthorizedAmount": 14.48,
                        "Currency": "EUR"
                    },
                },
                "LoyaltyResult": [
                    {
                        "LoyaltyAccount": {
                            "LoyaltyAccountID": {
                                "IdentificationType": "AccountNumber",
                                "EntryMode": [
                                    "Contactless"
                                ],
                                "LoyaltyID": "rEqQFLnckxJ3jCvmQoLmBh"
                            },
                            "LoyaltyBrand": "AppleVAS"
                        }
                    }
                ],
                "Response": {
                    "Result": "Success",
                    "AdditionalResponse": "...&alias=M469509594859802&...recurring.shopperReference=YOUR_UNIQUE_SHOPPER_ID&...shopperReference=YOUR_UNIQUE_SHOPPER_ID&shopperEmail=S.Hopper%40example.com&..."
                }
            },
            "MessageHeader": {...}
        }
    }

Case 2: The shopper doesn't have your pass

If the card acquisition response indicates the shopper doesn't have your NFC-enabled pass in their mobile wallet, you check whether they are enrolled in your loyalty program. If they are (or if you enroll them on the spot) you can issue a pass and add the pass details to your payment request. This will send a message to the shopper's device so that they can easily add your pass to their wallet.

  1. Check whether the shopper is enrolled in your loyalty program. Depending on how you have set up your loyalty program, you can:

    • Check the AdditionalResponse in the card acquisition response for a shopperReference. If this is present, you already have the shopper on record. (See the shopper loyalty use case.)
    • Or ask the shopper whether they are enrolled. If yes, ask them for their membership number or similar. You can use input requests to gather this information, or let your staff enter the information in your cash register software.

    If the shopper is already enrolled, skip to issuing a pass (step 4).

  2. If the shopper is not enrolled in your loyalty program yet, ask the shopper whether they want to enroll.

    • If the shopper doesn't want to enroll, make a payment request with a reference to the card acquisition. This is the same payment request from Case 1, only the response won't include a LoyaltyResult. The flow ends.
    • If the shopper wants to enroll, continue with the next step.

  3. To enroll the shopper in your loyalty program on the spot:

    • Collect shopper details like their email address. You can use input requests to gather this information, or let your staff enter the information in your cash register software.
    • Create a customer profile for the shopper in your loyalty program and pass server with the information you collected.

    You now have a customer profile for the shopper, either because it already existed or because you just created it.

  4. Using the shopperReference from the card acquisition response or some other reference, find the shopper's customer profile in your pass server. Then generate a unique pass identifier for the shopper.

  5. Make a payment request with:

    Parameter Description
    PaymentTransaction.AmountsReq An object with:
    • Currency: The transaction currency.
    • RequestedAmount: The final transaction amount.
    PaymentData.CardAcquisitionReference An object referencing the card acquisition:
    • TimeStamp: The timestamp returned in the POIData.POITransactionID of the card acquisition response.
    • TransactionID: The transaction ID returned in the POIData.POITransactionID of the card acquisition response.
    LoyaltyData An array with a LoyaltyAccountID object for each of your NFC-enabled passes. This lets the shopper add your NFC-enabled pass to their digital wallet. Each LoyaltyAccountID object contains:
    • EntryMode: Mobile
    • IdentificationType: AccountNumber.
    • LoyaltyID: The unique ID of the shopper's pass. This is the hash value of the URL of the pass as configured in your Customer Area, appended with the unique pass identifier for the shopper.
    SaleData.SaleToAcquirerData Optional. When you are enrolling the shopper in your loyalty program on the spot, use this parameter to create shopper identifiers on our platform.

    See the instructions below.

    For a newly enrolled shopper, you can include the following in SaleData.SaleToAcquirerData:

    • shopperEmail: The shopper's email address, if you collected that.
    • shopperReference: Your unique reference for this shopper (minimum length three characters).

    Pass the SaleToAcquirerData value in one of the following formats:

    • Option 1: A JSON object converted to a Base64 encoded string. Refer to Add information to a payment.
    • Option 2: Form-encoded key-value pairs (using & as a separator). For example:
      shopperEmail=S.Hopper@example.com&shopperReference=12345

    The format that you use here, will also be the format of the AdditionalResponse that you receive.

    The following example shows how to make a payment for a shopper who is already enrolled in your loyalty program but doesn't have your NFC-enabled pass yet.

    Issue a pass through a payment request
    {
        "SaleToPOIRequest":{
            "MessageHeader":{
                "ProtocolVersion":"3.0",
                "MessageClass":"Service",
                "MessageCategory":"Payment",
                "MessageType":"Request",
                "ServiceID":"0305p",
                "SaleID":"POSSystemID12345",
                "POIID":"V400m-346403161"
            },
            "PaymentRequest":{
                "SaleData":{
                    "SaleTransactionID":{
                        "TimeStamp": "2020-06-19T12:23:04.000Z",
                        "TransactionID": "042208"
                    },
                },
                "PaymentTransaction":{
                    "AmountsReq":{
                        "Currency":"EUR",
                        "RequestedAmount":14.48
                    }
                },
                "LoyaltyData": [
                    {
                        "LoyaltyAccountID": {
                            "EntryMode" : [
                                "Mobile"
                            ],
                            "IdentificationType": "AccountNumber",
                            "LoyaltyID": "HASHED_URL_AND_PASS_ID"
                        }
                    }
                ],
                "PaymentData":{
                    "CardAcquisitionReference":{
                        "TimeStamp": "2020-06-19T10:21:27.000Z",
                        "TransactionID": "8ha5001592562087001"
                    }
                }
            }
        }
    }
  6. The response contains a LoyaltyResult that echoes the LoyaltyData from the request.
    The shopper receives a message on their device that lets them add your pass to their wallet.

Overriding the configured flow

There may be situations when you want to use a different flow for a single transaction. To do that, you can make a card acquisition or payment request with one of the following tender options:

  • VASModeVASAndPayment: Collect both the NFC pass details and the NFC payment method details.
  • VASModeVASOrPayment: Leave it up to the shopper whether to collect the NFC pass details.
  • VASModeVASOnly: Collect the NFC pass details.
  • VASModePaymentOnly: Don't collect the NFC pass details.

Proceed as follows:

  1. Make a card acquisition request or payment request with:

    Parameter Description
    SaleData.SaleToAcquirerData The tender option, specified as explained below.

    Pass the SaleToAcquirerData value in one of the following formats::

    • Option 1: A JSON object {"tenderOption": "option"} converted to a Base64 encoded string.
      For example, encode {"tenderOption": "VASModeVASOnly"} to Base64, and pass the result:
      "SaleToAcquirerData": "eyJ0ZW5kZXJPcHRpb24iOiAiVkFTTW9kZVZBU09ubHkifQ=="

    • Option 2: tenderOption=option.
      For example: "SaleToAcquirerData": "tenderOption=VASModeVASOnly"
    Card acquisition with a tender option
    {
        "SaleToPOIRequest":{
            "MessageHeader":{
                "ProtocolVersion":"3.0",
                "MessageClass":"Service",
                "MessageCategory":"CardAcquisition",
                "MessageType":"Request",
                "ServiceID":"0305Acq",
                "SaleID":"POSSystemID12345",
                "POIID":"V400m-346403161"
            },
            "CardAcquisitionRequest":{
                "SaleData":{
                    "SaleTransactionID":{
                        "TransactionID":"422024",
                        "TimeStamp":"2021-05-07T12:12:34.000Z"
                    },
                    "SaleToAcquirerData":"tenderOption=VASModeVASOnly",
                    "TokenRequestedType":"Customer"
                },
                "CardAcquisitionTransaction":{
                    "TotalAmount": 14.98
                }
            }
        }
    }
  2. Depending on the tender option, the response includes NFC pass details and/or NFC payment method details.

See also