Vue Storefront is now Alokai! Learn More
Setting up the Modules

Setting up the Modules

The Stripe integration contains two modules that need to be set up and deployed:

  • the extension module is a node application responsible for communicating with Stripe from the level of commercetools platform,
  • the notification module is a node application responsible for receiving webhook calls from Stripe and making changes in commercetools payment object.

Preparing the apps

To be able to deploy the modules, you need to prepare the Dockerfiles for both the extension and notification modules. Creating Dockerfiles is necessary to build the images that will be deployed to the cloud. It's a good practice to use the Docker images provided by us, as they contain all the necessary dependencies. To create the Dockerfiles, follow the steps below.

  1. Create a .vuestorefrontcloud/docker/ct-stripe-extension/Dockerfile file with the following content:
FROM registry.vuestorefront.cloud/vsf-enterprise/commercetools-stripe-integration-extension:3.0.0

ARG INTEGRATION_PORT=8080
ARG INTEGRATION_CONFIG

ENV PORT=$INTEGRATION_PORT
ENV STRIPE_INTEGRATION_CONFIG=$INTEGRATION_CONFIG
  1. Create a .vuestorefrontcloud/docker/ct-stripe-notification/Dockerfile file with the following content:
FROM registry.vuestorefront.cloud/vsf-enterprise/ct-stripe-notification:3.0.0

ARG INTEGRATION_PORT=8081
ARG INTEGRATION_CONFIG

ENV PORT=$INTEGRATION_PORT
ENV STRIPE_INTEGRATION_CONFIG=$INTEGRATION_CONFIG

Now, the modules are ready to be built and deployed.

Make sure your Fusion Auth user has permission to vsf-enterprise namespace (instances array). Otherwise, you will get an HTTP 401 Code.

Continuous Delivery

To build and deploy the modules, you need to:

  1. Add a build_stripe_ct step to your .github/workflows/continuous-delivery.yml file:
name: Deployment

# ...

jobs:
  build-frontend:
    # ...
  build-middleware:
    # ...

+  build_stripe_ct:
+    name: Build Stripe CT
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout code
+        uses: actions/checkout@v3
+      - name: Build
+        uses: vuestorefront/storefront-deployment/build-stripe-ct
+        with:
+          docker_registry_url: ${{ vars.DOCKER_REGISTRY_URL || secrets.DOCKER_REGISTRY_URL }}
+          project_name: ${{ vars.PROJECT_NAME || secrets.PROJECT_NAME }}
+          cloud_username: ${{ vars.CLOUD_USERNAME || secrets.CLOUD_USERNAME }}
+          cloud_password: ${{ secrets.CLOUD_PASSWORD }}
+          extension_module_config: ${{ secrets.STRIPE_EXTENSION_CONFIG }}
+          notification_module_config: ${{ secrets.STRIPE_NOTIFICATION_CONFIG }}

  deploy:
    # ...
  1. Use deploy/stripe-ct action in your deploy step:
name: Deployment

# ...

jobs:
  build-frontend:
    # ...
  build-middleware:
    # ...

  build_stripe_ct:
    # ...

  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    permissions:
      contents: read
      deployments: write
-    needs: [build-frontend, build-middleware]
+    needs: [build-frontend, build-middleware, build_stripe_ct]
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Deploy
-        uses: vuestorefront/storefront-deployment/deploy
+        uses: vuestorefront/storefront-deployment/deploy/stripe-ct
        with:
          console_api_url: ${{ vars.CONSOLE_API_URL || secrets.CONSOLE_API_URL }}
          docker_registry_url: ${{ vars.DOCKER_REGISTRY_URL || secrets.DOCKER_REGISTRY_URL }}
          project_name: ${{ vars.PROJECT_NAME || secrets.PROJECT_NAME }}
          cloud_username: ${{ vars.CLOUD_USERNAME || secrets.CLOUD_USERNAME }}
          cloud_password: ${{ secrets.CLOUD_PASSWORD }}
          cloud_region: ${{ vars.CLOUD_REGION || secrets.CLOUD_REGION }}

Now the CD pipeline is ready to build and deploy the Stripe modules.

The last thing you need to do is to provide the configuration for the extension and notification modules.

Extension module configuration

Environment variables

It's a good practice to setup a Basic authentication for extension module. If you are interested, the process is described in Protecting extension module with basic auth document. It requires changes in this step.

The extension image configured in the previous steps has one mandatory environment variable called STRIPE_EXTENSION_CONFIG. It contains settings as attributes in a JSON structure:

