Stripe
Stripe uses Payment Intents for modern card payments (replace Charges for new integrations). Customers hold payment methods; Subscriptions link customers to recurring Prices. All IDs are strings (pi_, cus_, sub_, etc.). Test mode uses pk_test_/sk_test_; live uses pk_live_/sk_live_.
Data Model
- PaymentIntent (pi_) — primary payment flow. Create → confirm on client or server. Use for one-time payments.
- Charge (ch_) — legacy one-time payment. Prefer PaymentIntent for new code.
- Customer (cus_) — stores payment methods and metadata.
- PaymentMethod (pm_) — card/bank. Attach to customer for reuse.
- Subscription (sub_) — recurring billing. Links customer + Price.
- Product (prod_) and Price (price_) — define what you sell. Prices can be one-time or recurring.
- Refund (re_) — reverses a charge. Full or partial.
- Balance and Payout (po_) — moving funds to bank.
- Dispute (dp_) — chargeback. Submit evidence before deadline.
- Events (ev_) — webhook-style audit log.
Gotchas
- PaymentIntent vs Charge: Use PaymentIntent for new integrations. Charges are legacy; no 3D Secure on Charges.
- Idempotency: Use idempotency keys for create/upsert to enable safe retries.
- Price is immutable: Cannot change amount on existing Price. Create new Price, update Subscription to new price.
- Subscription status: active, past_due, canceled, etc. Check before assuming payment succeeded.
- Payout timing: Balance must be positive; payouts have a delay (typically 2–7 days). Cancellation only works before sent.