API-referentie

Partner-endpoints

Dit endpoint is voor een partner: een bedrijf met een app (een kassa, een webshop) die voor veel handelaars met Puntjes koppelt. Het vraagt een ander token dan alle andere endpoints. Lees eerst Partnerintegraties voor de hele flow.


Een API-client maken van een koppeling

POST /api/v1/partner/clients

Stuur het kenmerk connection uit de redirect nadat de handelaar je app toestond, samen met het access token dat je voor dezelfde code kreeg. Je krijgt een gewone API-client van die handelaar terug. Vanaf dan gebruikt je app client_id en client_secret met de client credentials grant, zoals elke integratie.

Het token moet uit de authorization code flow komen, voor je partnerclient en voor de gebruiker die de koppeling toestond. Een token uit client credentials krijgt 401 INVALID_CLIENT. Het partnertoken werkt alleen op dit endpoint: elk endpoint van een handelaar antwoordt erop met 401 INVALID_CLIENT.

Request body

VeldTypeVerplichtBeschrijving
connectionstringJaDe waarde connection uit de redirect nadat de handelaar je app toestond. 60 minuten geldig; hoogstens 64 tekens
labelstringJaDe naam van de nieuwe client, zoals de handelaar hem ziet bij API-clients. Hoogstens 100 tekens

Example request

{
    "connection": "3vX9kQ2mP7rT4wY8zB1nC6dF0gH5jL2sKaEuWiOo",
    "label": "Kassa 1"
}
curl -X POST https://puntjes.app/api/v1/partner/clients \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"connection":"3vX9kQ2mP7rT4wY8zB1nC6dF0gH5jL2sKaEuWiOo","label":"Kassa 1"}'

branch is de standaardvestiging die de handelaar koos toen hij je app toestond, of null als hij er geen koos. Je client mag in een request nog altijd elke vestiging van de handelaar noemen; de standaard geldt alleen voor een request zonder branch.

Response (201 Created)

{
    "data": {
        "client_id": "9f3c2a6e-4b1d-4c8e-9a7f-2d5e8b1c0a43",
        "client_secret": "JOUW_NIEUWE_CLIENT_SECRET",
        "vendor": {
            "id": 7,
            "name": "Bakkerij Peeters"
        },
        "branch": {
            "external_id": "kerkstraat",
            "name": "Kerkstraat",
            "type": "physical"
        }
    }
}

Opnieuw proberen met hetzelfde kenmerk

Stuur dezelfde connection opnieuw zolang ze geldig is (60 minuten nadat de handelaar je app toestond), en je krijgt dezelfde client_id en client_secret. Er komt geen tweede client bij, ook niet als twee aanroepen tegelijk binnenkomen. Een ander label bij een nieuwe poging telt niet. Bewaar het secret meteen: zodra het kenmerk verlopen is, geeft Puntjes het je niet meer.

Ook een nieuwe poging kijkt de handelaar na. Is de handelaar intussen opgeschort, dan krijg je zijn 403-code en niet het secret. Trok de handelaar de client in, dan krijg je CONNECTION_NOT_FOUND.

Fouten

CodeStatusBeschrijving
BRANCH_INACTIVE422De vestiging die de handelaar koos, is gesloten. De handelaar opent ze opnieuw en jij probeert opnieuw met hetzelfde kenmerk, of de handelaar koppelt opnieuw
CLIENT_LIMIT_REACHED422De handelaar heeft al zoveel actieve API-clients als hij mag hebben. De handelaar trekt er een in, daarna probeer je opnieuw met hetzelfde kenmerk voor het verloopt
CONNECTION_EXPIRED422Het kenmerk is ouder dan 60 minuten. Stuur de handelaar opnieuw door de koppelflow
CONNECTION_NOT_FOUND404Geen koppeling past bij dit kenmerk en je token: een onbekend kenmerk, een kenmerk voor een andere partner of gebruiker, een gebruiker die niet meer mag toestaan, of een client die de handelaar introk. Stuur de handelaar opnieuw door de koppelflow

De volgende twee endpoints zijn voor je app bij de handelaar: de kassa of de desktop-app die met POST /partner/clients een API-client ophaalde. Ze werken op die API-client. Stuur een token dat deze client met de client credentials grant kreeg, niet het partnertoken uit de koppelflow, en zet het huidige client_secret van de client in de JSON-body. Een token alleen wijzigt niets: een gestolen token mag geen nieuw secret of een verwijderde client opleveren. Puntjes leest het secret alleen uit de body, nooit uit de query string, want een URL komt in de toegangslogs terecht.

