This guide describes how to integrate an embedded payment form into your website using the Rebilly Instruments JavaScript library, Rebilly JS SDK, and Express JS.

This guide describes how to configure the payment form to retrieve a customer JWT from a backend endpoint and use the JWT to process payments for both invoices and transactions.

Prerequisites

To complete this guide, you must have: a website ID, an organization ID, a secret API key, a product ID, pricing plan ID, a customer ID, and an order ID.

You must also have a payment gateway configured in your Rebilly account. For sandbox testing, the TestProcessor gateway is pre-configured.

If you already have your IDs and API keys, continue to Step 1: Set up the server. If you do not, create a product and pricing plan, and get your IDs and API key in Set up your environment.

Step 1: Set up the server

Set up an Express node app to authenticate the client.

Declare dependencies

  1. Install the required dependencies in your project directory:

    npm install express rebilly-js-sdk body-parser --save
  2. Declare Express and the Rebilly SDK as dependencies.

Configure the server

Configure an Express.js web server to serve static files and parse JSON requests.

Provide credentials

Add your secret API key, organization ID, and website ID. For more information, see Prerequisites.

Initialize Rebilly JS SDK

Initialize the Rebilly JS SDK with sandbox mode and API key.

Define route for GET requests

Create a route for handling HTTP GET requests to the /checkout endpoint. For more information, see Express example.

Define route for POST requests

Create a route for handling HTTP POST requests to the /authenticate endpoint. This request authenticates the customer. You can use any endpoint. In this example it is called authenticate.

Rebilly passwordless login

In the request body, provide a customerId and set mode: "passwordless" for rebilly.customerAuthentication.login.

Rebilly exchange token

Exchange the login token for a JWT that will be used by the Rebilly Instruments library in the client.

ACL scope data

In the scope object, add your organization ID.

For more information, see Prerequisites.

ACL permissions data

In the permissions array, add operation IDs for all actions used in the Rebilly Instruments library in the client.

ACL customClaims data

In the customClaims object, add your website ID. For more information, see Prerequisites.

You can also add the invoiceId or transactionId in the customClaims object and omit them in the client when mounting the Rebilly Instruments library.

Set endpoint response

Return the JWT token from the token exchange.

Listen for requests

Start an Express server on port 3000 and log message to the console.

Step 3: Set up the client

This step describes how to set up the client using a Content Delivery Network (CDN).

Install the library

Include the Rebilly Instruments library using a CDN:

https://cdn.rebilly.com/instruments/@latest/core.js

Specify mounting controls

The default mounting points are:

  • rebilly-instruments
  • rebilly-instruments-summary

To use custom mounting points, pass a valid CSS class or HTML element to the RebillyInstrument.mount() function.

Step 4: Configure the library

This step describes the basic setup for mounting.

Gather values

Get the customerId from URLSearchParams of the hosting page and send it to the server endpoint to exchange for a customer JWT.

For demonstration purposes, this example uses a hardcoded customerId value in client.js. In a production environment, you must obtain the customerId value from the URLSearchParams of the hosting page.

Mount

Initialize the library and configure the experience. This method returns a promise and accepts a single configuration object.

For more information, see RebillyInstruments.mount().

Provide payment data

Select one of the following:

Process from an invoice

Add the invoiceId value of an invoice you want to process. To create an order, see Prerequisites.

invoiceId: 'an-invoice-id',
jwt: 'token',
Process from a transaction

Add the transactionId value of a transaction you want to process.

transactionId: 'a-transaction-id',
jwt: 'token',

Set the apiMode value as sandbox or live based on your environment. Website and organization IDs are obtained from the JWT token. A JWT is required to process a purchase based on invoiceId or transactionId.

The following purchase data properties are available: items, money, invoiceId, transactionId. For more information, see Purchase data examples.

It is also possible to obtain the invoiceId value from the jwt value. For more information, see Purchase data examples.

Step 4: Optional: Include listeners

Use the instrument-ready and purchase-completed events to connect to the Rebilly Instruments library lifecycle.

instrument-ready

Indicates when an instrument token is created and provides access to the instrument response. RebillyInstruments.on('instrument-ready')

purchase-completed

Indicates when a purchase is completed and provides access to the transaction response.

For more information, see RebillyInstruments.on('purchase-completed').

If you are using a local server, use this listener to view the transaction response in the browser console.

Preview

This is an interactive example of a payment form that uses the Rebilly Instruments library.

Complete the payment flow using this test card number: 4111 1111 1111 1111. Use any future expiration date and any 3 digits for the CVC number. For more test cards, see Test payment cards, IBANs, and ACH details.

const express = require("express");
const bodyParser = require("body-parser");
const RebillyAPI = require("rebilly-js-sdk").default;

const app = express();
const port = 3000;
app.use(express.static("client"));
app.use(express.json());
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: true }));

const REBILLY_API_SECRET_KEY = "REBILLY_API_SECRET_KEY";
const REBILLY_WEBSITE_ID = "REBILLY_WEBSITE_ID";
const REBILLY_ORGANIZATION_ID = "REBILLY_ORGANIZATION_ID";

const rebilly = RebillyAPI({
    sandbox: true,
    organizationId: REBILLY_ORGANIZATION_ID,
    apiKey: REBILLY_API_SECRET_KEY,
});

app.get("/checkout", async (req, res) => {
    res.redirect(301, "/checkout.html");
});

app.post("/authenticate", async function (req, res) {

    const { customerId } = req.body;
    const data = {
        mode: "passwordless",
        customerId,
    };
    const { fields: login } = await rebilly.customerAuthentication.login({
        data,
    });

    const { fields: exchangeToken } = await rebilly.customerAuthentication.exchangeToken({
        token: login.token,
        data: {
            acl: [
                {
                    scope: {
                        organizationId: [REBILLY_ORGANIZATION_ID],
                    },
                    permissions: [
                        "PostToken",
                        "PostDigitalWalletValidation",
                        "StorefrontGetAccount",
                        "StorefrontPatchAccount",
                        "StorefrontPostPayment",
                        "StorefrontGetTransaction",
                        "StorefrontGetPaymentInstrumentCollection",
                        "StorefrontPostPaymentInstrument",
                        "StorefrontGetPaymentInstrument",
                        "StorefrontPatchPaymentInstrument",
                        "StorefrontPostPaymentInstrumentDeactivation",
                        "StorefrontGetWebsite",
                        "StorefrontGetInvoiceCollection",
                        "StorefrontGetInvoice",
                        "StorefrontGetProductCollection",
                        "StorefrontGetProduct",
                        "StorefrontPostReadyToPay",
                        "StorefrontPostPreviewPurchase",
                    ],
                },
            ],
            customClaims: {
                websiteId: REBILLY_WEBSITE_ID,
            },
        },
    });

    res.send({ token: exchangeToken.token });
});

app.listen(port, () => {
    console.log(`Sandbox listening on port ${port}`);
});