@ordergroove/offers

2.42.0 • Public • Published

Get Started

Ordergroove's offers library allows you to display and track subscription optins.

Instalation

  npm install --save @ordergroove/offers

Local Development

To start local development server you can do

  cd packages/offers
  npm start

Browse http://localhost:8080

Merchant specific local development

You need to use http redirector chrome extension. And configure it to redirect staging/prod main.js to localhost:8080.

main.js

Pattern: https?://(staging\.)?static.ordergroove.com/\w+/main.js$
Redirect to: http://localhost:8080/dist/offers.js

soucemap Pattern: https?://(staging.)?static.ordergroove.com/\w+/offers.js.map Redirect to: http://localhost:8080/dist/offers.js.map

Configuration

Add og-offer elements

The offers library registers a custom element, <og-offer></og-offer>, that can be included anywhere on your page. The element has the following attributes:

  1. The product attribute is required and represents the id of the product for which the offer applies. The product attribute can be set either in HTML or via JavaScript.
<og-offer product="123"></og-offer>
  1. The product-components attribute is optional and is used for cases in which a product is comprised of one or more components, such as a bundle or a subscription box. The components attribute must be a an array of component IDs.
<og-offer product="123" product-components='["a","b","c"]'></og-offer>
  1. The first-order-place-date attribute is optional and it allows to set the place date of the first order created during checkout.
<og-offer first-order-place-date="2020-12-24"></og-offer>

Note supported format is YY-MM-DD and needs to be a day in the future. If some of these is missing, will be ignored.

  1. The product-to-subscribe is optional and allows to set an alternative product which the subscription is going to be created with.
<og-offer product="123" product-to-subscribe="678"></og-offer>

Even though offer applies to product "123", the subscription is created with product "678"

Behavior & Functionality

Multiple og-offer elements may exist on a single page. All elements referring to the same product share a state. If you update the state of a given offer referencing a given product, all other offers referencing the same product will also be updated. For example, you can have one offer beside a product description, and another in a cart dropdown, each referencing the same product.

The state of the offer is maintained for all products. If you set the product attribute to a given value, change the state of the offer, change the product attribute to a different value, and finally change the product attribute back to the first value, the prior state of the offer for the first product will be displayed.

The state of opted-in products is stored in local storage, with the key OG_STATE. On page load, the offer element reads from local storage to recreate state for opted-in products. For example, if a user opts in to a product on a given page, offers for that same product will appear as opted in on all other pages.

DOM Events

Event Description common scenarios
og-receive-offer offers is ready to be rendered in the UI Initialize custom UI logic when offer shows up
og-optout-product user has opted out the product
og-optin-product user has opted in the product
og-product-change-frequency user has changed the delivery frequency
og-cart-updated offer in the cart page has been changed Perform side effect such as update the subtotal or total fields
document.addEventListener('og-receive-offer', ev => {
  // ocurs when offers is ready to be rendered in the UI
  // initialize custom UI, style shadow dom
  const offer = ev.target;
});

document.addEventListener('og-optout-product', ev => {
  // perform a side-effect when OPTOUT_PRODUCT action happens
});

document.addEventListener('og-optin-product', ev => {
  // perform a side-effect when OPTIN_PRODUCT action happens
});

document.addEventListener('og-product-change-frequency', ev => {
  // perform a side-effect when PRODUCT_CHANGE_FREQUENCY action happens
});

Features

Default optin by product

The library supports the notion of default optin on a product-by-product basis. If a product is marked as optedin by default, the offer will appear as opted in upon initial load and for as long as the user has not explictly opted out. If a user explicitly opts out, the opt-out selection will be remembered for all offers across all pages for that same product.

If a product is marked as opted in by default and the user has not explicitly opted out, and has added the product to the cart, upon visiting the cart page, the offer will become opted in. The cart page is determined by the location="cart" attribute on the og-offer element. The product will then be included in the response from getProductsForPurchasePost.

<og-offer product="UD729" location="cart" autoship-by-default></og-offer>
  • autoship-by-default attribute is also configurable via product feed

Methods

The library resgisters a global variable, og.offers, that contains the following helper methods:

initialize(merchantId, environment, authUrl);

In order to initilize the library you need to call initialize() method or shortcut in UMD og.offers.

Argument Description
merchantId Your merchant public id
environment staging or production
authUrl The auth url endpoint to resolve customer level auth. Can be json or any response that set-cookie header.

