I’d like to make a few points before you read any further:

  • The topic of this blog post is the Stripe & GoCardless API (Node.js / React)
  • This blog assumes you have intermediate knowledge of JavaScript / React
  • I will be discussing the pros and cons of the API service that each provider offers
  • The specific sub-topic I will be discussing is checkouts and subscriptions
  • This is my opinion after my implementing and using both APIs

Introduction to the APIs

Stripe and GoCardless are payment service providers that offer you a flexible way to manage your customer payments online. If you’re looking for a way to get people to pay you, then both services tout user friendliness and a long history of helping companies and freelancers get paid.

Interestingly, both companies successfully applied to Y-Combinator, regarded as one of the best tech start-up incubators in the world. The likes of Dropbox, AirBnB, CoinBase, WebFlow and plenty of other companies were part of the Y-Combinator programme where they receive mentorship, access to an exclusive network of investors and founders, and business acceleration.

Stripe was founded in Dublin by two Irish brothers, Patrick and John Collison, and GoCardless in London by Hiroki Takeuchi. With the help of the Y-Combinator network, both Stripe and GoCardless received seed round investments of $2M in 2011 and $1.5M in 2012 respectively. (See Crunchbase)

Now, both companies are valued above $100 million. Their growth shows the demand for their services, and that’s partly why I am writing this post, to help you understand how to better utilise their services to help your business grow.

Their APIs provide us as web developers with a streamlined approach to interfacing with their service. For example, they give us the ability to show our website users a payment page where they can either set up a direct debit or simply pay for our products or services. However, that’s where these companies differ slightly.

Stripe lets you set up an online ordering system, take payments, and send receipts. Stripe also lets you set up subscriptions so you can take payments from customers at regular intervals. GoCardless on the other hand, only lets you do the latter – set up monthly direct debits.

What I needed to achieve

My company is offering a monthly subscription service. There are 3 things I needed to achieve, and it’s fundamentally simple:

  1. Users are able to visit our company website and sign up for a monthly subscription
  2. Users are billed automatically every month after their 30-day free trial period ends
  3. Users are automatically sent receipts or invoices, which are also stored on the platform for bookkeeping purposes

I was recommended to use GoCardless, and having set up Direct Debits myself for our business through GoCardless with The Agency Collective and our accountants, I already knew this could be a good solution. I was referred specifically to GoCardless for Xero, which is the integration for our accounting software.

The idea is to automate as much as possible, because more human intervention means less overall added value for our company. Our £35 per month subscription already requires some manual intervention on our side to set things up, so I want to minimise the amount of admin work I have to do when someone signs up, hence the desire for automating invoicing.

What happened with GoCardless

I began implementing the checkout feature for my company’s website and found everything fairly easy to set up with GoCardless. I didn’t really understand where Xero fit into all this. There were three different websites I felt I needed to sign up to when working with GoCardless: GoCardless, GoCardless for Xero, and GoCardless Sandbox for testing.

Already, right from the get-go, I’m a bit confused because I am setting up the API with GoCardless – how does Xero fit into all of this? Do I somehow need to link the Xero API with GoCardless? Do I need to use both APIs?

With GoCardless, the user journey (on the basic plan) for setting up a direct debit is like this:

  1. User submits their details (or doesn’t)
  2. User is redirected to the GoCardless hosted payment page (examples)
  3. User details (if submitted in step 1) are pre-filled on the payment page where the user has to enter their bank details
  4. User enters bank details, clicks ‘Set up Direct Debit’ and is then redirected to a temporary success page
  5. User is further redirected to a final page which could be a confirmation page, thank-you page, or next steps page

We write the code to store the user details to the database, and a customer and subscription are created in the GoCardless platform. We also set the customer and subscription ids to the user in the database for reference. That’s it, the user is then charged on a monthly basis. That’s really all there is to it. No invoicing, it just sets up a Direct Debit for the customer and takes money from them each month.

A closer look at the GoCardless code

  • User submits their details to a form on the front-endBasic Form
  • We then initialise the GoCardless client server-side and create a redirect flow object, passing the created object id and redirect_url back to the frontend

goCardlessController.js

const gocardless = require("gocardless-nodejs");
const Constants = require("gocardless-nodejs/constants");
const User = require("../models/User");
const environments = require("../../env.config");
const { getErrorMessage } = require("../handlers/errorHandlers");
const moment = require("moment");
const client = gocardless(
  process.env.GC_ACCESS_TOKEN,
  Constants.Environments.Sandbox,
  { raiseOnIdempotencyConflict: true }
);