{
  "stripe": {
    "stripeProfile1": {
      "secretKey": "sk_test_xxx"
    }
  },
  "logLevel": 20
}

STRIPE_EXTENSION_CONFIG JSON structure contains different attribute groups as described below:

  • stripe attribute group: Multiple child attributes can be provided in the stripe attribute. Each direct child attribute must representant a Stripe merchant account,
  • authentication attribute group: To setup required Basic authentication,
  • other attribute group: Attributes in this group can be set as direct child attributes in the root of the JSON.

Preparing the credentials

  • For a test environment, create a test account, then use that API Key.
  • For live environments, follow the official Stripe documentation.

Required attributes

GroupNameContent
stripesecretKeyStripe secret key.

Optional attributes

GroupNameContentDefault value
authenticationenabledWhether Basic authentication should be enabled or not.false
authenticationusernameUsername for Basic authentication.undefined
authenticationpasswordPassword for Basic authentication.undefined
otherlogLevelThe log level. Here you can find list of available options."info"

Commercetools project requirements

The resources below are required for the extension module to operate correctly.

Commercetools HTTP API Extension

It's a good practice to setup a Basic authentication for extension module. If you are interested, the process is described in Protecting extension module with basic auth document. It requires changes in this step.

In order to point the commercetools project to the listening extension module:

  1. Open API Playground,
  2. Make sure you've selected your desired project in the select input placed inside the page's header,
  3. Set:
  • Endpoint as Extensions,
  • Command as Create,
  • Payload as:
{
  "key": "ctp-stripe-integration-payment-extension",
  "destination": {
    "type": "HTTP",
    "url": "URL_TO_YOUR_EXTENSION_MODULE_INSTANCE"
  },
  "triggers": [
    {
      "resourceTypeId": "payment",
      "actions": ["Create", "Update"],
      "condition": "paymentMethodInfo is defined AND paymentMethodInfo(paymentInterface is defined) AND paymentMethodInfo(paymentInterface=\"ctp-stripe-integration\")"
    }
  ],
  "timeoutInMs": 10000
}

As destination.url you have to set URL address where Extension module is available.

  1. Click Go!!! button.

Custom payment type

In order to add Stripe payment type to the commercetools project:

  1. Open API Playground,
  2. Make sure you've selected your desired project in the select input placed inside the page's header,
  3. Set:
  • Endpoint as Types,
  • Command as Create,
  • Payload as:
{
  "key": "ctp-stripe-payment-elements-payment-type",
  "name": {
    "en": "commercetools Stripe integration payment custom type based on Payment elements"
  },
  "resourceTypeIds": ["payment"],
  "fieldDefinitions": [
    {
      "name": "stripeProfile",
      "label": {
        "en": "stripeProfile"
      },
      "required": true,
      "type": {
        "name": "String"
      },
      "inputHint": "SingleLine"
    },
    {
      "name": "createPaymentIntentRequest",
      "label": {
        "en": "createPaymentIntentRequest"
      },
      "type": {
        "name": "String"
      },
      "inputHint": "MultiLine",
      "required": true
    },
    {
      "name": "createPaymentIntentResponse",
      "label": {
        "en": "createPaymentIntentResponse"
      },
      "type": {
        "name": "String"
      },
      "inputHint": "MultiLine",
      "required": false
    }
  ]
}
  1. Click Go!!! button.

Notification module configuration

Register a webhook in Stripe dashboard

The Notification module requires you to create a new webhook in the Stripe dashboard and register a webhook endpoint. In order to do that:

  • Click "+ Add endpoint" button.
  • Endpoint URL should match pattern like https://<YOUR_STOREFRONT_URL>/ct-stripe-notification/<YOUR_PROFILE_NAME>.

For example, for the storefront under URL https://storefront-vyhi5b8f.europe-west1.gcp.storefrontcloud.io/ and STRIPE_INTEGRATION_CONFIG containing:

{
  "stripe": {
    "stripeProfile1": {
      "secretKey": "sk_test_***"
    }
  }
}

It would be equal to https://storefront-vyhi5b8f.europe-west1.gcp.storefrontcloud.io/ct-stripe-notification/stripeProfile1.

  • Then select the 2022-11-15 Version since the notification module has been developed using that one (the oldset supported API version is 2020-08-27),
  • Then add new events by clicking "+ Select events" button and select: payment_intent.payment_failed, payment_intent.succeeded, charge.refunded, charge.succeeded.
  • Submit by clicking "Add endpoint" button.
  • Then you are on the created webhook's view - here, find the "Signing secret" column and click "Reveal". A key starting with whsec_ will appear - copy it, as we will need it in the next step.