Returns Object as offers module to chain method calls.

Node/Webpack

import { initialize } from '@ordergroove/offers';

initialize('0e5de2bedc5e11e3a2e4bc764e106cf4', 'staging', '/auth');

UMD

og.offers('0e5de2bedc5e11e3a2e4bc764e106cf4', 'staging', '/auth');

config(configObject);

Configures the library options for advance usage or customization.

{
  "type": "object",
  "properties": {
    "frequencies": {
      "title": "Available frequencies",
      "type": "array",
      "items": {
        "$ref": "#/definitions/Frequency"
      },
      "default": [
        {
          "every": 1,
          "period": 2
        },
        {
          "every": 2,
          "period": 2
        },
        {}
      ],
      "uniqueItems": true,
      "minItems": 1,
      "maxItems": 99
    },
    "defaultFrequency": {
      "title": "Default frequency selection",
      "$ref": "#/definitions/Frequency"
    },
    "offerType": {
      "title": "Type",
      "type": "string",
      "enum": ["radio", "toggle", "select"],
      "enumNames": ["Radio Button", "Toggle Button", "Select Dropdown"],
      "default": "radio"
    }
  },
  "required": ["frequencies", "defaultFrequency", "offerType"]
}

Returns Object as offers module to chain method calls.

Node/Webpack

import { config } from '@ordergroove/offers';

config({
  frequencies: [
    {
      every: 3,
      period: 2
    },
    {
      every: 2,
      period: 2
    }
  ],
  defaultFrequency: {
    every: 2,
    period: 2
  },
  offerType: 'radio'
});

UMD

og.offers('0e5de2bedc5e11e3a2e4bc764e106cf4', 'staging', '/auth').config({
  frequencies: [
    {
      every: 3,
      period: 2
    },
    {
      every: 2,
      period: 2
    }
  ],
  defaultFrequency: {
    every: 2,
    period: 2
  },
  offerType: 'radio'
});

setLocale(localeObject);

Configures the library locale text copies

Property Description Default value
defaultFrequencyCopy string Default frequency copy Recommended
offerEveryLabel string Subscribe frequency label Ships Every:
offerOptInLabel string Subscribe option copy Subscribe and get 20% off
offerOptOutLabel string One-time option copy One-time
offerTooltipContent string Tool tip copy Subscribe to this product and have it conveniently delivered to you at the frequency you choose. Promotion subject to change.
offerTooltipTrigger string Tool tip link copy More info
showTooltip boolean Add a tool tip false
frequencyPeriods object defines the frequency period names {1:"days",2:"weeks",3:"months"}

Returns Object as offers module to chain method calls.

Node/Webpack

import { setLocale } from '@ordergroove/offers';

setLocale({
  defaultFrequencyCopy: 'Recommended',
  offerOptInLabel: 'Save Lots and Lots of Money',
  offerEveryLabel: 'Ships Every: ',
  offerOptOutLabel: "Don't save money",
  showTooltip: !0,
  offerTooltipTrigger: 'More info',
  offerTooltipContent:
    'Subscribe to this product and have it conveniently delivered to you at the frequency you choose. Promotion subject to change.',
  upsellButtonLabel: 'Add to upcoming subscription order and receive 20% off',
  upsellButtonContent: 'Add to Next Order on ',
  upsellModalContent:
    'Subscribe to this product and have it conveniently delivered to you at the frequency you choose. Promotion subject to change.',
  upsellModalOptOutLabel: 'Get one-time',
  upsellModalOptInLabel: 'Subscribe and get 10% off on every order',
  upsellModalConfirmLabel: 'Add',
  frequencyPeriods: {
    1: 'days',
    2: 'weeks',
    3: 'months'
  }
});

UMD

og.offers(...)
  .config(...)
  .setLocale({
    ....
  })

addOptinChangedCallback(callbackFn)

Registers a callback function that is invoked when a user either opts in or opts out of a product offer

Callback argument An object containing the properties productId components and optedIn

{
  productId: 'a123',
  components: [ 'a', 'b' ],
  optedIn: true
}

Returns Object as offers module to chain method calls

Node/Webpack

import { addOptinChangedCallback } from '@ordergroove/offers';

function onOptinChanged({ productId, components, optedIn }) {}
addOptinChangedCallback(onOptinChanged);

disableOptinChangedCallbacks()

Disables all callback functions registered via addOptinChangedCallback

Node/Webpack

