Skip to content

Chargebee Example

The code below is an example of a process connecting to Chargebee. Chargebee's API doesn't support MODLR's OAuth 2.0 flow, so this is an Advanced Integration - it authenticates with an API key over Basic Auth, and pages through results using Chargebee's next_offset cursor.

INFO

This process requires a Chargebee API key, stored as a Secret and retrieved with security.getSecret rather than hardcoded in the process.

Process Code

js
const CHARGEBEE_SITE = "";        // your Chargebee site name, e.g. "my-company"
const RESOURCE = "customers";     // the Chargebee resource to pull, e.g. "customers", "invoices", "subscriptions"
const PAGE_LIMIT = 100;           // Chargebee returns a maximum of 100 entries per request
const MAX_PAGES = 50;             // safety cap on the number of pages fetched per run
const OFFSET_FIELD = "created_at";

const baseUrl = `https://${CHARGEBEE_SITE}.chargebee.com/api/v2/${RESOURCE}`;

function pre() {
    // This function is called once before the process is executed.
    // Use this to setup prompts.
    script.log('process pre-execution parameters parsed.');
}

function begin() {
    // This function is called once at the start of the process
    script.log('process execution started.');

    // Chargebee uses Basic Auth with the API key as the username and an empty password.
    const authHeader = "Basic " + script.base64(`${security.getSecret("CHARGEBEE_API_KEY")}:`, "utf8");

    let offset = "";
    let page = 0;
    let itemsReturned = PAGE_LIMIT;

    while (itemsReturned == PAGE_LIMIT && page < MAX_PAGES) {
        if (script.IsCancelled()) {
            return;
        }

        page++;
        const url = `${baseUrl}?limit=${PAGE_LIMIT}${offset}`;
        const response = web.get(url, { "Authorization": authHeader });

        if (response.status < 200 || response.status >= 300) {
            script.abort(`Chargebee API request failed with status ${response.status}: ${response.body}`);
            return;
        }

        const body = JSON.parse(response.body);
        const items = body.list || [];
        itemsReturned = items.length;

        console.log(`Page ${page}: ${itemsReturned} items returned`);

        items.forEach(entry => {
            // process each entry here - build dimensions or stage data for the data() cycle
            console.log(entry);
        });

        offset = body.next_offset ? `&${OFFSET_FIELD}>${JSON.parse(body.next_offset)[0]}` : "";
    }
}

function data(record) {
    // This function is called once for each line of data on the second cycle
    // Use this to build dimensions and push data into cubes
}

function end() {
    // This function is called once at the end of the process
    script.log('process execution finished.');
}