Een betalingsflow op de server met bescherming bij nieuwe pogingen en tegen duplicaten.
1. Bereid ID's en toegang voor
Begin met een ingeschakelde winkel en geteste betaalmethoden. Maak in Instellingen → API-toegangeen lees-/schrijfreferentie aan die tot het benodigde project is beperkt. Bewaar het token op je backend, nooit in browsercode of een openbare repository.
Kopieer het Project-API-ID en Winkel-API-ID uit het vak Basisgegevens → API-ID's van de winkel. Dit zijn UUID's, niet de leesbare projectidentificator of je bestelnummer. Gebruik je eigen API-hostnaam.
Bekijk in Winkel → IPN, maak een ondertekeningsgeheim aan voordat je een ipn_urlopgeeft. Je HTTPS-ontvanger moet vanaf de handelaars-VPS bereikbaar zijn.
2. Maak een factuur aan
Vervang de plaatshouders en verstuur dit verzoek vanuit je backend. Bedragen zijn decimale tekenreeksen, geen drijvendekommaberekeningen.
curl --fail-with-body --request POST \
'https://api.example.com/v1/projects/YOUR_PROJECT_ID/stores/YOUR_STORE_ID/invoices' \
--header 'Authorization: Bearer YOUR_MERCHANT_API_TOKEN' \
--header 'Content-Type: application/json' \
--header 'Idempotency-Key: order-1042-attempt-1' \
--data '{
"amount": "10.00",
"currency": "EUR",
"order_id": "order-1042",
"description": "Example order",
"ipn_url": "https://shop.example.com/payments/wholly-ipn",
"metadata": {
"cart_id": "cart-1042"
}
}'Bewaar data.invoice_id bij je bestelling en verwijs de klant daarna naar links.checkout. Gebruik een unieke idempotentiesleutel voor een nieuwe betalingspoging. Probeer bij een time-out opnieuw met dezelfde referentie, sleutel en exacte inhoudsbytes.
Het weglaten van payment_methods gebruikt de geaccepteerde methoden van de winkel. Je kunt ze per factuur beperken met blockchainslugs en tickers; dit schakelt nooit een niet-geaccepteerd activum in. Alle verzoekvelden en antwoordvoorbeelden →
3. Kies IPN, webhooks of beide
IPN volgt de levenscyclus van de factuur. Stel de standaard-IPN-URL van de winkel in of overschrijf die met ipn_url voor een factuur. Webhooks abonneren een endpoint op geselecteerde gebeurtenissen, bijvoorbeeld invoice.settled.
Ze gebruiken hetzelfde handtekeningformaat, maar verschillende geheimen: IPN gebruikt het IPN-geheim van de winkel; elk webhookendpoint heeft een eigen geheim. Geen van beide gebruikt het API-bearertoken voor ondertekening.
Als beide aan je app afleveren, verwacht dan overlappende meldingen. Crediteer een bestelling niet tweemaal.
4. Verifieer de melding en sla die op
- Lees de exacte ruwe verzoekinhoud vóór het parsen van JSON. Verifieer
Wholly-Signaturemet het overeenkomende geheim en controles van tijdstempel/herhaling. De officiële SDK's bieden verifiers. - Valideer de identiteit van project, winkel, factuur en gebeurtenis in de ondertekende inhoud. Niet-ondertekende afleverheaders zijn geen authenticatiebron.
- Sla de gebeurtenis duurzaam op met een unieke
event_id, en retourneer daarna snel HTTP 2xx. Verwerk bestellingen in een achtergrondworker. - Haal de actuele factuur op vanaf je ingestelde API-host, niet vanaf een willekeurige host die in een verzoek wordt aangeleverd. Vergelijk je opgeslagen project, winkel, bedrag, valuta en bestelreferentie.
PHP · Python · JavaScript / TypeScript · Handtekeningspecificatie en ontvangervoorbeelden
5. Handel één keer af, bij voldoening
Voor een gebeurtenisgestuurde ontvanger verwerk je event_type = invoice.settled, en verifieer daarna de actuele status = settled en je uitzonderingsbeleid. Handel eenmaal af binnen een databasetransactie/met een uniciteitsbeperking op de bestelling.
Een blockchain met snelle finaliteit kan beide versturen: payment.received en invoice.settled met status = settled. Op een andere blockchain kan payment.received nog processing aangeven. Geen van beide flows is een fout.
Ontdubbel gebeurtenissen op event_id, niet alleen op volgnummer: verschillende gebeurtenistypen kunnen hetzelfde volgnummer delen. Statusgebaseerde SDK-handlers voegen in plaats daarvan factuurrevisies samen en controleren de toestand ongeacht het gebeurtenistype. Combineer die samenvoeging niet met een filter op gebeurtenistype. Beide benaderingen vereisen nog steeds duplicaatbescherming op bestellingsniveau.
Controleer requires_review en handmatige oplossingen voordat je afhandelt. amount_status = paid alleen bewijst geen bevestiging. De betaalde-activavelden op het hoogste niveau vatten de voldoening samen; payment_info bevat de gedetailleerde ontvangsten en koersgegevens. Alle statussen, gebeurtenissen en uitzonderingsregels →
6. Test nieuwe pogingen en herstel
Test een kleine betaling, dubbele aflevering, een verlopen factuur en een tijdelijk niet-beschikbare ontvanger. Een gebeurtenis opnieuw afspelen mag geen tweede creditering van een bestelling veroorzaken. Verwerk gebeurtenissen buiten volgorde zonder nieuwere toestand te overschrijven.
Controleer Winkel → IPN / Webhooks → Geschiedenis → Details, of de afleveronderdelen in Factuurdetails. Opnieuw verzenden hergebruikt de vastgelegde gebeurtenis, geen nieuwe voldoening.
Laag verwerkingstegoed pauzeert IPN/webhooks terwijl betalingen doorgaan. Stem openstaande bestellingen af via de API en verwerk bewaarde afleveringen na herstel. Handel nooit af op basis van een browserdoorverwijzing of een schermafbeelding van een klant.