Setting up Stripe Payment Elements with MeteorJS and Blaze.js templates

Setting up Stripe Payment Elements with MeteorJS (and BlazeJS template)

For those of us that are still using Blaze.js with Meteor, I find that there are some things that are a little trickier and less documented. 

So when I struggled with implementing Stripe’s new Payment Elements - I wanted to pay forward some of the help that I’ve received by documenting a few of the stickier parts. 

Problems that I faced: 

  • Accessing the “Payment Element” in the when the Form was Submitted 
  • Using the Payment Element’s to end the trial of a Stripe Subscription 

Accessing the Payment Element in the ‘Submit Form’ event

For me, the most difficult part of setting up Stripe’s new Payment Elements was handling the Submit Form event and actually passing the result of the Payment Element to the server for handling the payment (which in this case was ending a Subscription’s trial and initiating the first payment).

My first attempt was to handle the form submission in the common way that I handle all Blaze.js events:

However when trying this approach, I had trouble fetching the Payment Element that was initiated earlier in Template.templateName.onRendered()

I tried setting the Payment Element as a Reactive Variable, fetching it using Stripe.js API, and other doomed approaches -- but nothing seemed to work. 

So the way that I solved this was by attaching an event listener to the form within Template.templateName.onRendered() -- which is where we initially create and mount Stripe’s Payment Element. 

See code example below: 

Using the Payment Element (and Setup Intents) to end the trial of a Stripe Subscription 

The second issue that I kept having trouble with - was transitioning to Setup Intents and Payment Elements. 

Though, I’m sure this was from a lack of doc reading on my part (but let’s be honest, when it comes to Stripe … the docs are endless) - I struggled with understanding how Payment Intents, Setup Intents, Subscriptions, Customers, and confirming payments all interacted with each other. 

Here’s the situation that we were facing at Join It - and if you’re running a SaaS company that bills on Stripe’s subscriptions, then I’m sure you might be running into the same thing. 

  • We create Customers and Subscriptions (on a trial) when folks sign up for our app 
  • The Customers don’t have a payment method attached at the time of Customer or Subscription creation 
  • So we need to collect a Payment Method via Stripe Elements and attach this to the Subscription for Payment

In my case, I struggled because I was using a PaymentIntents instead of SetupIntents to enable this. 

So, here’s the process that I finally figured out: 

  • First, we create the Customer and Subscription objects (we were already doing this before migrating to Stripe Payment Elements)
  • Then, when the template that includes the Stripe Payment Elements is created - Template.templateName.onCreated() - we’ll call to the server to create a SetupIntent (make sure to attach the previously created ‘Customer’ ID)
  • Once that Setup Intent is passed back to the client, the ‘client_secret’ is used with stripe.confirmSetup() - this returns the setup intent that then has a payment_method ID attached to it. 
  • In our case, we then take this payment_method ID and attach it to the Subscription as the ‘default_payment_method’ -- and you’re done! 

Hopefully this article helps some other folks that were struggling with this implementation. 

And if you’re still having an issue, and perhaps I wasn’t clear enough, find me on twitter and I’d be happy to elaborate or clarify!