Environment variables

There is one mandatory environment variable called STRIPE_NOTIFICATION_CONFIG. It contains settings as attributes in a JSON structure:

{
  "commercetools": {
    "commercetoolsProjectKey1": {
      "clientId": "xxx",
      "clientSecret": "xxx",
      "apiHost": "xxx",
      "authHost": "xxx",
      "scopes": ["manage_payments:commercetoolsProjectKey1"]
    },
    "commercetoolsProjectKey2": {
      "clientId": "xxx",
      "clientSecret": "xxx",
      "apiHost": "xxx",
      "authHost": "xxx",
      "scopes": ["manage_payments:commercetoolsProjectKey2"]
    }
  },
  "stripe": {
    "stripeProfile1": {
      "secretKey": "sk_test_xxx",
      "endpointSecret": "whsec_xxx"
    }
  },
  "logLevel": 20,
  "maxRetry": 2
}

STRIPE_NOTIFICATION_CONFIG JSON structure contains different attribute groups as described below:

  • commercetools attribute group: Multiple child attributes can be provided in the commercetools attribute. Each direct child attribute must representant a commercetools project, the module requires only manage_payments scope,
  • stripe attribute group: Multiple child attributes can be provided in the stripe attribute. Each direct child attribute must representant a Stripe merchant account,
  • other attribute group: Attributes in this group can be set as direct child attributes in the root of the JSON.

Preparing the credentials

  • For test environment create a test account, then you will be able to find them here,
  • For live environment follow the official Stripe documentation.

Required attributes

GroupNameContent
commercetoolsclientIdAPI client's clientId
commercetoolsclientSecretAPI client's clientSecret
commercetoolsapiHostAPI host
commercetoolsauthHostAuth host
commercetoolsscopesAPI client's scopes
stripesecretKeyYou'll be making API requests that are authenticated with an Stripe secret key.
stripeendpointSecretIf you are testing your webhook locally with the Stripe CLI you can find the endpoint's secret by running stripe listen. Otherwise, find your endpoint's secret in your webhook settings in the Developer Dashboard. It starts with whsec_ (copied in the previois step)

Optional attributes

GroupNameContentDefault value
otherlogLevelThe log level. Here you can find list of available options."info"
othermaxRetryMaximum amount of retries if commercetools responds with 409 status code2

Local development

If you want to run both modules locally, you can use the Dockerfiles created in the "Getting an extension module" section.

Make sure to provide the required INTEGRATION_CONFIG environment variable.

Extension module

How to point commercetools to extension module that running locally

If you want to use your local extension module during development, we recommend using tunneling software, like ngrok or localtunnel. This will give you an URL with TLS for development purpose.

Make sure to remove pointer to your local instance of extension module from commercetools before you finish development. Otherwise, commercetools won't be able create and update payments as it will wait for the response from URL provided in Commercetools HTTP API Extension step.

Notification module

Main difference when compared to the extension module

The application listens on port 8081 by default. If you would like to change it, see Additional configuration section. It requires providing Stripe profile as a param in the URL. So if you hit http://localhost:8081/stripeProfile1 with the request, then the module will look for the configuration of stripe.stripeProfile1.

Testing locally

We recommend using the Stripe CLI in order to test the notification module locally. Using the CLI, you can forward webhook requests to localhost.

Example usage of Stripe CLI for the notification module listening on localhost:8081, and we want to use stripeProfile1:

stripe listen --forward-to localhost:8081/stripeProfile1

Additional configuration

By default, the name and path for extension and notification modules are set to ct-stripe-extension and ct-stripe-notification, and the port is set to 8080 and 8081.

To change the name and path where the modules are available, you need to:

  1. Add extension_module_name and notification_module_name to build_stripe_ct and deploy steps in your .github/workflows/continuous-delivery.yml file:
name: Deployment

# ...

jobs:
  build-frontend:
    # ...
  build-middleware:
    # ...

  build_stripe_ct:
    name: Build Stripe CT
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Build
        uses: vuestorefront/storefront-deployment/build-stripe-ct
        with:
          docker_registry_url: ${{ vars.DOCKER_REGISTRY_URL || secrets.DOCKER_REGISTRY_URL }}
          project_name: ${{ vars.PROJECT_NAME || secrets.PROJECT_NAME }}
          cloud_username: ${{ vars.CLOUD_USERNAME || secrets.CLOUD_USERNAME }}
          cloud_password: ${{ secrets.CLOUD_PASSWORD }}
