Skip to main content
Version: v1

Post Purchase

Examples

Adina Eden

SIJO Home

Base widget

SDK v1.31.0+ (current)

Replace the following in the example, including the {{ }}

  • apiKey - Your Beam SDK API Key
  • chainId - Your Beam Chain Id
  • storeId - Your Beam Store Id
  • domain - Your website’s top-level domain (eg: “myshop.com”). If your site uses different subdomains between your public storefront and your checkout flow (ie: myshop.com and checkout.myshop.com), this setting allows for storing nonprofit selections between each subdomain.
  • baseUrl Optional unless using credentials for the Beam staging server.
  • hidePostPurchaseWidget - true | false; true means the Beam post purchase widget should be hidden, but will still register transactions, false means that the Beam post purchase widget will show as normal.
  • lang - Beam supports changing the displayed language based on a lang parameter passed into the widgets. If your site supports multiple languages, this Liquid variable value should be updated based on any existing language detection method available in the theme. The supported values for this property can be found in the Beam Supported Languages documentation.
  • beamContainerSelector - This is the parent element that should be targeted to add the Beam widget to. The Beam widget will be added as the last child element in this container.
<script
type="module"
async
crossorigin
src="https://sdk.beamimpact.com/web-sdk/{{ BEAM VERSION }}/dist/components/post-purchase.esm.js"
></script>
<script type="module">
import {
waitForElement,
getCookieValue,
setCookieValue,
events,
createScopedLocalStorage
} from "https://sdk.beamimpact.com/web-sdk/{{ BEAM VERSION }}/dist/integrations/utils.esm.js";
import { init } from "https://sdk.beamimpact.com/web-sdk/{{ BEAM VERSION }}/dist/integrations/beam.esm.js";

// Post Purchase widget settings
const hidePostPurchaseWidget = false;
let beamContainerSelector = ".beam-post-purchase-container";

const beam = await init({
apiKey: "{{ SDK API Key }}",
chainId: {{ Chain Id }},
storeId: {{ Store Id }},
domain: "mystore.com",
// Optional unless using Beam staging server (https://api-staging.beamimpact.com)
baseUrl: "https://api.beamimpact.com",
plugins: [], // Add plugins like Statsig here
});

// Get order details
const orderId = "{{ order_id }}";
const cartTotal = parseFloat("{{ subtotal }}"); // Cart total before tax and shipping
const customerEmail = "{{ email }}"; // customer email
const postalCode = "{{ postal_code }}";
const countryCode = "{{ country_code }}";
const currencyCode = "{{ currency_code }}"; // "CAD" etc.
const orderLevelDiscounts = [{ code: "FREE_SHIPPING", applicable: true }]; // Applicable discount / promo codes at the order-level
// Loop through the line items in the order, and provide the id, SKU, and price
// of each item in the `items` array
const items = order?.items?.map((item) => {
return {
remoteProductIdentifier: item.sku,
localAmount: parseFloat(item.price_in_order_currency),
remoteSubscriptionId: "{{ subscription_id }}" // [Optional] String value of the subscription id of this line item, if it is a subscription
discounts: [{ code: "10OFF", applicable: true }], // [Optional] List of applicable line item level discounts
};
});

const subscriptions = order?.subscriptions?.map((subscription) => {
return {
remoteSubscriptionId: "{{ subscription_id }}",
isNew: true // Set this to false if this is not the first order of the subscription
};
});

let cart = {
schema: { source: "generic" }, // Use the actual string "generic" here
content: { items, discounts: orderLevelDiscounts, subscriptions }
};

let itemLevelDiscountCodes = items.reduce((acc, curr) => {
let lineItemDiscountCodes = curr?.discounts?.map((discount) => {
return discount.title || discount.code;
}) || [];
return acc.concat(lineItemDiscountCodes.filter(discount => discount != null));
}, [])
let orderLevelDiscountCodes = (orderLevelDiscounts || []).map((discount) => discount.code)

const isBeamEmail = customerEmail.includes("@beamimpact.com");

// UTILS -----------------------------------------------------------------
function shouldShowBeam() {
return (!hidePostPurchaseWidget || isBeamEmail);
}
// END UTILS -------------------------------------------------------------

if (!shouldShowBeam()) {
document.head.insertAdjacentHTML(
"beforeend",
`<style>beam-post-purchase { display:none; }</style>`
);
}

await waitForElement(beamContainerSelector);

const widget = document.createElement("beam-post-purchase");

widget.apiKey = beam.apiKey;
widget.storeId = beam.storeId;
widget.orderId = orderId;
widget.email = customerEmail;
widget.cartTotal = cartTotal;
widget.currencyCode = currencyCode;
widget.postalCode = postalCode;
widget.countryCode = countryCode;
widget.cart = cart;
widget.discountCodes = [...orderLevelDiscountCodes, ...itemLevelDiscountCodes],;
widget.lang = "en";
widget.domain = beam.domain;
widget.debug = false;
widget.baseUrl = beam.baseUrl;

