Audience: External POS developers integrating Diller loyalty via payment terminals
Last updated: February 2026
Introduction
Tap2ID allows loyalty members to identify themselves at the point of sale by simply tapping their payment card on the terminal — no phone number, no app, no barcode needed. The POS reads the card, matches it to a Diller loyalty member, fetches their coupons and benefits, applies discounts to the basket, and then charges the final amount — all in a seamless checkout experience.
This guide covers how to integrate Tap2ID into your POS system using two terminal families:
Nets (Ingenico/Baxi) — Uses BAXI.NET SDK with SendJson and DAM/Storebox for card identification
Verifone P630 — Uses PaymentSdk (PSDK) with Card Acquisition and tokenization
Both follow the same high-level flow but use different SDK calls to obtain the card identifier.
How Tap2ID Works
The checkout flow follows four key steps:
Card read (no charge) — The terminal reads the card and returns a token or member identifier without charging the card. For Nets, the terminal uses SendJson with GetAsset action 193. For Verifone, Card Acquisition with
tokenRequest: trueis used.Diller lookup — The POS sends the identifier to the Diller API to retrieve member details and available coupons.
Apply benefits — The POS applies the member's available coupons and discounts to the basket and calculates the final amount (e.g. 349 NOK → 299 NOK after discount).
Payment (card charged) — The terminal processes a normal payment for the discounted total. The customer taps or inserts their card again and may enter a PIN.
Note: The member must have pre-registered their card in the loyalty system. If the card is not recognized, the POS can fall back to phone number lookup and then register the card for future Tap2ID use.
Tap2ID with Nets (BAXI.NET)
Prerequisites
BAXI.NET SDK (
baxi_dotnet.dllv1.14.1 or later) — available from NexiGroupTerminal with Storebox/DAM support enabled (contact Nets/NexiGroup)
PreventLoyaltyFromPurchaseproperty set to0on the BaxiCtrl instanceUseExtendedLocalModeproperty set to1Diller API credentials (
client_id,client_secret,store_id)
Step 1: Read Card & Identify Member (SendJson)
At the start of checkout, send a SendJson call to the terminal with a GetAsset (action 193) request. This prompts the customer to tap their card. The terminal reads the card and queries Storebox for a linked member ID — without charging the card.
Key fields:
Field | Description |
| Asset query message type |
| GetAsset — read card and fetch linked data |
| Transaction + asset lookup mode |
| Basket total in øre (cents). 349.00 NOK = |
| Indicates a purchase context |
| A unique request identifier (e.g. timestamp + random) |
| Target the Storebox DAM system |
| Literal placeholder — terminal replaces with actual card reference after tap |
Important: The <cardref.001> value must be sent as a literal string including the angle brackets. Ensure your JSON serializer does not escape the < and > characters.
Calling SendJson in code:
var args = new SendJsonEventArgs { JsonString = jsonPayload }; _baxi.SendJson(args);The terminal fires the OnLocalMode event when the customer taps their card. The response contains the DAM data including the member identifier in the attributes payload.
Step 2: Query Diller for Member Details
Once you have the member identifier from Storebox, query the Diller API to get the full member profile and available coupons. Display the coupons to the cashier, apply selected discounts, and recalculate the basket total before proceeding to payment.
Step 3: Apply Discounts & Process Payment
After applying discounts and calculating the final amount, perform a standard TransferAmount call to charge the card:
var args = new TransferAmountEventArgs { OperID = "0000", Type1 = 0x30, // Purchase (0x31 for refund) Amount1 = 29900, // 299 NOK in øre — the discounted total Type2 = 0x30, Amount2 = 0, Type3 = 0x30, Amount3 = 0, HostData = "", ArticleDetails = "", PaymentConditionCode = "", AuthCode = "" }; _baxi.TransferAmount(args); // Wait for OnLocalMode event — customer taps/inserts card and enters PINField | Description |
| Purchase transaction |
| Refund transaction |
| Amount in øre (cents). 299.00 NOK = |
The OnLocalMode event fires when the transaction completes, providing the result, truncated PAN, auth code, timestamp, and terminal ID. After successful payment, sync the transaction to Diller using the Create Transaction endpoint (see Diller API Reference below).
Registering a New Card (InsertAsset)
If the Storebox lookup returns no member data (card not registered), ask the customer for their phone number, search Diller by phone, and if found, link the card using InsertAsset (action 191).
The InsertAsset request uses the same JSON structure as GetAsset but with action: 191. Key fields:
Field | Description |
| InsertAsset — associate card with member |
| Member's phone number with country code (e.g. |
| Diller member ID (from the phone search result) |
| Terminal replaces with the tapped card's reference |
The terminal prompts the customer to tap their card. On success, the card → member link is stored in Storebox and future taps will return the member ID automatically. Check statustext === "OK" to confirm successful registration.
Tap2ID with Verifone
Prerequisites
Verifone PaymentSdk (PSDK v3.68.7 or later) —
PaymentSdk-x64-net5.0.dllVerifone P630 terminal (or compatible model)
Tokenization enabled on the Verifone backend for your terminal TID (contact Verifone support)
Terminal connection via TCP/IP or serial
Diller API credentials (
client_id,client_secret,store_id)
Step 1: Card Acquisition & Tokenization
The PaymentSdk must be initialized and a session must be active before performing card acquisition. The initialization sequence is:
Initialize SDK →
PaymentSdk.InitializeFromValues(listener, params)Login →
TransactionManager.LoginWithCredentials(credentials)Start Session →
TransactionManager.StartSession(transaction)Card Acquisition →
TransactionManager.RequestCardData2(request)
var request = CardAcquisitionRequest.Create( tokenRequest: true, // IMPORTANT: Request tokenization message: "Please tap card", presentationMethods: new[] { CardPresentationMethod.CTLS_CARD, // Contactless CardPresentationMethod.CHIP, // Chip insert CardPresentationMethod.MAG_STRIPE // Swipe (fallback) } ); _transactionManager.RequestCardData2(request); // Wait for CardInformationReceivedEvent callback (up to 60 seconds)Critical: tokenRequest: true is essential — without this you will not get the identifier needed for Diller. Tokenization must also be enabled on the backend through Verifone support.
Extracting Card Data & Tokens
When the customer taps their card, the SDK fires the HandleCardInformationReceivedEvent callback:
public override void HandleCardInformationReceivedEvent(CardInformationReceivedEvent evt) { var cardInfo = evt.CardInformation; string brand = cardInfo.PaymentBrand; // "VISA", "MASTERCARD", etc. string panLast4 = cardInfo.PanLast4; // "1234" string expiry = cardInfo.CardExpiry; // "2612" (YYMM) var tokens = cardInfo.Tokens; foreach (var token in tokens) { string type = token.TokenType; // "ANALYTICS", "REUSE", etc. string value = token.Value; string scheme = token.Scheme; } string panHandle = cardInfo.PanHandle; }Token Type | Description | Use for Diller? |
| Persistent card identifier generated by Verifone backend | Yes — preferred |
| Token for reusing the card in subsequent transactions | Fallback if ANALYTICS not available |
Use the ANALYTICS token (or REUSE as fallback) as the card identifier for Diller member lookup.
Step 2: Query Diller for Member Details & Coupons
With the ANALYTICS token from card acquisition, query the Diller API to look up the member and retrieve available coupons. Display the coupons to the cashier and apply selected discounts to the basket before proceeding to payment.
Step 3: Process Payment
After discounts are applied, process payment using the standard PaymentSdk flow. Create a Payment object with the final discounted amount and the currency as an ISO 4217 numeric code (e.g. "578" for NOK, "752" for SEK, "978" for EUR). Call StartPayment and wait for the PaymentCompletedEvent callback (up to 90 seconds).
After successful payment, sync the transaction to Diller using the Create Transaction API endpoint (see Diller API Reference below).
Verifone Card Registration
If the Diller API returns no member for the ANALYTICS token (card not registered), ask the customer for their phone number, search Diller by phone, and if a member is found, register the card token:
POST https://api.dillerapp.com/api/v2.0/stores/{storeId}/members/{memberId}/register-card Authorization: Bearer {access_token} Content-Type: application/json { "identifier": "tok_analytics_xxxx...", "brand": "VISA", "expiry_date": "26-12" }Field | Description |
| The ANALYTICS token value from card acquisition |
| Normalized card brand, uppercase: |
| Expiry in |
Note: Terminal expiry formats vary (YYMM, MMYY, YY/MM). Normalize to YY-MM before sending to Diller. After registration, future Tap2ID lookups with this token will return the member instantly.
Diller API Reference
Authentication
Diller uses OAuth2 Client Credentials flow:
POST https://api.dillerapp.com/connect/token Content-Type: application/x-www-form-urlencoded grant_type=client_credentials&scope=api.retailer&client_id={your_client_id}&client_secret={your_client_secret}Cache the token and refresh when expired (tokens expire after ~1 hour). Use in all requests as Authorization: Bearer {access_token}.
Environment | Base URL |
Production | |
Pre-release / Testing |
Identify Member by Card Token
GET /api/v2.0/stores/{storeId}/members/search?cardidentifier={token} Authorization: Bearer {access_token}Returns member details if found, or an empty array [] if the card is not registered.
Search Member by Phone
GET /api/v2.0/stores/{storeId}/members/search?phone={phoneNumber} Authorization: Bearer {access_token}
Get Member Coupons
GET /api/v2.0/stores/{storeId}/members/{memberId}/coupons/ Authorization: Bearer {access_token}
Create Transaction
After a successful payment, sync the transaction to Diller so points and stamps are awarded:
POST /api/v2.0/stores/{storeId}/members/{memberId}/transactions Content-Type: application/json Authorization: Bearer {access_token}Include external_id, total, currency, created_at, origin, line item details, and any applied coupons in the request body.
For questions about Diller API access or terminal provisioning, contact support@diller.io.
