In one of my personal projects I needed an easy way to accept credit cards. I wanted a quick solution that was easy to integrate, didn’t cost an arm and a leg and would interact with the non-profit’s existing bank account without requiring a merchant account. In previous jobs I have worked with credit card processing software and it has never been one of my favorite tasks. I looked though many different choices and found https://stripe.com/ . I was hooked by their motto: “Payments for developers” and after looking through their documentation I decided they were the way to go.
One major thing to note about the form is that the credit card number, CVC (validation code) and expiration date inputs do not have names. This ensures that those values will never hit my server since they will not be in the form submission. This way I don’t have to worry about any serious PCI compliance efforts and I do not have the risk of leaking any credit card information since you cannot accidently disclose what you never knew.
The first thing I do on the backend is to set the private key value for the Stripe API. This is something that has to stay private and should only be placed in server side code. Then I get the form values that were posted and encode using them htmsepcialcharacters to prevent Cross-Site Scripting (XSS) attacks since I will be echoing this data back to the user.
Now in a try/catch block I try to charge the credit card, using the token that was created in the payment form. Note that the charge amount passed to the API call must be in cents and since I am storing the amount to be charged in dollars and cents I need to convert it to cents. If the call completes successfully then the charge has gone through and I can take appropriate action. The Stripe API returns JSON as the response for every call, so I deserialize the response. This will give me a set of objects that I can pull data out of to provide a confirmation screen to my user. I want to get some of the details of the actual card used, so I deserialize that data as well.
Once I have the data I can construct a response page for the user and so that they know the confirmation details. I also need a more permanent record of the transaction so I insert the details into a MySQL table. I don’t want to leave myself open to a SQL injection attack so I make sure that I use a parameterized query to perform the insert.
If the charge did not succeed the Stripe API call will throw an exception. In my catch block I let the user know what happened and display the error reported by the API.
Without much effort at all I have now built a safe and secure online payment form that let’s my users pay online and seven days later the money appears in my bank account. There is more complex functionality available from Stripe such as the ability to create “Customers” and make recurring charges to their cards, again so that you don’t have to store their credit card numbers, as well as a range of other actions you can take with cards (refunds, pre-authorization, etc.). All in all it is a very complete service that charges reasonable fees and is a breeze to integrate into an existing system. For my simple use case, it took me less than a day to go from 0 to production.
- Fall 2012–Crypto, AOP and AppSec
- CodeMash Door Decorating Competition