+          extension_module_name: ${{ vars.STRIPE_EXTENSION_MODULE_NAME || secrets.STRIPE_EXTENSION_MODULE_NAME }}
          extension_module_config: ${{ secrets.STRIPE_EXTENSION_CONFIG }}
+          notification_module_name: ${{ vars.STRIPE_NOTIFICATION_MODULE_NAME || secrets.STRIPE_NOTIFICATION_MODULE_NAME }}
          notification_module_config: ${{ secrets.STRIPE_NOTIFICATION_CONFIG }}

  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    permissions:
      contents: read
      deployments: write
    needs: [build-frontend, build-middleware, build_stripe_ct]
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Deploy
        uses: vuestorefront/storefront-deployment/deploy/stripe-ct
        with:
          console_api_url: ${{ vars.CONSOLE_API_URL || secrets.CONSOLE_API_URL }}
          docker_registry_url: ${{ vars.DOCKER_REGISTRY_URL || secrets.DOCKER_REGISTRY_URL }}
          project_name: ${{ vars.PROJECT_NAME || secrets.PROJECT_NAME }}
          cloud_username: ${{ vars.CLOUD_USERNAME || secrets.CLOUD_USERNAME }}
          cloud_password: ${{ secrets.CLOUD_PASSWORD }}
          cloud_region: ${{ vars.CLOUD_REGION || secrets.CLOUD_REGION }}
+          extension_module_name: ${{ vars.STRIPE_EXTENSION_MODULE_NAME || secrets.STRIPE_EXTENSION_MODULE_NAME }}
+          notification_module_name: ${{ vars.STRIPE_NOTIFICATION_MODULE_NAME || secrets.STRIPE_NOTIFICATION_MODULE_NAME }}
  1. Rename the directories where the Dockerfiles are located, e.g.: from .vuestorefrontcloud/docker/ct-stripe-extension to .vuestorefrontcloud/docker/your-extension-name. It should be the same as the value of extension_module_name and notification_module_name.

To change the port where the modules are available, you need to add extension_module_port and notification_module_port to build_stripe_ct and deploy steps in your .github/workflows/continuous-delivery.yml file:

name: Deployment

# ...

jobs:
  build-frontend:
    # ...
  build-middleware:
    # ...

  build_stripe_ct:
    name: Build Stripe CT
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3
      - name: Build
        uses: vuestorefront/storefront-deployment/build-stripe-ct
        with:
          docker_registry_url: ${{ vars.DOCKER_REGISTRY_URL || secrets.DOCKER_REGISTRY_URL }}
          project_name: ${{ vars.PROJECT_NAME || secrets.PROJECT_NAME }}
          cloud_username: ${{ vars.CLOUD_USERNAME || secrets.CLOUD_USERNAME }}
          cloud_password: ${{ secrets.CLOUD_PASSWORD }}
+          extension_module_port: ${{ vars.STRIPE_EXTENSION_MODULE_PORT || secrets.STRIPE_EXTENSION_MODULE_PORT }}
          extension_module_config: ${{ secrets.STRIPE_EXTENSION_CONFIG }}
+          notification_module_port: ${{ vars.STRIPE_NOTIFICATION_MODULE_PORT || secrets.STRIPE_NOTIFICATION_MODULE_PORT }}
          notification_module_config: ${{ secrets.STRIPE_NOTIFICATION_CONFIG }}

  deploy:
    name: Deploy
    runs-on: ubuntu-latest
    permissions:
      contents: read
      deployments: write
    needs: [build-frontend, build-middleware, build_stripe_ct]
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Deploy
        uses: vuestorefront/storefront-deployment/deploy/stripe-ct
        with:
          console_api_url: ${{ vars.CONSOLE_API_URL || secrets.CONSOLE_API_URL }}
          docker_registry_url: ${{ vars.DOCKER_REGISTRY_URL || secrets.DOCKER_REGISTRY_URL }}
          project_name: ${{ vars.PROJECT_NAME || secrets.PROJECT_NAME }}
          cloud_username: ${{ vars.CLOUD_USERNAME || secrets.CLOUD_USERNAME }}
          cloud_password: ${{ secrets.CLOUD_PASSWORD }}
          cloud_region: ${{ vars.CLOUD_REGION || secrets.CLOUD_REGION }}
+          extension_module_port: ${{ vars.STRIPE_EXTENSION_MODULE_PORT || secrets.STRIPE_EXTENSION_MODULE_PORT }}
+          notification_module_port: ${{ vars.STRIPE_NOTIFICATION_MODULE_PORT || secrets.STRIPE_NOTIFICATION_MODULE_PORT }}