exports.goCardlessFlow = async (req, res, next) => {
  const {
    email,
    company,
    bill_to_address_1,
    bill_to_address_2,
    bill_to_city,
    bill_to_postcode,
    phone,
  } = req.body;

  const redirectFlow = await client.redirectFlows.create({
    description:
      "£35 per month + VAT Direct Debit Mandate",
    session_token: req.sessionID,
    success_redirect_url:
      environments.PUBLIC_URL + `/success-redirect?email=${email}`, // change to https in prod
    prefilled_customer: {
      address_line1: bill_to_address_1,
      address_line2: bill_to_address_2,
      city: bill_to_city,
      company_name: company,
      country_code: "GB",
      email,
      phone_number: phone,
      postal_code: bill_to_postcode,
    },
  });

  return res.json({
    id: redirectFlow.id,
    url: redirectFlow.redirect_url,
  });
};
  • The user submits their details to the GoCardless hosted payment page

GoCardless Hosted Payment Page

  • User is then redirected to the success_redirect_url, a temporary page created with React that fires off another POST request with the redirect_flow_id and email in the body, both of which are taken from query parameters (the redirect_flow_id is automatically appended as a query parameter).

SuccessRedirect.jsx

import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
import Link from "next/link";

const SuccessRedirect = () => {
  const [id, setId] = useState();
  const [getEmail, setEmail] = useState();
  const router = useRouter();
  const { redirect_flow_id, email } = router.query;

  useEffect(() => {
    setId(redirect_flow_id);
    setEmail(decodeURIComponent(email));
  }, [redirect_flow_id]);

  const completeRedirect = () => {
    fetch("http://localhost:3000/api/gocardless/complete", {
      method: "POST",
      headers: {
        Accept: "application/json, text/plain, */*",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ id, getEmail }),
    })
      .then((res) => {
        return res.json();
      })
      .then((res) => {
        if (res) router.push("/thank-you");
      })
      .catch((err) => {
        if (err) router.push("/something-went-wrong");
      });
  };

  id && getEmail ? completeRedirect() : null;

  return (
    <div className="success-redirect">
      <div className="success-redirect__inner">
        <div className="success-redirect__tick">
          <img
            src="/assets/images/icons/success.png"
            className="success-redirect--tick"
          ></img>
        </div>
        <h3 className="success-redirect--title">
          Thank you for signing up with Digital Speed!
        </h3>
        <p className="success-redirect--subtitle">
          Redirecting you now - click{" "}
          <Link href="/thank-you">
            <a>here</a>
          </Link>{" "}
          if this doesn't happen automatically.
        </p>
      </div>
    </div>
  );
};

export default SuccessRedirect;
  • Here’s what that page looks like to users… They will only see it for a few seconds.

Success Redirect Page

  • The final POST request fired off after landing on the placeholder SuccessRedirect.js page above, which runs the following:

goCardlessController.js

exports.completeRedirectFlow = async (req, res, next) => {
  try {
    const { getEmail, id } = req.body; // gets query params that were passed in

    // creates a complete object with the session
    const redirectFlow = await client.redirectFlows.complete(id, {
      session_token: req.sessionID,
    });

    const listResponse = await client.customers.list();
    const customers = listResponse.customers;
    const str = customers.length.toString();
    const subNumb = str.padStart("4", 0);
    // ignore above, simply creates a customer reference number to be stored in the database
    // using moment.js library to create the start date of the subscription (after free trial ends)
    const freeTrialEnds = moment().add(1, "M").format("YYYY-MM-DD");

    const subscription = await client.subscriptions.create({
      amount: "4200",
      currency: "GBP",
      name: "Monthly Subscription",
      interval_unit: "monthly",
      day_of_month: "1",
      start_date: `${freeTrialEnds}`,
      metadata: {
        subscription_ref: `SUB${subNumb}`,
        customer_ref: redirectFlow.links.customer,
      },
      retry_if_possible: true,
      links: {
        mandate: redirectFlow.links.mandate,
      },
    });

    await User.findOneAndUpdate(
      { email: getEmail },
      {
        $set: {
          mandate: redirectFlow.links.mandate,
          customer: redirectFlow.links.customer,
        },
      },
      { new: true, runValidators: true, context: "query" }
    );

    return res.status("200")
  } catch (err) {
    return res.status("400").json({
      error: getErrorMessage(err),
    });
  }
};
  • Finally the user is redirected to the appropriate confirmation page and all the info is stored in the database, subscription and customer is created in GoCardless.

