Purchase access to watch this video.

Unlock course for £159

Already purchased access? Login

Creating a Stripe Checkout session

  1. If we go to the Cashier docs and to the "Creating Subscription" section,
  2. we can see that the example code it expects a payment method ID to be submitted
  3. in order to create a subscription.
  4. This approach expects you to create a payment UI using Stripe's
  5. Elements UI kit
  6. to capture the customer's payment details and tokenize it and then submit it to
  7. an endpoint in our application.
  8. Luckily, however, there's a much easier way to create subscriptions and capture
  9. payments and that's Stripe Checkout.
  10. Stripe Checkout is a checkout page hosted by Stripe.
  11. We can redirect to a checkout page and then listen for webhooks to be notified
  12. when the checkout is completed and the subscription should be activated.
  13. We'll also get a webhook notifying as if the customer has left the checkout or
  14. the session expires, allowing us to clean up subscriptions with incomplete
  15. payments.
  16. We first need a route that will redirect to Stripe Checkout.
  17. I do like to try and keep things as resourceful as possible in my applications.
  18. So in this instance, we're creating a checkout for a subscription here.
  19. So I'm going to create a "SubscriptionCheckoutController".
  20. Open up the file.
  21. And then I'm going to delete every method except the "create" method.
  22. Rather than showing a form, this method will just redirect to Stripe Checkout.
  23. If you go back to the Cashier docs, there's a section for creating checkouts
  24. for subscriptions.
  25. We can copy this code.
  26. Paste it in our new controller action.
  27. And leave the first parameter, the name, as "default".
  28. But we do need to get our pricing plan ID from Stripe to use as the second
  29. parameter.
  30. If you go back to Stripe dashboard, click "Products".
  31. And then click the name of your product.
  32. You should see a pricing plan underneath the "Pricing" heading.
  33. We want the API ID. Click this button to copy its value.
  34. And then back in our controller, we can paste that here.
  35. We also need to type hint the Request object here.
  36. We only want authenticated users to be able to subscribe.
  37. So let's add the "auth" middleware.
  38. Create a constructor for the controller.
  39. And then add the "auth" middleware.
  40. A user will now be required to log in or sign up before they can subscribe.
  41. Finally, let's create a new route pointing to our controller action.
  42. We should also add a name to our default route.
  43. Call it "home".
  44. That's the name of the route Cashier is expecting when redirecting back from
  45. checkout.
  46. Now, if we've go to /subscribe in the browser, we should be
  47. redirected to a Stripe Checkout.
  48. We should also add a name to our default route.
  49. Call it "home".
  50. That's the name of the route Cashier is expecting when redirecting back from
  51. checkout.
  52. Now, if we've go to /subscribe in the browser, we should be
  53. redirected to a Stripe Checkout.
  54. Before we go ahead and test this checkout, we need a set of webhook listening
  55. otherwise our application won't be updated.
  56. For example, if I were to complete this checkout session now, we won't know
  57. because we haven't told Stripe where to deliver webhooks yet.
  58. The very first thing we need to do is open up the VerifyCsrfToken middleware
  59. Just like the Mux webhook, we need to add an exclusion for Stripe.
  60. Back in your Stripe dashboard, go to "Developers", click the "Webhooks" tab, and
  61. ensure you're in test mode.
  62. If you click the "Test in the local environment" button, it will show you that
  63. you can listen to webhooks in a local environment such as ours.
  64. The first step is to download and install the Stripe CLI.
  65. There are instructions on how to install the CLI for Windows, macOS, and Linux.
  66. Once you've installed the CLI, come back.
  67. With the CLI installed and set up on your computer, you can now run the
  68. following command:
  69. stripe listen --forward-to localhost/stripe/webhook
  70. With this command running we'll now see webhook events coming in from Stripe.
  71. For commands like the above, instead of having to remember them each time, I
  72. like to create small scripts that can be executed when I need them.
  73. If you are a macOS or Linux, create a bin/stripe-webhook.sh file at the !#
  74. header, and then copy and paste this command.
  75. And paste it into the file.
  76. Make the file executable.
  77. Now I can now run ./bin/stripe-webhook.sh whenever I need to test something that
  78. relies on a Stripe webhook.
  79. You'll be able to do something similar on Windows with a .bat file.
  80. Now that we're listening for any sent webhooks, we can resume testing create
  81. in subscriptions.
  82. If I hit the subscribe endpoint again, we should be redirected to Stripe Checkout.
  83. As we're in test mode, we can use a test card number 4242 4242 4242 4242.
  84. We can set a future expiry date, and we can use any three digits for the CVC.
  85. Click "Subscribe".
  86. Once the payment is completed, we're redirected back to our application.
  87. If we look in our database in the "subscriptions" table and refresh, we'll see
  88. that we now have a new subscription with a status of "active".
  89. So users can now subscribe, but there's nothing stopping them from hitting the
  90. subscribe endpoint again and erroneously creating another subscription.
  91. Let's prevent users from doing this, so they don't accidentally create multiple
  92. concurrent subscriptions.
  93. In our SubscriptionCheckoutController, at the top of our "create" method, let's
  94. abort the request if the user is already subscribed.
  95. Now, if we go to the subscribe endpoint, if we're already subscribed, we'll get
  96. an error message saying as much.
  97. Right now, our webhook handler is open. This isn't so much of a problem locally
  98. where we can only receive requests if we create a tunnel and expose our
  99. application to the public internet,
  100. but it's definitely something you want to address when you deploy your
  101. application and make it live.
  102. When installing Cashier, you may remember there was a "STRIPE_WEBHOOK_SECRET"
  103. environment variable that we didn't set.
  104. When Stripe sends webhooks to our application, those requests will also include
  105. a signature that an application can verify using this secret,
  106. but it's up to our application to do the checking.
  107. You may have also noticed that when we use the Stripe CLI to forward webhook
  108. events to our local environment, that it gives us a webhook secret key.
  109. We could have used the value of this webhook secret for our Stripe webhook
  110. secret environment variable.
  111. When you do deploy your application to a live environment, you won't be using
  112. to Stripe CLI to forward it webhooks.
  113. Instead, you'll need to add the URL of your webhook handler in the Stripe
  114. dashboard, since you won't be using localhost, but rather an actual domain name.
  115. You'll also need to make sure you use your live mode publishable key and secret
  116. key for your live application.
  117. When you add your webhook URL, you'll also get a signing secret. This is what
  118. you should use as the value of your "STRIPE_WEBHOOK_SECRET" in your live
  119. environment.
  120. Now we're creating subscriptions, accepting payments via Stripe, but also
  121. learned how to listen to webhooks coming from Stripe in both local and live
  122. environments and how to secure those webhook listeners.
Connect GitHub