Review request

Tattoo studio deposits, is it wrong that I store the card number myself?

Solved · 8 views · asked by sam_builds · edited

Repo or live app

github.com/samokafor/ink-deposits

Unsure about: Security

Clients pay a 50 euro deposit when they book. Claude Code built a form that posts the card number to my API, saves it in a payment_methods table so the artist can charge the rest on the day, and then calls Stripe. It works in test mode. Something about it feels off and I cannot articulate why.

Comment

1 answer

Marked as helpful by the asker
priya_ships · edited

Your instinct is right and this is the one thing you should stop today. The moment a raw card number touches your server you are in PCI scope: annual assessment, quarterly scans, real liability if that table leaks. Nobody at your size wants that.

The supported pattern keeps the number out of your stack entirely. Collect it with Stripe Elements or Checkout in the browser, create a Customer, and save the card with a SetupIntent using usage: 'off_session'. You store the customer id and the payment method id, both harmless strings. On the day of the appointment you charge with:

stripe.paymentIntents.create({
  amount: rest, currency: 'eur', customer, payment_method,
  off_session: true, confirm: true
})

Then drop the payment_methods columns and rotate nothing, because you never had anything worth rotating.

Comment