This clearly has nothing to do with Xero, so that GoCardless for Xero ‘integration’ requires some manual intervention – you have to create the customer who signed up in the steps above on Xero’s platform, and then set up a repeating invoice for them… 😒

I decided that this wasn’t the optimal solution for what we wanted to achieve, and I began looking for alternatives. I found Stripe.

What happened with Stripe

A Xero representative explained over the phone alternative ways to get customers to pay us on a monthly basis, and one of those methods was Stripe. She said Stripe and Xero have a partnership in which you can use a feature called ‘Autopay‘ to set up subscriptions on Stripe, take payments and invoice customers from Xero. Initially, I thought this was the perfect solution. I soon found out that in order to receive payments, I still needed to create and send an invoice on the Xero platform.

A short excerpt from the ‘Xero and Stripe’ integration page on Xero’s website states,

To set up, just tick the ‘Offer auto pay’ check box on your repeating invoice templates. When your customers go to pay those invoices, they can opt in to be automatically billed on the same credit card the next time the invoice is due.

So what this means is that we still need to go into Xero, create a repeating invoice, and then find and select ‘Offer auto pay’ – oh, and hope customers accept! I don’t even consider this to be close to the perfect solution. This led me to emailing our accountants, as they suggested Xero in the first place.

I wrote a long email to our accountant asking the following questions…

  1. Does ALL invoicing need to happen in Xero, or could we have a whole new system in place for the subscriptions? As it seems like the Xero with Stripe and GoCardless integrations offer the ability to easily charge people a Direct Debit on a monthly basis, but NOT the ability to automate invoicing.
  2. Do you have any experience with regards to setting up repeating invoicing with Stripe  or GoCardless integrations? And if so…
  3. If I were to handle subscriptions from Xero by setting up repeating invoices for your customer contacts, and select Stripe as the chosen payment service – how would that work? Would customers sign up via the website, then I’d create a repeating invoice? I don’t really understand the customer journey here.

And that’s just part of the lengthy email which I sent. The response I received was:

A very simple answer to this would be, that we don’t need the invoices to exist in Xero if you can have it automated elsewhere. The receipts of money can simply be receipted into Xero as sales and from the bank transaction instead.

This is exactly what I had hoped for. Now I could solely use either GoCardless or Stripe as our company’s payment platform for subscriptions. I found Stripe to be the more appropriate option because they had built-in auto invoicing feature, among other things, whereas GoCardless didn’t.

After researching how I’d go about implementing the Stripe subscription / checkout feature I ended up deleting most of the code I wrote for the GoCardless redirect flow 🙄

It was time for a new approach to taking subscription payments on our website…

Looking at the API that Stripe provides, I gathered that it was a similar flow as GoCardless for creating subscriptions. Here’s the customer journey that I had gathered from the API:

  1. User submits details to a form on our website (or doesn’t)
  2. User is redirected to a payment page hosted by Stripe (example)
  3. User details (if submitted in step 1) are pre-filled on the payment page where the user has to enter their bank details
  4. User fills in their bank details, submits, and is then temporarily redirected to a ‘success’ page
  5. User shortly thereafter is redirected to the final confirmation / thank you page

As you can probably tell, it’s basically the exact same journey as the GoCardless API for creating subscriptions. Except, it’s also very different in terms of what the API offers, because it also offers excellent automation – you can automate invoicing, you can automate emails, you can even enable customers to manage their billing via your website without having to cancel a Direct Debit with their bank. So let’s go into a bit more detail.

A closer look at the Stripe code

  • User submits their details to a form on the frontend of our site. To set up the stripe API for subscriptions, you first need to create a checkout session, and in my case, adding VAT (the Tax Rate object). You’ll note that the success_url property has a {CHECKOUT_SESSION_ID} template variable, which essentially means that this will be auto-populated with an ID (we’ll come to that later).

stripeController.js

const User = require("../models/User");
const stripe = require("stripe")(process.env.STRIPE_SECRET);
const environments = require("../../env.config");
const { getErrorMessage } = require("../handlers/errorHandlers");
const jwt = require("jsonwebtoken");

