What Happens When You Type a URL and Press Enter
DNS lookups, TCP and TLS handshakes, HTTP requests, servers, and the browser's rendering pipeline. The whole journey of a web page, explained so it finally clicks.
Read →Taking money online is mostly a solved problem, if you avoid the classic mistakes. Hosted checkout vs embedded forms, webhooks as the source of truth, money as integers and testing every edge case.
Adding payments sounds intimidating, and for good reason: bugs here cost real money and real trust. The good news is that modern payment providers handle the hardest parts. Your job is to integrate them correctly and avoid a handful of well-known mistakes.
Storing or even touching full card numbers puts you in scope for strict security requirements (PCI DSS). The simplest, safest approach is to let the payment provider handle card details entirely:
Either way, your servers only ever see tokens and IDs, never card numbers.
This is the most important rule. Users close tabs, lose connections and press Back. Some will pay successfully and never see your success page. Others could load the success URL without paying at all.
Use the webhook as the source of truth. Fulfil orders (grant access, ship goods, send receipts) when a verified webhook confirms payment, not when someone visits a URL. The success page should just show "processing" or the current order status. (Handling webhooks reliably.)
Never store money as floating-point numbers:
0.1 + 0.2 // 0.30000000000000004
Store amounts as integers in the smallest currency unit: cents, paise, pence. $49.99 becomes 4999. Always store the currency alongside the amount, and only format for display at the very end. Most payment APIs already work this way.
Never trust a price sent from the browser. A user can edit any request. The client sends what they want to buy (product IDs, quantities, coupon codes); your server looks up the prices, applies discounts and taxes, and creates the payment for that amount. (Input validation.)
Double-clicks and retries happen. Make sure one checkout can't charge twice:
Orders aren't just "paid" or "not paid." Common states:
pending → paid → fulfilled, plus failed, cancelled, refunded and partially_refunded.
Record every state change with a timestamp. When a customer emails about a charge, you'll want a clear history.
If you charge recurring payments, handle:
Most providers manage the billing schedule; you listen to their webhooks and update access accordingly. Many also offer a hosted customer portal for updating cards and cancelling, which saves you building it.
Providers offer test API keys and test card numbers that simulate success, declines, insufficient funds, authentication challenges and disputes. Test:
Keep test and live keys strictly separate, in environment variables. (Config best practices.)
Use a payment provider's hosted checkout or embedded payment elements, create payments from your server with server-calculated amounts, and fulfil orders when a verified webhook confirms payment.
No. Let your payment provider store card details and give you tokens. Handling raw card data brings strict compliance requirements and serious risk.
As integers in the smallest currency unit (for example, cents) with a separate currency column, never as floating-point numbers.
DNS lookups, TCP and TLS handshakes, HTTP requests, servers, and the browser's rendering pipeline. The whole journey of a web page, explained so it finally clicks.
Read →There are dozens of HTTP status codes, but about fifteen cover nearly everything. What each one means, when to return it, and the mix-ups (401 vs 403, 301 vs 302) that confuse everyone.
Read →A, AAAA, CNAME, MX, TXT and NS records in plain English, why DNS changes seem slow, and the troubleshooting commands that tell you what is really going on.
Read →