Handling Payments with Stripe (the easy way) πŸ’³

At Arbington.com we use Stripe.com to handle all of our payments.

It's secure, fast, and honestly it's a developers dream.

For this, you should be familiar with Ajax/Fetch requests and being able to work with an API. We use Python on the backend, so we use Stripes's Python API.

We will show some demo code, but you'll need to fill in the blanks.

Getting started

First, you'll need a Stripe.com account. It's free to setup, and they give you two sets of API keys:

  1. A test pair of public and private keys
  2. A live pair of public and private keys

The test keys will make payments to your test account, and toggling between testing data and real payment data is as easy as clicking a toggle button in their dashboard.

Two things to note about Stripe:

  1. You need a bank account attached to your Stripe account when you start accepting real data.
  2. You never EVER send credit card numbers or CVV's (the 3 digits on the back) to your server.

How it works

On the frontend (JavaScript) you need to create a token. This token is encrypted and used by your backend so you don't ever need to send credit card information to your server.

Always. use. tokens! Never EVER send a customers raw credit card information to your server. It's unsafe and requires a thing called PCI compliance, which is a headache to obtain and maintain.

The code looks a bit like this:

<script src="https://js.stripe.com/v2/"></script>
<script>
  Stripe.setPublishableKey('your_test_publishable_key');
  const card = {
    name: nameOnCard, // Use JavaScript to get the <input> text value
    number: cardNumber,
    cvc: cardCvc,
    exp_month: cardExpMonth,
    exp_year: cardExpYear,
    address_line1: address1,
    address_line2: address2, // Optional
    address_city: city,
    address_state: state,
    address_country: country,
    currency: 'usd',
    address_zip: postalCode
  }
  Stripe.card.createToken(card, stripeResponseHandler);

  function stripeResponseHandler(status, response) {
    if (response.error) {
      // Problem!
      // Show the error
      alert(response.error.message);
    } else {
      // Token was created!

      // Get the token ID:
      const token = response.id;

      // TODO: Ajax the token to your backend/server
      // Make sure you create a POST request and not a GET request 
    }
  }

And just like that, you're creating a Stripe token for a credit card.

You don't need to save this token because a new token will be created every time you submit the payment form.

Also, on that note, don't actually wrap your html in a <form> because that could be submitted by accident and could share credit card info in a POST or GET request.

Oh, and one more thing you'll need: a JavaScript event listener. I typically tie the eventListener to a button click event, perform some light frontend validation to make sure fields aren't missing and are formatted correctly.

After you've sent the token to your backend/server, you can start to process it.

In this article I'll be using Python because it's the worlds most popular programming language, and we use it at Arbington.com.

Let's tackle that next.

Creating a payment in the backend

As mentioned, we'll be using Python. But Stripe has AMAZING documentation and AMAZING support for multiple languages, including PHP, Python, Ruby, .NET, Java, Go, and Node.js.

Let's take a look at some sample code:

import stripe
stripe.api_key = "sk_test_blah_blah_blah"

# `source` is obtained with Stripe.js this is your "token"
charge = stripe.Charge.create(
  amount=2000,  # Value in pennies, so this is 20.00
  currency="usd",
  source=request.POST.get("token"),
  description="A test token payment of $20.00 USD",
)

Pro tip: Wrap the stripe.Charge.create() method in a try/catch block.

Here's how I typically wrap a charge in Python:

try:
    charge = stripe.Charge.create(
        amount=2000,  # Value in pennies, so this is 20.00
        currency="usd",
        source=request.POST.get("token"),
        description="A test token payment of $20.00 USD",
    )
except stripe.error.CardError as e:
    # Since it's a decline, stripe.error.CardError will be caught
    ...
except stripe.error.InvalidRequestError as e:
    # Invalid parameters were supplied to Stripe's API
    ...
except stripe.error.AuthenticationError as e:
    # Authentication with Stripe's API failed
    # (maybe you changed API keys recently)
    # Log the failed transaction in the users account
    ...
except stripe.error.StripeError as e:
    # Display a very generic error to the user
    ...
except Exception as e:
    # Something else happened, completely unrelated to Stripe
    print(type(e))
    print(e)

If the charge was successful, you'll have a variable called charge (from the code above) and it'll hold A LOT of useful information you can store for later, including an id that always starts with ch_ - this can be used later for issuing refunds.

To see the entire object that Stripe returns, check out the Charge.create object in their docs

What to do next

With the data from the Charge.create object available you can save the charge id that Stripe gives you - save it in your database. This isn't considered sensitive information so you can plop it in your database without worries.

Then in your application, you can check if a user has a recent charge and possibly offer a refund - if your service offers a free trial that is.

Lastly, check your Stripe dashboard (in test mode) to see if the charge came through successfully.

If you create too much test data, you can always delete your test data in your Stripe settings. This will only effect your localhost and has no effect on your real life payments once your application is live.

Going live

Going live is SUPER easy.

If your code works in test mode, it WILL work in live mode. All you need to do it swap out your test publishable key and test private key for your live publishable key and live private key.

Remember: These keys work together. Use both testing keys together, or use both live keys together, but don't mix and match them.

And that's all there is to it.

Subscriptions are a wee bit trickier, but the concept is the same. If you'd like to learn more about how we handle subscriptions or tying a card to a specific user, let me know in the comments below!

Learning JavaScript or Python

Want to learn JavaScript or Python? Great!

Arbington.com offers over 1,500 online courses from industry experts, all for just $15/month. And it comes with a 14 day free trial.

25+ JavaScript courses

Want to learn more JavaScript? That's awesome! At Arbington we have over 25 JavaScript courses to choose from. Check them out here. These are all included in your Arbington subscription - so feel free to take them all for as low as $15/month.

40+ Python courses

Want to learn more Python? That's even more awesome! I personally LOVE Python! And at Arbington we have over 40 Python courses. These are also all included in your monthly subscription.

18