Hoppa till huvudinnehåll

Diller Tap2ID — POS Integration Guide

Skrivet av Knut Hauge

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:

  1. 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: true is used.

  2. Diller lookup — The POS sends the identifier to the Diller API to retrieve member details and available coupons.

  3. 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).

  4. 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.dll v1.14.1 or later) — available from NexiGroup

  • Terminal with Storebox/DAM support enabled (contact Nets/NexiGroup)

  • PreventLoyaltyFromPurchase property set to 0 on the BaxiCtrl instance

  • UseExtendedLocalMode property set to 1

  • Diller 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

type: 101

Asset query message type

action: 193

GetAsset — read card and fetch linked data

mode: 4

Transaction + asset lookup mode

amount

Basket total in øre (cents). 349.00 NOK = "34900"

txntype: "30"

Indicates a purchase context

requestid

A unique request identifier (e.g. timestamp + random)

template.name: "storebox"

Target the Storebox DAM system

cardref: "<cardref.001>"

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 PIN

Field

Description

Type1 = 0x30

Purchase transaction

Type1 = 0x31

Refund transaction

Amount1

Amount in øre (cents). 299.00 NOK = 29900

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

action: 191

InsertAsset — associate card with member

msisdn

Member's phone number with country code (e.g. "4712345678" for Norway)

memberno

Diller member ID (from the phone search result)

cardref: "<cardref.001>"

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

  • Verifone 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:

  1. Initialize SDK → PaymentSdk.InitializeFromValues(listener, params)

  2. Login → TransactionManager.LoginWithCredentials(credentials)

  3. Start Session → TransactionManager.StartSession(transaction)

  4. 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?

ANALYTICS

Persistent card identifier generated by Verifone backend

Yes — preferred

REUSE

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

identifier

The ANALYTICS token value from card acquisition

brand

Normalized card brand, uppercase: VISA, MASTERCARD, AMERICAN EXPRESS

expiry_date

Expiry in YY-MM format (e.g. "26-12" for December 2026)

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.

Fick du svar på din fråga?