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
| Veld | Type | Beschrijving |
|---|---|---|
id | integer | Uniek klant-ID |
first_name | string | Voornaam van de klant |
last_name | string | Achternaam van de klant |
email | string | E-mailadres (uniek per handelaar) |
phone | string | Telefoonnummer |
date_of_birth | date | Geboortedatum |
customer_since | date | Optionele startdatum van de klantrelatie. Laat je hem leeg, dan telt Puntjes vanaf de dag waarop het record werd aangemaakt. |
locale | string | Voorkeurstaal (nl of en, standaard: nl) |
status | string | Huidige 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:
| Type | Beschrijving |
|---|---|
loyalty_card | Een 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. |
email | Het 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
| Status | Beschrijving |
|---|---|
| Active | Klant kan gewoon punten sparen en inwisselen |
| Deactivated | Klant staat uit: geen nieuwe transacties of inwisselingen |
| Anonymized | Persoonsgegevens 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.
| Kanaal | Betekenis |
|---|---|
portal | Iemand van je team vinkte het vakje aan in het adminportaal |
api | Jouw integratie stuurde marketing_consent mee |
email | De 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.