Handling Offline Payments with Stripe
We use Stripe for managing customer payments and subscriptions at Recruiterbox. Stripe works really well for us because it handles the complexity of managing credit cards and the entire subscription lifecycle from trial periods, recurring charges, payment retries and cancellation. Stripe also has a comprehensive API and web hooks system. We use it in our app to listen to interesting events like when a payment succeeds or when a customer’s subscription gets cancelled because Stripe failed to charge the customer mostly because of a faulty card.
This is amazing for a growing SaaS company with self served customers who use credit cards to pay for the service. As Recruiterbox is growing, we see an increasing number of customers who would rather wire the money over to our bank account because the processes in their company may not allow setting up a credit card. This what we call ‘Offline payments’ at Recruiterbox. Stripe’s documentation does not explicitly tell you how to handle this scenario.
Some people suggest that we should use a separate accounting system as the system of record for all payments and subscriptions. This is a fair approach but it would take time and effort to build, especially since you may have already built your system with Stripe as the system of record for all your payment and subscription information. So if you want to keep your ‘offline subscriptions’ also in Stripe, we figured that there is indeed a way of doing it.
The ‘Credit Card’ scenario
* The customer signs up on your app on a $500 per year plan. At this point you create a corresponding ‘Customer’ on Stripe
* The customer sets up a credit card (using Stripe.js).
* You create a Subscription for the customer associated with a plan and a trial period on Stripe (Stripe does not let you create one if there is no card set up)
* The customer’s trial period ends, Stripe generates an invoice charges the customer’s card $500 to pay for the invoice. Stripe fires the invoice.payment_succeeded event and charge.succeeded event.
Why it fails for the ‘Offline payment’ Scenario
The offline workflow is similar the credit card workflow, but the customer does not set up a credit card. Instead the customer wires money directly to your bank account. Stripe does not allow you to create a subscription because it does not know how the customer will pay for it. If you update the customer’s account balance on Stripe with credits worth the money the customer paid, then Stripe will allow you to create a subscription because Stripe does not need to ‘charge’ the customer because the customer has enough account balance (credits) to pay for her next invoice.
The ‘Offline payments’ scenario
* The customer signs up on your app on a $500 per year plan. You create a corresponding ‘Customer’ on Stripe
* The customer wires $500 to your bank account.
* You update the customer’s account balance on Stripe by -$500 (credit).
* You create a subscription on Stripe with or without a trial period. Stripe will allow you to create it because the customer has enough account balance to pay for the next invoice.
* The customer’s trial period ends, Stripe creates an invoice and updates the customer’s account balance by $500(debit). There is no charge.succeeded event but just an invoice.payment_succeeded event fired by Stripe.
This way you can have your ‘Offline’ subscriptions also managed on Stripe. There are many advantages to managing it on Stripe, the chief one being that the lifecycle for all subscriptions is managed by Stripe. So for example if you set up a rule on Stripe which says that subscriptions get cancelled if payments retries fail twice, it will still work for both Credit card based and account balance based approaches. The other advantage is that you can spend time and effort in building your app rather than writing and maintaining code to manage customer subscriptions.