import { disableOptinChangedCallbacks } from '@ordergroove/offers';

disableOptinChangedCallbacks();

UMD

og.offers(...)
  .addOptinChangedCallback(() => {})

getOptins

og.offers.getOptins returns a serialized representation of the products that have been opted in to by the customer. The return value is in the format expected by Ordergroove's Purchase POST endpoint, which is called during checkout. The parameter, productIds, is an optional array of product IDs for which to return the serialized optins. If the parameter is not supplied in, all optins will be returned.

Syntax

og.offers.getOptins(productIds);

Parameters

productIds optional array of product IDs for which to return the serialized optins. If not supplied in, all optins will be returned.

Examples

var result = og.offers.getOptins();
console.log(result);
/**
[
  {
    product: '123',
    subscription_info: {
      components: []
    },
    tracking_override: {
      offer: 'offerId1',
      every: 2,
      every_period: 1
    }
  },
  {
    product: '456',
    subscription_info: {
      components: ['a', 'b', 'c']
    },
    tracking_override: {
      offer: 'offerId2',
      every: 3,
      every_period: 1
    }
  }
]
**/
var result = og.offers.getOptins(['123']);
console.log(result);
/**
[
  {
    product: '123',
    subscription_info: {
      components: []
    },
    tracking_override: {
      offer: 'offerId1',
      every: 2,
      every_period: 1
    }
  }
]
**/

clear

og.offers.clear clears the optins from the browser's local storage. This method should be called upon successful checkout.

Syntax

og.offers.clear();

Customization (Coming Soon)

CSS

Global styling can be styled by using CSS Variables

* {
  --og-global-font-family: Arial, Helvetica, sans-serif;
  --og-global-font-size: 15px;
  --og-global-font-color: #bd10e0;
  --og-tooltip-font-family: Arial, Helvetica, sans-serif;
  --og-tooltip-font-size: 13px;
  --og-tooltip-background: #ececec;
  --og-tooltip-box-shadow: 2px 2px 6px rgba(0, 0, 0, 0.28);
  --og-tooltip-font-color: #298266;
  --og-checkbox-border-color: #000000;
  --og-upsell-font-family: Arial, Helvetica, sans-serif;
  --og-upsell-font-size: 13px;
  --og-upsell-font-color: #298266;
  --og-upsell-background-color: #7cf8d1;
  --og-modal-button-font-family: inherit;
  --og-modal-button-font-size: 12px;
  --og-modal-button-color: inherit;
  --og-modal-button-background-color: #e6e6e6;
  --og-modal-primary-button-color: inherit;
  --og-modal-primary-button-background-color: #00449e;
}

Slots

The offer element supports customized content via slots.

<og-offer product="123">
  <span slot="opt-out-label">Purchase one time</span>
  <span slot="opt-in-label">Subscribe</span>
</of-offer>

Date Formating

Elements such as <og-next-upcoming-order> supports date formatting by passing format attribute

{{day}} Day of the month as a decimal number (range 01 to 31).
{{day-numeric}} Day of the month as a decimal number (range 1 to 31).
{{day-short}} Abbreviated name of the day of the week.
{{day-long}} Full name of the day of the week.
{{month}} Month as a decimal number (range 01 to 12).
{{month-numeric}} Month as a decimal number (range 1 to 12).
{{month-short}} Abbreviated month name.
{{month-long}} Full month name.
{{year}} Year as a decimal number without a century (range 00 to 99).
{{year-numeric}} Year as a decimal number including the century.

Examples

<og-next-upcoming-order format="{{month-long}} {{day}}, {{year-numeric}}"></og-next-upcoming-order>

API

og-tooltip

Displays a tooltop with some content.

<og-tooltip placement="left">
  <div slot="content">
    <p>Information about your subscription</p>
  </div>
  <span slot="trigger">Hover for more info</span>
</og-tooltip>

Options placement top|bottom|left|right

Css customization

og-tooltip

Suports the following css variables

  • --og-tooltip-family
  • --og-tooltip-size
  • --og-tooltip-color
  • --og-tooltip-background
  • --og-tooltip-box-shadow

The placement attribute can be one of top, top-left, top-right, bottom, bottom-left, bottom-right, right or left

og-incentive-text

Display information from dynamic incentives. By default the component will search for a ongoing discount class. Attribute initial can be specified to force search in initial incentives.

Current keys allowed in from clause are:

  • DiscountAmount Shows discount amount in dollars
  • DiscountPercent Shows discount amount in percent
  • ShippingDiscountPercent Shows whether or not is free shipping

