Review request

Internal tool for my team built in Bolt, feedback on the Stripe checkout wanted

Solved · 197 viewsasked by tomvibes

Repo or live app

internal-deposits.example.com ↗

Not customer-facing, but we do take card payments from clients for deposits through this. Bolt set up Stripe Checkout for me and it works in test mode. Before we flip to live keys I'd like someone who has actually shipped Stripe before to look at it.

Comment

2 answers

Marked as helpful by the asker
priya_ships

Checkout session setup looks right. What I'd add before going live: you're trusting the amount from the frontend when creating the session. Move that to the server, look up the deposit amount from your own bookings table by id instead of accepting it as a parameter, otherwise anyone can pay €1 for a €200 deposit by editing the request.

Also set up the webhook for checkout.session.completed before flipping keys, not after, it's how you'll know a payment actually landed.

Comment
femi_o

Agree with Priya on the amount. One more before live keys: your webhook handler has to cope with the same event arriving twice. Stripe retries anything that didn't get a quick 2xx, and if the handler marks the deposit paid and sends the confirmation mail, a retry sends the mail again.

Store the event id and skip what you've already seen:

create table stripe_events (id text primary key, received_at timestamptz default now());

Insert first; if the insert hits the primary key, return 200 and do nothing.

Also: test mode and live mode have different webhook signing secrets. When you flip, create the live endpoint in the dashboard and swap STRIPE_WEBHOOK_SECRET as well, not just the secret key. That's the classic first-live-payment failure.

Comment
Didn't know the webhook secret is different per mode. That would have been me on day one. tomvibes
And subscribe the live endpoint only to the events you actually handle. Less noise in the logs. priya_ships