Taking money is less frightening than it looks, provided you follow one rule absolutely: card details never touch your server. The payment provider handles those. You handle what happens afterwards.

Use a hosted checkout

Stripe Checkout, Paddle, Lemon Squeezy and the rest give you a URL or an embedded component. The customer types their card details on the provider's infrastructure. That removes almost the entire compliance burden and every opportunity for you to leak a card number.

Paddle and Lemon Squeezy also act as merchant of record, handling sales tax and VAT across jurisdictions. For a solo developer selling internationally that is worth real money and a great deal of paperwork.

The part that actually goes wrong

Not the payment — the fulfilment. Deciding somebody has paid, and granting them access.

The tempting flow is: customer pays, gets redirected to your success page, success page grants access. That's broken both ways. People close the tab before the redirect and get charged with nothing to show for it. And anyone can visit your success URL directly.

The correct flow is webhooks. The provider POSTs to your server when payment succeeds; your server verifies the signature and grants access. The redirect page only says thank you.

payment-webhook.txt
I'm using <provider> hosted checkout. On successful payment I need to
<grant access / send a licence / mark the order paid>.

Build the webhook endpoint:
- Verify the signature before trusting a single byte.
- Idempotent — the same event delivered twice must not grant or charge
  twice. Providers retry.
- Return 200 quickly, do the work after.
- Log every event received, including rejected ones.

Then tell me what my success redirect page should and should not do.

Money in code

Never floats. Store integer minor units — pence, cents — or a proper decimal type. Store the currency alongside the amount. Round exactly once, at the point of display or charge, and know which direction.

Before you launch

Refunds happen — have a process. Failed recurring payments happen — know what your provider does about them. And most jurisdictions give consumers specific rights over digital goods; a short read now beats a chargeback dispute later.

Test the failure paths with the provider's test cards: declines, insufficient funds, expiry. The happy path always works. Your logic is wrong in the others.