og-incentive-text examples

<og-incentive-text from="DiscountPercent"></og-incentive-text>
<og-incentive-text from="DiscountPercent" initial></og-incentive-text>
<og-incentive-text from="ShippingDiscountPercent"></og-incentive-text>

og-when

Element that renders it children when test condition matches

DESCRIPTOR SUMMARY Example
inStock When the product that offers is linked to is in stock <og-when test="inStock">
eligible If product is configured as eligible for subscription program <og-when test="eligible">
subscriptionEligible Product is eligible for create a subscription. Is true when inStock and eligible are both true. <og-when test="subscriptionEligible">
hasUpsellGroup If product in DB is configure to be eligible for upsell <og-when test="hasUpsellGroup">
hasUpcomingOrder If user is authenticated and has an upcoming order <og-when test="hasUpcomingOrder">
upcomingOrderContainsProduct If the upcoming order contains the product being offered <og-when test="upcomingOrderContainsProduct">
upsellEligible when an offer and product are eligible for upsell and usr has an upcomming order <og-when test="upsellEligible">
regularEligible this is similar to subscriptionEligible but it also checks that is not upsellEligible <og-when test="regularEligible">
prepaidEligible Product is eligible for creating a prepaid subscription. Can be set on rc3 product config <og-when test="prepaidEligible">
prepaidSubscribed If the customer optedIn into a prepaid subscription <og-when test="prepaidSubscribed">
hasPrepaidOptions If prepaid subscription options are available <og-when test="hasPrepaidOptions">

Combine descriptors

Supported logical operators

| Or
& And
! Not
() Parentheses

Examples

!inStock
inStock&(!eligible)
regularEligible|upsellEligible

1. Simple use case: show a regular offer

The folowing code will show and offer only if regular and it will show nothing if upsell

<og-offer product="<some-id">
  <og-when test="regularEligible">
    ... markup ...
  </og-when>
</og-offer>

2. Simple use case: show a regular and upsell offer

The folowing code will show and offer only if regular and it will show nothing if upsell

<og-offer product="<some-id">
  <og-when test="regularEligible">
    ... markup for regular ...
  </og-when>
  <og-when test="upsellEligible">
    ... markup for upsell offer ...
  </og-when>
</og-offer>

3. Advance show same offer for both cases

The folowing code will show and offer only if regular and it will show nothing if upsell

<og-offer product="<some-id">
  <og-when test="regularEligible|upsellEligible">
    ... markup for regular or  upsell offer...
  </og-when>
</og-offer>

og-prepaid-data

Display information from the prepaid plan selected when merchant and product is prepaid eligible.

  <og-prepaid-data total-price></og-prepaid-data>
PROPERTY SUMMARY Example
total-price Total price of the prepaid subscription that will be billed on checkout <og-prepaid-data total-price></og-prepaid-data>
per-delivery-price The price of each product being delivered <og-prepaid-data per-delivery-price></og-prepaid-data>
total-savings Total savings in money ($0.00) format compared with product price <og-prepaid-data total-savings></og-prepaid-data>
per-delivery-savings Savings per product in money ($0.00) format compared with the product price <og-prepaid-data per-delivery-savings></og-prepaid-data>
percentage-savings Percentage of the total being saved when opting-in into a prepaid subscription <og-prepaid-data percentage-savings></og-prepaid-data>
extra-percentage-savings Percentage of what is being saved compared to the pay as you go (normal) subscription <og-prepaid-data extra-percentage-savings></og-prepaid-data>
number-of-shipments Number of shipments that is selected on the prepaid box <og-prepaid-data number-of-shipments></og-prepaid-data>

Readme

Keywords

none

Package Sidebar

Install

npm i @ordergroove/offers

Weekly Downloads

130

Version

2.42.0

License

ISC

Unpacked Size

2.8 MB

Total Files

131

Last publish

Collaborators

  • ogdevs
  • og-jenkins
  • bestnewkevin
  • evasilchenko
  • brian-lewis-5
  • eugenio63
  • nicolasmoise
  • rusoftware
  • federc88
  • agustinog
  • eloycolella
  • manuelog
  • lindyordergroove
  • stephenwidom
  • jchiocchio
  • npnkenacc
  • willycamargo
  • lisandroec
  • swieckowski
  • brandonrichog
  • ericbreno
  • gugaog
  • spossonog