Integrate the Stripe Online Payments Platform with CrafterCMS

Introduction

Stripe is a robust payment processing platform that can facilitate online payments. Using Stripe, you can quickly establish payment options on your website, process credit card payments, and manage transactions. Some of the salient features of the Stripe platform include support for a comprehensive range of payment methods, such as credit cards, Apple Pay, and Google Pay. By integrating Stripe with CrafterCMS, you can leverage all of these features and more to devise a powerful, flexible payment processing system for your website.

In this tutorial, we will illustrate how to integrate Stripe payment subscriptions with CrafterCMS and develop and install this integration as a plugin in your project. This plugin endows a payment plans page for your website in which you can freely modify its content, encompassing adding or removing payment plans via the Experience Builder. When your website’s users select a plan, they will be redirected to the Stripe payment gateway to subscribe with a credit card.


Prerequisites

Before beginning, make sure you have the following:

  1. Stripe account
  2. CrafterCMS instance (version 4.0.2 or later)
  3. Basic knowledge of CrafterCMS
  4. Basic knowledge of Stripe payment APIs

Getting Started with a Pre-Built Plugin

For convenience, we have developed a plugin that enables you to integrate a Stripe subscription with your CrafterCMS project seamlessly. This plugin is a modified version of stripe-samples/checkout-single-subscription and adapted for CrafterCMS. You can access the full version of this plugin at this link.


  1. Download and install CrafterCMS 4.0.2 or a later version.
  2. Create a new project from Empty Blueprint.



  1. Install the Stripe pre-built plugin


This tutorial will guide you through the steps of installing the plugin using CrafterCMS CLI Commands.


  1. Clone the plugin using Git
git clone https://github.com/phuongnq/craftercms-plugin-stripe

Using CLI commands to copy the plugin

$ cd YOUR_CRAFTERCMS_STUDIO/bin
$ ./crafter-cli add-environment -e local -u http://localhost:8080 --token
Enter value for --token (The access token for authentication):
Environment added
$ ./crafter-cli copy-plugin -e local -s YOUR_PROJECT --path PATH_FOR_PLUGIN_GIT/craftercms-plugin-stripe
OK


In this case, the token is a JWT token created with Token Management Tool.


  1. Once the plugin is successfully installed, please verify that you have the items located in the following paths:
/static-assets/plugins/org/craftercms/plugin/stripe
/templates/plugins/org/craftercms/plugin/stripe
/scripts/classes/plugins/org/craftercms/plugin/stripe

/scripts/controllers/plugins/org/craftercms/plugin/stripe

/scripts/rest/plugins/org/craftercms/plugin/stripe

/config/studio/content-types/page/plugins/org/craftercms/plugin/stripe/stripe_prices




By navigating to the Content Types configuration, you will also discover the Stripe Prices page content type:



  1. For the next step, update the Engine Project Configuration with your Stripe credentials.

In the opening XML editor, please input the following:

<site>
   <version>4.0.1</version>
   <stripe>
     <publishableKey>${enc:CCE-V1#bUhsL6BIy...}</publishableKey>
     <secretKey>${enc:CCE-V1#z48hAv...}</secretKey>
     <webhookSecret>${enc:CCE-V1#sO73Bk...}</webhookSecret>
     <basicPriceId>price_1MiauI...</basicPriceId>
     <proPriceId>price_1MiVkS...m</proPriceId>
     <enterprisePriceId>price_1Miavy...</enterprisePriceId>
     <callbackDomain>http://localhost:8080</callbackDomain>
   </stripe>
</site>

Where:

  • publishableKey: Stripe publishable key
  • secretKey: Stripe secret key
  • webhookSecret (optional): Webhook Secret
  • basicPriceId: basicPrice ID (We can add this later when creating the Stripe price)
  • proPriceId: proPrice ID (We can add this later when creating the Stripe price)
  • enterprisePriceId: enterprisePrice ID (We can add this later when creating the Stripe price)
  • callbackDomain: Callback domain of your application

Values starting with ${enc:...} are encrypted text using CrafterCMS Encryption Tool.


The document from Stripe on how to build a Stripe payment integration is available at this link.

Create a Payment Plan Page

We will proceed with the integration by developing our own payment plans page.


  1. With the Studio left sidebar opening, right-click the Home page and create a new Stripe Prices page.


  1. Input basic form information:
  1. Page URL: /plans
  2. Internal Name: Plans
  3. Nav Label: Plans
  4. Heading: Choose a CrafterCMS plan
  1. Input your designed plans. In this example, we will create 3 plans including basicPrice, proPrice, and enterprisePrice. These are some sample inputs:
  1. basicPrice:
  1. Title: Starter
  2. Thumbnail: /static-assets/plugins/org/craftercms/plugin/stripe/img/starter.png
  3. Price: $12
  4. Price Name: basicPrice (Note: Price name has a determined value to retrieve from server API /scripts/rest/plugins/org/craftercms/plugin/stripe/config.get.groovy)
  5. recurring: month
  1. proPrice:
  1. Title: Professional
  2. Thumbnail: /static-assets/plugins/org/craftercms/plugin/stripe/img/professional.png
  3. Price: $18
  4. Price Name: proPrice (Note: Price name has a determined value to retrieve from server API /scripts/rest/plugins/org/craftercms/plugin/stripe/config.get.groovy)
  5. recurring: month
  1. enterprisePrice:
  1. Title: Enterprise
  2. Thumbnail: /static-assets/plugins/org/craftercms/plugin/stripe/img/enterprise.webp
  3. Price: $250
  4. Price Name: enterprisePrice (Note: Price name has a determined value to retrieve from server API /scripts/rest/plugins/org/craftercms/plugin/stripe/config.get.groovy)
  5. recurring: year


Observe that the recurring attribute has the value of month for basicPrice and proPrice, and the value of year for enterprisePrice.

Upon creating the Plan page, you also have the option to edit it with the Experience Builder.

Use the Stripe CLI to create equivalent products

In the previous section, we developed a plans page. To make this functional, we also need to create the corresponding products in the Stripe system. This can be accomplished via the Stripe Dashboard UI or using the Stripe CLI tool.

In this section, we will employ the Stripe CLI tool. You can refer to this documentation to get started with the Stripe CLI.

  1. Create products

Starter product:

./stripe products create --name="Starter" --description="Starter plan"

Professional product:

./stripe products create --name="Professional" --description="Professional plan"

Enterprise product:

./stripe products create --name="Enterprise" --description="Enterprise plan"
  1. Create prices

Please record the id value for the products you just created as you will require this to create prices. For example:

{
 "id": "price_RANDOM_ID_VALUE"
}

Now you can a create price for the basic product, substituting ID_OF_STARTER_PRODUCT with the appropriate product Id:

./stripe prices create \
 -d "product=ID_OF_STARTER_PRODUCT" \
 -d "unit_amount=1200" \
 -d "currency=usd" \
 -d "recurring[interval]=month"

Next, create a price for the premium product, substituting ID_OF_PROFESSIONAL_PRODUCT with the appropriate product Id:

./stripe prices create \
 -d "product=ID_OF_PROFESSIONAL_PRODUCT" \
 -d "unit_amount=1800" \
 -d "currency=usd" \
 -d "recurring[interval]=month"

Lastly, create a price for the enterprise product, substituting ID_OF_ENTERPRISE_PRODUCT with the appropriate product Id:

./stripe prices create \
 -d "product=ID_OF_ENTERPRISE_PRODUCT" \
 -d "unit_amount=25000" \
 -d "currency=usd" \
 -d "recurring[interval]=year"

With all the prices created,  you can now navigate to Engine Project Configuration to update with these values:



Test Plan Page

When everything is ready, visit http://localhost:8080/plans to test the plan page. When you choose a plan, the browser will redirect you to the Stripe payment page:




To test the payment functionality, you can enter 4242424242424242 as a dummy credit card number. The rest of the details can be arbitrary.


Once the subscription is processed successfully, you will be redirected back to your website with a confirmation page indicating that the payment has been completed.



If you access your Stripe admin dashboard, you should be able to see a new payment record.




Congratulations on your first Stripe subscription!

Inside the Plugin - How it works

In the preceding section, we presented our pre-built Stripe payment plugin and explained how to integrate it with CrafterCMS.

In this section, we will examine the plugin source code in detail to comprehend its structure and its integration with the Stripe APIs.

Stripe Payment Core functionality

Our plugin utilizes Groovy script to implement all Stripe core functionalities with the help of their Stripe Java client library.

The @Grab annotation is used to incorporate the stripe-java library in our Groovy scripts:

@Grapes([
   @Grab(group='com.stripe', module='stripe-java', version='22.10.0', initClass=false)
])

Workflow

Our Stripe Prices page content type employs the template /templates/plugins/org/craftercms/plugin/stripe/index.ftl as the view in the MVC model. When accessing the plans page http://localhost:8080/plans, the index.ftl Freemarker template is utilized to display the plan's content.

Within the template, you can observe that we execute a POST on submitting the form when a user selects a plan:

<form action="/plugins/org/craftercms/plugin/stripe/create-checkout-session" method="POST">
             <input type="hidden" id="${item.priceName_s}" name="priceId">
...

In this case, create-checkout-session is a controller that is located in /scripts/controllers/plugins/org/craftercms/plugin/stripe/create-checkout-session.post.groovy. This controller handles the form submission by using the default form handler:

/scripts/classes/plugins/org/craftercms/plugin/stripe/form/DefaultFormHandler.groovy

def handle(params, request, response, siteConfig, siteItemService) {

SessionCreateParams sessionParams = new SessionCreateParams.Builder()
           .setSuccessUrl(domain + '/plugins/org/craftercms/plugin/stripe/success.ftl?session_id={CHECKOUT_SESSION_ID}')
           .setCancelUrl(domain + '/plugins/org/craftercms/plugin/stripe/canceled.ftl')
           .setMode(SessionCreateParams.Mode.SUBSCRIPTION)
           .addLineItem(new SessionCreateParams.LineItem.Builder()
           .setQuantity(1L)
           .setPrice(params.priceId)
          .build()).build()

try {
     Session session = Session.create(sessionParams)
     response.setStatus(303)
     response.sendRedirect(session.getUrl())
     return ' '
} catch(Exception e) {
     def responseData = [:]
     responseData.message = e.getMessage()
     println responseData
     return '/templates/plugins/org/craftercms/plugin/stripe/500.ftl'
}

In this default form handler, we will create a checkout session to direct the user to the Stripe payment gateway.

Examining the SessionCreateParams in more detail, you can notice that we also provide callback URLs if the payment is completed or when the user cancels the payment:


.setMode(SessionCreateParams.Mode.SUBSCRIPTION)

We also configure the subscription payment mode with the following line:

REST APIs

This plugin also contains 2 supporting REST APIs:


/scripts/rest/plugins/org/craftercms/plugin/stripe/checkout-session.get.groovy

This API retrieves a payment session by its ID and displays it in the succes.ftl page when a payment is completed.

Session session = Session.retrieve(sessionId)

Gson gson = new Gson()

return gson.toJson(session)

/scripts/rest/plugins/org/craftercms/plugin/stripe/config.get.groovy

This API retrieves the publishable key and prices IDs which are used in the client-side script (/static-assets/plugins/org/craftercms/plugin/stripe/js/script.js) to replace price keys with their IDs.

def result = [:]




result.publishableKey = siteConfig.getString('stripe.publishableKey')

result.basicPrice = siteConfig.getString('stripe.basicPriceId')

result.proPrice = siteConfig.getString('stripe.proPriceId')

result.enterprisePrice = siteConfig.getString('stripe.enterprisePriceId')




return result

We also use the siteConfig templating API variable to decrypt our credentials in Site Engine Configurations.


This concludes the plugin source code overview.

Conclusion

This tutorial illustrated the benefits of integrating the Stripe payment platform with CrafterCMS for enhancing the payment options on your website. By adhering to these straightforward steps, you can integrate your CrafterCMS-powered digital experience with  Stripe and begin accepting payments online. Further, with Stripe’s support for a comprehensive range of payment methods and robust fraud detection tools, you can devise a flexible and secure payment processing system for your website.


This tutorial also demonstrates how to construct and deploy plugins in CrafterCMS. A plugin is an add-on that augments the functionality of the content management system.

In this instance, we developed a plugin to integrate Stripe Payments with CrafterCMS, endowing your sites and apps with the payment functionality powered by the headless CMS. The plugin encompasses the requisite API calls and methods for integrating with the Stripe payment gateway, as well as a bespoke UI that is editable with the Experience Builder.


Have questions about CrafterCMS? Join our Slack channel today.