Beide endpoints werken voor een client die een partner maakte. Voor een client die de handelaar zelf in het portaal maakte, krijg je 403 CLIENT_NOT_PARTNER_MADE. Ze werken ook als het abonnement van de handelaar afgelopen is en de rest van de API alleen nog leest. Weigert de API de handelaar (in afwachting, gedeactiveerd, of opgeschort na de respijtdagen), dan krijg je zijn 403-code. Elke client mag samen 10 aanroepen per minuut naar de twee endpoints doen. Puntjes schrijft elke wijziging en elke verwijdering in het auditlogboek van de handelaar, met je partner als onderwerp.


Het secret van een client wijzigen

POST /api/v1/client/secret

Roep dit endpoint aan als het secret van de client misschien uitgelekt is, bijvoorbeeld omdat iemand de opslag van je app kopieerde.

Request body

VeldTypeVerplichtBeschrijving
client_secretstringJaHet huidige client_secret van de client van het token, of het oude in zijn 60 minuten na een wijziging. Hoogstens 255 tekens

Example request

{
    "client_secret": "JOUW_CLIENT_SECRET"
}
curl -X POST https://puntjes.app/api/v1/client/secret \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"client_secret":"JOUW_CLIENT_SECRET"}'

Response

{
    "data": {
        "client_id": "9f3c2a6e-4b1d-4c8e-9a7f-2d5e8b1c0a43",
        "client_secret": "JOUW_CLIENT_SECRET"
    }
}

Het antwoord bevat het nieuwe client_secret, en Puntjes toont het alleen deze keer. client_id blijft hetzelfde. Elk access token van de client stopt meteen, ook het token van deze aanroep. Bewaar het nieuwe secret en vraag er meteen een nieuw token mee: dat eerste token beëindigt het oude secret. Tot dan kan iemand die alleen het oude secret heeft de client nog gebruiken.

Het oude secret werkt nog 60 minuten

Na de wijziging krijgt het oude secret nog 60 minuten een token bij POST /oauth/token. Zo blijft een app werken die het nieuwe secret nog niet bewaard heeft. Het oude secret en elk token dat het kreeg stoppen meteen zodra de client voor het eerst een token krijgt met het nieuwe secret. Puntjes houdt maar één oud secret bij: de volgende wijziging vervangt het.

Opnieuw proberen als het antwoord verloren ging

Zonder het antwoord heb je het nieuwe secret niet. Vraag binnen de 60 minuten een token met het oude secret, en stuur deze aanroep opnieuw met het oude secret in de body. Je krijgt een vers secret, en het secret uit het verloren antwoord werkt niet meer. Het oude secret houdt zijn eerste deadline: een nieuwe poging geeft het geen 60 minuten extra.

Fouten

CodeStatusBeschrijving
CLIENT_NOT_PARTNER_MADE403De handelaar maakte deze client in het beheerportaal. Alleen de handelaar kan daar het secret wijzigen
INVALID_CLIENT_SECRET401Het client_secret is niet het huidige secret van de client, en ook niet het oude secret in zijn 60 minuten na een wijziging. Er is niets gewijzigd

Een client verwijderen

DELETE /api/v1/client

Roep dit endpoint aan als je app opnieuw geïnstalleerd wordt, naar een andere account van een handelaar verhuist, of niet meer gebruikt wordt. Het trekt de client en al zijn access tokens in, en maakt zijn plaats vrij onder het maximum aantal API-clients van de handelaar. Zonder deze aanroep laat elke herinstallatie een actieve client achter, tot de handelaar aan zijn maximum zit. Binnen de 60 minuten na een wijziging van het secret werkt ook het oude secret hier.

Request body

VeldTypeVerplichtBeschrijving
client_secretstringJaHet huidige client_secret van de client van het token, of het oude in zijn 60 minuten na een wijziging. Hoogstens 255 tekens

Example request

{
    "client_secret": "JOUW_CLIENT_SECRET"
}
curl -X DELETE https://puntjes.app/api/v1/client \
  -H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"client_secret":"JOUW_CLIENT_SECRET"}'

Antwoord

204 No Content als het lukt. Vanaf dan krijgt de client geen token meer.

Fouten

CodeStatusBeschrijving
CLIENT_NOT_PARTNER_MADE403De handelaar maakte deze client in het beheerportaal. Alleen de handelaar kan hem daar intrekken
INVALID_CLIENT_SECRET401Het client_secret is niet het huidige secret van de client, en ook niet het oude secret in zijn 60 minuten na een wijziging. Er is niets verwijderd