Betalen zonder gedoePersoonlijk advies: 085 560 12 01
REST API · versie 2.0.0

Integreer betalingen.
Vandaag geregeld.

Complete implementatiehandleiding voor betalingen, transactiestatussen, webhooks, terugbetalingen en klantaanmelding. Van eerste API-call tot een betrouwbare betaalflow.

€ 2,50 per terminal p/m CCV & Worldline Webhooks Nederlandse support
Ga naar een onderdeel ↓
Snel startenAPI-key vindenAPI-testerAuthenticatieIBAN-controleClient aanmakenTransacties zoekenTransactie startenStatus ophalenAnnulerenBon mailenTerugstortingCTMPTransactielijstLaatste transactieWebhookSDK & support
Geen onderdeel gevonden. Probeer een andere zoekterm.
Aan de slag

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.

REST API-tarief: € 2,50 per terminal per maand. Het maandbedrag geldt voor iedere betaalterminal die u via de REST API verbindt. Transactieverwerking en eventuele overige diensten worden afzonderlijk berekend.
Uw kassa of applicatie stuurt een betaalverzoek.
De REST API roept de gekozen terminal aan.
De terminal wacht op de betaling van de klant.
Na een statuswijziging ontvangt uw callback een webhook.
Uw applicatie verwerkt de definitieve transactiestatus.

Ondersteunde betaalterminals

PAX A77PAX A920PAX A35 ITSIngenico DX8000Ingenico RX5000Verifone V400mVerifone P400Verifone Vx680 (wifi)Worldline YomaniWorldline Yoximo
Gelijke statussen, verschillende responses. Statuswaarden zoals success, failed en unknown werken bij Worldline en CCV op dezelfde manier. Andere responsevelden kunnen per route en betaalprovider verschillen.

Beschikbare endpoints

PinPortal

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:

  1. Klik op de gewenste klant.
  2. Klik op Bewerk klant.
  3. Open het tabblad Overige.
  4. Klik op API Keys.
  5. Het Terminal ID verschijnt in het overzicht.
  6. De bijbehorende API KEY staat naast het Terminal ID.
Behandel de API-key als een wachtwoord. Deel de sleutel niet en sla deze nooit op in openbare broncode of een GitHub-repository.
Direct uitvoeren

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.

Gebruik bij voorkeur een testterminal. Een opdracht zoals Transactie starten wordt echt naar de terminal gestuurd.
POST/instore/transactions/start
ResponseNog niet uitgevoerd
De API-response verschijnt hier.
Beveiliging

Authenticatie

Aanbevolen methode: stuur bij ieder verzoek de API key mee in de header X-API-KEY. De oude secret is hierbij niet nodig.

X-API-KEY gebruiken

cURL
curl --location 'https://rest-api.pinvandaag.com/V2' \
  --header 'X-API-KEY: API_TOKEN'
PHP
<?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);
Bewaar uw API key veilig. Plaats de sleutel nooit in openbare broncode, een browserapp of een GitHub-repository. Voer API-aanroepen uit vanaf uw eigen beveiligde server.
Oude OAuth 2.0 / Basic-methode

Bij de oudere flow codeert u API_KEY:SECRET met Base64 en stuurt u dit via Basic Authentication. De API retourneert een access token, dat daarna via Bearer Authentication wordt gebruikt. Voor nieuwe implementaties adviseren wij de eenvoudigere X-API-KEY-methode.

PHP · legacy
<?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);
REST API v2

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.

200Verzoek geslaagd
400Ongeldige invoer
404Niet gevonden
500Interne serverfout
Tip: baseer uw programmastroom eerst op de HTTP-statuscode en controleer daarna de velden status, message en data in de response.
Service

IBAN-naamcontrole

/services/iban/name-check
POST

Controleert een Nederlandse IBAN en vergelijkt de opgegeven rekeninghouder. De functie werkt uitsluitend voor Nederlandse IBANs.

Betaalde service met tokens. Per verwerkt verzoek wordt één token van uw API key afgeschreven. In de response staat hoeveel tokens nog beschikbaar zijn. Bij een interne serverfout of een niet-verwerkbaar verzoek worden geen tokens afgeschreven.
VeldVerplichtBeschrijving
nameJaNaam van de rekeninghouder.
ibanJaNederlandse IBAN, exact 18 tekens. Patroon: ^NL[0-9]{2}[A-Z]{4}[0-9]{10}$
cURL
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

