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-person payments with the mobile wallet using a service like Apple Pay. The payment terminal communicates 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 can 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

Work in progress: this feature is not supported yet on Android payment terminals.

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 very similar. The main 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.

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.

    For easier shopper enrollment, 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, see Shopper recognition and tokenization.

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

To send the notification to the shopper's device, we need to know the URL where people can add a pass to their wallet, and the pass number. You can provide this information in two ways:

  • Configure the URL in your Customer Area. Then, in the LoyaltyData.LoyaltyID field of your payment request, specify only the pass number.
  • Don't configure the URL in your Customer Area. In your payment request, in the LoyaltyData.LoyaltyID field, specify the URL appended with the pass number.

Configure NFC-enabled passes in your Customer Area

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.
  4. At Choose a set up, select an option for the flow you want to use.

    • 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.your-company.your-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 for shopper enrollment, 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, select Decrypted, go to the slot that you selected in the previous step, and enter the private key for your NFC pass.

    Include the begin and end lines -----BEGIN EC PRIVATE KEY-----\n and \n-----END EC PRIVATE KEY-----.

    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. For example:

    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.EntryMode Indicates how the NFC pass details were obtained.
      LoyaltyAccountID.IdentificationType AccountNumber. The type of ID of the shopper's pass.
      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": {
                "LoyaltyResult": [
                    {
                        "LoyaltyAccount": {
                            "LoyaltyAccountID": {
                                "EntryMode": [
                                    "Contactless"
                                ],
                                "IdentificationType": "AccountNumber",
                                "LoyaltyID": "rEqQFLnckxJ3jCvmQoLmBh"
                            },
                            "LoyaltyBrand": "pass.com.your-company.your-pass-name"
                        }
                    }
                ],
                "POIData": {
                    "POIReconciliationID": "1000",
                    "POITransactionID": {
                        "TimeStamp": "2020-06-15T16:13:16.000Z",
                        "TransactionID": "fanx001580400796015.NC6HT9CRT65ZGN82"
                    },
                    "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"
                    }
                },
                "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"
                    },
                    "TokenRequestedType": "Customer"
                },
                "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.EntryMode Indicates how the NFC pass details were obtained.
      LoyaltyAccountID.IdentificationType AccountNumber. The type of ID of the shopper's pass.
      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": {
                "LoyaltyResult": [
                    {
                        "LoyaltyAccount": {
                            "LoyaltyAccountID": {
                                "EntryMode": [
                                    "Contactless"
                                ],
                                "IdentificationType": "AccountNumber",
                                "LoyaltyID": "rEqQFLnckxJ3jCvmQoLmBh"
                            },
                            "LoyaltyBrand": "pass.com.your-company.your-pass-name"
                        }
                    }
                ],
                "POIData": {
                    "POIReconciliationID": "1000",
                    "POITransactionID": {
                        "TimeStamp": "2020-06-19T10:18:48.000Z",
                        "TransactionID": "8ha5001592561928000"
                    }
                },
                "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": "..."
                }
            },
            "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"
                    },
                    "TokenRequestedType": "Customer"
                },
                "PaymentTransaction":{
                    "AmountsReq":{
                        "Currency":"EUR",
                        "RequestedAmount":14.48
                    }
                },
                "PaymentData":{
                    "CardAcquisitionReference":{
                        "TimeStamp": "2020-06-19T10:21:27.000Z",
                        "TransactionID": "8ha5001592562087001"
                    }
                }
            }
        }
    }
  3. When you receive the payment response, note that:

    • In the single-tap redeem flow, the payment response doesn't include the LoyaltyResult again.
    • In the double-tap redeem flow, the payment response includes the same LoyaltyResult as in the card acquisition response.
    Payment response - Double-tap redeem flow
    {
        "SaleToPOIResponse": {
            "PaymentResponse": {
                "LoyaltyResult": [
                    {
                        "LoyaltyAccount": {
                            "LoyaltyAccountID": {
                                "IdentificationType": "AccountNumber",
                                "EntryMode": [
                                    "Contactless"
                                ],
                                "LoyaltyID": "rEqQFLnckxJ3jCvmQoLmBh"
                            },
                            "LoyaltyBrand": "pass.com.your-company.your-pass-name"
                        }
                    }
                ],
                "POIData": {
                    "POITransactionID": {
                        "TimeStamp": "2020-06-19T10:24:03.000Z",
                        "TransactionID": "8ha5001592562087001.KHQC5N7G84BLNK43"
                    },
                    "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"
                    },
                },
                "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 POS app.

    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 POS app.
    • 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 identifier of the shopper's new pass.

      If in your Customer Area you configured the URL where people can get your pass, only specify the pass ID. For example: oGvXzNSwEeQgZYVfZPU4pu

      If you didn't configure the URL of your pass, specify the URL appended with the pass ID. For example: https://uc.seamless-checkout.net/getWallet/oGvXzNSwEeQgZYVfZPU4pu

    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":{
                "LoyaltyData": [
                    {
                        "LoyaltyAccountID": {
                            "EntryMode" : [
                                "Mobile"
                            ],
                            "IdentificationType": "AccountNumber",
                            "LoyaltyID": "oGvXzNSwEeQgZYVfZPU4pu"
                        }
                    }
                ],
                "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"
                    }
                }
            }
        }
    }
  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 in SaleToPOIData:

  • 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.SaleToPOIData The VASModeOverride option, specified as explained below.

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

    • Option 1: a JSON object {"VASModeOverride": "option"} converted to a Base64 encoded string.
      For example, encode {"VASModeOverride": "VASModeVASOnly"} to Base64, and pass the result:
      "SaleToPOIData": "eyJWQVNNb2RlT3ZlcnJpZGUiOiAiVkFTTW9kZVZBU09ubHkifQ=="

    • Option 2: VASModeOverride=option.
      For example: "SaleToPOIData": "VASModeOverride=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"
                    },
                    "SaleToPOIData":"VASModeOverride=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