beamContainerSelector.appendChild(widget);
</script>

SDK before v1.31.0

  • apiKey - Your Beam API Key

  • chainId - Your Beam Chain Id

  • storeId - Your Beam Store Id

  • storeTopDomain - Your website’s top-level domain (eg: “myshop.com”). If your site uses different subdomains between your public storefront and your checkout flow (ie: myshop.com and checkout.myshop.com), this setting allows for storing nonprofit selections between each subdomain.

  • hidePostPurchaseWidget - true | false; true means the Beam post purchase widget should be hidden, but will still register transactions, false means that the Beam post purchase widget will show as normal.

  • lang - Beam supports changing the displayed language based on a lang parameter passed into the widgets. If your site supports multiple languages, this Liquid variable value should be updated based on any existing language detection method available in the theme. The supported values for this property can be found in the Beam Supported Languages documentation.

  • beamContainerSelector - This is the parent element that should be targeted to add the Beam widget to. The Beam widget will be added as the last child element in this container.

    <script
    type="module"
    async
    crossorigin
    src="https://sdk.beamimpact.com/web-sdk/v1.31.0/dist/components/post-purchase.esm.js"
    ></script>
    <script type="module">
    import {
    waitForElement,
    getCookieValue,
    setCookieValue,
    events,
    createScopedLocalStorage
    } from "https://sdk.beamimpact.com/web-sdk/v1.30.1/dist/integrations/utils.esm.js";

    // Post Purchase widget settings
    const hidePostPurchaseWidget = false;
    let beamContainerSelector = ".beam-post-purchase-container";

    let resolve;
    let reject;

    window.BeamImpact = {
    ...(window.BeamImpact || {}),
    apiKey: "{{ Api Key }}",
    chainId: {{ Chain Id }},
    storeId: {{ Store Id }},
    storeTopDomain: "mystore.com",
    baseUrl: "https://api.beamimpact.com",
    initialized: false,
    awaitable: new Promise((res, rej) => {
    resolve = () => { window.BeamImpact.initialized = true; res(true); };
    reject = (err) => { window.BeamImpact.initialized = false; rej(err); };
    }),
    logEvent: async (eventName, value, metadata = {}) => {
    const eventMetadata = {
    ...(metadata || {})
    };
    console.debug("🚀 Beam event logged", eventName, value, eventMetadata);
    },
    };

    // Get order details
    const orderId = "{{ order_id }}";
    const cartTotal = parseFloat("{{ subtotal }}"); // Cart total before tax and shipping
    const customerEmail = "{{ email }}"; // customer email
    const postalCode = "{{ postal_code }}";
    const countryCode = "{{ country_code }}";
    const currencyCode = "{{ currency_code }}"; // "CAD" etc.
    const discountCodes = ["{{ PROMO10 }}", "{{ CLEARANCE_50 }}"]; // discount / promo codes
    // Loop through the line items in the order, and provide the id, SKU, and price
    // of each item in the `items` array
    const items = order?.items?.map((item) => {
    return {
    remoteProductIdentifier: item.sku,
    localAmount: parseFloat(item.price_in_order_currency)
    };
    });

    let cart = {
    schema: { source: "generic" },
    content: { items }
    };

    const isBeamEmail = customerEmail.includes("@beamimpact.com");

    // UTILS -----------------------------------------------------------------
    function shouldShowBeam() {
    return (!hidePostPurchaseWidget || isBeamEmail);
    }
    // END UTILS -------------------------------------------------------------

    if (!shouldShowBeam()) {
    // Default behavior is to not show the Beam Select Nonprofit widget if it is empty
    document.head.insertAdjacentHTML(
    "beforeend",
    `<style>[data-beam-widget="post-purchase"]{display:none;}beam-post-purchase{display:none;}</style>`
    );
    }

    await waitForElement(beamContainerSelector);

    window.addEventListener(events.BeamNonprofitSelectEvent.eventName, async (event) => {
    const {selectedNonprofitId, selectionId} = event.detail;
    window.BeamImpact.logEvent("beam_selection", true, {
    nonprofitId: selectedNonprofitId,
    widget: 'redeem-transaction',
    selectionId,
    });
    });

    const widget = document.createElement("beam-post-purchase");

    widget.apiKey = window.BeamImpact.apiKey;
    widget.storeId = window.BeamImpact.storeId;
    widget.orderId = orderId;
    widget.email = customerEmail;
    widget.cartTotal = cartTotal;
    widget.currencyCode = currencyCode;
    widget.postalCode = postalCode;
    widget.countryCode = countryCode;
    widget.cart = cart;
    widget.discountCodes = discountCodes;
    widget.lang = "en";
    widget.domain = window.BeamImpact.storeTopDomain;
    widget.debug = false;
    widget.baseUrl = window.BeamImpact.baseUrl;

    beamContainerSelector.appendChild(widget);
    </script>