JSON
{
  "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.

Partners

Client aanmaken in PinPortal

/instore/clients/create
POST

Partners kunnen hiermee automatisch een nieuwe klant aanmelden in PinPortal.

Verplichte velden

VeldBeschrijving
kvkKamer van Koophandel-nummer van de klant.
ibanIBAN van de klant.
iban_nameNaam van de rekeninghouder.
phoneTelefoonnummer van de klant.
emailE-mailadres van de klant.
ubo_sexGeslacht UBO: f of m.
ubo_firstnameVoornaam van de UBO.
ubo_lastnameAchternaam van de UBO.
ubo_phoneTelefoonnummer van de UBO.
ubo_emailE-mailadres van de UBO.
ubo_birthdateGeboortedatum in formaat dd-mm-YYYY.
ubo_nationalityNationaliteit van de UBO.
ubo_addressAdres van de UBO.
ubo_postcodePostcode van de UBO.
ubo_cityWoonplaats van de UBO.
ubo_countryLandcode 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 4Beschikbare suffixen
ubo2_*, ubo3_*, ubo4_*sex, firstname, lastname, phone, email, birthdate, nationality, address, postcode, city, country
cURL
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"'
Succesresponse
{
  "status": "success",
  "message": "Client created with id 50065"
}
Dashboard

Transacties zoeken

/instore/transactions_dashboard/search
GET

Haalt transacties op voor Worldline, CCV, PIN, iDEAL, Cloud Connect en MultiSafepay.

Optionele queryparameters

ParameterBeschrijving
clientsVoor partners: kommagescheiden client-ID's.
terminalsKommagescheiden terminal-ID's.
datefromBegindatum als UNIX-tijdstempel. Standaard: eerste dag van de huidige maand.
datetoEinddatum als UNIX-tijdstempel. Standaard: huidige dag.
amountfromMinimumbedrag in euro.
amounttoMaximumbedrag in euro.
transaction_typesepay (PIN), pay (iDEAL), cc (Cloud Connect), msp (MultiSafepay) of all.
show_failed1 om mislukte transacties te tonen; 0 om ze te verbergen.
group_bycustomerId of date.
buckaroo_typeamex, maestro, mastercard, mastercard debit, vpay, visa, visa debit of all.
cURL
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'
Succesresponse
{
  "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"}
      ]
    }
  }
}
Betaling

Transactie starten

/instore/transactions/start
POST
CCVWorldline

Start een nieuwe betaling op de gekozen terminal. Bedragen worden altijd in centen opgegeven.

VeldTypeBeschrijving
terminal_idVerplichtTerminal waarop de betaling wordt gestart.
amountVerplichtBedrag in centen; € 12,50 wordt 1250.
callbackUrlOptioneelHTTPS-URL waarop de webhook wordt ontvangen.
ownReferenceOptioneelUw eigen unieke bestel- of betalingsreferentie.
ReturnUrlOptioneelAlleen CCV: URL waarnaar de gebruiker terugkeert.
Payment URL gebruiken? Geef bij CCV ook een ReturnUrl mee. Zonder ReturnUrl kan de gebruiker steeds naar dezelfde pagina worden teruggestuurd.
cURL
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"'
Succesresponse
{
  "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"
}
Betaling

Transactiestatus ophalen

/instore/transactions/status
POST
CCVWorldline

Haalt de actuele status van een betalingstransactie op.

CCV: maximaal één vernieuwing per 30 seconden. Vraagt u dezelfde transactie binnen 30 seconden opnieuw op, dan kan dezelfde nog niet bijgewerkte response terugkomen.
VeldVerplichtBeschrijving
terminal_idJaTerminal waarop de transactie plaatsvond.
transaction_idJaID uit de response van transactie starten.
cURL
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

