Ordergroove's offers library allows you to display and track subscription optins.
npm install --save @ordergroove/offers
To start local development server you can do
cd packages/offers
npm start
Browse http://localhost:8080
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
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:
- 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>
- 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>
- 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.
- 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"
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.
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
});
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
The library resgisters a global variable, og.offers
, that contains the following helper methods:
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.
import { initialize } from '@ordergroove/offers';
initialize('0e5de2bedc5e11e3a2e4bc764e106cf4', 'staging', '/auth');
og.offers('0e5de2bedc5e11e3a2e4bc764e106cf4', 'staging', '/auth');
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.
import { config } from '@ordergroove/offers';
config({
frequencies: [
{
every: 3,
period: 2
},
{
every: 2,
period: 2
}
],
defaultFrequency: {
every: 2,
period: 2
},
offerType: 'radio'
});
og.offers('0e5de2bedc5e11e3a2e4bc764e106cf4', 'staging', '/auth').config({
frequencies: [
{
every: 3,
period: 2
},
{
every: 2,
period: 2
}
],
defaultFrequency: {
every: 2,
period: 2
},
offerType: 'radio'
});
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.
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'
}
});
og.offers(...)
.config(...)
.setLocale({
....
})
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
import { addOptinChangedCallback } from '@ordergroove/offers';
function onOptinChanged({ productId, components, optedIn }) {}
addOptinChangedCallback(onOptinChanged);
Disables all callback functions registered via addOptinChangedCallback
import { disableOptinChangedCallbacks } from '@ordergroove/offers';
disableOptinChangedCallbacks();
og.offers(...)
.addOptinChangedCallback(() => {})
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.
og.offers.getOptins(productIds);
productIds
optional array of product IDs for which to return the serialized optins. If not supplied in, all optins will be returned.
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
}
}
]
**/
og.offers.clear
clears the optins from the browser's local storage. This method should be called upon successful checkout.
og.offers.clear();
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;
}
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>
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. |
<og-next-upcoming-order format="{{month-long}} {{day}}, {{year-numeric}}"></og-next-upcoming-order>
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
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
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 from="DiscountPercent"></og-incentive-text>
<og-incentive-text from="DiscountPercent" initial></og-incentive-text>
<og-incentive-text from="ShippingDiscountPercent"></og-incentive-text>
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"> |
Supported logical operators
| Or
& And
! Not
() Parentheses
Examples
!inStock
inStock&(!eligible)
regularEligible|upsellEligible
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>
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>
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>
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> |