Een wallet-adres is geen betalingssysteem. Het is een bestemming, niets meer. Iedereen met de reeks kan op elk gewenst moment alles naar dat adres sturen. Voor een eenmalige deal tussen twee mensen die elkaar vertrouwen, is dat misschien voldoende. Maar als je een SaaS-product, een marktplaats of een webshop beheert, is het plakken van een statisch adres op een betaalpagina een recept voor operationele chaos. Je zult je dagen doorbrengen met het koppelen van mysterieuze transacties aan echte klanten, het raden wie wat heeft betaald, en het opruimen van de puinhoop wanneer iemand de verkeerde token via het verkeerde netwerk stuurt.
Om iets te bouwen dat schaalbaar is, moet je stoppen met denken als een donatiepot en beginnen te denken als een gestructureerd betalingssysteem.
Waarom een wallet-adres faalt bij schaalvergroting
Het probleem is context, of het gebrek daaraan. Wanneer een klant jouw wallet-adres kopieert en crypto verstuurt vanaf een exchange of een self-custody wallet, registreert de blockchain alleen wat er is verplaatst: een bedrag, een tijdstempel en twee publieke adressen. Het registreert je factuurnummer niet. Het bevat de klant-ID niet. Het vermeldt niet of de overboeking een abonnementverlenging, een naar rato upgrade of een volledig nieuwe aankoop is.
Stel je een SaaS-bedrijf voor dat elke maand vijfhonderd klanten factureert in stablecoins. Als elke klant USDT naar hetzelfde statische adres stuurt, krijgt je boekhoudteam te maken met een spreadsheet-nachtmerrie. De ene overboeking ziet er identiek uit aan de andere. Je kunt niet zien of de twintig dollar die om 2 uur 's nachts binnenkwam, afkomstig was van Klant A die zijn abonnement verlengde, of van Klant B die halverwege de cyclus een upgrade uitvoerde. De blockchain ziet een getal. Jouw bedrijf heeft een verhaal nodig.
Marktplaatsen ervaren deze pijn aan beide kanten van de transactie. Je moet weten dat de koper fondsen heeft gestort, deze vasthouden terwijl de verkoper verzendt, en ze pas vrijgeven na leveringsbevestiging. Een ruw adres biedt geen programmeerbare manier om de storting van een koper te onderscheiden van een willekeurige inkomende overboeking of de eigen fondsen van een leverancier. E-commerce is net zo rommelig. Zonder een transactie te koppelen aan een specifieke bestelling, kun je de levering niet in gang zetten. Iemand moet handmatig de chain scannen, de overboeking vinden en je database bijwerken. Doe dat tien keer per dag en je mist matches. Doe dat duizend keer en je verliest geld.
De verschuiving is eenvoudig maar cruciaal. Stop met vragen of er fondsen zijn aangekomen op een adres. Begin met vragen of een specifieke betalingsaanvraag de juiste status heeft bereikt.
Bouw rondom de betalingsaanvraag
Een betrouwbare crypto-betalingsstroom behandelt de betalingsaanvraag als het centrale object. Het wallet-adres wordt een tijdelijke container die bestaat ten dienste van de aanvraag. De aanvraag bevat de metadata die een blockchain-overboeking verandert in een herkenbare zakelijke gebeurtenis.
Voordat je een betaaloptie presenteert, definieer je de gegevenspunten die de betaling identificeerbaar maken:
- Een aankoop- of abonnements-ID, zodat je precies weet waarom het geld wordt verplaatst.
- Het verwachte bedrag, tot op de decimalen nauwkeurig gespecificeerd.
- Het exacte type asset en netwerk, omdat het versturen van USDT op Ethereum niet uitwisselbaar is met het versturen ervan op Tron of Polygon.
- Een referentie naar de klant of een interne rekening.
- Een vervaltijd, zodat een half betaalde offerte uit maart niet per ongeluk een bestelling in juni sluit.
Wanneer een klant op 'betalen' klikt, genereert je systeem een aanvraag met deze velden. De klant betaalt vervolgens tegen die specifieke aanvraag, en niet simpelweg tegen een adres. De transactie op de chain heeft nu een off-chain identiteit. Je systeem weet waar de betaling voor is, nog voordat het de block explorer raadpleegt.
Modelleer de status eerlijk
Geld op een blockchain beweegt in fasen. Je interne systeem heeft een vocabulaire nodig dat bij die fasen past, anders zullen je engineering-, support- en operations-teams langs elkaar heen praten.
Houd het model plat en beschrijvend. Een niet-technische medewerker van de klantenservice moet een status kunnen lezen en weten wat hij of zij tegen een klant moet zeggen.
- Created: Het verzoek bestaat, maar de blockchain laat nog niets zien. De klant heeft nog geen transactie uitgezonden.
- Detected: Je monitoring heeft een relevante transactie gespot in de mempool of een recent blok, maar deze heeft nog geen finaliteit. Verstuur het product nog niet.
- Confirming: De transactie staat op de chain en verzamelt bevestigingen. Chains bewegen met verschillende snelheden. Bitcoin vereist mogelijk zes blokken. Ethereum heeft er misschien twaalf of meer nodig, afhankelijk van je risicobereidheid. Je systeem moet het eigen gedrag van het netwerk respecteren.
- Completed: De betaling komt overeen met het verwachte bedrag, de asset, het netwerk en de context. Aan elke door jou gedefinieerde regel is voldaan. Nu kun je de bestelling verwerken, het abonnement activeren of de escrow vrijgeven.
- Expired: De klant heeft het betalingsvenster gemist. Het verzoek mag geen toekomstige betalingen meer accepteren, tenzij je het expliciet opnieuw activeert.
- Mismatch: De klant heeft fondsen verzonden, maar er is iets mis. Het bedrag is te laag, het netwerk wijkt af of de asset komt niet overeen. Stuur dit door naar de klantenservice. Laat je fulfillment-systeem niet gissen.
Deze pipeline verandert een chaotische stroom aan chain-data in een proces waar je hele bedrijf logica op kan toepassen.
Stop met pollen. Start met luisteren.
Een van de snelste manieren om je infrastructuurbudget te verbranden, is door je backend elke paar seconden aan je provider te vragen of het geld al is aangekomen. Dit verspilt middelen aan beide kanten en zorgt voor onnodige latentie.
Een betere architectuur maakt gebruik van een status-notificatiemodel. Je betalingsprovider of node-infrastructuur moet een event naar je systeem pushen op het moment dat een status verandert. Je ontvangt een webhook wanneer de transactie wordt gedetecteerd, een andere wanneer deze wordt bevestigd, en een laatste wanneer deze is voltooid of is mislukt.
Dit houdt je systeem responsief zonder onnodige CPU-cycli te verbruiken.
