5 ms·
Roll your own. Start with a subscription table with a paid_through column, and a payment table for recordkeeping. Your billing code is a daily cron job running
by dangrossman 10y ago
Roll your own. Start with a subscription table with a paid_through column, and a payment table for recordkeeping. Your billing code is a daily cron job running a single simple script, that selects all rows with paid_through less than current date, charges each user's card on file, and updates the two tables. Discounts, different subscription terms, receipts, dunning mails are all simple additions to the daily billing script that you can add as you grow.
This has worked for me with tens of thousands of customers and millions in billings, and I've never had to worry about being locked into some payment company's proprietary system. Whatever pricing scheme you initially come up with for your app probably won't be right. You might have 6 plans when you only need 2. You might find out you were charging a flat monthly rate when you really need to be charging per widget or per user or per server. The more you rely on someone else running your billing, the harder it will be to experiment and find the right way to do billing for your customers.
You can avoid being locked in to a payment processor for storing and charging payment info too. I use Spreedly (https://www.spreedly.com https://www.spreedly.com) which provides payment card tokenization and a single unified API for over 100 payment gateways. I can use Braintree today, Stripe tomorrow and ShinyPaymentStartup next year without changing any code or re-collecting billing info from customers.
- tamalsaha001 10y agoWe actually built a similar version based using Braintree api. But somehow from all the hype of Stripe/Braintree, I thought it will be one click and go. But this requires continued time investment everytime I want to change something. Also, I am little worried that we will mess up money stuff. I just wanted to see what other people are doing. Looks like we should stick to our home grown solution.
- newsat13 10y agoThis. Make it easy for yourself to avoid lock in. The code in question is not that complex either (100-200 lines)
- DougN7 10y ago+1 The few days you spend on this will save you many thousands of dollars in fees in the years to come. Great ROI. Having said that, I found Authorize.net to be a good way to go. No affiliation, just a happy customer.
- dangrossman 10y ago> I found Authorize.net to be a good way to go Authorize.net is just a payment gateway, an API between you and a merchant account provider. Since just about every API has existing client libraries you can use, they're no better or worse than each other. What makes Authorize.net a bad choice is that you don't own any of the data you store with them. If you keep your customers' billing info in their CIM vault, it's never coming out. They won't give it to you, and they won't transfer it to another account. That means if you ever want to change merchant account providers, or your account gets frozen, you're stuck. You need to re-collect every customer's billing info to continue their subscriptions on another platform, and that usually means a big chunk of your customer base will churn out all at once. This is what using an independent payment vault solves.
- DougN7 10y agoThat's true. One thing I like about CIM is it's trivially easy for me to be PCI compliant, because that particular sensitive data doesn't hit my server. But you're right - I can't export it.
- dangrossman 10y agoHave they come out with a new integration method? Last time I looked at Authorize.net, all the sensitive data hit your server before you stored it in CIM via an API. You'd need quarterly vulnerability scans, SAQ-C or worse, all that onerous stuff.
- DougN7 10y agoI don't remember what they call it, but basically you pop-up a form that is loaded from their website that gets credit card info, etc, and then posts back to their site. So a credit card number never touches my server. It's very nice.
- pcglue 10y agoThis means you actually store customer credit card numbers and have to deal with PCI compliance? Is ensuring PCI compliance very onerous?
- dangrossman 10y agoNope, I don't store credit card numbers, payment info never touches my servers at all. I mentioned that I use Spreedly. Spreedly works exactly like Stripe Checkout if you've ever used that. You only store a token referring to payment info they're storing, and pass that token to the API to make charges against it as needed.
- brianwawok 10y agoThat's at least $200 to use Spreedly. What benefit have you gotten with it so far? Do you find yourself switching gateways to get lower rates, or do you just stick with one gateway?
- dangrossman 10y agoActually $150/mo for up to 5000 stored cards. The benefit is mostly peace of mind: a "PayPal horror story" type situation (frozen account), processor raising rates, or payment gateway having an extended downtime event are non-issues instead of major headaches or potential company-enders.
- brianwawok 10y agoIs there reason example of a gateway that was down more than a day or 7? A big player like stripe just vanishing in the night? Would rather spend $150 on some AdWords or something that has a more realistic chance to do something.
- jurgenwerk 10y agoCan't stress enough how much I agree with this. I've seen far too many businesses off-loading all billing jobs to an external provider (Stripe, Braintree,...) and then facing troubles when subscriptions get a bit more diverse and greater flexibility and control is needed. I've written about this in one of my posts (http://codeandtechno.com/posts/subscription-payments-use-external-service-or-make-your-own/ http://codeandtechno.com/posts/subscription-payments-use-ext...). Basically, let an external service handle the PCI compliance part (storing sensitive data) and just use their tokens in your billing implementation.
- shanecleveland 10y agoJust recently followed Dan's advice from an early comment of his [1]. Turned out being easier than other solutions to implement anyway. It's doing exactly what I need now, and not more. And it forces you to be very aware of this workflow. I hope I have the need to add the "simple additions" later. [1] https://news.ycombinator.com/item?id=12161235 https://news.ycombinator.com/item?id=12161235
- jjoe 10y agoI had to build a custom billing system for Cachoid too ( https://www.cachoid.com/ https://www.cachoid.com/ ). You definitely need the upfront time to build it from the ground up but it's worth it in the long run. I'm doing monthly recurring with Stripe and one-time also with Stripe and Paypal. And Bitcoin through Stripe. I found that charging per server/FQDN (one FQDN === one service === one billing item) rather than per user provides more flexibility. But I'm not comfortable with single-homed APIs like Spreedly. What if it gets acquired tomorrow? It isn't something you can replace overnight. I'd rather have a multi-homed setup with direct relationship with multiple gateways