Jamin pointed to the link on testing cards, a free trial (even for just a minute) with the card that attaches but decline is quite useful.
A subscription has multiple statuses, trialing, active, past_due, and unpaid. Note, a ton of crazy stuff happens with unpaid subscriptions, so unless you have a really good reason, I recommend sticking to canceling a subscription after the 3 failed attempts as opposed to marking it as unpaid.
When a subscription is up for renewal, Stripe will send you an invoice.created webhook. 1 hour later, Stripe will attempt to charge that invoice resulting in an invoice.payment_succecced or invoice.payment_failed. Normally you’ll want to send an email on payment_failed and update your code so that during the next login your customer is prompted to update their card.
After the failed attempt, Stripe will attempt to charge the invoices pursuant to your retry schedule (as set in your account settings), or when you update a customer’s card (customer.card = “tok_”, not customer.cards.add(“tok_)).
Once its billed successfully you’d get a invoice.payment_succeeded.
You also get a customer.subscription.updated (status would become past_due) and customer.updated (if they become delinquent) if the payment fails and again when it unfails, but in most cases people listen to the invoice.* web hooks.
--
Matt Arkin
Kollective Solutions