Kernconcepten

Klanten

Een klant is een eindgebruiker die meedoet aan het loyaliteitsprogramma van een handelaar. Klanten sparen punten met transacties en wisselen ze in voor beloningen.


Klantgegevens

VeldTypeBeschrijving
idintegerUniek klant-ID
first_namestringVoornaam van de klant
last_namestringAchternaam van de klant
emailstringE-mailadres (uniek per handelaar)
phonestringTelefoonnummer
date_of_birthdateGeboortedatum
customer_sincedateOptionele startdatum van de klantrelatie. Laat je hem leeg, dan telt Puntjes vanaf de dag waarop het record werd aangemaakt.
localestringVoorkeurstaal (nl of en, standaard: nl)
statusstringHuidige status: active, deactivated of anonymized

Identifiers

Elke klant heeft een of meer identifiers: waarden waarmee je de klant aan de kassa terugvindt tijdens een transactie. Er zijn twee types:

TypeBeschrijving
loyalty_cardEen code van 8 tekens met hoofdletters en cijfers (A-Z, 0-9). Puntjes geeft er automatisch een uit, of je maakt vooraf een reeks aan en laat die op fysieke kaarten drukken.
emailHet e-mailadres van de klant.

Identifierwaarden zijn uniek binnen één handelaar. Hoofdletters maken bij het opzoeken geen verschil.

Je eigen ID's

Met een identifier herkent Puntjes een klant. Je external_id staat daar los van: dat is jouw eigen sleutel voor die klant (het recordnummer in je kassa of webshop), bewaard bij de klant en uniek binnen je zaak. Puntjes verzint er nooit een, en scannen doe je er niet mee.

Stel hem in bij de registratie. Bij klanten die al bestonden voordat je koppelde, voeg je hem later toe met POST /customers/link-external-id. Eenmaal gekoppeld lees en update je die klant op je eigen ID, en hoef je het onze niet te bewaren.

Klantenkaarten

Elke klant krijgt een klantenkaart. Je hoeft geen kaartnummer te verzinnen: geef je bij de registratie geen kaart mee, dan geeft Puntjes er een uit en krijg je de code terug als loyalty_card_code.

Wil je fysieke kaarten, dan maak je eerst een reeks aan in het adminportaal, exporteer je de codes als CSV voor de drukker en deel je de gedrukte kaarten aan de kassa uit. Scan je zo'n kaart tijdens de registratie, dan krijgt de klant precies die kaart. Zie Klanten beheren voor de werkwijze.

Een klant kan uiteindelijk meer dan één kaart hebben (maximaal vijf), meestal omdat hij er een verloor en een vervangende kaart kreeg. Precies één daarvan is de kaart die hij scant: wijs je in het adminportaal een kaart toe, dan wordt dat de scankaart, dus in de praktijk is het de laatst toegewezen kaart. Die staat in loyalty_card_code en op zijn wallet-pas. Zijn oudere kaarten blijven actief en werken nog bij het scannen, dus wat je eerder uitdeelde wordt nooit onbruikbaar.

De e-mailidentifier beheert Puntjes voor je

De e-mailidentifier is een afspiegeling van het e-mailadres in het klantprofiel. Puntjes maakt hem aan, past hem aan bij elke latere wijziging van het adres en verwijdert hem zodra je het adres wist. Los bewerken of deactiveren kan niet: wijzig het e-mailadres van de klant, dan volgt de identifier vanzelf.

Status van een identifier

Identifiers van het type loyalty_card zet je los van elkaar aan of uit. Met een gedeactiveerde identifier zoek je geen klant op en dien je geen transactie in.

Oudere identifierwaarden blijven werken

Puntjes aanvaardde vroeger meerdere andere identifiertypes, voor verschillende scantechnologieën. Die types zijn samengevoegd tot loyalty_card. De bestaande waarden verhuisden mee en worden nog altijd gevonden bij het opzoeken, dus kaarten die klanten al op zak hebben blijven werken. Nieuwe waarden van die types kun je niet meer aanmaken, en een API-client die een vervallen type meestuurt krijgt een validatiefout. Zie Foutafhandeling.