exports.initialiseSession = async (req, res, next) => {
  const taxRate = await stripe.taxRates.create({
    display_name: "VAT",
    description: "UK VAT",
    percentage: 20,
    inclusive: false,
    active: true,
  });

  const session = await stripe.checkout.sessions.create({
    payment_method_types: ["card"],
    customer_email: req.body.email,
    subscription_data: {
      trial_period_days: 30,
    },
    line_items: [
      {
        price_data: {
          unit_amount: 3500,
          currency: "gbp",
          product: "prod_HKbYi2EnbXAOZ5",
          recurring: {
            interval: "month",
          },
        },
        tax_rates: [taxRate.id],
        quantity: 1,
      },
    ],
    mode: "subscription",
    success_url: `${environments.PUBLIC_URL}/success-redirect?session_id={CHECKOUT_SESSION_ID}`,
    cancel_url: `${environments.PUBLIC_URL}/cancel`,
  });

  res.json({ sessionId: session.id });
};
  • We pass the session.id back to our the frontend because Stripe has its own redirect function method in which it needs to be passed to so it can authenticate the session:

MasterForm.js

import { loadStripe } from "@stripe/stripe-js";
const environments = require("../env.config");
const stripePromise = loadStripe("pk_test_etc");

// this is within a function component
onStripeRedirect = async () => {
    const { sessionId } = await fetch("/api/stripe", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ email: this.state.email }),
    })
      .then((res) => {
        return res.json();
      })
      .catch((err) =>
        this.props.dispatch({
          type: "flash",
          text: err,
          class: "alert-danger",
        })
      );
    const stripe = await stripePromise;
    const { error } = await stripe.redirectToCheckout({ sessionId });

    if (error) {
      this.props.dispatch({
        type: "flash",
        text: error.message,
        class: "alert-danger",
      });
    }
  };
// this is within a function component
  • The user is then redirected to the, quite frankly, beautiful Stripe hosted payment page.

Stripe Hosted Payment Page

  • The users email will be pre-filled here so long as you include the customer_email property with your users email from the request body. The user can clearly see all the relevant information, including tax rate and subtotal to pay for free trials which would be £0. It’s a comprehensively detailed page. So the user enters their bank details, clicks “Start Free Trial” – and is redirected.

  • This page looks exactly the same but, as you can see, it includes less code than when we were using GoCardless because all we’re doing here is pulling the {CHECKOUT_SESSION_ID} (the template variable I mentioned earlier) out from the query parameter.

http://localhost:3000/success-redirect?session_id=SESID2Y3UI3NI...

SuccessRedirect.jsx

import React, { useEffect, useState } from "react";
import { useRouter } from "next/router";
import Link from "next/link";
const environments = require("../env.config");

const SuccessRedirect = () => {
  const [id, setId] = useState();
  const router = useRouter();
  const { session_id } = router.query;

  useEffect(() => {
    setId(session_id);
  }, [session_id]);

  const completeRedirect = () => {
    fetch(`${environments.PUBLIC_URL}/api/stripe/complete`, {
      method: "POST",
      headers: {
        Accept: "application/json, text/plain, */*",
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ id }),
    })
      .then((res) => {
        return res.json();
      })
      .then((res) => {
        if (res) router.push("/thank-you");
      })
      .catch((err) => {
        if (err) router.push("/something-went-wrong");
      });
  };

  id ? completeRedirect() : null;

  return (
    <div className="success-redirect">
      <div className="success-redirect__inner">
        <div className="success-redirect__tick">
          <img
            src="/assets/images/icons/success.png"
            className="success-redirect--tick"
          ></img>
        </div>
        <h3 className="success-redirect--title">
          Thank you for signing up to Facebook Marketplace with Digital Speed!
        </h3>
        <p className="success-redirect--subtitle">
          Redirecting you now - click{" "}
          <Link href="/thank-you">
            <a>here</a>
          </Link>{" "}
          if this doesn't happen automatically.
        </p>
      </div>
    </div>
  );
};

export default SuccessRedirect;
  • We pass the session_id generated in the query string to complete the redirect flow. It’s used to retrieve the session and any customer data that was created so we can store it in the database against the User. I also use moment.js to store the customer number by getting the length of how many customers exists and storing it like so… 0001… 0002… 0003… etc…