JSON
{
  "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

JSON
{
  "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

JSON
{
  "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

JSON
{
  "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
}
Betaling

Transactie annuleren

/instore/transactions/stop
POST
WorldlineCCV · experimenteel

Annuleert uitsluitend een transactie die op dat moment door de terminal wordt verwerkt.

CCV-limiet: dezelfde transactie kan maximaal drie keer worden aangeboden om te annuleren. Daarna wordt dit annuleerverzoek voor die transactie automatisch beperkt.
VeldWorldlineCCV
terminal_idVerplichtVerplicht
transaction_idNiet nodigVerplicht

Worldline

cURL
curl --location --request POST \
  'https://rest-api.pinvandaag.com/V2/instore/transactions/stop' \
  --header 'X-API-KEY: API_TOKEN' \
  --form 'terminal_id="TERMINAL_ID"'

CCV

cURL
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

Bon per e-mail versturen

/instore/transactions/mail
POST
CCVWorldline

Verstuurt de bon van een geslaagde transactie naar de klant.

VeldVerplichtBeschrijving
terminal_idJaTerminal waarop de transactie is geslaagd.
transaction_idJaID van de geslaagde transactie.
emailJaE-mailadres van de ontvanger.
cURL
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]"'
Betaling

Terugstorting starten

/instore/transactions/refund
POST
Alleen Worldline

Start een terugbetaling op het pinapparaat.

VeldVerplichtBeschrijving
terminal_idJaTerminal waarop de terugbetaling wordt uitgevoerd.
amountJaTerug te betalen bedrag in centen.
cURL
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="BEDRAG_IN_CENTEN"'
Terminalbeheer

CTMP-verzoek

/instore/transactions/ctmp
POST
Alleen Worldline

Laat een Worldline-terminal handmatig een nieuwe configuratie ophalen vanaf de Worldline-server.

VeldVerplichtBeschrijving
terminal_idJaTerminal waarnaar het CTMP-verzoek wordt gestuurd.
cURL
curl --location --request POST \
  'https://rest-api.pinvandaag.com/V2/instore/transactions/ctmp' \
  --header 'X-API-KEY: API_TOKEN' \
  --form 'terminal_id="TERMINAL_ID"'
Transacties

Transactielijst per terminal

/instore/transactions/{TERMINAL_ID}/{LIMIT}/{PAGE}/
GET
CCVWorldline
ParameterVerplichtBeschrijving
TERMINAL_IDJaTerminal waarvan de transacties worden opgehaald.
LIMITJaMaximumaantal resultaten, van 1 t/m 100.
PAGEJaOp te halen paginanummer.
datefromOptioneelBegindatum als UNIX-tijdstempel.
datetoOptioneelEinddatum als UNIX-tijdstempel.
Datumcontrole: dateto mag niet vóór datefrom liggen.
cURL
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'
Transacties

Laatste transactie ophalen

/instore/transactions/last_transaction
POST
CCVWorldline
VeldVerplichtBeschrijving
terminal_idJaTerminal waarvan de laatste transactie wordt opgehaald.
cURL
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

JSON · datatypen als voorbeeld
{
  "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.
400 · validatiefout
{
  "status": "error",
  "http_code": 400,
  "message": {
    "error": "Invalid data was provided.",
    "validation_errors": {
      "terminal_id": {
        "integer": "The Terminal id must be integer"
      }
    }
  },
  "data": null
}
Integratie

Webhook ontvangen

De webhook wordt uitsluitend aangeroepen wanneer de transactiestatus verandert. Stuur bij /transactions/start een publiek bereikbare HTTPS-URL mee in callbackUrl.

Huidig aflevergedrag: de transactiedata wordt één keer naar de webhook gestuurd. Bouw daarom daarnaast een controle in die bij twijfel de transactiestatus opvraagt.
Voorbeeld webhookbody
{
  "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

  1. Accepteer uitsluitend HTTPS-verzoeken op uw callback-URL.
  2. Zoek de betaling op via transactionId en/of ownReference.
  3. Maak verwerking idempotent: dezelfde status mag nooit dubbel een order afronden.
  4. Verwerk success als geslaagd; behandel failed als mislukt.
  5. Vraag bij onduidelijkheid de status opnieuw op via het statusendpoint.
  6. Log de ontvangen body veilig, zonder uw API key op te slaan.
Implementatiehulp

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
composer require pinvandaag/pin-php-sdk
Voor u live gaat: test altijd een geslaagde betaling, een geweigerde betaling, een annulering, een time-out, webhookverwerking en herstel na een tijdelijke netwerkfout.