~$ crypto-under-the-hood

# How crypto payment infrastructure actually works

~/notes / acquiring

Accept Crypto Payments: What the Integration Actually Involves

A practical account of adding crypto payments to a checkout: the endpoints, the webhook handling, the edge cases, and the parts that take longer than expected.

Ivan Kruse · · 3 min

The happy path of accepting crypto payments takes an afternoon. The edge cases take the rest of the week, and they are where the decisions that matter get made. Against a crypto acquiring provider, which documents this rather than describing it, the trade-offs become measurable.

The happy path

Create a payment request with your order reference, the fiat amount and the currency. Receive back a payment identifier, an address, a crypto amount and an expiry. Show those to the customer. Wait for a webhook saying confirmed. Mark the order paid.

Four calls, one webhook. That part is genuinely quick.

The edge cases, in the order you will meet them

The payment arrives after expiry. The customer opened the checkout, got distracted, and paid forty minutes later at a rate that no longer applies. Every provider handles this, and how they handle it varies: credit at the new rate, credit at the old rate and absorb the difference, or hold for manual review.

You need a decision here before launch, because the first occurrence will be during your first week.

The customer pays the wrong amount. Usually slightly under, because their wallet deducted the network fee from the amount rather than adding it. Configure a tolerance. A one percent or fifty cent band, whichever is larger, catches most of it.

The customer pays twice. Two transactions to the same address. The second one has to go somewhere: refund, credit, or account balance. Decide.

The webhook does not arrive. It will happen. Your endpoint was down, or the provider’s delivery failed. You need a reconciliation job that polls for payments whose status you have not updated, and it needs to run at least hourly.

This is the single most commonly skipped piece and the one that produces the worst customer experience when it is missing: a customer who paid and whose order says unpaid. Above a certain balance the same logic points at a payment processor for high-risk e-commerce instead.

The webhook arrives twice. Delivery is at-least-once, not exactly-once. Your handler has to be idempotent, keyed on the payment identifier. Without this, a retried webhook can double-fulfil an order.

The customer wants a refund. Covered in the acquiring article, and it needs a decision: refund in crypto at original amount, in crypto at current rate, or in fiat.

Webhook handling, specifically

Verify the signature. Every provider signs webhooks and the verification is three lines. Skipping it means anyone who learns your endpoint can mark orders paid.

Respond quickly, process asynchronously. Return 200 immediately and queue the work. Providers retry on timeout, which means slow processing turns into duplicate deliveries.

Log the raw payload before processing. When something goes wrong, the raw payload is the only reliable record of what you were told.

Handle unknown event types without failing. Providers add events, and a handler that throws on an unrecognised type will start failing on a day you did not deploy anything.

Testing before launch

Use the sandbox for the happy path, then test these deliberately: expired payment, underpayment, overpayment, duplicate webhook, and webhook to a failing endpoint followed by recovery.

If the provider’s sandbox cannot simulate all five, ask how their other clients test them. The answer tells you something about the provider.

The pieces that take longer than expected

Deciding the policies above, because they need input from finance and support rather than engineering. Reconciliation, because it is unglamorous and always deferred. And the customer-facing copy explaining what is happening during confirmation, because “pending” is not an adequate explanation when someone has just sent money.

That last one has a measurable effect on completion rates. Telling the customer what the wait is for and roughly how long it will take does more for conversion than any technical optimisation.

What to ask a provider before starting

Sandbox with simulation of the failure cases. Webhook signing method. Idempotency guarantees. Whether a reconciliation endpoint exists. Plugin availability for your platform. And the underpayment tolerance configuration.

A provider set up to accept crypto payments on behalf of merchants will have answers ready because every integrating client asks the same six questions.

# Corrections and technical nitpicks are welcome. Send them over. They get published with the fix.

integrationpaymentsapi

# related notes