exports.completeRedirectFlow = async (req, res, next) => {
  try {
    const session = await stripe.checkout.sessions.retrieve(req.body.id);
    const customers = await stripe.customers.list();
    const str = customers.data.length.toString();
    const customerNumber = str.padStart("4", 0);

    await User.findOneAndUpdate(
      { email: session.customer_email },
      {
        $set: {
          subscription: session.subscription,
          customer: {
            ref: session.customer,
            number: customerNumber,
          },
        },
      },
      { new: true, runValidators: true, context: "query" }
    );

    return res.status("200").json({ message: "Success!" });
  } catch (err) {
    return res.status("400").json({
      error: getErrorMessage(err),
    });
  }
};
  • Finally, the user is redirected to thank-you page

That’s not all

According to the Stripe documentation, you MUST give your users the ability to cancel their subscription (makes sense). This wasn’t clearly stated in the GoCardless documentation, likely because the customer needs to cancel their direct debit by either asking us, or cancelling it via their bank.

Stripe actually offer a hosted page called the ‘Self Serve Portal’ in which customers can manage their billing – I was very impressed. So I checked out how to integrate it.

You need to be able to authenticate users based on their login details, of course, as a form of authentication and identification. I went about implementing Json Web Tokens for authentication (which is outside the scope of this blog post) and storing the user id into Cookies. This way, users can log in to our site, click on ‘manage billing’ in the header, which fires off a POST request, and be sent to a portal where they can view invoices, cancel their subscription or update their payment methods.

So, after coding up the user authentication for our site, enabling users to be able to log in and log out, I set up the redirect flow for managing billing. It was as simple as adding another POST request to the onClick handler on an element in your site header (and also making it only viewable if a user is logged in). This post request runs the following code:

stripeController.js

exports.redirectToSelfServePortal = async (req, res, next) => {
  const { token } = req.cookies;
  const { userId } = jwt.verify(token, process.env.JWT_SECRET);
  const user = await User.findById(userId);

  if (!user) {
    res.status(400).json({ error: "You are not logged in!" });
  }

  const { url } = await stripe.billingPortal.sessions.create({
    customer: user.customer.ref,
    return_url: environments.PUBLIC_URL,
  });

  return res.json(url);
};

Stripe creates a billingPortal session and returns the url to the Self Serve Portal. You need to include the customer reference number (which was stored on the User object in a previous step) and a return_url – where your users will be returned to when they leave the Self Serve Portal. Your POST request element will look something like this:

  <a
  style={{ cursor: "pointer" }}
  onClick={async () => {
    const res = await fetch("/api/stripe/serve", {
      method: "POST",
      headers: {
        Accept: "application/json",
        "Content-Type": "application/json",
      },
    })
      .then((res) => {
        return res.json();
      })
      .then((data) => {
        window.location.href = data;
      })
      .catch((err) => {
        dispatch({
          type: "flash",
          text: err,
          class: "alert-error",
        });
      });
  }}
>
  Manage Billing
</a>

As you can see we’re using window.location.href = data to change the url to the Self Serve Portal that was returned in the previous step. Here’s what the Self Serve Portal looks like:

And there you have it! Stripe also has all the bells and whistles for automating invoicing and customer receipts. Just go to your Stripe dashboard and visit Settings > Subscriptions and emails.

Pros & Cons: a detailed comparison

With COVID-19 looming over all of us right now, it’s the perfect time to get your services online and start getting paid from the comfort of your own home. It’s part of the reason why I wrote this blog post, because I know some developers out there will benefit from it. I’ll go through a final summary of the pros and cons of both API providers. Having gone through the lengthy process of implementing both GoCardless and Stripe as payment gateways for monthly billing, this is my opinion about which provider I think is worth putting the time and effort into.

API ease of use

Both APIs were fairly easy to learn and use. With basic knowledge of JavaScript, it wasn’t difficult understanding the flow of data you needed to achieve when implementing.  5 stars for both!

Stripe 5 vs GoCardless 5 Rating


API documentation

Both website’s documentation is great. There were a few annoyances that I came across. With Stripe, it was simply the fact that they mention the {CHECKOUT_SESSION_ID} is a template variable, but they don’t give you an explanation of what it does, or its purpose. They expect you to know it will auto-generate a session id. I was trying to pass my own ID through, not realising it was generated on the fly by that template variable. Stripe’s docs are really cool though, because they populate the docs with your actual data – ids, customer emails, etc. So it’s really easy to just copy and paste.

