Having written two billing systems in the past year, I'll never build one again.
There are certainly advantages to writing your own, we generate custom PDF receipts at GitHub that customers really seem to like, but the amount of time wasted building and maintaining the system was/is fairly substantial.
If I were to do it again, I'd use a hosted service that you can skin to look like your site and let them manage everything.
I'd strongly echo this - it's the reason I grabbed some co-founders and started Spreedly. After spending weeks building a billing system for a client and not being at all pleased with the result (bad API, insufficient budget, etc.) I knew there had to be a better way. Billing is the red-headed stepchild of an application, never getting as much time as it needs and simultaneously taking up more time than it should - indicators that point towards outsourcing it ASAP. I think Spreedly's the best option, but even if you don't go with us, please don't do it yourself!
I too have had the same experience. Think about upgrading services (and appropriately provisioning services while billing correctly and adjusting the recurring billing), downgrading services, recurring billing for monthly payments, auditing all interactions with whatever payment API you're using, then retrying API calls when appropriate. It's getting to the point where most of the man hours in my project have been on the billing system.
We use Prawn, read more about it here: http://github.com/blog/204-pdf-receipts. There's a code snippet in the comments that looks a lot like the code we use to generate the PDF.
There are certainly advantages to writing your own, we generate custom PDF receipts at GitHub that customers really seem to like, but the amount of time wasted building and maintaining the system was/is fairly substantial.
If I were to do it again, I'd use a hosted service that you can skin to look like your site and let them manage everything.