Payment iframe - the easiest way to insert Stripe into your website

Stripe is a fantastic service for processing credit cards, but if you're new to javascript, their "building a payment form" instructions can look a bit daunting. Depending on your level of paranoia (as the author of a secure online backup service, my level of paranoia is quite high), there's another problem: Using the "stripe.js" code, you need to load javascript into a page which is served from your domain — meaning that if someone can tamper with that code, Javascript's "same origin" policy won't protect you. While I have every confidence in the Stripe team's attention to security, one of the basic principles of security is to avoid trusting people unnecessarily — even if you think they're great people who are very unlikely to ever get anything wrong.

Using a payment iframe solves these problems. Just insert one <iframe> tag into your site, and when your customers enter their credit card details and click on the button a form will be submitted to your server with a stripe_token (for credit card payments) or a stripe_receiver (for bitcoin payments) for you to process.

How to use a payment iframe (credit card version)

Paste the following code into your website, after replacing "YOURCGISCRIPT" with the URL of the CGI script you want the stripe_token submitted to, and replacing "STRIPEPUBLISHABLEKEY" with your Stripe publishable API key:

<iframe src="https://paymentiframe.com/tag.cgi?u=YOURCGISCRIPT&k=STRIPEPUBLISHABLEKEY" frameBorder=0 height=230px width=350px></iframe>

That code will produce a form which looks like this (feel free to try it out — it's in Stripe "test mode", and "4242 4242 4242 4242" is a good number to try):

If you want to change the button text from "Make payment" to something else, add a t=YOURTEXTGOESHERE parameter to the iframe src URL.

If you want to add a "hidden" input to the form which is submitted to your server (say, to let you know which customer just entered their card details), add n0=NAME and v0=VALUE to the iframe src URL. More hidden variables? Add n1 and v1, n2 and v2, all the way up to n999 and v999.

How to use a payment iframe (bitcoin version)

Paste the following code into your website, after replacing "YOURCGISCRIPT" with the URL of the CGI script you want the stripe_receiver submitted to, replacing "STRIPEPUBLISHABLEKEY" with your Stripe publishable API key, replacing "CURRENCY" with the currency code (e.g., "usd"), replacing "AMOUNT" with the currency amount in Stripe's units (e.g., in cents for USD), and replacing "DESCRIPTION" with the description parameter you want passed to Stripe (this last parameter is optional but highly recommended, in case bitcoins arrive but the form submission to your server never arrives):

<iframe src="https://paymentiframe.com/btctag.cgi?u=YOURCGISCRIPT&k=STRIPEPUBLISHABLEKEY&c=CURRENCY&a=AMOUNT&d=DESCRIPTION" frameBorder=0 height=200px width=500px></iframe>

For a payment of 10 USD, that code will produce a form which looks like this (note that since this example is using a "test mode" key, it creates an obviously fake bitcoin address to send coins to):

Since Stripe only guarantees an exchange rate for 10 minutes, the iframe asks customers to make a payment within 5 minutes and then asks Stripe for a new "payment receiver" which is valid for the next 10 minutes. (The iframe continues checking if a payment has been received by the old receiver for an extra minute to allow for propagation delays in case a payment is sent just before the five minute timer expires).

If you want to add a "hidden" input to the form which is submitted to your server (say, to let you know which customer just entered their card details), add n0=NAME and v0=VALUE to the iframe src URL. More hidden variables? Add n1 and v1, n2 and v2, all the way up to n999 and v999.

Payment iframe code generator

If you prefer, instead of inserting parameters into your payment iframe tag by hand, you can use the this form to build your payment iframe code:

Mandatory payment iframe parameters
Optional parameters
Generated code (credit card)
Generated code (bitcoin)

What a payment iframe won't do for you

Using a payment iframe makes it easier to integrate Stripe into your website, but you still need to:

  1. Create a Stripe account, and sign up for the Bitcoin beta if you want to accept bitcoins.
  2. Write code which takes the submitted form (the stripe_token or stripe_receiver and any other variables you've added) and makes a Stripe API request to charge the card, create a "customer" object which you can charge later, or create a bitcoin payment from a filled receiver.

FAQ

Why does this exist?
I wanted to be able to use something like this, and Stripe was taking too long, so I figured I'd build it myself.

Does it cost anything?
This is free (you still have to pay Stripe's processing fees on credit card charges you make, of course). If I find that lots of people use this I might set up a "tip jar" to cover the cost of running it.

Is there any warranty or SLA?
You're joking, right? Use at your own risk. Beware of dog. Slippery when wet. Of course, if you want to pay for the cost of running it, I would be happy to make this a geographically redundant service which scales automatically based on load.

Why should I trust you?
It depends what you want to protect. If all you want to protect is your customers' credit card details, you should load javascript directly from Stripe's servers — after all, you're already trusting Stripe with your customers' credit cards. If your top priority is to protect your logged-in users from having javascript do evil things to their accounts, you can safely use a Payment iframe because the iframed code is not able to tamper with anything outside of its frame. If you're worried about both, consider this a proof-of-concept which you should replicate on your own server (using a separate domain name from the rest of your site).

Who is the guy behind this?
Dr. Colin Percival — author of Tarsnap and FreeBSD Security Officer Emeritus.

How can I contact you?
You can email me at cperciva@tarsnap.com, or tweet @cperciva.