GoCardless docs were also very good, but they don’t populate the data like Stripe do.

Stripe 4 vs GoCardless 4 Rating


Payment pages

The clear winner here is Stripe because their hosted checkout page looks way more sleek, has all the necessary information, and displays it in a way that’s professional. They include recognisable payment provider logos such as Visa and MasterCard, displaying credibility and giving the user a sense of security. Everything the customer needs to see is there:

  • the length of the trial and how much it will cost in total each month thereafter
  • it displays the price inclusive of VAT as well as exclusive of VAT, so the user knows exactly what they’ll be paying for
  • it clearly displays the ‘Total due today’ – which is £0 – due to being a free trial
  • it even displays your own brand logo and copies over the favicon too
  • the exact date that the free trial ends and the users card will be charged is displayed
  • And finally, the button for submitting your details says ‘Start trial’

There’s a lot to be said for Stripe’s checkout page… Whereas GoCardless offers Direct Debit Mandate set-ups, which means a lot of this information is disregarded or even irrelevant. Users are simply signing up to a Direct Debit Mandate in which they are giving their consent for you to take money from them. It’s probably best for business-to-business monthly payments, and maybe that’s who it’s targeted at. But the payment page, quite frankly, looks like it could be a scam. If users are redirected there, there’s no branding and it looks like a random form on the internet. Unless you’re familiar with GoCardless, I could see lots of people questioning that form, especially in these troubling COVID times when scamming is at an all-time high.

Stripe 5 vs GoCardless 2 Rating


Costs

For what it’s worth, I think both companies offer low fees for the service they provide. As of the time of writing this blog post, in the UK, GoCardless fees are 1% + £0.20 per transaction with £4 max and Stripe fees are 1.4% + 20p per transaction. GoCardless is the winner here.

Stripe 4 vs GoCardless 5 Rating


Security

Stripe are much more thorough when it comes to making your customers feel safe and secure. In the Stripe settings on your dashboard, you can easily toggle on and off an automatic email to notify customers 7 days before the trial subscription converts to paid. Stripe also offer the Self Serve Portal, which was fairly easy to set up, so that customers can manage and view their billing details – invoices, payment methods, renewal date, etc.

GoCardless on the other hand doesn’t offer any of that, so I can imagine that users wouldn’t feel as secure. It’s okay when you’ve already established trust with a customer, say, when its Business-to-Business Direct Debits, but not otherwise.

Stripe 4 vs GoCardless 3 Rating


Developer appeal

I have to admit, when I heard about Xero integrating with Stripe, I thought ‘Hell yes!’ because they feel like a well-known, well-established company. They’re branding is on point, and you often hear people discussing how good their website’s design and User Experience is.

I know now that GoCardless have been around a while, about the same amount of time as Stripe, but for some reason when I first heard about the Xero and GoCardless integration, I genuinely thought they were quite a new, up-and-coming company.

I think both have developer appeal, but Stripe wins by a small margin on this occasion.


Customer Experience

Stripe have a team of devs or support engineers working around the clock by the looks of it! Head on over to https://webchat.freenode.net/ and type in any username, and the channel ‘#stripe’ – and you’re instantly speaking to a ton of devs – some of the most well-known devs in the JavaScript landscape, in fact. I was quickly able to find a solution to the issue of not being able to display the price properly including tax rates on the checkout page, with the help of a support engineer on that chat.

GoCardless don’t have a live chat feature, so you either have to give them a call or submit a support ticket. Both of which I found to be quite tedious. It’s for this reason that Stripe wins for me on this occasion.


Free Trial

Unfortunately, I found that you’re only able to display as small excerpt of information on the GoCardless hosted checkout page. Whereas with Stripe, it’s clearly displayed on their checkout page that the user is signing up for a free trial, as it states so in several places, by the subtotal to pay right now, as well as the button, and underneath the button where it says the date payments will start. This is a much better experience for our customers.

Stripe 5 vs GoCardless 2 Rating

That pretty much covers everything. I hope this helps some of you in making your decision about how to get paid online. If you have any questions, please feel free to email me at sdktlr@gmail.com. You can also read about why I used Stripe versus GoCardless in this blog post.