soft decline
Recoverable failure type.
A decline code is Stripe's classification of why a payment failed. There are roughly 30 codes covering everything from card_declined (generic) to insufficient_funds (soft) to fraud_suspected (hard) to expired_card (most-recoverable). Decline codes drive both retry strategy and recovery email copy.
Porchops maps Stripe's ~30 decline codes into four buckets for the email layer: hard decline (non-recoverable; customer must update), soft decline (recoverable via retry plus email), expired card (most-recoverable; clear update walkthrough), and generic (lowest-pressure email; don't guess wrong).
Lou drafts different copy for each bucket. The bucket classification is configurable; defaults are conservative based on what works for $5K-$500K ARR SaaS.
expired_card → expired-card bucket → "Your card expired; here's how to update" walkthrough.
insufficient_funds → soft-decline bucket → "Your card was declined for insufficient funds; we'll retry" friendly note.
card_declined (generic) → generic-decline bucket → "Something happened with your card; here's a payment-update link" no-pressure email.
fraud_suspected → hard-decline bucket → "Your card couldn't be processed; please update payment method" no-urgency note.
Stripe's documentation lists every code with descriptions. Lou's classification logic maps each to a bucket; the mapping is configurable per founder if you want custom routing.
Expired card recovers at ~70%+ (clear walkthrough works). Soft declines at ~50%. Hard declines at ~15%. Generic declines vary widely; the no-pressure framing maximizes recovery.
Yes. Defaults are conservative; you can re-bucket specific codes (e.g., move processor_temporarily_down from soft to retry-only). Configure once; the audit log tracks outcomes.