Zo werkt de betaalflow
Voor de koppeling ontvangt u van Pin Vandaag een Terminal ID en een API-token. De API werkt met CCV- en Worldline-terminals; bepaalde functies zijn merkgebonden en staan per endpoint vermeld.
Ondersteunde betaalterminals
Transactiestatussen
De statuswaarden werken bij Worldline en CCV op dezelfde manier. Andere responsevelden kunnen per route en betaalprovider verschillen.
| Status | Betekenis |
|---|---|
started | De transactie is aangeboden aan de terminal. |
pending | De klant is bezig op de terminal; de transactie is nog niet afgerond. |
success | De betaling is geslaagd. |
failed | De betaling is geweigerd of afgebroken. |
Beschikbare endpoints
/services/iban/name-check
POST/instore/clients/create
GET/transactions_dashboard/search
POST/instore/transactions/start
POST/instore/transactions/status
POST/instore/transactions/stop
POST/instore/transactions/mail
POST/instore/transactions/refund
POST/instore/transactions/ctmp
GET/instore/transactions/{terminal}/{limit}/{page}
POST/instore/transactions/last_transaction
Waar vindt u het Terminal ID en de API-key?
U vindt de gegevens van een betaalterminal in PinPortal.nl. Log in met uw klant- of partneraccount en volg deze stappen:
- Klik op de gewenste klant.
- Klik op Bewerk klant.
- Open het tabblad Overige.
- Klik op API Keys.
- Het Terminal ID verschijnt in het overzicht.
- De bijbehorende API KEY staat naast het Terminal ID.
Interactieve API-tester
Voer REST API-opdrachten vanaf deze pagina uit. De webpagina stuurt de opdracht eerst naar een beveiligde proxy op hetzelfde domein; die proxy roept daarna de Pin Vandaag REST API aan. Kies een endpoint, vul uw API-key en de vereiste waarden in en klik op Uitvoeren. De HTTP-status en response verschijnen direct onder het formulier.
Authenticatie
X-API-KEY gebruiken
curl --location 'https://rest-api.pinvandaag.com/V2' \
--header 'X-API-KEY: API_TOKEN'<?php
$apiKey = 'API_TOKEN';
$headers = [
'X-API-KEY: ' . $apiKey,
];
$ch = curl_init('https://rest-api.pinvandaag.com/V2');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);Legacy-methode: Basic Authentication (niet aanbevolen voor nieuwe koppelingen)
Stuur bij ieder verzoek een Authorization-header mee met Basic Authentication: Authorization: Basic base64(API_KEY:SECRET). Er wordt geen apart token uitgegeven; de header gaat bij elk verzoek mee. Voor nieuwe koppelingen raden wij de header X-API-KEY aan.
<?php
$apiKeyAndSecret = 'sleutel:geheim';
$encoded = base64_encode($apiKeyAndSecret);
$headers = ['Authorization: Basic ' . $encoded];
$ch = curl_init('https://rest-api.pinvandaag.com/V2');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);HTTP-statuscodes
Versie 2 geeft passende HTTP-statuscodes terug. Hierdoor kunt u fouten betrouwbaarder afhandelen en sneller zien of invoer ontbreekt, een terminal niet bestaat of er een serverprobleem is.
IBAN-naamcontrole
Controleert een Nederlandse IBAN en vergelijkt de opgegeven rekeninghouder. De functie werkt uitsluitend voor Nederlandse IBANs.
| Veld | Verplicht | Beschrijving |
|---|---|---|
name | Ja | Naam van de rekeninghouder. |
iban | Ja | Nederlandse IBAN, exact 18 tekens. Patroon: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$ |
curl --location --request POST \
'https://rest-api.pinvandaag.com/V2/services/iban/name-check' \
--header 'X-API-KEY: API_TOKEN' \
--form 'name="REKENINGHOUDER_NAAM"' \
--form 'iban="NL44ABNA0543946959"'Voorbeeldresponse
{
"status": "success",
"message": "IBAN has been checked",
"http_code": 200,
"data": {
"IBANCheckTransactionResponse": {
"IBAN": "NL44ABNA0543946959",
"AssumedName": "Test Holder",
"DebtorReference": "1682765065",
"IBANCheckResult": {
"IBANResult": "SERVICE_TEMPORARILY_NOT_AVAILABLE"
}
}
}
}De precieze inhoud van data kan verschillen afhankelijk van de informatie die aan de IBAN is gekoppeld.
Client aanmaken in PinPortal
Partners kunnen hiermee automatisch een nieuwe klant aanmelden in PinPortal.
Verplichte velden
| Veld | Beschrijving |
|---|---|
kvk | Kamer van Koophandel-nummer van de klant. |
iban | IBAN van de klant. |
iban_name | Naam van de rekeninghouder. |
phone | Telefoonnummer van de klant. |
email | E-mailadres van de klant. |
ubo_sex | Geslacht UBO: f of m. |
ubo_firstname | Voornaam van de UBO. |
ubo_lastname | Achternaam van de UBO. |
ubo_phone | Telefoonnummer van de UBO. |
ubo_email | E-mailadres van de UBO. |
ubo_birthdate | Geboortedatum in formaat dd-mm-YYYY. |
ubo_nationality | Nationaliteit van de UBO. |
ubo_address | Adres van de UBO. |
ubo_postcode | Postcode van de UBO. |
ubo_city | Woonplaats van de UBO. |
ubo_country | Landcode van de UBO. |
Alle optionele velden tonen
vat (btw-nummer) en web (website-URL) zijn optioneel. Voor een tweede, derde of vierde UBO kunt u dezelfde gegevens toevoegen met het voorvoegsel ubo2_, ubo3_ of ubo4_.
| UBO 2 t/m 4 | Beschikbare suffixen |
|---|---|
ubo2_*, ubo3_*, ubo4_* | sex, firstname, lastname, phone, email, birthdate, nationality, address, postcode, city, country |
curl --location --request POST \
'https://rest-api.pinvandaag.com/V2/instore/clients/create' \
--header 'X-API-KEY: API_TOKEN' \
--form 'kvk="01234567"' \
--form 'iban="NL01BANK0123456789"' \
--form 'iban_name="Bank Account Name"' \
--form 'vat="NL012345678B01"' \
--form 'phone="0612345678"' \
--form 'email="[email protected]"' \
--form 'ubo_sex="f"' \
--form 'ubo_firstname="Voornaam"' \
--form 'ubo_lastname="Achternaam"' \
--form 'ubo_phone="0612345678"' \
--form 'ubo_email="[email protected]"' \
--form 'ubo_birthdate="31-12-1987"' \
--form 'ubo_nationality="Nederlandse"' \
--form 'ubo_address="Straat 1"' \
--form 'ubo_postcode="1234AB"' \
--form 'ubo_city="Amsterdam"' \
--form 'ubo_country="NL"'{
"status": "success",
"message": "Client created with id 50065"
}Transacties zoeken
Haalt transacties op voor Worldline, CCV, PIN, iDEAL, Cloud Connect en MultiSafepay.
Optionele queryparameters
| Parameter | Beschrijving |
|---|---|
clients | Voor partners: kommagescheiden client-ID's. |
terminals | Kommagescheiden terminal-ID's. |
datefrom | Begindatum als UNIX-tijdstempel. Standaard: eerste dag van de huidige maand. |
dateto | Einddatum als UNIX-tijdstempel. Standaard: huidige dag. |
amountfrom | Minimumbedrag in euro. |
amountto | Maximumbedrag in euro. |
transaction_type | sepay (PIN), pay (iDEAL), cc (Cloud Connect), msp (MultiSafepay) of all. |
show_failed | 1 om mislukte transacties te tonen; 0 om ze te verbergen. |
group_by | customerId of date. |
buckaroo_type | amex, maestro, mastercard, mastercard debit, vpay, visa, visa debit of all. |
curl --location --request GET \
'https://rest-api.pinvandaag.com/V2/instore/transactions_dashboard/search?transaction_type=pay&show_failed=0&datefrom=1664575200&dateto=1664920800&terminals=CT164623,CT236543' \
--header 'X-API-KEY: API_TOKEN'{
"status": "ok",
"data": {
"status": "success",
"message": "Transacties gevonden",
"data": {
"date_from": "2022-09-30T22:00:00.000000Z",
"date_to": "2022-10-04T22:00:00.000000Z",
"amount_from": 0,
"amount_to": 0,
"transactions": [
{"id": 1135554309, "customer_id": 12019, "time": "2022-10-04T21:03:29+00:00", "amount": 45.98, "type": "iDEAL"},
{"id": 1135539732, "customer_id": 12019, "time": "2022-10-04T20:44:23+00:00", "amount": 57.21, "type": "iDEAL"}
]
}
}
}Transactie starten
Start een nieuwe betaling op de gekozen terminal. Bedragen worden altijd in centen opgegeven.
| Veld | Type | Beschrijving |
|---|---|---|
terminal_id | Verplicht | Terminal waarop de betaling wordt gestart. |
amount | Verplicht | Bedrag in centen; € 12,50 wordt 1250. |
callbackUrl | Optioneel | HTTPS-URL waarop de webhook wordt ontvangen. |
ownReference | Optioneel | Uw eigen unieke bestel- of betalingsreferentie. |
ReturnUrl | Optioneel | Alleen CCV: URL waarnaar de gebruiker terugkeert. |
curl --location --request POST \
'https://rest-api.pinvandaag.com/V2/instore/transactions/start' \
--header 'X-API-KEY: API_TOKEN' \
--form 'terminal_id="TERMINAL_ID"' \
--form 'amount="1250"' \
--form 'callbackUrl="https://uw-app.nl/webhooks/pinvandaag"' \
--form 'ownReference="ORDER-2026-001"'{
"transactionId": "2405102",
"status": "started",
"amount": 1250,
"terminal": "50303253",
"createdAt": "2022-06-25 17:10:36",
"callbackUrl": "https://uw-app.nl/webhooks/pinvandaag",
"ownReference": "ORDER-2026-001"
}Transactiestatus ophalen
Haalt de actuele status van een betalingstransactie op.
| Veld | Verplicht | Beschrijving |
|---|---|---|
terminal_id | Ja | Terminal waarop de transactie plaatsvond. |
transaction_id | Ja | ID uit de response van transactie starten. |
curl --location --request POST \
'https://rest-api.pinvandaag.com/V2/instore/transactions/status' \
--header 'X-API-KEY: API_TOKEN' \
--form 'terminal_id="TERMINAL_ID"' \
--form 'transaction_id="TRANSACTION_ID"'CCV · geslaagd
{
"transactionId": "TL220611120248997CB8FB114.1",
"status": "success",
"amount": 1,
"terminal": "706249441",
"createdAt": "2022-06-11 12:01:29",
"callbackUrl": null,
"paymentUrl": null,
"errorMsg": null,
"ownReference": null,
"receipt": "[...]",
"journalReceipt": "[...]"
}CCV · mislukt
{
"transactionId": "TL220618175406586CB893D27.2",
"status": "failed",
"amount": 1,
"terminal": "706249441",
"createdAt": "2022-06-18 17:53:46",
"callbackUrl": null,
"receipt": null,
"paymentUrl": "https://redirect.jforce.be/terminal/poll?reference=...",
"errorMsg": "processing_error",
"ownReference": null
}Worldline · geslaagd
{
"transactionId": "2340636",
"status": "success",
"amount": 1,
"terminal": "50303253",
"createdAt": "2022-06-18 16:23:45",
"callbackUrl": null,
"incidentCode": null,
"errorMsg": null,
"ownReference": null,
"receipt": "[...]"
}Worldline · mislukt
{
"transactionId": "2340627",
"status": "failed",
"amount": 1,
"terminal": "50303253",
"createdAt": "2022-06-18 16:22:39",
"callbackUrl": null,
"receipt": null,
"incidentCode": "2628",
"errorMsg": "External Equipment Cancellation",
"ownReference": null
}Transactie annuleren
Annuleert uitsluitend een transactie die op dat moment door de terminal wordt verwerkt. Gebruik voor Worldline en CCV altijd dezelfde aanvraag met zowel terminal_id als transaction_id. Zo blijft uw integratie uniform wanneer u van terminalmerk wisselt.
| Veld | Verplicht | Beschrijving |
|---|---|---|
terminal_id | Ja | ID van de terminal waarop de transactie wordt verwerkt. |
transaction_id | Ja | ID uit de response van transactie starten; altijd meesturen voor Worldline en CCV. |
curl --location --request POST \
'https://rest-api.pinvandaag.com/V2/instore/transactions/stop' \
--header 'X-API-KEY: API_TOKEN' \
--form 'terminal_id="TERMINAL_ID"' \
--form 'transaction_id="TRANSACTION_ID"'Bon per e-mail versturen
Verstuurt de bon van een geslaagde transactie naar de klant.
| Veld | Verplicht | Beschrijving |
|---|---|---|
terminal_id | Ja | Terminal waarop de transactie is geslaagd. |
transaction_id | Ja | ID van de geslaagde transactie. |
email | Ja | E-mailadres van de ontvanger. |
curl --location --request POST \
'https://rest-api.pinvandaag.com/V2/instore/transactions/mail' \
--header 'X-API-KEY: API_TOKEN' \
--form 'terminal_id="TERMINAL_ID"' \
--form 'transaction_id="TRANSACTION_ID"' \
--form 'email="[email protected]"'Terugstorting starten
Start een terugbetaling op het pinapparaat. De klant houdt de pas bij de terminal; de terugstorting verloopt daarna net als een betaling. Bedragen worden altijd in centen opgegeven.
| Veld | Verplicht | Beschrijving |
|---|---|---|
terminal_id | Ja | Terminal waarop de terugbetaling wordt uitgevoerd. |
amount | Ja | Terug te betalen bedrag in centen; € 12,50 wordt 1250. |
transaction_id | Optioneel | Alleen CCV: transaction_id van de oorspronkelijke betaling op deze terminal. De terugstorting wordt dan aan die betaling gekoppeld; met een lager amount is het een gedeeltelijke terugbetaling. Zonder dit veld is het een losse terugstorting. |
callbackUrl | Optioneel | HTTPS-URL waarop de webhook wordt ontvangen. |
ownReference | Optioneel | Uw eigen referentie, bijvoorbeeld het retour- of ordernummer. |
curl --location --request POST \
'https://rest-api.pinvandaag.com/V2/instore/transactions/refund' \
--header 'X-API-KEY: API_TOKEN' \
--form 'terminal_id="TERMINAL_ID"' \
--form 'amount="1250"' \
--form 'callbackUrl="https://uw-app.nl/webhooks/pinvandaag"' \
--form 'ownReference="RETOUR-2026-001"'curl --location --request POST \
'https://rest-api.pinvandaag.com/V2/instore/transactions/refund' \
--header 'X-API-KEY: API_TOKEN' \
--form 'terminal_id="TERMINAL_ID"' \
--form 'amount="500"' \
--form 'transaction_id="TRANSACTION_ID_VAN_DE_BETALING"'{
"status": "started",
"type": "refund",
"terminal": 706249441,
"amount": 500,
"transaction_id": "TL260611120248997CB8FB114.1",
"original_transaction_id": "TL260610093112412CB8FA201.1",
"payment_url": "https://redirect.jforce.be/terminal/poll?reference=...",
"createdAt": "2026-06-11 12:02:48",
"callbackUrl": "https://uw-app.nl/webhooks/pinvandaag",
"ownReference": "RETOUR-2026-001"
}Bij Worldline bevat de response eveneens status en transaction_id; de overige velden komen rechtstreeks van Worldline.
CTMP-verzoek
Laat een Worldline-terminal handmatig een nieuwe configuratie ophalen vanaf de Worldline-server.
| Veld | Verplicht | Beschrijving |
|---|---|---|
terminal_id | Ja | Terminal waarnaar het CTMP-verzoek wordt gestuurd. |
curl --location --request POST \
'https://rest-api.pinvandaag.com/V2/instore/transactions/ctmp' \
--header 'X-API-KEY: API_TOKEN' \
--form 'terminal_id="TERMINAL_ID"'Transactielijst per terminal
| Parameter | Verplicht | Beschrijving |
|---|---|---|
TERMINAL_ID | Ja | Terminal waarvan de transacties worden opgehaald. |
LIMIT | Ja | Maximumaantal resultaten, van 1 t/m 100. |
PAGE | Ja | Op te halen paginanummer. |
datefrom | Optioneel | Begindatum als UNIX-tijdstempel. |
dateto | Optioneel | Einddatum als UNIX-tijdstempel. |
curl --location --request GET \
'https://rest-api.pinvandaag.com/V2/instore/transactions/TERMINAL_ID/LIMIT/PAGE/?datefrom=FROM_TIMESTAMP&dateto=TO_TIMESTAMP' \
--header 'X-API-KEY: API_TOKEN'Laatste transactie ophalen
| Veld | Verplicht | Beschrijving |
|---|---|---|
terminal_id | Ja | Terminal waarvan de laatste transactie wordt opgehaald. |
curl --location --request POST \
'https://rest-api.pinvandaag.com/V2/instore/transactions/last_transaction' \
--header 'X-API-KEY: API_TOKEN' \
--form 'terminal_id="TERMINAL_ID"'Response bij 200
{
"id": 1,
"status": "failed",
"terminal": "12345678",
"amount": 1,
"transaction_id": "123456789",
"own_reference": "",
"which_api": "Worldline|CCV",
"created_at": "2024-04-05T00:00:00+00:00",
"updated_at": "2024-04-05T00:00:00+00:00",
"callback_url": "",
"payment_url": null,
"receipt": null,
"incident_code": "1",
"error_msg": "",
"cancel_counter_ccv": null
}Velden zoals payment_url en receipt kunnen null of een string bevatten. cancel_counter_ccv kan null of een geheel getal zijn.
Foutstatussen
- 400: ongeldige of ontbrekende POST-data; de response bevat validation_errors.
- 404: terminal niet gevonden of er zijn geen transacties.
- 500: interne serverfout; neem contact op met het developmentteam van Pin Vandaag.
{
"status": "error",
"http_code": 400,
"message": {
"error": "Invalid data was provided.",
"validation_errors": {
"terminal_id": {
"integer": "The Terminal id must be integer"
}
}
},
"data": null
}Webhook ontvangen
De webhook wordt uitsluitend aangeroepen wanneer de transactiestatus verandert. Stuur bij /transactions/start een publiek bereikbare HTTPS-URL mee in callbackUrl.
Levering
De webhook wordt als POST met een JSON-body (Content-Type: application/json) naar uw callbackUrl gestuurd.
{
"transactionId": "1234567",
"status": "failed",
"amount": 1,
"terminal": "12345678",
"createdAt": "2022-07-08 18:21:03",
"callbackUrl": "https://uw-app.nl/webhooks/pinvandaag",
"paymentUrl": null,
"receipt": null,
"ownReference": "ORDER-2026-001"
}Aanbevolen verwerking
- Accepteer uitsluitend HTTPS-verzoeken op uw callback-URL.
- Zoek de betaling op via transactionId en/of ownReference.
- Maak verwerking idempotent: dezelfde status mag nooit dubbel een order afronden.
- Verwerk success als geslaagd; behandel failed als mislukt. Elke andere status is nog niet definitief (zie Transactiestatussen).
- Vraag bij onduidelijkheid de status opnieuw op via het statusendpoint.
- Log de ontvangen body veilig, zonder uw API key op te slaan.
PHP SDK en support
Pin Vandaag biedt een klein PHP SDK-pakket voor REST API v2. U kunt het pakket rechtstreeks gebruiken of als voorbeeld nemen voor uw eigen implementatie.
composer require pinvandaag/pin-php-sdk