Statussen van een klant

Active → Deactivated
Active → Anonymized
StatusBeschrijving
ActiveKlant kan gewoon punten sparen en inwisselen
DeactivatedKlant staat uit: geen nieuwe transacties of inwisselingen
AnonymizedPersoonsgegevens gewist voor de AVG; klant valt standaard buiten elke query

Anonimisering is onomkeerbaar

Anonimiseer je een klant, dan zijn de persoonsgegevens definitief weg. Geanonimiseerde klanten vallen buiten elke API-response en elke query. Je kunt dit niet terugdraaien.


Registratie

Registreer een nieuwe klant via de API met zijn persoonsgegevens. Een identifier hoeft niet. Puntjes geeft een klantenkaart uit en stuurt de code terug:

POST /api/v1/customers
{
    "first_name": "Jan",
    "last_name": "De Vries",
    "email": "jan@example.com",
    "phone": "+31612345678",
    "date_of_birth": "1990-05-15",
    "locale": "nl"
}

Wil je een voorgedrukte kaart meegeven, scan die dan en stuur de code mee:

{
    "first_name": "Jan",
    "last_name": "De Vries",
    "identifiers": [{ "type": "loyalty_card", "value": "K7M2QX4P" }]
}

Elke nieuwe klant krijgt automatisch een wallet. Staat er een welkomstbonus ingesteld (Instellingen → Welkomstbonus in het adminportaal), dan komt dat aantal punten er bij de inschrijving direct op. Puntjes boekt ze in het grootboek als een gewone earn, dus ze vervallen net als alle andere punten.


Marketingtoestemming

Campagnemail (een verjaardagsbericht, een jubileumbeloning) gaat alleen naar klanten die er uitdrukkelijk om vroegen. Eén vlag bepaalt dat, marketing_consent, en die staat uit bij elke klant tot iemand hem op true zet. Niemand komt er met terugwerkende kracht bij: klanten die al bestonden voor de vlag er was, staan uitgeschreven, en elke klant uit een import ook.

Puntjes bewaart niet alleen de keuze, maar ook waar ze vandaan komt. Een opt-in legt het moment vast en het kanaal waarlangs die binnenkwam. Trekt iemand de toestemming later in, dan krijgt dat zijn eigen moment en kanaal, en blijft het eerste paar staan. Toestemming die je niet kunt dateren en toeschrijven, kun je ook niet aantonen. En dat is precies de situatie waarin een AVG-verzoek je zet.

KanaalBetekenis
portalIemand van je team vinkte het vakje aan in het adminportaal
apiJouw integratie stuurde marketing_consent mee
emailDe klant gebruikte de uitschrijflink in een e-mail

Drie kanalen kunnen de vlag wijzigen: jouw integratie, via marketing_consent op POST /customers of het update-endpoint; iemand van je team, op de klantpagina in het adminportaal; en de klant zelf, via de uitschrijflink in campagnemail. Die link is ondertekend en verloopt nooit, dus een mail van een jaar oud werkt nog altijd, en erop klikken vraagt geen account en geen wachtwoord.

Uitschrijven werkt meteen en vraagt geen bevestiging. marketingConsent leest bij de volgende request false, en het moment van toekenning blijft staan waar het stond, zodat je nog altijd ziet wanneer de klant zich had ingeschreven.

De vlag weglaten bij een update is iets anders dan false sturen

Laat je marketing_consent weg op PUT|PATCH /customers/by-external-id/{external_id}, dan blijft de opgeslagen keuze staan. Alleen een expliciete false trekt hem in. Een nachtelijke kassasync die namen en telefoonnummers pusht, kan de klanten die hij aanraakt dus niet uitschrijven. Zie Klant-endpoints voor de volledige regel, inclusief wat een expliciete null betekent.


Opzoeken

Zoek een klant op via een van zijn actieve identifiers:

GET /api/v1/customers/lookup?identifier=K7M2QX4P

De response bevat het profiel van de klant en zijn huidige walletsaldo. Dit is de voornaamste manier waarop kassasystemen een klant herkennen bij het afrekenen.

Zie Klant-endpoints voor de volledige API-referentie.