Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
Loading...
The Cart and Checkout flow is most likely right for you if your site:
Will sell a selection of products
Physical or Digital
Where the user can select one or many to purchase at once
Optionally charge for shipping
Optionally offer discounts
Bulk Discounts
Discount Codes
Include tax in prices
Will eventually want to sell the products, but as an extra step will want to send an official quote to the customer for their selection of products.
While building Product and Attribute Layouts, a large range of dynamic data is available- here is a full reference guide.
The "this" object can be accessed on Product detail/item.liquid, list/item.liquid and attribute layout files. It contains the properties of the current Product and contains further relevant objects e.g. Price.
The entire "this" object can be outputted on the page for reference: {{this | json}}
The following fields are available:
Custom Field Set data linked to Products is available in Product detail/item.liquid, list/item.liquid and attribute layout files.
Any Custom Field Sets that have been associated with the product will be stored under: {{this.cfs_data}}
You can output the above liquid in the item.liquid file to see all of Custom Field Sets associated with the Product. Each of these will have the key "cfs_1", "cfs_2" etc. For example, a developer has created just one Custom Field Set to store information about the Guarantee on the Product. The field can be accessed via: {{this.cfs_data.cfs_1.Guarantee}}
See more information about Custom Field Sets here.
The Price object contains all the information you need to display the Product's price in the format you want. It is available in Product detail/item.liquid, list/item.liquid and attribute layout files.
The Inventory object contains the fields related to the current Inventory of this Product. It is available in Product detail/item.liquid, list/item.liquid and attribute layout files.
These are available once Attributes have been added against the Product in Admin and you are inside a detail/item.liquid file or an Attribute layout file.
You can access the Attributes Object via the following liquid output: {{ this.product_attribute_options }}
Inside the Attribute Layout, you can access just the Options for that specific Attribute: {{ product_attribute_options }}
You can also access the name of the Attribute this Layout is currently displaying: {{this_attribute.properties.name}}
As explained in the Attributes Layout Doc, we recommend you loop over the object and access the fields via the "option" liquid variable.
Assuming the above example liquid forloop has been implemented, you can access the fields in the table below. Remember the "option" liquid variable can be renamed, so if you have done this, replace "option" with the name you have given the variable. The Object contains Attribute Options and each of these contains information on the Attribute it is linked with.
Information about how to output information about volume pricing can be found here:
You have Installed the eCommerce Module
The Siteglide Ecommerce Module makes it easy to set up a secure and reliable Shopping Cart and Checkout flow. As usual, you can customise your layouts at every step.
In this tutorial, we will show you how to create the simplest Cart and Checkout flow- the Guest Checkout. Users can buy Products without having to sign in, but their details are stored in the CRM so the Site Owner can send them their Products.
In eCommerce/Settings, select the desired default currency for your Site:
In eCommerce / Products, create at least one product with a price:
Check the "Pricing" tab to add a price.
Users will need to see your products in order to access their Product Detail Pages, or add to their Carts directly. You can use the following code to add a Product List view with the default layout:
To set a Detail Layout, start at eCommerce / Products and click the "View Table" button:
Select the Detail Page Template and Layout:
...and Optionally on your List View!
Make sure your Product Detail pages have an add to Cart Button in their layout’s item.liquid file.
This liquid include tag will add the "Add to Cart" Button:
`
`
`
`
If adding an Add to Cart Button to a List View, make sure that the highest level component in the wrapper.liquid file has the HTML data-attribute added: data-product-list
.
Create a new Page for your Cart and use liquid to include the Cart.
`
`
Note- the Cart does not need to be on it’s own page, but this is the easiest place to start.
If you are using SiteBuilder, or have already added your own CSS for the Cart, we recommend settingremove_default_css: 'false'
Use the layout
parameter to select the folder which contains the wrapper.liquid and the item.liquid file you would like to use for your layout. For now, you can use the "cart" layout which is included in the eCommerce Module.
This will store a paying User against the CRM and submit their payment details securely via your chosen Payment Gateway.
You will need to add the following information when creating your form:
Form Name: e.g. Checkout Form
Redirect URL - This is the relative URL you want a user to be redirected to after submission of payment details e.g. a confirmation page.
In the payments tab, toggle "Use as a payment form?" on
Payment Form Type will appear under the payments tab. Select "Standard Checkout".
Save your changes.
Include the Checkout Layout in your page - use the ID from the CMS / Forms list as the form_id
parameter. If you use the Toolbox to add this code, you can lookup your form by name.
`
`
The layout parameter should refer to the folder which contains your form layout file. This file exists here:
layouts/forms/form_2/default.liquid
For now, you can use the "default" layout that is included with the eCommerce module.
If the page is visited while the user has an empty cart, an alternative "empty" layout will show. The default form layout will automatically add an empty layout at the path:
layouts/modules/module_14/checkout/default/empty.liquid
If you create a custom layout, you should also create an empty.liquid file, renaming the default folder in the filepath above with the name of your form layout.
Users will be added to the CRM in Admin.
You can see the records of transactions in Admin by navigating to the Orders list or finding the User in the CRM.
You've now completed the simplest version of the Cart and Checkout Flow, however there are plenty of improvements you can still make and lots more to learn.
After a User has submitted your Checkout form, an order will be automatically generated. You can see a list of orders under ECOMMERCE/Orders
in the left-hand menu.
Click on the name of the order for more information.
It is more difficult to give "Guest" Users access to their past orders, as you would need to verify that the order belongs to them, potentially manually by asking them to provide some information.
You can add Secure Zones to this flow in the next article, allowing you to easily show the User their past orders when logged in:
As a user buys a Product, the Inventory decreases accordingly.
A User cannot buy a Product if its Inventory is 0, but you can also hide Products that have sold out from the Product List Views.
Similar to WebApp List Layouts, a Product List Layout can allow users to browse Products. It can be filtered and sorted too!
You have created Products in the Admin
This Tutorial will show you how to output a list of Products on your site.
It will cover how to:
Find where Product layouts are stored on Code Editor
Develop a wrapper.liquid file
Develop an item.liquid file
layout
- choose the layout file for this list.
category_ids
- filter the List by these category ids
sort_type
- the field you wish the sort by
sort_order
- 'asc' or 'desc' - the order you wish to sort by.
type
- Should be list
, for a List View layout. This can also be used to display different types of layouts, like a Cart in a different context.
show_pagination
- if pagination should be displayed after the products. Default is 'true'
If you need to refer to the folder structure for where layout files should go, refer to this:
To create a new set of Product layouts- create a new folder bearing the name of your layout, and create within it:
product
name_of_my_layout
list
wrapper.liquid
item.liquid
detail
wrapper.liquid
item.liquid
A list view for products is made up of two parts.
The wrapper contains the code for the main part of the section you are building. For example, the section title or some margin or padding that separates your list from other sections.
In the wrapper.liquid file, it is important to include the liquid file which loops over the Product items:
The item_layout parameter should be the name of a liquid file in the same folder as the current file. Usually this will be "item", but you could have an alternative Layout.
item.liquid -- list view example
This file contains the code for each iteration of the loop that displays the Products. You should expect this code to be rendered multiple times; once for each product displayed in the list. (Hint: Try not to run any GraphQL calls inside a loop or item.liquid file, as they would have an impact on performance. It is better to run these inside the wrapper.)
Output all data available in the "this" object: {{this | json}}
In order to help the JavaScript understand which Quantity and Attribute Control belongs to which Product, we've added a new requirement to Product List Layouts. Please add the following data-attribute on the highest-level HTML element in your item.liquid
file.
In this example, the highest level element in the file is a <div>
element which is wrapped around the rest of the content in the file, but yours could be any element. The important thing is that this element is wrapped around any controls in the File.
For old sites which do upgrade the eCommerce Module, but do not add this data-attribute, we'll add a console log in dev-tools to act as a reminder, but any functionality which worked previously will continue to work.
As with Detail Layouts, you'll need to include the following Liquid and HTML code within the item.liquid
file. It's also now important that these elements lie within the element with the data-product-group
Attribute, when you're building a List Layout. See the section above for details.
The "Add to Cart" Button
For more on developing the Add to Cart Button:
The Quantity Control
This is mandatory, but can be hidden and hard-coded to have a value of 1, if you want to simplify the UI:
Attribute Control
Full Example: Example of an item.liquid
file in a Product Layout which supports Adding to Cart:
Customise the way Products look on their automatically generated Detail Pages and add functionality for adding the Product to the Cart.
You have in the Admin
This Tutorial will show you how to output information about a Product on its automatically-generated Detail Page.
It will cover how to:
Find where Product layouts are stored on Code Editor
Develop a wrapper.liquid file
Include an item.liquid file
Add functionality for a User to add the Product to Cart
In SITE MANAGER/Code Editor
, the folder structure for eCommerce layouts is as below:
layouts
modules
module_14
product
name_of_my_layout
list
wrapper.liquid
item.liquid
detail
wrapper.liquid
item.liquid
product_attributes
my_attribute_layout.liquid
See more:
To create a new set of Product layouts- create your folder at the level of "name_of_my_layout". Inside that, the folders and files should be created as shown above.
As with list views, the detail folder inside your new layout folder should contain a wrapper.liquid and an item.liquid file. Refer to the folder structure at top of the document for reference. You also have the option of creating an attribute layout which can be included inside your item.liquid file to show Product Variations.
wrapper.liquid -- detail view example
This is the file for the main section code e.g. a section title or padding. You will need to use the following liquid to include your item.liquid file inside the wrapper and give it access to information about the Product:
item.liquid -- detail view example
To create a button to add the current Product to the Cart use the following Liquid code
See more:
In order to use the "Add to Cart" Button, you'll also need to have an input element where Users can select the quantity they'd like to add. Make sure it has the correct data-attribute.
We've split the eCommerce Module into the following sections:
All eCommerce features require you to first set up at least one Payment Gateway.
Siteglide offers three main different kinds of eCommerce flow. You can use a combination of these or just one depending on which kinds of products your Site will be selling.
Below we'll give you some common use cases which might point you towards a particular route so you can start reading there:
Most Suitable for:
Allowing the User to decide how much to pay
E.g. Charitable Donations
Paying Invoices or one off payments
Buying Lifetime Access to content stored within one of your Secure Zones
Most suitable for:
Customers Choosing multiple products with a price and then purchasing
E.g. An online shop
Customers Choosing multiple products and requesting a Quote on their list
Most Suitable for:
Storing a Customer's Card in the Payment Gateway with permission to charge it on regular occasions to provide continued access to a product
Taking regular Payments to provide access to a Secure Zone on your site, removing access once the payments are cancelled or stop.
Customise the "Add to Cart" button to keep customers on the Page or redirect them straight to the Checkout Flow with a "Buy Now" button.
This Article assumes you've already:
Added a "cart_add" button to a Layout.
If you've not already done this, you can read the following Articles to learn more:
Although we've had an "Add to Cart" button for a while now, we've recently added the ability to add a custom Layout for this component.
This will allow you to:
Change the style of the button
Change the style of the button when the Product is out of stock
Change the behaviour of JavaScript when adding to the Cart is successful
You can add a Layout to the Cart Add Button by adding a component_layout
parameter to the Liquid:
<div data-gb-custom-block data-tag="include" data-0='ecommerce/cart_add' data-1='custom_layout' data-2='custom_layout'></div>
This feature is backwards compatible, so if you have a Site which does not specify a Layout for these buttons, the default Layout will be chosen automatically- and this will be identical to the style and behaviour you are used to.
We store these Layout files at the following path: layouts/modules/module_14/components/add_to_cart_button/my_custom_layout.liquid
You can either edit the default Layout or create your own by right-clicking on the "my_custom_layout" folder.
Looking at the default layout, you can see that it has some key characteristics you may wish to keep in your new Layout:
Checking if the Product is in stock
Running the JavaScript function
You can use a Liquid If Statement to check if the Product is in stock.
To achieve the functionality of adding a Product to the Cart, you'll need to run a JavaScript function when the button is clicked. The first argument is mandatory- you must pass in the ID of the Product using Liquid: onclick="s_e_cart_add({{this.id}})"
The second argument in the JavaScript function is optional. If you like, you can add in the name of a function you've defined on your Page. This will run instead of the default "alert" message when a Product is successfully added:
As in the example above, you can use this to add a different alert message with a different message. Or you could run any other JavaScript you like instead.
Remember, you also have access to the function: s_e_live_cart_update()
which will return the number of Items now in the Cart. You could incorporate this number into the message.
Some eCommerce Sites require a "Buy Now" button which adds the Product to the Cart and then sends them directly into the Checkout Flow. You can turn your "Add to Cart" button into a "Buy Now" button using customisation options:
has an out-of-the-box Product List design ready for you in a Bootstrap 5 or Tailwind version.
has an out-of-the-box Product Detail design ready for you in a Bootstrap 5 or Tailwind version.
Learn more about Product Detail pages .
This needs to be in the item.liquid file to work, because this will have access to the correct data for this Product. To add a custom Cart Add layout, see the for the correct directory and use the component_layout
parameter to reference it:
Learn more about Cart Layouts
has an out-of-the-box Cart design ready for you in a Bootstrap 5 or Tailwind version.
You can add a form by navigating to CMS/Forms
in the left hand Menu and then clicking the "+ Add New Form" button in the top right of the page. Learn more about forms here: .
If you are using the PayPal Payment Gateway, you will need to carry out an .
has an out-of-the-box Checkout Form Layout design ready for you in a Bootstrap 5 or Tailwind version.
Remember, you will need to use the test cards from your chosen Payment Gateway. Find more information
use_search
- See
As it is inside the loop, the item.liquid file has access to the "this" object and dynamic information specific to an individual product. A full reference for the fields you can use can be found or you may find it convenient to output the "this" object on the page you are developing:
As this code can be complex, so please refer to the doc for further information, or take a look at the full example below.
Unlike the List View, the code in the item.liquid file in the Detail folder will only be displayed once instead of looped. Inside the item.liquid
file, you'll have access to the "this" object, which contains the fields you'll need. See for available fields or output {{this | json}}
in the item.liquid file to see the exact data available to you.
Field Name
Liquid Tag
Description
Item Name
{{this.name}}
The Product's name
Item Slug
{{this.slug}}
The part of the URL for this Product's Detail Page which refers directly to this Product
Creation Date
{{this.create_date}}
The date the Product was created in Admin
Last Edit Date
{{this.last_edit_date}}
The date this Product was last edited in Admin
Release Date
{{this.release_date}}
The date this Product is scheduled for release, or was first released on the Site. (A Product will not appear in the list if it has not been released.)
Expiry Date
{{this.expiry_date}}
The date this Product will be no longer visible on the Site. (A Product will not appear in the list if it has expired.)
Enabled
{{this.enabled}}
A "true" or "false" boolean value. If "false", the Product will not appear in the list.
Category Array
{{this.category_array}}
An array of ids of categories associated with this Product.
Description
{{this.Description}}
A description of the Product.
Image
{{this.Image}}
This is the main image for the Product, but more can be added with Custom Field Sets.
Field Name
Liquid Tag
Description
Price ID
{{this.price.id}}
The unique ID of this Product's price.
Product ID
{{this.price.product_id}}
The unique ID of the Product this Price belongs to.
Currency
{{this.price.currency}}
The currency code for the currency used by this Product e.g. "GBP".
Price Charge
{{this.price.price_charge}}
The price of the Product as an integer e.g. for the price "£200.00" this field will display "20000"
Display Price
{{this.price.price_display}}
If the optional field Display Price was filled out when the Product was created, this will show that price as an integer, else, it will output null. This could be for example the RRP or price before tax.
Currency Symbol
{{this.price.currency_symbol}}
The HTML entity for the currency symbol. e.g. "£" outputted on the page will display "£" when HTML is rendered.
Price Display Formatted
{{this.price.price_display_formatted}}
If the optional field Display Price was filled out when the Product was created, this will show that price as an decimal number, else, it will output null. This could be for example the RRP or price before tax.
Price Charge Formatted
{{this.price.original_price_charge_formatted}}
This is the price that will be charged to the user, formatted into dollars and cents.
Price Charge Before Tax Formatted
{{this.price.price_charge_before_tax_formatted}}
This is the price before any tax is applied, formatted into dollars and cents.
Field Name
Liquid Tag
Description
Inventory ID
{{this.inventory.id}}
The unique ID of the object containing the Product's Inventory.
Enabled
{{this.inventory.enabled}}
A "true" or "false" boolean, defaults to true.
Product ID
{{this.inventory.product_id}}
The unique ID of the Product this Inventory Object belongs to.
Quantity
{{this.inventory.quantity}}
The number of products in the inventory.
Inventory Type
{{this.inventory.inventory_type}}
The type of Inventory. Currently, only "Global" is available.
Display Type
{{this.inventory.display_type}}
This stores the policy on what to do when the Inventory reaches zero. Either the Product can not be ordered, or it should be hidden from view.
Field Name
Liquid Tag
Description
Attribute Option ID
{{ option.id }}
The unique ID of this Attribute Option
Attribute Option Name
{{ option.name }}
The name of this Attribute Option
Attribute Option Chargable Price
{{ option.price_charge }}
Chargable price for this Attribute Option
Attribute Option Chargable Price Formatted
{{ option.price_charge_formatted }}
Formatted chargable price for this Attribute Option
Attribute Option Display Price
{{ option.price_display }}
Display price for this Attribute Option
Attribute Option Display Price Formatted
{{ option.price_display_formatted }}
Formatted display price for this Attribute Option
Attribute Option Image
{{ option.image}}
The image for this Attribute Option
Attribute ID
{{ option.product_attribute.id }}
The Unique ID of this Attribute
Attribute Name
{{ option.product_attribute.name }}
The Name of the Attribute e.g. Size or Colour
Attribute
{{ option.product_attribute.product_id }}
The Unique Product ID that this Attribute is associated with.
Shipping Options let customers choose how fast they'd like eCommerce Products delivered and prices are added onto the price at Checkout.
Shipping Options let customers choose how fast they'd like eCommerce Products delivered and prices are added onto the price at Checkout.
Here's what it does:
Admin Users can add and remove Shipping Options e.g. "Free Delivery", "Premium"
You can output the Shipping Options in your Cart with their own sub-layout
Once chosen, the Shipping Option will be saved alongside the customer's Cart and the price of shipping will be added to the total price displayed.
When an Order is made, the customer will pay for the price of Shipping and the option chosen will be displayed against their Order in the Admin.
You can add, edit and remove Shipping Options in the Admin. Go to ECOMMERCE/Shipping Options in the left-hand menu.
The Options are designed to be included in an HTML Select box in the Cart.
You'll need to add the following Liquid where in your Cart you want to include your Shipping sub-layout: <div data-gb-custom-block data-tag="include" data-0='ecommerce/shipping_option' data-1='siteglide_example'></div>
The only parameter you'll need to include is your Layout.
You won't need to do anything else to implement this feature. Any options selected by the customer will have their prices added to the price total in Checkout.
Include your Custom Layout alongside my_layout:
layouts
modules
module_14 (eCommerce)
shipping_option
siteglide_example.liquid
my_layout.liquid
Here's an example:
Some key points to note from the example:
You'll need to put the onchange
attribute on the HTML Select element itself and use the Siteglide function.
You'll need to loop over the shipping_options array we've created for you to build your HTML Option elements.
You can use a Liquid if statement to mark an option as the Shipping Option currently selected by the User: `
`
Wondering how to adjust the Product Detail Page based on Category?
As a User navigates to your Product Detail Page, Siteglide will load the Detail View you have specified in your eCommerce Settings. However, it is perfectly possible to customise this based on Categories, using Liquid logic! You can read more about using Categories on the Layout of the WebApp or Module Item they belong to here.
In this example, you'd need to know the ID of a category you want to display; this can be found in Admin when you select a category. E.g. let's say we want to display something special when something has the category "Featured" and you know it has an ID of "111111":
This Article will look in detail at the JavaScript function which updates the Product price as the customer selects Attributes.
Your eCommerce Module should be updated to version 1.0.5 to get the latest version of this feature described by this Article. Earlier versions of the Module will have limited support for this feature on Product List views.
You have created Attributes on some of your Products and included an Attributes sub-Layout nested inside your Product Layout.
On the Product List and Detail Views you can provide customers with an option to select Product Attributes- changing features like "size" or "colour", depending on the Product.
This Article will look in detail at the JavaScript function which achieves this and adjusts the displayed Price of the Product appropriately.
A note on security: the prices we are working with in this topic are cosmetic only. There's no need to worry about malicious users "choosing their own prices" at this stage, as prices will be calculated afresh securely on the server if and when an Order is created.
This function will update the currently displayed price of a Product to take into account any selected Attributes.
To optionally set the initial prices to be displayed on:
Product Detail View
Product List View (support added in eCommerce version 1.0.5)
To update the prices to be displayed on:
Product Detail View
Product List View (support added in eCommerce version 1.0.5)
To display the initial price of a Products on the Product List, or Detail View, on Page Load, you can run the function within the following Event Listener. No arguments are required.
To watch an Attribute for change, add the listener: onchange="s_e_update_price()"
to the <select>
element in your chosen Attributes Layout:
The JavaScript looks for data in the HTML attributes in order to make its calculations. In the usage notes below we'll detail everything you need to provide for this function to do it's work.
The purpose of this function is to dynamically update the displayed Price, but the choice of where this should be within the Layout is up to you.
To mark an element within the item.liquid
file as being the element which will receive the dynamic price as its text content when calculated, add the following HTML attributes:
data-price-control
data-currency-control
The value of these Attributes should be set using Liquid to the Product's initial price and currency:
In this example above- we also add the initial Price to the text content of the element using Liquid on Page Load. Instead, you can run the function on Page Load to display the initial price, should you choose.
In order to add the prices of Attributes to the base price- you'll need to define the prices against the <option>
element that contains a selectable Attribute Option: data-attribute-price-control="{{option.price.raw}}"
For example:
item.liquid
fileIf you're using this function on the Product List View, you'll need to carry out additional steps to define the container for each Product. This helps the JavaScript to smoothly identify relationships between Products, their Prices and their Attributes.
The HTML attribute data-product-group
should be added to the highest level HTML element in your Product Layout item.liquid
file. Which type of tag this element is doesn't matter- the important thing is that all Prices and Attributes related to this Product are nested inside this element.
If you do not add this Attribute- the JavaScript will treat the Product List like a Detail view- and you may experience unexpected behaviour like all prices changing at once.
This function is useful for updating the displayed price of a Product when new Attribute Options are selected- or removed- by the User / Customer.
Product Attribute Layouts allow you to customise the way that you present users with a choice of which variation of a Product they want.
Product Attribute Layouts allow you to customise the way that you present users with a choice of which variation of a Product they want.
You have created Products in the Admin
You have created a Product Detail View
This Tutorial will show you how to use Attributes to let Users pick Variants on the Product's automatically-generated Detail Page.
It will cover how to:
Find where Product layouts are stored on Code Editor
Develop a my_attribute_layout.liquid file
Allow the User to select Attribute Options before adding to Cart
In SITE MANAGER/Code Editor
, the folder structure for product attributes layouts is as below:
See a more complete Cart & Checkout Folder Structure here:
To create a new set of Product layouts- create your folder at the level of "name_of_my_layout". Inside that, the folders and files should be created as shown above.
If you are making a layout where you know exactly which Attribute a Product has, you can include an Attribute layout to display an Attribute with a given name: detail/item.liquid
(including a single Attribute)
If your Products have multiple Attributes, or you want to write code which can dynamically display any Attribute given to the Product, you can use liquid to loop over all Attributes. We've recently updated this example to be much simpler and easier to use.
Loop over all Attribute Options
Check if the Attribute is enabled
If so, include the relevant Attribute layout, dynamically filling in the "name" parameter.
detail/item.liquid
-- (looping over all Attributes linked to this Product)
There is no need to create a wrapper file for Attributes, as they are already included inside an item.liquid file. Your Attribute layout can be given a name of your choice. Different Attributes for the same Product may use different Attribute layouts, e.g. "Colour" may include colour swatches.
You can output the name of the Attribute that the current Layout displays: {{this_attribute.properties.name}}
The following liquid outputs an array of the options that have been created for this Attribute: {{product_attribute_options}}
You can loop over this array with the following liquid code, (where the example has the variable "option", you could choose any variable name):
To get the full benefits of Attribute functionality, including the user's choice of Attribute affecting what is added to the Cart, the data-attributes and function calls in the example should be included:
As you can see in the example, inside the loop it is possible to access the specific Attribute Option in this iteration via the "option" variable you created when setting up the loop, but you can also still access the "this" object specific to the Detail Layout that wraps around and includes the Attribute Layout. See the Product Layout Liquid Reference to see the fields available in the "this" object and those specific to Attributes and Attribute Options.
This Article explains how to output a Discount Codes Layout in either Basic Payment Form, Cart, Checkout or Subscription Layouts
Discount Codes allow your Client to provide special offers to their customers.
You can learn how to set up Discount Codes in the Admin here.
The role of a Discount Code Layout is to give the customer an opportunity to enter and apply a Discount Code on your Site. Additionally, once a code is applied, the Layout will give the customer information about how their code has been applied along with any terms and conditions, and the opportunity to remove the code.
This Article will explain how you can include a Discount Codes Layout in either your:
Cart wrapper.liquid file
Checkout Form Layout (Discount Code Layouts for the Cart and Checkout will have the same syntax).
Basic Payment Form Layout - This will have slightly different syntax due to the unique properties of Basic Payment Forms, but we'll cover this below.
Subscription Form Layout - This will have slightly special considerations because the discount has the potential to be applied to all invoices for a specified number of months. It's also possible to use Subscription Discount Codes to take 100% off the price giving a free trial.
Once a customer uses the button in the Layout to successfully add a Discount Code, this will be stored in their session alongside any Cart Data. We'll store one code at a time for each payment type, with Basic Payment Forms storing their codes in {{context.session.basic_payment_discount}}
, Cart saving its codes in {{context.session.cart_discount}}
and Subscriptions saving their codes in {{context.session.subscription_discount}}
.
When a customer completes a Payment Form, the Server-side checks will apply the code and reduce the amount they are charged. This means your Site will be secure and safe against malicious users choosing their own discounts.
The screenshot below shows how the Discount Code Layout can be nested inside the Cart. However, step 1 also applies in all kinds of Layout.
The following Liquid will add the Layout:
The only parameter you'll need will be layout
which refers to the file name of the Layout. We'll look at where to create the Layout files in Step 2.
In order to better support adding Discount Code Layouts on Forms, we've added the option to reload just the Layout, instead of the whole Page. The main benefit of this is that Users will not have to refill their form data after adding a Discount Code. We'll discuss this more in Step 3) b)
For now, you can add the data-attribute data-s-e-refresh-layout-discount-code
to the element which serves as a wrapper for your Layout e.g.
In a Cart Layout, you may also wish to set prices to automatically update when the discount code is added.
You can add the following data-attributes:
data-s-e-live-cart-currency
- the element will be filled dynamically with the Cart currency when the Layout refreshes
data-s-e-live-cart-total
- the element will be filled dynamically with the updated Cart Total Price.
e.g.
A Discount Code Layout will typically contain:
An input field for the customer to enter a discount code
A button which allows them to submit the code
A button which allows them to remove a code (if perhaps the code is no longer valid and blocking payment).
Feedback to the user regarding successful and unsuccessful attempts to apply their discount code.
Essential HTML, JavaScript and Liquid which controls functionality
Discount Code Layouts will be stored here, inside: layouts/modules/module_14/discount_code
You'll just need a single Liquid file with the same name as your Layout. Optionally, you can use folders to organise Layouts of different types.
If you haven't already, make sure your layout parameter in the Liquid tag matches the name of your Layout File. Any custom folders like 'cart/' should also be added to the layout parameter path.
As there are subtle differences in implementation depending on the type of payment, we've created three different default layouts to help you get started:
"basic_payment/default"
"cart/default"
"subscription/default"
For steps 3 and onwards, you may find it easier to copy and edit the code from the default Layout, but we'll break this down into steps here so you can see all the elements you'll need.
HTML Attributes Explained:
{{discount\_code}}" or
| If a code is already successfully added, it will be autofilled. or Any successful code is autofilled and the current field value is readonly until removed in step b) | One of these |
When adding the 'Apply' button, you can customise how the JavaScript will behave on successful and unsuccessful attempts to add a Discount.
In the examples below, we'll show the basic options recommended for different types of Layout, then explain the full range of options you have for JavaScript behaviour.
Note
We recommend hiding the apply button after the Subscription Order has been created and the Discount Code has been redeemed. See Subscription Specific Instructions.
At this stage, you have a choice about whether you'd like the whole Page to reload after a successful Discount Code is added, or whether you'd like to only reload the Discount Code Layout itself.
We'd strongly recommend that for Layouts on Forms that you set reload: false
as this will prevent the User having to re-enter their Form data, and will preserve any custom amount chosen on the Basic Payment Form.
Note also that the value of spend
will be different for Basic Payment Forms:
Basic Payment Forms store the spend
value in document.querySelector('#s_e_amount').value
- as this can be dynamically changed by JavaScript, there is no Liquid value for it.
Cart and Checkout Forms can use the Liquid value: '{{context.exports.cart_base_price.data | json}}'
Subscriptions store the spend in {{spend}}
'{{context.exports.cart_base_price.data | json}}'
'{{spend}}' | Required - no default | Basic Payment Forms use spend: document.querySelector('#s_e_amount').value - as this can be dynamically changed by JavaScript, there is no Liquid value for it. Cart and Checkout Forms can use the Liquid value:spend: '{{context.exports.cart_base_price.data | json}}' | | reload: * true
false | default: true | Setting true will refresh the entire Page. Setting false will refresh the Discount Code Layout only. We'd strongly recommend that for Layouts on Forms that you set reload: false as this will prevent the User having to re-enter their Form data, and will preserve any custom amount chosen on the Basic Payment Form. If you select false
, you must add the data-attribute data-s-e-refresh-layout-discount-code to the element which wraps around the Layout see Step 1) b) | | error_cb: * custom JavaScript function name (don't call the function yet!) error_cb: myErrorFunction | default: * A JavaScript alert message will display the error. | For arguments and how to customise your own function, head to step 6. | | success_cb: * custom JavaScript function name (don't call the function yet!) success_cb: mySuccessFunction | default: * Depending on the reload option, will reload the Page or Layout
If reload is false and the Payment Type is Checkout, will update the total Price by running the s_e_cart_update_prices(); | For arguments and how to customise your own function, head to step 7. |
You can optionally add a button to the Layout which will allow the customer to remove a Discount Code that has already been applied.
The Liquid IF statement helps make sure the button is only displayed if there is a code present to be removed.
The JavaScript function will make the button functional.
false | default: true | Setting true will refresh the entire Page. Setting false will refresh the Discount Code Layout only. We'd strongly recommend that for Layouts on Forms that you set reload: false as this will prevent the User having to re-enter their Form data, and will preserve any custom amount chosen on the Basic Payment Form. If you select false, you must add the data-attribute data-s-e-refresh-layout-discount-code to the element which wraps around the Layout see Step 1) b) ---------------------------------------------------------------------------------------------------------------------------------------------------------- | | success_cb: | Default: Depending on how you set the refresh setting, will refresh the Page or the Layout. | For arguments and how to customise your own function, head to step 8. |
Why is this helpful? Although we check Discount Codes are valid when they are added, there are cases where the code is no longer valid by the time the customer reaches the Checkout, for example:
The User may have adjusted the quantity of items in the Cart, causing the spending amount to drop lower than the minimum payment allowed by the Discount Code.
The Code may have been close to expiry.
Adding a "remove" button gives the User a clear way to solve any problems stopping them from completing their purchase.
Note
You cannot remove a Subscription Discount Code after the Subscription Order has been created and the Discount redeemed. See Subscription Specific Instructions.
On Page refresh (or if you've chosen reload: false
on Layout refresh), after a successful Code is applied, the following Liquid will explain the minimum spend needed and the discount available.
Depending on where your Layout is, different syntax may be needed to fetch the currency to display.
On Subscription Layouts it is important to know whether or not the Subscription Order has been created, if it has, then the Discount will already be redeemed. The difference in display needs to account for the fact that a redeemed discount is time-limited.
For both situations, we can use the fields inside the discount variable to access details on the Discount.
*Before the Subscription Order is Created *At this stage, we can use general details of the discount which is applied, but not yet redeemed, from the this
object.
*After the Subscription Order is Created and the Discount Redeemed *At this stage, we can use details of the actual discount code stored against the Subscription Order. As this is time limited, we may also wish to give details of how much longer the Discount will be active for and the specific Subscription Order will provide these details.
The following code can be used to display the minimum spend needed to keep using the discount:
The following code can be used to display the minimum spend needed to keep using the discount:
It's probably only really necessary to display the minimum spend before the Subscription Order is created and the Discount redeemed. Once the discount is redeemed, the amount spent will be fixed.
This code will display a message if the minimum spend is not set strictly enough and the resulting payment total is below that allowed by the Payment Gateway.
discount_saving_maximum_reached
will always return false for Subscriptions and these allow any size of Discount (controlled only by the Partner and Client setting Minimum Spend values on each Discount Code in the Admin.) Therefore, it's not necessary to add this code to a Discount Code Layout for a Subscription.
Read more about the Discount Maximum requirement
discount_code
is a variable which contains the Discount Code successfully applied after page refresh
discount_minimum
is a variable which contains the minimum spend needed for this Discount Code to be valid.
discount_amount
is a variable which stores the calculated saving on the current Cart value.
{{context.exports.cart_currency.data}}
will output the currency symbol on Cart and Checkout Layouts
`
` will output the currency symbol on Basic Payment Layouts
`
You can use this Liquid tag to format any Liquid price variable with the correct decimalisation. To use, set the
price_data` parameter to the variable you wish to format.
discount_saving_maximum_reached
- if true
, the Minimum Amount for the Discount Code has not been set strictly enough and the total Payment Due is below that allowed by the Payment Gateway. You can use this to display a warning message that it has not been possible to apply the full discount.
For Subscriptions, your Layout will inherit the variables of the Layouts it's nested within- meaning it will inherit variables from the Subscription Detail Page, then the Subscription Form. See details of these objects here. e.g. {{this.price.currency_symbol}}
There are lots of reasons why the customer may enter a code but be refused a discount. For example, the code may have expired, or the Cart's value may not be above the minimum spend.
You can start with the JavaScript function below and make your own changes to decide how these errors are displayed to the customer:
As the comments in the example mention, each error returned from a failed discount code will give both a code and a default message. You can choose which one you will use.
Here are the full list:
If you want to change the message, you can use logic to display different messages using the error code:
Once you've created your function, use the error_cb
option in step 3) b) and pass it your function name. e.g. error_cb: myErrorFunction
Setting reload
to either true
or false
in the s_e_cart_discount_code
function will both effectively refresh your Discount Code Layout and the Liquid will update with new values, so most use-cases will not need a custom success function. However, if you do need to make changes, you can use the function below as a starting point:
Once you've created your function, use the success_cb
option in step 3) b) and pass it your function name. e.g. success_cb: mySuccessFunction
Setting reload
to either true
or false
in the s_e_cart_discount_code
function will both effectively refresh your Discount Code Layout and the Liquid will update with new values, so most use-cases will not need a custom success function. However, if you do need to make changes, you can use the function below as a starting point:
Once you've created your function, use the success_cb
option in step 3) b) and pass it your function name. e.g. success_cb: mySuccessFunction
Note
We recommend for Subscriptions to add some logic checking whether a Subscription Order has already been created and if so, to hide the apply button. This is because once the Subscription Order is created- any Discount Code already applied will be redeemed.
At this point it's not possible to apply or change the Discount Code, only display details of the Order that's active. The purpose of the Form at this point is actually to allow Users to edit their payment details only.
You could add this logic around the whole Layout (as in the default Layout), or just around individual components. For the sake of clarity, in the "subscription/default" Layout, we've opted to wrap the logic around the whole Layout, creating two distinctly separate blocks of Liquid for before and after redemption.
You can also add the statement to check if the Discount will apply to the next invoice or if the Discounted period of months is over.
eCommerce - Discount Codes - Adding and editing Discount Codes in the Siteglide Admin
Use the s_e_cart_inventory_check function to check the stock levels of items in the Cart and take appropriate action before Checkout.
To give the customer the best experience and avoid disappointment, you'll want to make them aware of any problems with their Order as soon as possible.
Using the s_e_cart_inventory_check
function in the Cart Layout, you can check each row in the current Cart to check that the required quantity is available. Items will remain in the Cart, but a warning message will display.
The function will also check for any Products which have been been disabled, expired or have a selected Attribute which has been disabled. These products will be automatically removed from the Cart and a warning message will be displayed to explain this.
One way to use this function is as immediate feedback when the User loads the Page or adjusts quantity in their Cart. Alternatively, you can run the function on the "Checkout" button press, to run a final check and redirect the User to the Checkout if successful.
In order for the JavaScript to read the up-to-date quantities in the Cart, you'll need to add the following attributes to your Layouts:
In the item.liquid
file of your Cart Layout, add data-s-e-cart-id="{{this.cart_data.cart_id}}"
to the highest level element.
In the item.liquid
file of your Cart Layout, check that the <input>
element containing the up to date quantity for this row has the name
attribute with the value quantity
. e.g. <input name="quantity">
Add the s_e_cart_inventory_check({})
function - we'll document which Event Listeners and arguments can be used later in this Article.
A common starting point would be to add the function to a button on a click event e.g.
If any Products in the Cart are no longer 'enabled' or have been deleted- or if the Product is enabled, but one of the selected Attributes is not, we'll automatically remove these rows from the Cart when the function is run.
Adding the following data-attribute to an element will display a message explaining this when it happens: data-s-e-cart-has-removed-products
Meanwhile you can use the following Liquid to fetch the same message. This is useful if the Page is refreshed after running the function and you wish to keep the message up:
You can clear the message from the session when you believe the User has had a chance to read it and it will no longer be relevant. (In most cases, you'd display this straight after the Liquid version of the message). We'll clear this automatically if the function is run again without removing any products. `
`
We'll explain how you can customize the message itself later in the function options.
The function loops over every row in the Cart, and checks the desired Quantity against available Inventory.
Any disabled, expired or deleted Products are removed from the Cart. So are any Products whose selected Attributes have been disabled or deleted.
An item callback function is then run to handle each remaining row of the Cart, carrying out a different behaviour whether that Item is in stock or not.
If every Item in the Cart is in stock, a success callback function will be run, which may for example optionally redirect the User to the Checkout Page.
As Attributes do not currently have their own Inventory tracking, the function will share out available inventory between all Items in the Cart with the same Product ID.
This means the quantities of each variation of the Product in the Cart will be added up- and if the total is greater than the Global Inventory, all of the rows with this Product ID will return as "out of stock".
Note that where two rows in the Cart list the same Product with different Attributes, the inventory will be shared between them.
The s_e_cart_inventory_check
function accepts a single argument containing a settings object. For example:
The table below details the available settings. Leave the setting undefined
or remove the setting from the object if you desire to keep default behaviour:
checkout_url
Passing a checkout_url
option to the function allows the function to redirect the Page to the Checkout if the inventory check is successful.
If you use a custom success function, this will be available in your parameters. Else, the default success function will use this to redirect the Page.
Default Behaviour Leaving checkout_url
undefined means the default Success Function will not redirect to the Checkout.
This option allows you to define a custom callback function which runs against each row in the Cart, telling you whether the Item is in stock or not.
The main function will loop over every row of Items in the Cart. For each Item, the default error function will be run.
Available Parameters
***Default Behaviour ***For all items:
The "max" attribute of the quantity <input>
will be adjusted to match the available inventory.
If the item in the row is out of stock:
The class .s-e-cart-out-of-stock
is added to the row element with the data-attribute data-s-e-cart-id
The following HTML will be added as a sibling element to the quantity
If the Item in the row is in stock:
The class .s-e-cart-out-of-stock
is removed from the row element with the data-attribute data-s-e-cart-id
Previous error message elements with the class 's-e-cart-inventory-warning'
in this row will be removed.
The success_cb
function runs only if all Cart rows contain a lower quantity than the available inventory, in other words, it runs if all items remaining in the Cart are in stock.
Available Parameters
Default Behaviour
Any .s-e-cart-out-of-stock
classes will be removed from all Cart rows
Previous error message elements with the class 's-e-cart-inventory-warning'
in all rows will be removed.
If a value for checkout_url
is available, the Page will be redirected to the Checkout. Otherwise, it will not refresh the Page.
This can be useful so that as soon as the User arrives at the Cart they can be updated on whether items are in stock. In this example, we don't want to refresh the Page on success because the User has just arrived on the Cart Page and will need time to review:
***Example ***To be added to the wrapper.liquid file:
***Example ***To be added to the item.liquid file:
This is useful if the Customer has clicked the "Checkout" button and you wish to run a final Inventory check first. Here we make use of the checkout_url
option and the default Success function:
***Example: ***To be added to the wrapper.liquid file:
How to customise the Shopping Cart Layout
You have completed How to Create a Shopping Cart and Guest Checkout
Cart layouts are stored in the following structure:
See the full Cart & Checkout folder structure here:
The wrapper.liquid file should contain the code for the main section of code that wraps around the loop of Products in the Cart. It should include the following liquid to insert the loop of Products:
<button onclick="s_e_cart_empty(true)">Empty Cart</button>
Of course, this is just an ordinary link. It will need updating with the slug of your Checkout Page: <a href="/checkout>Proceed to checkout</a>
The following reference shows how to output useful data about your Cart as a whole:
If you have added Product Attributes to the Products in the Siteglide Admin, you can also access the cart_product_attributes
with the following liquid: {{ context.exports.cart_product_attributes }}
Normally though, Attributes will be handled in the next step- the item.liquid file.
The cart layout will iterate in a loop, outputting the item.liquid file for each line in the customer's cart.
cart_id
Each line in the cart has a cart_id
accessible at {{this.cart_data.cart_id}}.
When modifying the cart with JS, this cart_id
will be needed.
Multiple lines in the cart may refer to the same product if a different combination of attributes is selected.
Building the Cart's item.liquid file is similar to building an item.liquid layout file for a Product List View. Learn more about the available fields here.
There are some additional points to bear in mind when creating a cart layout's item.liquid file:
The s_e_cart_remove
function can be used to remove a line from the cart.
If the cart has several lines containing the same product, but with different attributes, only the targeted line and its attributes will be removed.
In this example, the function is called when a button is clicked and Liquid is used to pass the cart ID into the function:
You can optionally pass in a callback function to the third argument to be called after the row has been removed from the cart. In order for this to work, you need to set reload
(the first argument) to false
.
See the full Article on updating Product quantities here.
Note that, after updating this input field, the User will also have to click the "Update Cart" button. Following the link above will lead to a more detailed article.
In order to make sure Users do not increase the quantity of items in their Cart, when the Product is out of stock, you could add a "max" attribute to the quantity input:
Items added to a Cart in Siteglide are not reserved. It is possible for two or more customers to add the last product in stock to their cart at once.
How to use Module Custom Fields to output similar, related products
Your eCommerce Module is updated to at least version 1.2.0
You have already created eCommerce Products and outputted them in List or Detail Layouts on the Site
Module Custom Fields allow a wide range of use cases for connecting up different areas of your Site. In this Article we'll look at how you can create a new Custom Field for your eCommerce products to store similar, related Products which could be displayed on the Product's Detail Page.
You could of course use this same technique with the Blog Module or any other Module or WebApp.
To add a Custom Field to Products, first select Edit Module Structure from the Products List in Admin.
At the bottom of the available fields, you can find the Custom Fields section, and press the "Add new field" button.
The name of your field can be whatever you want, here we'll call it Related Products. The Datasource Multi type prompts us to choose a Module or WebApp that we will be able to select Items from.
When you're ready, press save and your new Custom Field will be set up. You'll then be able to use this field when creating and editing Products.
In this example, we'll edit the new Custom Field on an existing Product to create a relationship with another Product. From the Product Edit Page, select the Custom Fields tab:
As we used the Datasource Multi field type and selected Products as the Module to be linked to, Siteglide knows what we're trying to do and will help us find the related Items.
Select as many as you need. Each Product's unique ID will be stored in array format in your Custom Field.
When you're ready, save the Product.
For the next steps (3 - 6), we'll be navigating to Code Editor to develop custom Layouts to display the Related Products Front End. We'll start by working in the "item.liquid" file of the Layout you're using for the Product Detail View. We'll nest a new List of Related Products inside this Detail Layout.
Inside the item.liquid file, we can access the Custom Field by name:
It is sometimes more reliable to access a field by its ID, in case the name is changed in future. E.g. {{this.properties.module_field_custom_14/product_1}}
This outputs an array of the IDs of each of the related Products stored against our current Product. It should look something like this: ["55","75","147"]
In Step 5, we'll need to nest a new List Layout of Products inside the Detail Layout and filter this by the IDs of our Related Products. However, the IDs are currently in an Array format and the include
Liquid tag's item_ids
parameter expects a comma separated String.
We can change the type by assigning a new variable:
Next, we need to output a Product List, nested within our existing Product Detail Layout.
Item Ids Parameter
Without the item_ids
parameter, our List outputs only the first few Products alphabetically, instead of fetching our dynamic Related Products.
We can change that by adding the item_ids
parameter and feeding in our comma-separated String of IDs (that we stored in a new Liquid variable):item_ids: related_products
Datasource Parameter
datasource: 'true'
When you output an include inside a Detail Layout, by default Siteglide will try to fetch a Detail Layout. This is one reason why it's important to set the datasource: 'true'
parameter, which will then cause Siteglide to look for a List type Layout.
Another benefit of the datasource: 'true'
parameter is that if no Related Product IDs are available, the List will return empty, instead of returning an unfiltered List. This prevents the List from showing unrelated Products in this situation.
Per Page Parameter
per_page: '3'
In the example, the per_page has been set to 3. In some cases, you may wish to limit the number of "related" results in this way, so they don't distract from the main subject of the Page. It is completely optional.
Layout Parameter Select the name of a Product List Layout you'll use to style how the dynamic Related Products List will look (see Step 7).
Optionally, you can add Liquid logic to only display the subtitle and Related Products content when the field is not empty. As the field contains an array, a safe way to check if it holds a value is to check its size (Liquid for the length of the array).
You can style and write Liquid for the Related Products List Layout in the same way you do for any Product List. For example, you could provide a link to the Detail Pages of those Related Products using the Slug property.
You've now completed the Step by Step guide for adding Related Products.
Mostly Checkout Form Layouts are developed in the same way as , with a few differences included below:
This liquid include used to output payment fields in a checkout form.
You should include this in the layout file for a checkout form at the position in the layout where you would expect the card payment elements to appear.
Outputting 1 payment gateway option
This will output the Payment Gateway that you most recently updated in Siteglide Admin.
Outputting multiple payment gateway options
This will output the Payment Gateway with the ID you select. When outputting by ID, you should select which is the default option.
When using Stripe as your Payment Gateway, the default payment method option is locked to 'Card Only' (type: 'card_only'
).
Alternatively you can show other payment method options such as Klarna or Apple Pay. You can control exactly which options show by configuring them in your Stripe Dashboard here -> https://dashboard.stripe.com/settings/payment_methods Then you need to update your code to include the 'type' parameter with a value of 'payment' as follows:
Once you've added multiple Payment Gateways to your form using the include above, you can add JavaScript to switch between them on the client side:
Help customers find regular purchases and favourite products with the reorder button.
Help customers find regular purchases and favourite products with the reorder button. The button can be added to a Layout or any other Layout where you have access to an Order ID.
For this reorder feature to work, the User:
Must be logged in
Must have been logged in when they originally made the Order
The feature fetches all Products from that Order and adds those that are still available to the Cart. This gives the User a chance to review and adjust quantities before Checkout.
A message can also be displayed to the User to detail any Products from that previous Order which are no longer available. Though, this is only possible where an Order still exists in the database and has not been deleted.
The following Liquid will output the reorder button:<div data-gb-custom-block data-tag="include" data-0='ecommerce/reorder_button' data-1='default' data-2='default'></div>
Parameters:
layout
order_id
The button can be added in any Liquid Layout, but you'll need to have access to the ID for an Order belonging to that User- which is most easily available in the Layout or the Layout (note that a User can't be logged in when reading an email, so this feature will not work from an Order Details Layout in an email).
In the User Orders Layout, the exact Liquid for the ID will depend on the variable you've set in the loop. In the following example, the variable assigned to each iteration of the loop is this. so the Order ID is available inside the loop as this.id.
The button will only work if the User is logged in, so you may wish to add the following logic to an Order Details Layout to make sure the User is logged in before displaying:
Adding the button will load a small button layout. You can find the default Layout or create a custom Layout at the following path: layouts/modules/module_14/components/reorder_button/my_layout_name.liquid
***Adding the function ***The styling of the button is completely up to you. To carry out its main functionality, the button requires an event to be attached to it which will run a JavaScript function:
The function takes a single argument containing an options object. The available arguments are as follows:
***Adding a Custom Error Function ***The Custom Error function will be called in the following circumstances (the table also shows the value of the "error" parameter passed back when this occurs):
Parameters returned:
error
- see above
reorder_unavailable_products
- an object containing all Products which could not be added to the Cart from the Order. Looping over this object can allow you to display the ID and/or name of these Products. Expiry dates are also provided, where they exist, for context.
The default error behaviour is to display an "alert" containing the error message.
***Adding a Custom Success Function ***If you add a Custom Success Function, you must add a Custom Error Function.
The custom success function will run if an Order was successfully found and at least one Product was successfully added to the Cart. Not all Products related to the Order may have been available.
Parameters returned:
cart_url
- The URL of the Cart that you passed into the function originally.
reorder_unavailable_products
- An Object containing the Products which are no longer available and couldn't be added to the Cart.
reorder_added
- an integer representing the number of unique products with either a different Product ID or the same Product ID but different Attributes, that were successfully added to Cart. The number ignores the actual quantity of each product added and is more useful as a measure of successfully added rows.
The default success behaviour is to re-direct the Page to the Cart URL.
You can choose whether to display a message about the unsuccessful items before that, using JavaScript or display that information via Liquid when the User arrives at the Cart.
Successfully added Products are automatically added to the User's Cart. When they arrive at their Cart Page- they can review the quantities and Check Out when ready.
The following Liquid tags can be used to either confirm the Order ID which has been added to the Cart, or present a detailed breakdown of the Products which were not successfully added; this is an alternative to showing this information in the Custom Success Function.
| By looping over the unavailable Products and accessing the \[0] index, you can access their key: - the Product ID. | "123" | || By looping over the unavailable Products and accessing the \[1] index, you can access their fields: - the Name- the expiry date of the Product- the expiry date of the Product (formatted) | * "Classical Summer"
"2145916800"
"01/11/2020" | |
| Clear the reorder_unavailable_products data from the session This would only happen automatically if another Order is reordered, the Cart is emptied, or Checkout is completed. | | || Clear the reorder_added_to_cart data from the session.This would only happen automatically if another Order is reordered, the Cart is emptied, or Checkout is completed. | |
The above Liquid tags are accessing the User's session. This means they are temporary messages for that User. Each time an order is reordered the old message will be replaced.
This example will, if an Order was successfully reordered -display a message to Users confirming the Order ID which was reordered. If any Products were not available, these are displayed in a table. Finally, the session is cleared, so the User only sees this once.
In this Article we'll take an in-depth look at the JavaScript needed to update the quantity of items in the Cart Layout.
In this Article we'll take an in depth look at the JavaScript needed to update the Cart when the customer makes changes in the Cart itself.
There are two main flows you can implement:
A second choice is between whether you want to reload the Page to get new values or have our JavaScript function live update them for you.
We'll take a look at the key functions involved and the different ways they can be used within your Layout.
The function will queue a change to the Cart in your local storage, but will not yet confirm the change- unless you explicitly ask it to.
This function is designed to work as a callback function to Events triggered on the element which controls the quantity of items in the currently viewed Cart e.g. it could be added to this element in the Cart Layout item.liquid
file.
Like so:
You must pass the arguments 1-3. Argument 4 is optional.
s_e_cart_update_quantity(value, cart_id, token, update_entire_cart);
value
- The quantity required of this Item. Usually set to event.target.value
if the event was triggered on a target input element.
cart_id
- Set to {{this.cart_data.cart_id}}
to get the ID referring to the current Item in the item.liquid
file.
token
- Set to '{{context.authenticity_token}}
'
update_entire_cart
- Boolean - defaults to false
. If you pass true, we'll automatically run the s_e_cart_update()
function (see below) as a further callback, confirming the Cart update immediately.
Your choice of which event is watched will affect the User Experience e.g. onkeyup
as opposed to onchange
.
In conclusion, this function prepares an update to the Cart quantities. In the next section, we'll look at how to apply those changes.
This function will apply the changes in the Cart quantities that you have already queued using the previously discussed s_e_cart_update_quantity();
You can either use this function directly to confirm Cart changes when the User is ready, or indirectly.
If true is passed for the 4th argument of the previously discussed s_e_cart_update_quantity()
function, we'll run this function immediately. In this case, you won't need to directly call this function yourself.
Normally this function will be used as a callback to an event triggered on a button on your Cart wrapper.liquid
file. E.g.
You must pass the arguments 1-2.
s_e_cart_update(reload, token);
reload
- Boolean - true
will refresh the Page after updating; false
will not. This can also be overridden by passing in a success_cb
function.
token
- Set to '{{context.authenticity_token}}
'
check_inventory_after
- Boolean - false
- will check inventory stock levels without refreshing the page if set to true.
success_cb
- function - s_e_cart_update_cb_default
- optionally pass in a callback function which will be called after the cart has finished updating. Your function will be passed the parameters: reload
, check_inventory_after
- both are Booleans which can be used to modify behaviour or ignored.
``
false
When passing in a false
reload argument, you will need to follow additional steps to update the following:
The total quantity
The total price
The price of the line item that was just updated.
-optional- the currency symbol
The s_e_cart_update()
function will automatically call the s_e_live_cart_update()
function for you- but you'll need to wrap your displayed total in a <span> class with the following data-attribute: <span data-s-e-live-cart-quantity>{{items_in_cart}}</span>
In the wrapper.liquid
file, wrap the following element and data-attribute around the Liquid value for the total Cart Price: <span data-s-e-live-cart-total></span>
e.g.
In the item.liquid
file for your Cart Layout, wrap the following element and data-attribute around the Liquid value for the item's price: <span data-s-e-live-cart-item-price="{{this.cart_data.cart_id}}"></span>
e.g.
It is necessary to add this item's Cart ID as the attribute's value, in order to locate the correct record within the Cart. This will continue to use the Liquid value on initial Page load, but will now replace it with the live value when needed.
Depending on your HTML structure, you may already be displaying the currency symbol. If the JavaScript is overwriting it, you can add the following HTML to have the JavaScript return it when the function runs: <span data-s-e-live-cart-currency></span>
If you want to allow Users to press the enter button in the quantity input to trigger the event, you may need to modify your wrapper.liquid
file so that the Cart is no longer wrapped in a <form>
element but a <div>
instead. Make sure to adapt your stylesheets if you do this.
We'd recommend against any solution which stops the default submit behaviour on the Cart buttons that should press on focus and enter keypress- as this will negatively impact Accessibility.
If you want Users to be able to instantly update the Cart by changing values in the quantity input, you can run just the s_e_cart_update_quantity();
function with the 4th argument set to true. You may wish to use the onkeyup
event for even more instant feedback.
If you want Users to have the option to confirm Cart Quantity updates before they are applied- you'll need to first run s_e_cart_update_quantity()
when each input is changed and afterwards run s_e_cart_update()
when the User is ready to confirm.
Use Workflow and Autoresponder Emails to send confirmation messages to customers, including a detailed breakdown of their Order.
You have installed eCommerce Module v0.12.0 or later. Checkout to find out how you can install the latest version.
You have set up a Checkout or Quote-only Form. Learn more about Checkout here: or learn more about the Quote-only feature here:
You can now add details of a customer's eCommerce Order to Workflow and Autoresponder transactional emails. Give your Client and the customer peace of mind, as well as valuable records for their safekeeping.
eCommerce Orders are created by Checkout and Quote-only Forms.
Within the email, you can also access any fields that were submitted along with the original Form. Learn more here:
Add the following Liquid tag to include the details of the customer's most recent Order: <div data-gb-custom-block data-tag="include" data-0='ecommerce/order_details' data-1='email' data-2='email'></div>
In an email notification, this will always be based on the Form that triggered the email. Only an Order generated by that Form submission will be visible in this context. This means that Autoresponder emails will always show Form Submission data from the correct User.
You can use an existing Layout, or create a new one in this File Structure: layouts/modules/module_14/order/my_layout/
Within your Layout folder, you'll need:
An item.liquid
and a wrapper.liquid
file
Inside your order_details
layout you'll find an item.liquid
and wrapper.liquid
file.
You can use the wrapper.liquid
file to build the main HTML structure of your Layout. When you're ready to include the Order Details, use the following Liquid to include the item.liquid
file:
The item.liquid
file will have access to the This object, which will contain details about the Order:{{this}}
Orders involve several different types of models and can be complex. When developing you will need to use loops to take into account each different eCommerce element which may be a part of the Order.
When developing a custom layout, it may be helpful to refer to the default Layout.
Looping over Products This loop will find any Products in the Order and loop over them.
*Looping over Products and accessing Fields *Within a Product Loop, you can access the fields associated with that Product.
{{ product.product_name }}
{{ product.quantity }}
{{ product.product_code }}
{{ product.currency_symbol }}
{{ product.price }}
Looping over Products, then looping over Attributes
Outputting Shipping Method The following fields are available relating to the Shipping Method:
this['Shipping Method Name']
this['Currency Symbol']
this['Shipping Method Price']
`
` - a formatted Shipping Price
Example of only including Shipping Information if it was set:
Outputting Totals
{{ this['Currency Symbol'] }}
this['Total Price']
`
` - A formatted total price
You have installed the eCommerce Module
You have set up a Payment Gateway
You have added Products to the database
You have set up a Product List View
You have set up Product Detail Pages
Using PayPal as a Payment Gateway? There are additional setup instructions .
The Siteglide Ecommerce Module makes it easy to set up a secure and reliable Shopping Cart and Checkout flow. As usual, you can customise your layouts at every step.
In this tutorial, we will show you how to create the simplest Cart and Checkout flow- the Guest Checkout. Users can buy Products without having to sign in, but their details are stored in the CRM so the Site Owner can send them their Products.
In future tutorials we will show how to extend this with the following features:
Use the Secure Zone Module to Sign Up and Login users at different stages of their shopping experience.
Use Product Attributes to add Products with variations to your shopping Cart.
Use Categories to Create Pages which display different lists of Products.
Add a Cart Summary to the Header
Make sure your Product Detail pages have an add to Cart Button in their layout’s item.liquid file.
This liquid include tag will add the "Add to Cart" Button:
{% include 'ecommerce/cart_add' -%}
This needs to be in the item.liquid file to work, because this will have access to the correct data for this Product.
Create a new Page for your Cart and use liquid to include the Cart.
(Note- the Cart does not need to be on it’s own page, but this is the easiest place to start.)
Use this liquid to include the Cart layout in your page.
{%- include 'ecommerce/cart', layout: 'cart', remove_default_css: 'false' -%}
Use the layout
parameter to select the folder which contains the wrapper.liquid and the item.liquid file you would like to use for your layout. For now, you can use the "cart" layout which is included in the Ecommerce Module.
Use the remove_default_css
parameter to choose if you want to remove siteglide_example.css
from output or not.
This will store a paying User against the CRM and submit their payment details securely via your chosen Payment Gateway.
You will need to add the following information when creating your form:
Form Name: e.g. Checkout Form
Redirect URL - This is the relative URL you want a user to be redirected to after submission of payment details e.g. a confirmation page.
In the payments tab, toggle "Use as a payment form?" to on
Payment Form Type will appear under the payments tab. Select "Standard Checkout".
Save your changes.
Include the Checkout Layout in your page:
{% include 'ecommerce/checkout', form_id: '2', layout: 'default' -%}
The form_id parameter should be the id of your Checkout Form. If you use the Toolbox to add this code, you can lookup your form by name.
The layout parameter should refer to the folder which contains your form layout file. This file exists here:
layouts/forms/form_2/default.liquid
For now, you can use the "default" layout that is included with the eCommerce module.
If the page is visited while the user has an empty cart, an alternative "empty" layout will show. The default form layout will automatically add an empty layout at the path:
layouts/modules/module_14/checkout/default/empty.liquid
If you create a custom layout, you should also create an empty.liquid file, renaming the default folder in the filepath above with the name of your form layout.
Users will be added to the CRM in Admin.
You can see the records of transactions in Admin by navigating to the Orders list or finding the User in the CRM.
After a User has submitted your Checkout form, an order will be automatically generated. You can see a list of orders under ECOMMERCE/Orders
in the left-hand menu.
Click on the name of the order for more information.
As a user buys a Product, the Inventory decreases accordingly.
You have read
You have Installed the eCommerce Module
You have installed the Secure Zones Module
Siteglide eCommerce is even more powerful with Secure Zones. With the security of a Secure Zone, you can show your Users more sensitive data about their shopping experience.
Create a Secure Zone which will used by shoppers on your eCommerce site.
Alternatively, you can use a Secure Zone that you have created already.
Find out more about the Secure Zones Module here:
Create a new page which will display a list of Products Users have ordered.
Make a note of the Page slug, because you will want to add this to the Checkout Form’s "Redirect URL" field later.
In CMS / Pages, open the Page you have chosen and open the Details tab. Click the Secure Zones accordion to reveal the "Select a Secure Zone" field.
Click in this to open a drop-down list of your Secure Zones and select the one you wish to be accessed by Users after they complete Checkout.
Make sure your Checkout Form is still in "Test Mode" unless the Site is Live.
Find Forms in the Siteglide Admin’s left-hand side menu under CMS / Forms. Select your checkout Form in the list:
Next, click the "View Form" button to edit:
Select the Secure Zones tag and then click in the Secure Zones Input field to see a dropdown of Secure Zones you have already created.
Select the Secure Zone you want to log your Users in to when they complete the form.
Press the "Save" Button to save your changes. At this point:
Completing the Checkout Form will log Users in to the Secure Zone It will also redirect the Users to the My Orders Page The Users will be allowed to access the My Orders Page, because they are logged into the Secure Zone. Other Users who are not logged in will be unable to access the My Orders Page.
As Orders List Layouts are for showing secure information about Users, they are stored under the following file structure:
module_5/user_orders/name_of_my_layout.liquid
Create a new file in the user_orders folder and give it a name of your choice. Make a note of the name you gave it.
Add the following liquid to your Orders page to output a list of the current logged-in User’s Orders:
The layout parameter should take the name of the list layout you created.
Your layout will have access to the "orders" object. You can loop over each order in the "Order" object with the following liquid (the "order" variable can be renamed to anything you like). For example:
See the orders reference for available fields:
You could add a Secure Zone to other pages related to your eCommerce flow, for example the Cart, in the same way you did with the Orders page. You could redirect the users to a login page when they visit the Cart page and are not logged in.
Learn more about Secure Zones here.
Within the Orders Detail Layout you will have access to the orders array variable. To display a list of items in the single order, you should add a Liquid loop like this:
Within the loop, you can use properties of the object within the loop iteration as detailed in the table:
Field Name | Liquid Tag | Description |
---|
In this tutorial we'll be using both Categories and Collections, if you're unfamiliar with either of these we'd recommend refreshing your memory:
Often in eCommerce, you will have Products that are similar to one another. e.g. You might have a brand of chocolate with certain different flavours available. Or you might have different sized packs.
On Siteglide, we provide the Attributes feature- which allows you to merge these multiple varieties into a single Product with options. Users choose which Attributes to select as they add the Product to the Cart, and the Price can be adjusted accordingly. Follow these links to find out more about , or .
Adobe Business Catalyst, on the other hand, also allowed Users to "group" these similar Products instead. Product Grouping treated the Product variations as separate entities which could show up in Product Lists independently. Meanwhile, the Product Detail Page for one variation would display a list of alternate Products in the group, allowing you to switch to view the different information. Many partners have expressed an interest in re-creating this Product Grouping feature on their Siteglide Site.
There are several ways to achieve this:
Use Categories to group the Products
Use Datasources to build a relationship between a Product and similar Products in the Group
Convert an existing Product Grouping setup to use single Products with instead.
In this Article, we'll demonstrate how to group the products using Categories.
First, create a Category that will link the products together.
If you will also have some non-grouped Products, you may wish to create a "Product Groups" Category as well as a parent to organise all your product grouping Categories inside- bellow I'll explain how you can ensure that only Categories within the parent Category are used.
Here's how I've structured my Categories, "Chocolate" and "Crisps" each represent separate groups of Products, the parent Category "Product-group" will be used to identify them as Product grouping Categories, allowing you to keep them separate from the other Categories your Products may have:
Now let's look at how we can ensure only the Categories within "Product-group" are used when outputting our related Products. First I assign an object containing all the Categories on my Site (this gives us access to all the Categories fields, rather than just the ID): <div data-gb-custom-block data-tag="assign"></div>
Next loop over all of our Products categories, at each iteration we'll store the "full_slug" of the Category (this will include the parent Categories slug, which we can use to check the Category is being used for Product grouping).
Note: "this" contains one of the Category IDs assigned to our Product, we then use that ID to find all of the Categories details in "context.exports.categories.items
":
We've now created an array of all the individual "parameters" in our "full_slug" field, next we'll loop over this and check none of the parameters equal "product-group"- if they do then we know that Category is being used for Product Grouping and store its ID. Add this code to the for loop above:
This will check all of the parameters, make sure you replace "product-group" with whichever slug your wrapping Category is using. If it is a Product grouping Category, we store the ID in the variable "group_category". We'll use this ID later to output our Related Products.
Now add all the related Products to this Category. You can do this in the Categories tab when editing your Product. In this example- we'll be selecting the "Crisps" Category to add to our "Ready Salted" flavour Product.
Repeat step 2 for all the Products you'd like to be linked together.
On the Detail Page of each Product in the group, we'll next need to List the other Products in the group.
There are now two ways we could output the related Products. You can choose one of the following methods:
Include the other Products in group by nesting a filtered Product List Layout inside the Product Detail Layout.
Keep all the code tidy inside the Detail Layout using a Collection to fetch the same data.
We'll demonstrate how you can use method 3) b).
If you'd like to use a separate Layout to output your products, add this include to the Layout you're working in:
...where group_category
contains the ID of the category containing the related Products. In your chosen Layout, you would be able to add Content regarding the Related Products.
Now we know which Products are related to one another, we can output them. For this demo, I'll be outputting them within the Detail Layout.
If you're in a Detail layout, make sure to include the type: 'list'
parameter. Also, ensure collection: 'true'
is added to the include, along with your Category ID.
The Collection will call all the specified items into {{context.exports}}
, to save us writing the whole path to the item each time we output something, we'll store them in an Object: `
`
Now loop over the object, at each iteration we'll check that the ID doesn't equal the ID of the Product being displayed on the Detail Page (this will stop the Product on the Detail page being displayed as related). We'll use {{this.id}}
to do this:
Many partners who have expressed interest in the Product Grouping feature have also requested a demonstration of how to include a dropdown menu which allows easy access to links to other products in the Product group.
As always when using custom JavaScript, you may wish to adjust the simplified examples in order to add in improvements to SEO and accessibility.
For this demo, I've chosen to output my Related Products using <select> & <option>
, and some Javascript that will redirect the Page.
This will output ---Select alternative Product---
as the placeholder for the options, then will loop over all the items in the Object we've just created, each iteration will output another <option>
where the value contains a relative link to that Products Detail Page.
Lastly, we'll need to add the Javascript for the "handleOption" function above, this will simply redirect to the slug within the options value attribute:
If you used the method 3) b) above, you'll need to move some of the code from 4) a) inside the products Layout.
Make sure your Wrapper still includes the items inside the <select>
element:
The HTML and Liquid for each option should then be included inside the item.liquid
file: <option value="/{{item['module_slug']}}/{{item['slug']}}">{{item.name}}</option>
As above, you'll need to include a JavaScript function to make the dropdown functional.
Alright, that's everything we need to link our Products. Here is a screenshot of the solution:
Offer your customers better prices when they purchase in bulk. This feature lets you define as many levels of Volume Pricing as you like.
Volume Pricing allows your Client to offer better prices to customers who buy products in greater quantities.
Let's say for example a product normally costs £5, but to encourage larger sales , the following table of prices are available:
If the customer orders 105 items, they will have passed the quantity threshold of 100, so will have access to the price of £4 per product for all 105 items. They did not order a high enough quantity to get the best available price.
At the present, when two alternate versions of the same Product with different attributes are present in the Cart, both their quantities will be added up and counted towards the Volume Pricing Calculation.
There is no need to implement any front-end code in order to start using Volume Pricing. All you need to do is define the pricing in the Admin against individual products and those prices will become available.
You may wish Front End to dynamically display the available prices for a product. To do so, you can loop over each pricing threshold and display the prices in a table, list or format of your choice.
Inside the Product List/ Detail Page item.liquid file, you'll have access to the following fields:
When looping over an object like this['Volume Pricing']
, .first
allows you to access the key (here the quantity threshold) and .last
allows you to access the value (here the price).
First though, we use logic in the first line to check if the pricing has been enabled:
Inside the Order Confirmation Email, you'll have access to the following relevant fields.
The following example shows how the Volume Pricing can be shown inside a <td> element in an Order Confirmation Email.
In this article I'll explain how you can use our Media Download and eCommerce Modules to sell digital products
Prerequisites
You have installed the Module's latest version
You have installed the and
You have created .
You have followed our document on
In this article, I'll explain how you can datasource to a Media Download Item to a Product- allowing the Product to be downloaded after it has been purchased.
To ensure that the Media Download can only be accessed after the Product has been purchased we'll output it within a User Orders Layout.
Firstly, let's create our downloadable Product, to do this we'll create a new Media Download Item, you'll need to repeat this step for every product that can be downloaded. We'll be using an image for this example, but you can use any file type that the Media Download Module supports:
Now we've added our downloadable product, let's Datasource it to the Product it is related to, we'll need to add a new Custom Field to our Products- to do this go to: eCommerce > Products > Edit Module Structure.
Then add a new field and set the type to 'Datasource (Single item)':
Finally, let's link each of our Media Download items to the Products they're associated with, to do this head to eCommerce > Products > Your product > Custom Fields. You should see a dropdown containing all the Media Download items, select the one that matches your Product:
Now we've got everything needed for our Products to be downloadable, let's output the download somewhere it can only be accessed after being purchased.
Locate the `user_orders` layout within the Secure Zone Module: Code Editor > Modules > Module_5 (Secure Zones) > user_orders.
Within this layout we'll have access to the `orders` object, containing all of the User's previous purchases, this should also contain a order_products
(old) or order_products_flat
(new) object (depending on your eCommerce Module version) within each order. This contains information about the Product purchased, we'll have access to the Media Download Item ID from here.
We can output the Products data like so
However, we just need the Media Download Item ID which can be outputted like so, if you have other Custom Fields you'll need to replace 'product_1' with the field name
If there are multiple Products in one Order, we'll need to create an array of the Media Download Item IDs for each Product, we'll nest another loop within the loop above over {{orders}} - here's how this would look:
So no we've assigned all of our Media Download IDs to 'media_download_id
'- we'll use this within the 'item_ids' parameter on our Media Download Layout include:
Now, locate your Media Download layouts- these can be found under: Code Editor > Modules > Module_17 (Media Downloads).
From here you can either use an existing layout or copy the default layout structure to create your own (ensure you've added a 'list' folder within the folder for your layout, the 'list' folder should then contain item and wrapper layouts).
We'll only need to include the Media Download Items within the 'wrapper' file, here's how this looks:
Then within the 'item' layout, we'll add an anchor to allow the items to be downloaded- we'll also output the name of the Media Download Item as the anchor's text: <p><a href="{{this['url']}}">{{this['name']}}</a></p>
This is useful if you want the Inventory checked immediately after the User changes the desired quantity. In the example we want to time this function straight after the . Instead of running the function directly then, we'll set the check_inventory_after
option against the s_e_cart_update_quantity
function.
Field Name | Liquid Tag |
---|---|
You can use our to get the new total quantity of items in the Cart.
Inside your email notification file, you'll have access to the Form object: {{form.properties}}
This contains the fields submitted with the Form. Learn more here:** ** You'll still have access to these fields throughout the Order Details Layouts.
Learn more about Product Detail pages .
Learn more about Cart Layouts
You can add a form by navigating to CMS/Forms
in the left hand Menu and then clicking the "+ Add New Form" button in the top right of the page. Learn more about forms .
Learn more about pages
Remember, you will need to use the test cards from your chosen Payment Gateway. Find more information
A User cannot buy a Product if its Inventory is 0, but you can also hide Products that have sold out from the Product List Views. See to learn more.
The explained how to create a Checkout Form. Here we will modify this form so that it also either signs in a User or logs them in, depending on their current status.
In the "Redirect URL" field add your Orders , preceded by a forward slash. E.g. /my-orders
has an out-of-the-box Orders List design ready for you in a Bootstrap 5 or Tailwind version.
To do this we'll use a Collection (read more here: ) which will be filtered by the parameter "category_id", meaning only items within the specified category are included (please follow step 1 for instructions on how we can do this dynamically).
See the documentation for more.
Total Quantity
{{context.exports.cart_total_quantity.data}}
Shipping Price
Shipping Price Before Tax
Shipping Price Tax Amount
Total Item Price
Total Item Price before Tax
Total Item Tax Amount
Total Price Reduction (due to discounts)
Final Total Price before Tax
Final Total Tax Amount
Final Total Price
Code
Purpose
Required
data-s-e-discount-code
Attribute should be added to input field
Yes
value="
Option
Required / Default
Notes
spend: * document.querySelector('#s_e_amount').value
Option
Required / Default
Notes
reload: * true
error.type
error.message
Notes
no_code
Error: This Discount Code does not exist.
expired
Error: This Discount Code has expired.
below_min_spend={min-spend}
Error: This Discount Code has a minimum spend of {min-spend}
used_up
This Discount Code has already been used the maximum number of times.
incorrect_type
Error: This Discount Code does not apply to this kind of payment. It may apply in another area of the Site.
By default, Discount Codes are only redeemable on Cart / Checkout flow. You can change this for an individual code in the Admin using the "Valid on Payment Form Type" field.
Argument
Example
Purpose
reload default: true
The value of the reload setting passed into the function. Defaults to true for backwards compatibility.
discount
An object containing details of the newly applied discount code.
payment_type
'Checkout' or 'Basic Payment'
Can be used in logic
refreshed_discount_layout
A DOMstring containing the HTML generated by the refreshed Discount Code Layout
This can be used to refresh only the Discount Code Layout, if you choose.
Argument
Example
Purpose
reload default: true
The value of the reload setting passed into the function. Defaults to true for backwards compatibility.
payment_type
'Checkout' or 'Basic Payment'
Can be used in logic
refreshed_discount_layout
A DOMstring containing the HTML generated by the refreshed Discount Code Layout
This can be used to refresh only the Discount Code Layout, if you choose.
Setting key | Example | Optional |
checkout_url: | '/checkout' | Yes |
item_cb: | exampleItemFunctionName | Yes |
success_cb: | exampleSuccessFunctionName | Yes |
no_longer_available_message: | 'Sorry, some Products in your Cart have been removed because they are no longer for sale.' | Yes Note: the attribute data-s-e-cart-has-removed-products must be added to an element in the Cart Layout in order to display the message when needed. |
Number | Parameter | Purpose | Example |
1st | element | A DOM element referencing the element with the data-attribute data-s-e-cart-id where not enough quantity is available. You can target elements inside this when adding and removing error messages. | <tr data-s-e-cart-id="{{this.cart_data.cart_id}}"></tr> |
2nd | in_stock | A Boolean telling you if this Item is in stock or not. If true, you may wish to remove previously added error messages. If false, you should display the error message to the User. | true or false |
3rd | quantity | An Integer for the quantity desired by the customer. | 5 |
4th | inventory | An Integer for the inventory available for this Product. | 4 |
5th | name | The name of the Product in this row. | "T-Shirt" |
Number | Parameter | Purpose | Example |
1st | checkout_url | A String containing the value of checkout_url originally passed as an option to the main function. Can be used to redirect to the Cart, if available. | '/checkout' |
Option | Purpose | Example/ Default | Required? |
order_id: | The Order ID to be looked up and added to Cart | '{{order_id}}' | Yes |
token: | Access token from Liquid | '{{token}}' | Yes |
cart_url: | Cart URL for redirection after successful result | '/cart' | Yes |
error_cb: | Custom Error Function Name | error | Optional |
success_cb | Custom Success Function Name | success | Optional |
Error |
|
Order found but does not belong to this User, or User is not logged in. | "Unauthorized." |
Order does not exist | "Order was not found." |
All associated products are disabled, expired, unreleased or deleted. | "Order was found, but no products were available." |
Any other error | "Could not reorder." |
Liquid Tag | Purpose | Example Output |
{{context.session.reorder_added_to_cart}} | The ID of the ( at least partially ) successfully added Order. This can be used in Logic to decide whether to display feedback at all- as if it equals blank, there will be no recent reorder. | "345" |
{{context.session.reorder_unavailable_products}} | An Object containing details on unsuccessful Products- if there were any. This contains the same information returned to the Custom JavaScript Callback Functions. | {"173":{"product_id":"173","name":"Classical Summer Album","expiry_date":"2145916800"}} |
Use Case | **Step 1) ** | **Step 2) ** |
Change Cart Quantity with a single action | Run the |
Change Cart Quantity by: 1) Making a change 2) Confirming the change | Run the | Run the |
Quantity Threshold | Price |
1 | £5 |
100 | £4 |
1000 | £3.50 |
Field Name / Liquid Tag | Example | Notes |
{{this['Volume pricing Enabled']}} | true | Contains a boolean. If false, normal pricing will be used. |
{{this['Volume Pricing']}} | { "100": 400, "1000": 350} | Contains a JSON object of the currency thresholds for this product set in Admin. When stored in the database, this is organised by currency, but front-end we'll fetch the relevant currency for you. |
Field Name / Liquid Tag | Example | Notes |
{{product.volume_pricing_original_price}} | 60.00 | A formatted price representing the price of the row, had the better volume price not been applied. |
{{product.volume_pricing_threshold_reached}} | 4 | The highest quantity threshold reached. If no volume pricing was accessed, this will have the value nil. You can use it in logic to check if Volume Pricing has been applied - see code example below. |
{{product.currency_symbol}} | £ |
{{product.price}} | 19.00 | This formatted price shows the actual price of the order row. This will either be the default price, or a volume price if available. |
Order ID |
| The unique ID of the order |
Order URL |
| The unique slug of the order |
Order Full URL |
| The unique slug of the order including Order Slug |
User ID |
| The unique ID of the Current User |
User Email |
| The email address of the User who completed the Order |
Status |
| The status of the Order |
Price |
| The Price paid for the Order as a decimal |
Currency |
| The currency the Order was made in |
You have set up a PayPal Payment Gateway, with the required authentication: Payments Gateways
The PayPal Payment Gateway is compatible with Basic Payment Forms and Checkout Forms. However, there are a few differences to take into account when you choose this Payment Gateway.
PayPal creates its own secure Submit Buttons for the payment Form. This means you should remove the default submit button from the Form Layout if you are using the PayPal Payment Gateway. We've included an error log in the JavaScript console to remind developers of this.
As custom error functions are normally passed in as an argument on the submit button's onclick listener, we've had to provide an alternative means to attach this: a global JavaScript variable.. You can set this in a <script> tag inside your Form Layout like so:
We recommend using a Custom Error Notification with PayPal. JavaScript alert messages are sometimes covered by the secure PayPal browser window- meaning the User Experience can become impaired. We'd recommend outputting error messages directly on the Page instead or using a library like Sweet Alert 2.
You can see an example which does this in our updated Custom Error Function Article.
Basic Payments are a way to take a payment when a form is submitted. They may be useful for allowing Users to pay invoices etc.
You have installed the eCommerce Module in Site Settings
You have set up a Payment Gateway
Using PayPal as a Payment Gateway? There are additional setup instructions here.
Basic Payments are a way to take a payment against a standard Form submission.
You set the currency, and the minimum payment value in Form Builder.
When submitting the form, a value is sent to our payment processor, and validated server-side to check that it's higher than the minimum payment value you have set.
Here's 3 examples of when you'd use this payment system:
If you're sending invoices to a customer, and want them to pay online, they can enter their invoice number (in a custom field) and the amount to pay. You would then check 'offline' that the value paid matches that on the invoice. In this case you'd set the minimum payment value as '0.00'.
You know the exact value you want the users to pay (for example $10.00), so you set the minimum payment value as '10.00'. This is validated server-side to make sure they cannot pay less than that.
You want to charge a variable amount based on their form selections, and know the minimum value that should be. For example, the charge might be $10.00 as standard, but then have some optional custom fields that bring the price up to $20.00. See the section below: "Changing the Price based on User Form Input".
Remember, this kind of payment is designed for use cases where the customer intends to make a charitable donation or pay an invoice that is due. It is possible for the customer to modify the JavaScript and pay less (but not less than the minimum payment value). You should only use this kind of payment either when the customer does have a genuine choice, or the Client will be reconciling invoices and chasing where the correct amount has not been paid.
PayPal allows you to include different parameters as part of the SDK such as disabling payment options that are unwanted, as per the following link -> https://developer.paypal.com/docs/checkout/reference/customize-sdk
To use these parameters add this code to top of your Form layout, containing the parameters you want:
This specific example will stop Sofort being offered as a payment option.
The Stripe Payment Gateway provides its own iframe to accept Card Details securely so direct styling isn't possible. Instead use JavaScript.
The Stripe Payment Gateway provides its own iframe to accept Card Details securely so it's not possible to have full access to the HTML structure so you can apply your own styles. Instead, you can use JavaScript to pass your styles safely to Stripe.
This method will work on any kind of Payment Form which uses Stripe. This includes:
Basic Payment Form
Checkout
Subscription Sign Up
Styles are passed securely to Stripe using JavaScript, rather than your traditional method of applying styles directly with a CSS file.
To do this, create a global JavaScript variable stripe_style
at the top of your Form Layout or Page. Its value should be an object like the following:
As in the example above- the stripe_style
variable is passed a JavaScript object.
You can see Stripe's full definition of how this object should be structured using their documentation here: https://stripe.com/docs/js/appendix/style. The first set of keys e.g. base represents a "variant" or state the elements might be in. Nested within this, certain allowed CSS properties may be set.
You can ask Stripe to rename some of the available classes by redefining the classes
object. To do this in Siteglide, create a global variable stripe_classes
:
Any styles you set in the stripe_styles
object to base will still apply after changing the class, unless you specifically override them.
You can see a full reference for the available properties for this object in the Stripe documentation here: https://stripe.com/docs/js/elements_object/create_element?type=card#elements_create-options-classes
This section covers our Currency & Tax Code changer tools.
Our Tax Code Changer will allow you to output a list of all Tax Codes on your site that are linked to the current session's currency. You can then set a new Tax Code for that session.
The JS function must be sent a valid Tax Code ID. See the layout named default
for an example of how this is achieved via a <select />
dropdown.
You can add a Tax Code Changer to your site using the following include:
<div data-gb-custom-block data-tag="-" data-0='ecommerce/tax_code_changer' data-1=', layout: ' data-2='default'></div>
You can find layouts at layouts > modules > module_14 (eCommerce) > components > tax_code_changer > your_layout_name_here
The layout will require a wrapper
and item
file, which you can see in place in the layout named default
that comes installed with the eCommerce Module.
After you've installed the eCommerce Module on a Site, setting up a Payment Gateway is the next step!
Siteglide never stores your customers' full card details. Instead we integrate with globally recognised and trusted payment gateways to store that information and process payments on your behalf e.g. Stripe or PayPal.
Stay in this section for information about how to set up, different configuration advice for different gateways and how to run multiple gateways on a site and let customers choose between them.
At the current time, some Payment Gateways allow more access to Siteglide features than others.
The Stripe Payment Gateway is recommended as fully compatible with all Siteglide Features.
PayPal is compatible with Basic Payment Forms and Cart + Checkout
Authorize.net is only compatible with Basic Payment Forms
Our Currency Changer will allow you to output a list of all currencies on your site, and then set a new currency for that session.
The JS function must be sent a valid currency code in lowercase. See the layout named default
for an example of how this is achieved via a <select />
dropdown.
When changing currency, then default Tax Code for that currency is also automatically applied.
You can add a Currency Changer to your site using the following include:
<div data-gb-custom-block data-tag="-" data-0='ecommerce/currency_changer' data-1=', layout: ' data-2='default'></div>
You can find layouts at layouts > modules > module_14 (eCommerce) > components > currency_changer > your_layout_name_here
The layout will require a wrapper
and item
file, which you can see in place in the layout named default
that comes installed with the eCommerce Module.
Use Emails to send confirmation messages to customers, including a detailed breakdown of their Basic Payment Submission
You have installed eCommerce Module v1.1.4 or later. Check out Modules Overview to find out how you can install the latest version.
You have set up a Basic Payment Form using the Stripe Payment Gateway
You can now add details of a customer's Basic Payment Form to Workflow and Autoresponder transactional emails. Give your Client and the customer peace of mind, as well as valuable records for their safekeeping. Within the email, you can also access any fields that were submitted along with the original Form. Learn more here: Dynamic Content in Workflow and Autoresponder Emails
To include the details of the customer's most recent Order, include the following Liquid tag:
This can be outputted in one of two places:
Inside the body of an automation email e.g. autoresponder or workflow
Inside a Form Confirmation Layout
Placing in either of these locations will allow the system to identify the last submitted Form case and, if there is one, the associated payment.
You can use an existing Layout, or create a new one in this File Structure: layouts/modules/module_14/payment/my_layout.liquid
Note
Unlike the similar Order Details Layout, Payment Details is simpler, so there are no wrapper and item files.
Inside your automation email body, you'll have access to the Form object: {{form.properties}}
This contains the fields submitted with the Form. Learn more here: Dynamic Content in Workflow and Autoresponder Emails You'll still have access to these fields throughout the Payment Details Layouts as they will be inherited.
***Accessing Payment Details ***The layout file will have access to the this
object, which will contain details about the Payment: {{this}}
Within this object, you'll have access to the following fields:
For a basic fixed-amount set up, set the minimum payment value to exactly what you want users filling in the Form to Pay. For charitable donations and invoice payments, set the minimum payment to something minimal like $5 which avoids you making a loss on payment gateway fees for tiny transactions. Then look to Steps to Allow User to Decide Amount they Will Pay
In the Secure Zones tab, pick a Secure Zone. Access will be granted when payment is made and the Form is submitted.
Back in CMS Forms, find the ID for your newly created Form:
Use this ID in the Liquid tag when you insert the Form on the Page (or use Toolbox as a quick shortcut):
Your Payment Form is now set up and ready to accept payments using the minimum payment value you set.
If your Payment Gateway is in 'Test Mode', then you may need to enter card details specific to the testing environment.
If you are using the Stripe Payment Gateway, this step is optional.
For PayPal or Authorize.net, you will need to follow the relevant extra steps:
See SiteBuilder to install a plug and play, themed Form Layout for your payment Form:
And set your Form to use it with the layout parameter.
See the Forms Reference for creating your own Layout:
By default, the Form will charge the minimum amount, but for some use cases like donations or invoices, you may want to allow them to pay more:
First, set up a Basic Payment Form with a minimum payment amount by following the steps here:
In some use-cases you may wish the amount to be paid to depend on the User's input into the Form Fields e.g.
The User is making charitable donations. The minimum payment is $2, but they can choose to donate any amount above that they wish.
The User will select options on the Form that will inform a logical function to decide how much they need to pay.
Both use-cases will require you to write a JavaScript function which will update the value of the amount due.
You may find the following Liquid tags helpful while developing:
` | The currency for the Form defined in Admin | gbp | | `` | The symbol for the currency for the Form defined in Admin | £ | | `` | The `minimum payment` value defined in Admin, in the lowest denomination of that currency | 100 | | `` | The `minimum payment` value defined in Admin, formatted | 1.00 |
The end goal of such a JavaScript function will be to set the value of hidden field with the ID "s_e_amount
". The default value of this field will be the same as the minimum payment value you set in Admin, until it is changed via JavaScript. The final value should be an integer (whole number) of the number of cents that will be paid.
We'll give you an example of how this JavaScript may work here. You can adapt this example to suit your use case. The important thing is that you set the value of the field with the ID "s_e_amount
".
The following example allows the User to enter an amount of their choice into an input in the Form. Our function changes the format, then sets the value of the hidden field.
This example shows how you can add an "amount" parameter to the URL- if this parameter exists then the s_e_amount
will be updated.
The following Javascript can be added to your Basic Payment Form's Layout. The first half of the function will store the amount parameter within the "amount" variable, the second half checks if "amount" exists (this prevents "null" from getting added to s_e_amount
) if so then s_e_amount
is updated with the new price:
An example URL might be, to set the price to 20.00 or 2000 pence/cents:
To include a Basic Payment Form on the Page, use the same syntax as a standard form:
This is used to output payment fields in a basic payment form.
You should include this inside a basic payment form layout.
Also see Switching Payment Gateways
This HTML input field with the ID s_e_amount can be used to modify the amount which will be paid when the Form is submitted, see:
You must include 3 extra fields in the Form Layout for Authorize.net to work.
The payment flow will look for code in your set Custom Payment Gateway Partial Path. The file it's looking for is {{Custom Payment Gateway Partial Path}}/checkout.liquid
(e.g. modules/my_ecommerce/payment_gateways/money_take/checkout
)
Your code will be included inside the Form - where in the Form Layout you see the tag
To access information about your custom Payment Gateway such as the API Keys, you can output {{payment_gateway}}
into the layout.
You may notice that many of the steps are similar to the steps for the Basic Payment Form and you may wish to re-use some of your code.
When building you layout consider the following process that needs to be take place.
Initially set up any Client-side HTML or JavaScript which the Payment Gateway requires to be rendered on Page Load e.g. elements for securely entering card details.
Define a JavaScript function which will set up and carry out the payment transaction. Depending on the complexity of your Payment Gateway, this may include multiple steps.
You should assign this function to window.s_e_payment = my_payment_function
. The Siteglide Form will call this function when validation is complete and it is ready to begin the payment.
The function definition should return a JavaScript Promise- this will allow the Siteglide Form Submit function to wait for the payment to finish, before it continues submitting the Form.
Your function definition can use the parameter form
- this contains the DOM element for the Form which has been submitted. This will be used in the JS selectors in the next step to make sure we target the DOM in the correct Form where more than one Form is present on the Page.
Unlike Basic Payment Forms, the amount to be paid is not stored in a JavaScript variable. Instead, the amount will be calculated using the contents of the User's Cart.
As the process of converting Cart Data to an Order is lengthy, we've opened up our endpoint for your use:
Cart
Shipping Method (ID)
Order ID (should normally be blank-this is to prevent duplicates)
Slug
Discount Code (ID) | var data = { user_id: form.querySelector('#s_user_id').value, email: form.querySelector('#s_email').value, cart: form.querySelector('#s_e_cart').value, shipping_method: form.querySelector('#s_e_cart_shipping').value, order_id: form.querySelector('#s_e_order_id').value, slug: form.querySelector('#s_e_slug').value, discount_code: form.querySelector('#s_e_cart_discount').value, form_id: form.querySelector('[name=parent_resource_id]').value, hcaptcha: form.querySelector('[name=h-captcha-response]')? form.querySelector('[name=h-captcha-response]').value : null}; | | Response | { "order_id": "xxxxx", "slug": "xxxxx", "errors": { "example_error_key": { "id": "xxxxx", "message": "example_message" } } } |
After receiving your response, you should store the resulting order_id as the value of the hidden field #s_e_order_id. This will allow the Form to store a relationship between the Order and the Case when the submission is complete. It will also allow you to access that Order when needed server-side.
Depending on the complexity of your Payment Gateway, the payment can either be carried out in a single step, or in multiple steps - this is up to you.
You will however have to send at least one API call to your Payment Gateway from your own Liquid endpoint Page in order to securely send the details of the Order.
To do this, you'll need to run a GraphQL query to fetch the Order, filtering by its ID (the ID returned from the order_pre_payment_processor endpoint) and model_schema_name: "module_14/order".
The table below shows the fields you can access or update in the Order model:
To halt both your Payment Function and Form Submission and throw errors to the User, you'll need to resolve your Payment Function's promise with an object containing an errors property - an array of objects, each with a message String property.
Note, your Promise should not include a reject, as this will not be used.
Once your my_payment_function payment function is complete and the funds have been captured, you will want to let the Siteglide Form Submit Function finish submitting the Form. To do this, resolve the Promise (without an errors object):
Good understanding of Liquid
Good understanding of JavaScript
Good understanding of GraphQL, including queries, related_models, mutations and using mutations to send API calls.
Good understanding of APIs
Siteglide have built integrations between its eCommerce Module and three Payment Gateways:
Stripe - integrated with all Siteglide eCommerce Features
PayPal - for Checkout and Basic Payment Forms
Authorize.net - for Basic Payment Forms
In order to focus on improving features for the Payment Gateways we have, we won't be building integrations to any other Payment Gateways at this point. Instead, this Article is intended to help experienced Siteglide Partners build their own Payment Gateway Integrations.
We've opened up the Payment Gateway model (model_schema_name: "module_14/payment_gateway") to allow you to customize it to suit your own Payment Gateway:
Use GraphQL to create a record in this table using the filelds above.
Now your Payment Gateway exists, it's time to give it some functionality. You can add support for one or more of the following:
This section gives you a detailed understanding of the different payment gateway options available:
The payment flow will look for code in your set Custom Payment Gateway Partial Path. The file it's looking for is {{Custom Payment Gateway Partial Path}}/basic_payment.liquid
(e.g. modules/my_ecommerce/payment_gateways/money_take/basic_payment
)
Your code will be included inside the Form - where in the Form Layout you see the tag
<div data-gb-custom-block data-tag="-" data-0='ecommerce/basic_payment' data-1=', amount: ' data-2='500' data-3='500' data-4=', currency: '></div>
To access information about your custom Payment Gateway such as the API Keys, you can output {{payment_gateway}}
into the layout.
When building you layout consider the following process that needs to be take place.
Initially set up any Client-side HTML or JavaScript which the Payment Gateway requires to be rendered on Page Load. E.g. elements for securely entering card details.
Define a JavaScript function which will set up and carry out the payment transaction. Depending on the complexity of your Payment Gateway, this may include multiple steps.
You should assign this function to window.s_e_payment = my_payment_function
. The Siteglide Form will call this function when validation is complete and it is ready to begin the payment.
The function definition should return a JavaScript Promise - this will allow the Siteglide Form Submit function to wait for the payment to finish, before it continues submitting the Form.
Your function definition can use the parameter form
- this contains the DOM element for the Form which has been submitted. This will be used in the JS selectors in the next step to make sure we target the DOM in the correct Form where more than one Form is present on the Page.
All of the following information is available in the HTML DOM and therefore is also accessible via JavaScript.
The parameter form
from the previous step is used for specificity.
See the next step r.e. checking the amount on the Server Side.
Siteglide Basic Payment Forms have a "Minimum Value" defined in the Form Structure. This can be used in two ways:
As the actual value of products or services
When the User is choosing their own price e.g. a donation Form, the minimum price the Client will accept in order to not make a loss on the donation when the Payment Gateway's fees are paid.
All of our native Payment Gateways include a server-side check to make sure the amount is met- so most likely you'll wish to do the same.
In order to do this- your Payment Gateway should make a request to a Liquid Page you create. The Form Configuration ID and Amount should be sent over in your data payload or query parameters.
The Endpoint Page should run an admin_form_configurations
query:
In the results of this query, you'll be able to verify the true minimum amount and currency. You can compare these to the s_e_amount value calculated on the Front-end. Depending on the result_name you choose - the values from this example query of note are:
On this endpoint, you'll have secure access to these values, so it might make sense to use this same endpoint to:
send an API call to your Payment Gateway to set up a Payment Intent (or complete Payment Transaction).
run a GraphQL mutation to create a "module_14/payment" model in the database, (with a status of "Intent Created" or "Payment Complete" as appropriate) (see below)
In order for the Client to see a record of the Payment in the Siteglide Admin, you must:
Create a database object with the model_schema_name of module_14/payment.
Via the JavaScript in your Payment function, store the ID of this newly created Payment Model in the hidden HTML field #s_e_order_id. This way it will be submitted with the Form and a relationship will be established between the Payment and the Case- allowing their information to be linked in the Admin.
Depending on the complexity of your Payment Gateway, you may wish to:
Create the Payment Model at the same time a Payment Intent is created with the status Intent Created. After capturing funds in a later step, you may wish to update the same model by referring to it by its ID, this time giving it the status Payment Complete.
Create the Payment Model at the end of the Payment process- to confirm its success. This would immediately be given the status Payment Complete.
The key fields you will need to set on the Payment Model are shown in the following table:
To halt both your Payment Function and Form Submission and throw errors to the User, you'll need to resolve your Payment Function's promise with an object containing an errors property - an array of objects, each with a message String property.
Note, your Promise should not include a reject, as this will not be used.
Once your my_payment_function payment function is complete and the funds have been captured, you will want to let the Siteglide Form Submit Function finish submitting the Form. To do this, resolve the Promise (without an errors object):
Create a Form in the Siteglide Admin and turn on the setting to use it as a payment form. (Basic Payment Form and Checkout will be supported as both support at least 2 payment gateways.)
You can use to quickly create a custom Form Layout
In Code Editor or CLI, make a copy of the default form layout, ready to customise it.
In any Page, output your form and select the custom layout with the layout parameter. E.g. if your form ID is 1
, your layout should be at marketplace_builder/views/partials/layouts/forms/form_1/
my-custom-layout.liquid
For Basic Payment forms:
For Checkout Forms, use the ecommerce/checkout_standard include to output multiple payment gateways inside your checkout form Liquid layout file.
For Basic Payment Forms:
Once you have multiple options, you'll need a way to tell the system which to use.
The following JS function will do that for you:
Pass in the name of the Payment Gateway you wish to switch to as the only argument.
This can be applied as a callback to any JS event you like, such as clicking a radio button, or opening an accordion. e.g.
```liquidSelect a payment gateway: Stripe PayPal
If the JS function is not called, the default payment gateway from the multiple available gteways will be used.
Stripe:
PayPal:
Authorize.net
Parameter | Type | Notes |
---|---|---|
Field Name | Field ID | Purpose / Notes |
---|---|---|
amount
Integer
The amount to be charged in cents/pence (e.g. 500 = $5.00)
currency
String
The currency to charge the user
id
Integer
The ID of the Payment Gateway to be used. If not included, then the system will output the Payment Gateway that you most recently updated in Siteglide Admin
Tag
Description
Example Output
{{this.currency}}
Currency code
gbp
{{this.currency_symbol }}
Currency symbol
£
{{this.amount_paid}}
Amount Paid
100
{{this.amount_paid_formatted}}
Amount Paid Formatted
1.00
{{this.payment_id}}
Stripe Payment ID
pi*
Field Name
Example
Notes
Card Number
<input id="s_e_card_num" class="required" type="text" />
Card Expiry
<input id="s_e_card_exp" class="required" type="text" placeholder="MM-YYYY" />
The data format must follow that in the placeholder in our example
Card CVV
<input id="s_e_card_cvv" class="required" type="text" />
amount
Integer
The amount to be charged in cents/pence (e.g. 500 = $5.00)
currency
String
The currency to charge the user
id
Integer
The ID of the Payment Gateway to be used. If not included, then the system will output the Payment Gateway that you most recently updated in Siteglide Admin
Setting
Value
URL
api/ecommerce_general/order_pre_payment_processor.json
Method
POST
Required Headers
xReq.setRequestHeader('content-type', 'application/json'); xReq.setRequestHeader('X-CSRF-Token', form.querySelector('[name=\'authenticity_token\']').value); xReq.setRequestHeader('X-Requested-With', 'X-Requested-With: XMLHttpRequest');
Body Data: * User ID
Field Name
Field ID
Purpose/Notes
User ID
module_field_14/order_1
User Email
module_field_14/order_2
Status
module_field_14/order_3
Either Intent Created, Payment Complete or a custom status of your choice.
Billing Address
module_field_14/order_4
Not yet used by Siteglide
Shipping Address
module_field_14/order_5
Not yet used by Siteglide
Payment Method
module_field_14/order_6
Not yet used by Siteglide. You must not use this field to store full card numbers. You may choose to store either an ID or fingerprint (e.g. https://stripe.com/docs/api/payment_methods) which your Payment Gateway uses to reference a payment method.
Shipping Method ID
module_field_14/order_7
Tracking Number
module_field_14/order_8
Not yet used by Siteglide
Total Price
module_field_14/order_9
Currency
module_field_14/order_10
Discount Code
module_field_14/order_11
Shipping Method Price
module_field_14/order_12
Shipping Method Name
module_field_14/order_13
Discount Code ID
module_field_14/order_14
Subtotal Price
module_field_14/order_15
Subtotal Before Tax
module_field_14/order_16
Subtotal Tax Amount
module_field_14/order_17
Shipping Option Price
module_field_14/order_23
Total Before Tax
module_field_14/order_25
Total Tax Amount
module_field_14/order_26
Cart Data
module_field_14/order_27
Shipping Data
module_field_14/order_30
Field Name
Field ID
Purpose/Notes
Name
module_field_14/payment_gateway_1
Payment Gateway Display Name
Active
module_field_14/payment_gateway_2
Boolean Only one Payment Gateway should be active at a time.
Type
module_field_14/payment_gateway_5
Payment Gateway Name in snake_case - Must be unique to your Payment Gateway
In test mode?
module_field_14/payment_gateway_8
Boolean
Custom Payment Gateway Partial Path
module_field_14/payment_gateway_19
Folder path for the partials you will use to include your Gateway code on the Form (see next section)
Field
JavaScript Selector
Purpose/Notes
Amount
form.querySelector('#s_e_amount').value;
The amount of money the customer intends to pay. For Basic Payment Forms, this value is editable on the Client Side. If you need the original Minimum Amount defined against the Form, run a server -side check.
Currency
form.s_e_currency('#s_e_currency').value;
The currency the customer intends to use. If you need the original currency set up against the Form, use a server-side check.
Form Configuration ID
form.querySelector('[name="form_id"]').value;
This Form Configuration ID can be sent to your own Liquid XHR endpoint and used in a GraphQL query to confirm the details of this Form.
Payment ID
module_field_14/payment_1
The Payment Gateway's ID for this Payment Intent
Gateway ID
module_field_14/payment_2
Optional - The ID of the Payment Gateway in Siteglide that handled this payment.
Gateway Type
module_field_14/payment_4
Optional - The type of the Payment Gateway in Siteglide that handled this payment.
Status
module_field_14/payment_5
The status of this Payment: Intent Created, Payment Complete or a custom Status of your choice.
Charge ID (Stripe), Capture ID (PayPal) or use for a similar purpose in another Payment Gateway.
module_field_14/payment_6
Optional
Currency
module_field_14/payment_7
The actual currency used.
Amount
module_field_14/payment_8
The actual amount to be paid.
Liquid
Role
Example
`
Our integration with Stripe Billing allows you to create Subscription Products and bill customers on a regular basis.
This section gives you a detailed understanding of the different tool options and functionality.
This view allows you to display available Subscription products for customers to browse through.
The Subscriptions List View displays a list of Subscription products. Like other List Views, it can be sorted and filtered via Liquid.
This is slightly different from the user_subscriptions
List view in the Secure Zones Module. This can be used to display a List of Subscription Orders belonging to a User. Learn more here.
You can use the type parameter to output a List Layout in most Liquid files:
Subscription Layouts can be found at the path: layouts/modules/module_14/subscription
Within this folder, you can create a folder for each Layout. Each Layout folder can contain a further "list" folder containing the wrapper
and item
files it needs.
The wrapper.liquid
file should be used to add any HTML structure you may require around your main list.
You must include the following Liquid, which will in turn loop over the Items and output the item.liquid
file for each Subscription Item. Most fields are specific to the Item and will only be available inside the item.liquid
file.
Subscription Fields
{{this}}
- Output all fields as JSON
{{this.id}}
{{this.weighting}}
{{this.release_date}}
{{this.expiry_date}}
{{this['Description']}}
{{this['Interval']}}
{{this['Interval Count']}}
{{this.full_slug}}
- URL for the Product Detail Page
{{this['Secure Zones']}}
- Array containing the IDs of Secure Zones associated with this Subscription.
{{this.price.id}}
{{this.price.currency}}
{{this.price.price_charge}}
- The chargeable price of this Subscription each Interval. Integer format.
{{this.price.price_display}}
- A field for displaying a secondary price of your choice, e.g. recommended retail price. This is not used by the integration. Integer format.
{{this.price.currency_symbol}}
{{this.price.price_charge_formatted}}
- The chargeable price of this Subscription each Interval. Currency format
{{this.price.price_display_formatted}}
- A field for displaying a secondary price of your choice, e.g. recommended retail price. This is not used by the integration. Currency format.
*Subscription Order Fields *You'll see when developing a Subscription Detail Page that when the User is logged in, it is also possible to access fields relating to a subscription_order the User has made for that Subscription product already.
This is not currently available on the List view- as the List view is designed as a way to browse Subscription products. To allow the user to view and manage their Subscription Orders, we recommend the User Subscriptions view.
The Detail Layout for Subscriptions displays details of the Subscription Product and also a Form for creating/editing Subscription Orders
A Subscription Detail Layout allows you to display detailed content about an individual Subscription product to a customer. It also is an important part of outputting a Subscription Sign Up Form, as these must be outputted within the Layout of the Subscription they will subscribe Users to.
The most common place where Detail Views are displayed is on the automatically generated Detail Page, if you have enabled these. However, they can also be outputted within most Liquid files, including ordinary Pages.
Heading to ECOMMERCE > Settings will allow you to select the Subscriptions tab.
Here you can set up Detail Pages by:
Choosing the slug which will begin the URL to Subscription Detail Pages
Choose a Page Template to use on Subscription Detail Pages
Choose a Detail Layout to use on Subscription Detail Pages
You can use the type
parameter to output a Detail Layout in most Liquid files:
Parameters:
type
- give the value
'detail'
.
layout
- give the name of a Detail Layout for Subscriptions
item_ids
- this parameter is usually optional, but it's essential when you are outputting a Detail View as only one Item ID must be displayed.
Bear in mind that Forms will not work properly inside Emails, so if displaying a Detail Page inside an Email, it is best to provide an alternative Detail Page without the Sign Up Form.
To output the Layout here, you need to add a Detail Layout name to the Liquid as a parameter. Read more here.
Subscription Layouts can be found at the path: layouts/modules/module_14/subscription
Within this folder, you can create a folder for each Layout. Each Layout folder can contain a further "detail" folder containing the wrapper
and item
files it needs.
We provide an example of some logic you can use to explain to logged in Users what the Form will do:
In the case where the User is not currently logged in and is not responding to an email, the logic won't be able to determine the exact status straight away.
Instead, if a non-logged in User tries to Sign up for a Subscription, Siteglide will first log them in and check if they have an active Subscription already. If they do, we'll throw an error, but allow the User to try again if they wish to update their payment details.
Adding a Form to the Detail Layout allows users to Sign Up to this Subscription product. You can read more about creating this Form here.
If you've already created your Form, you can skip this step.
Once you've created a Form and made a note of its ID, you'll be able to add it to your Detail Layout.
As a guide, we've added a Liquid comment to remind you to add your Subscription Sign Up Form to this Layout: `
`
This is just a suggestion, you can actually include your Form anywhere you like in the Layout. Use the following Liquid: <div data-gb-custom-block data-tag="include" data-0='form' data-1='1' data-2='1' data-3=', layout: '></div>
Parameters:
id
- the ID of your Subscription Sign Up Form, you can check this in CMS > Forms. Remember you can use the same Form Layout for all Subscriptions. The this.id field controls which Subscription product is associated with the Form.
layout
- Choose a Form Layout
The wrapper.liquid
file could be used to add any HTML structure you may require around your layout.
You must include the following Liquid, which will output the item.liquid
file for the Subscription Item. Most fields are specific to the Item and will only be available inside the item.liquid
file.
On the Subscription Detail View, we provide you with fields relating to the Subscription and also the Subscription Order for a logged in User.
Subscription Fields
{{this}}
- Output all fields as JSON
{{this.id}}
{{this.weighting}}
{{this.release_date}}
{{this.expiry_date}}
{{this['Description']}}
{{this['Interval']}}
{{this['Interval Count']}}
{{this.full_slug}}
- URL for the Product Detail Page
{{this['Secure Zones']}}
- Array containing the IDs of Secure Zones associated with this Subscription.
{{this.price.id}}
{{this.price.currency}}
{{this.price.price_charge}}
- The chargeable price of this Subscription each Interval. Integer format.
{{this.price.price_display}}
- A field for displaying a secondary price of your choice, e.g. recommended retail price. This is not used by the integration. Integer format
{{this.price.currency_symbol}}
{{this.price.price_charge_formatted}}
- The chargeable price of this Subscription each Interval. Currency format
{{this.price.price_display_formatted}}
- A field for displaying a secondary price of your choice, e.g. recommended retail price. This is not used by the integration. Currency format.
*Subscription Order Fields *If a User is logged in, Siteglide will establish if they have an existing Subscription Order for this Product. Using any of these fields should be done cautiously, as they will not be available if the User is logged out, or if they don't have an existing Subscription.
To determine this, you can use Liquid Logic to hide an entire block of code in which you use these fields:
Fields:
{{subscription_order}}
- Output all Subscription Order fields as JSON
{{active_subscriptions}}
- Array containing all Subscription IDs connected with one of the current User's Subscription Orders, where those orders have status Active
{{subscription_order['Status']}}
- These relate to the Subscription Status in Stripe and are the best way to understand the status of the Subscription Order at a glance. More information available below.
{{subscription_order['Stripe Subscription ID']}}
- This refers to a Subscription on Stripe and can be searched by the Client on the Stripe Dashboard to find out detailed information about this Subscription Order and the associated customer, invoices, payment_intents and charges.
{{subscription_order['Cancel At Period End']}}
- "true" or "false"- if true, this Subscription has been set by the User to be automatically Cancelled at the end of the current billing period. The User has a chance to change their minds until this date.
{{subscription_order['Stripe Plan ID']}}
- The Stripe ID for the Plan this Subscription Order is using. This may be an older plan than the current plan used by the Subscription product.
{{subscription_order['Plan Chargeable Price']}}
- A snapshot of the Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
{{subscription_order['Plan Display Only Price']}}
- A snapshot of the Display Only Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
{{subscription_order['Plan Chargeable Price Formatted']}}
- A snapshot of the Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product. Formatted as a decimal (e.g. 1.00).
{{subscription_order['Plan Display Only Price Formatted']}}
- A snapshot of the Display Only Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product. Formatted as a decimal. (e.g. 1.00)
{{subscription_order['Plan Interval']}}
- A snapshot of the Interval of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
{{subscription_order['Plan Interval Count']}}
- A snapshot of the Interval Count of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
*Tip: Changes in the Pricing Plan *It's possible to change the price and billing interval of a Subscription. This change will only affect new subscribers and existing customers will continue on the plan they signed up for originally. You can read more about this here: eCommerce Subscriptions - Changing the Price and Billing Interval
When outputting fields, be aware that the Price might have changed globally for a Subscription, while a User may already have an existing Subscription with a different price. When changing their payment Details on the Subscription Detail View, these Users may be reassured to see the price displayed they are paying currently.
For these Users (if they are logged in) there will be two sets of fields available. For example:
{{this.price.price_charge}}
- Shows the current price of the Subscription if a new User were to sign up now.
{{subscription_order['Plan Chargeable Price']}}
- This field, if it is available, shows the price of the older plan that this customer is currently paying. See Subscription Orders in the next section for more of these fields.
You can use logic to display a different price to Users in this situation.
Or alternatively, you can use the default filter:
Tip: Working with the interval As you can see above, there are multiple fields involved in storing the interval of charges, which you can use to display the interval in a user-friendly way. Here's one example of using Liquid to programmatically decide the format to display the Interval:
If the Interval Count is 1, it will use formatting like "per day".
If the Interval Count is greater than 1, it will use formatting like "every 2 days".
Check out all the available Liquid filters over on the platformOS Liquid docs.
The Detail Layout for Subscriptions displays details of the Subscription Product and also a Form for creating/editing Subscription Orders
A Subscription Detail Layout allows you to display detailed content about an individual Subscription product to a customer. It also is an important part of outputting a Subscription Sign Up Form, as these must be outputted within the Layout of the Subscription they will subscribe Users to.
The most common place where Detail Views are displayed is on the automatically generated Detail Page, if you have enabled these. However, they can also be outputted within most Liquid files, including ordinary Pages.
Heading to ECOMMERCE > Settings will allow you to select the Subscriptions tab.
Here you can set up Detail Pages by:
Choosing the slug which will begin the URL to Subscription Detail Pages
Choose a Page Template to use on Subscription Detail Pages
Choose a Detail Layout to use on Subscription Detail Pages
You can use the type
parameter to output a Detail Layout in most Liquid files:
Parameters:
type
- give the value
'detail'
.
layout
- give the name of a Detail Layout for Subscriptions
item_ids
- this parameter is usually optional, but it's essential when you are outputting a Detail View as only one Item ID must be displayed.
Bear in mind that Forms will not work properly inside Emails, so if displaying a Detail Page inside an Email, it is best to provide an alternative Detail Page without the Sign Up Form.
To output the Layout here, you need to add a Detail Layout name to the Liquid as a parameter. Read more here.
Subscription Layouts can be found at the path: layouts/modules/module_14/subscription
Within this folder, you can create a folder for each Layout. Each Layout folder can contain a further "detail" folder containing the wrapper
and item
files it needs.
We provide an example of some logic you can use to explain to logged in Users what the Form will do:
In the case where the User is not currently logged in and is not responding to an email, the logic won't be able to determine the exact status straight away.
Instead, if a non-logged in User tries to Sign up for a Subscription, Siteglide will first log them in and check if they have an active Subscription already. If they do, we'll throw an error, but allow the User to try again if they wish to update their payment details.
Adding a Form to the Detail Layout allows users to Sign Up to this Subscription product. You can read more about creating this Form here.
If you've already created your Form, you can skip this step.
Once you've created a Form and made a note of its ID, you'll be able to add it to your Detail Layout.
As a guide, we've added a Liquid comment to remind you to add your Subscription Sign Up Form to this Layout: `
`
This is just a suggestion, you can actually include your Form anywhere you like in the Layout. Use the following Liquid: <div data-gb-custom-block data-tag="include" data-0='form' data-1='1' data-2='1' data-3=', layout: '></div>
Parameters:
id
- the ID of your Subscription Sign Up Form, you can check this in CMS > Forms. Remember you can use the same Form Layout for all Subscriptions. The this.id field controls which Subscription product is associated with the Form.
layout
- Choose a Form Layout
The wrapper.liquid
file could be used to add any HTML structure you may require around your layout.
You must include the following Liquid, which will output the item.liquid
file for the Subscription Item. Most fields are specific to the Item and will only be available inside the item.liquid
file.
On the Subscription Detail View, we provide you with fields relating to the Subscription and also the Subscription Order for a logged in User.
Subscription Fields
{{this}}
- Output all fields as JSON
{{this.id}}
{{this.weighting}}
{{this.release_date}}
{{this.expiry_date}}
{{this['Description']}}
{{this['Interval']}}
{{this['Interval Count']}}
{{this.full_slug}}
- URL for the Product Detail Page
{{this['Secure Zones']}}
- Array containing the IDs of Secure Zones associated with this Subscription.
{{this.price.id}}
{{this.price.currency}}
{{this.price.price_charge}}
- The chargeable price of this Subscription each Interval. Integer format.
{{this.price.price_display}}
- A field for displaying a secondary price of your choice, e.g. recommended retail price. This is not used by the integration. Integer format
{{this.price.currency_symbol}}
{{this.price.price_charge_formatted}}
- The chargeable price of this Subscription each Interval. Currency format
{{this.price.price_display_formatted}}
- A field for displaying a secondary price of your choice, e.g. recommended retail price. This is not used by the integration. Currency format.
*Subscription Order Fields *If a User is logged in, Siteglide will establish if they have an existing Subscription Order for this Product. Using any of these fields should be done cautiously, as they will not be available if the User is logged out, or if they don't have an existing Subscription.
To determine this, you can use Liquid Logic to hide an entire block of code in which you use these fields:
Fields:
{{subscription_order}}
- Output all Subscription Order fields as JSON
{{active_subscriptions}}
- Array containing all Subscription IDs connected with one of the current User's Subscription Orders, where those orders have status Active
{{subscription_order['Status']}}
- These relate to the Subscription Status in Stripe and are the best way to understand the status of the Subscription Order at a glance. More information available below.
{{subscription_order['Stripe Subscription ID']}}
- This refers to a Subscription on Stripe and can be searched by the Client on the Stripe Dashboard to find out detailed information about this Subscription Order and the associated customer, invoices, payment_intents and charges.
{{subscription_order['Cancel At Period End']}}
- "true" or "false"- if true, this Subscription has been set by the User to be automatically Cancelled at the end of the current billing period. The User has a chance to change their minds until this date.
{{subscription_order['Stripe Plan ID']}}
- The Stripe ID for the Plan this Subscription Order is using. This may be an older plan than the current plan used by the Subscription product.
{{subscription_order['Plan Chargeable Price']}}
- A snapshot of the Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
{{subscription_order['Plan Display Only Price']}}
- A snapshot of the Display Only Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
{{subscription_order['Plan Chargeable Price Formatted']}}
- A snapshot of the Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product. Formatted as a decimal (e.g. 1.00).
{{subscription_order['Plan Display Only Price Formatted']}}
- A snapshot of the Display Only Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product. Formatted as a decimal. (e.g. 1.00)
{{subscription_order['Plan Interval']}}
- A snapshot of the Interval of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
{{subscription_order['Plan Interval Count']}}
- A snapshot of the Interval Count of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
*Tip: Changes in the Pricing Plan *It's possible to change the price and billing interval of a Subscription. This change will only affect new subscribers and existing customers will continue on the plan they signed up for originally. You can read more about this here: eCommerce Subscriptions - Changing the Price and Billing Interval
When outputting fields, be aware that the Price might have changed globally for a Subscription, while a User may already have an existing Subscription with a different price. When changing their payment Details on the Subscription Detail View, these Users may be reassured to see the price displayed they are paying currently.
For these Users (if they are logged in) there will be two sets of fields available. For example:
{{this.price.price_charge}}
- Shows the current price of the Subscription if a new User were to sign up now.
{{subscription_order['Plan Chargeable Price']}}
- This field, if it is available, shows the price of the older plan that this customer is currently paying. See Subscription Orders in the next section for more of these fields.
You can use logic to display a different price to Users in this situation.
Or alternatively, you can use the default filter:
Tip: Working with the interval As you can see above, there are multiple fields involved in storing the interval of charges, which you can use to display the interval in a user-friendly way. Here's one example of using Liquid to programmatically decide the format to display the Interval:
If the Interval Count is 1, it will use formatting like "per day".
If the Interval Count is greater than 1, it will use formatting like "every 2 days".
Check out all the available Liquid filters over on the platformOS Liquid docs.
Customise the Email and Landing Page used to take updated payment methods and authorisation from Subscription customers.
When a Stripe subscription changes status, a customer may need to update their payment details or carry out 3D Secure authorisation.
The email and landing page used in this flow can be customised and branded.
You can find the System Email under Site Manager > System Emails with the name Subscription User Action Required
.
The purpose of this Email is to inform the User that the Subscription Order needs action from them before it can continue to be processed.
You must add a link to the Landing Page where your customer can take action. You can use the Liquid below:
Parameters:
button_text
- sets the text displayed on the button
button_id
- optional - allows you to set the ID of the button
button_class
- optional - allows you to set the class of the button
Subscription Order Fields
{{data.subscription_order}}
- Output all available fields as JSON (except the new_subscription_status - see below).
{{data.subscription_order['User ID']}}
- The ID of the customer in Siteglide.
{{data.subscription_order['Subscription ID']}}
- The ID of the Subscription Order in Siteglide.
{{data.subscription_order['Status']}}
- The previous status of the Subscription Order before the update that triggered this Email
{{data.new_subscription_status}}
- the new status of the Subscription Order. This is the Event which will have triggered the Email.
{{data.subscription_order['Stripe Subscription ID']}}
- The ID of the Subscription in the Stripe Dashboard.
{{data.subscription_order['Cancel At Period End']}}
- "true" or "false"- if true, this Subscription has been set by the User to be automatically Cancelled at the end of the current billing period. The User has a chance to change their minds until this date.
{{data.subscription_order['Stripe Plan ID']}}
- The Stripe ID for the Plan this Subscription Order is using. This may be an older plan than the current plan used by the Subscription product.
{{data.subscription_order['Plan Chargeable Price']}}
- A snapshot of the Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
{{data.subscription_order['Plan Display Only Price']}}
- A snapshot of the Display Only Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
{{data.subscription_order['Plan Chargeable Price Formatted']}}
- A snapshot of the Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product. Formatted as a decimal (e.g. 1.00).
{{data.subscription_order['Plan Display Only Price Formatted']}}
- A snapshot of the Display Only Price of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product. Formatted as a decimal. (e.g. 1.00
{{data.subscription_order['Plan Interval']}}
- A snapshot of the Interval of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
{{data.subscription_order['Plan Interval Count']}}
- A snapshot of the Interval Count of this Subscription Order's plan. This may be an older plan than the current plan used by the Subscription product.
Subscription Fields
{{data.subscription_order.subscription}}
- Output all available fields as JSON
{{data.subscription_order.subscription.name}}
- The name of the Subscription Product
{{data.subscription_order.subscription['Description']}}
{{data.subscription_order.subscription['Image']}}
{{data.subscription_order.subscription['Interval Count']}}
{{data.subscription_order.subscription['Stripe Product ID (Live)']}}
- The ID of the product in Stripe Live Mode
{{data.subscription_order.subscription['Stripe Product ID (Test)']}}
- The ID of the product in Stripe Test Mode
Customer Fields
{{data.subscription_order.related_user}}
- Output all available fields as JSON
{{data.subscription_order.related_user.id}}
- The ID of the User in Siteglide
{{data.subscription_order.related_user.name}}
{{data.subscription_order.related_user.first_name}}
{{data.subscription_order.related_user.last_name}}
{{data.subscription_order.related_user.email}}
*Tip: Changes in the Pricing Plan *It's possible to change the price and billing interval of a Subscription. This change will only affect new subscribers and existing customers will continue on the plan they signed up for originally. You can read more about this here: eCommerce Subscriptions - Changing the Price and Billing Interval
When outputting fields in the email, Subscription Order fields beginning with the word "Plan" will normally be the appropriate choice. These will show the price that these Users will be paying- the original plan when they signed up.
The other Price and Interval fields stored against the Subscription, could be used to show how much the User is saving on their current plan compared to the current price. In the different context of the Subscription Detail Page- we give a different recommendation as here it may not always be possible to identify immediately if the User is subscribed to a different plan.
Tip: Working with the Interval Fields As you can see below, there are multiple fields involved in storing the Interval of charges, which you can use to display the Interval in a user-friendly way. Here's one example of using Liquid to programmatically decide the format to display the Interval:
If the Interval Count is 1, it will use formatting like "per day".
If the Interval Count is greater than 1, it will use formatting like "every 2 days".
Check out all the available Liquid filters over on the platformOS Liquid docs.
You can find the System Page under Site Manager > System Emails
with the name Subscription User Action Required
.
The purpose of this Page is to provide a reliable URL where the above email can send Users to update their Payment Method. We'll provide the URL parameters to let the Page know which Subscription and Subscription Order to load. We'll also provide security to check that the User owns that Subscription Order before continuing.
This page may function very similarly to the standard Subscription Detail Page, however, you do have the option to use a different Layout or logic if you prefer.
The following Liquid will include a Subscription Detail Layout for the Subscription referenced in the link from the above Email. Note, this is different from the usual Liquid for including a Layout, because Siteglide will in this case be setting some of the parameters for you automatically.
Parameters:
subscription_detail_page_layout
- This allows you to choose which Detail Layout will be used for the Subscription Detail View. You can choose a different Layout than you use on your Subscription Detail Page.
If that Detail Layout contains a Form, we'll use the URL parameters to set the Form to edit the payment details for the correct Subscription Order referenced in the link from the Email.
You can add any other static content you like to this Page, but we recommend you use the Subscription Detail Layout itself to add any dynamic content and you can see available fields there.
In the eCommerce Module, a formatted price is generated so partners can quickly output the correct price. However, you may sometimes need to convert a "raw" price integer to a currency format.
Instead, we can include price_formatter
, which will convert the price from cents to dollars (or your currency's equivalent)
Here my_price_variable
is the variable containing a price you'd like to format. This will then output the formatted price.
The customer can schedule their Subscription to end, while continuing to use services until the end date.
Ending a Subscription is not as simple as deleting most database objects. The customer may wish to arrange for their Subscription to end, but they may wish to continue using the services they've paid for until the end of the billing period!
When a User "cancels" a Subscription front-end, we send an API call to Stripe, instructing them to mark the Subscription to be cancelled at the end of the current billing period.
Subscription Orders marked for cancellation will have the field "cancel_at_period_end" ("module_field_14/subscription_order_9") marked as "true". This corresponds to the equivalent property on Stripe.
The following Liquid can be added within a user_subscriptions
List Layout:<div data-gb-custom-block data-tag="-" data-0='ecommerce/subscription_cancel'></div>
You may wish to use logic to only show the button when it can be used.
Until that time, we'll allow Users to change their mind and choose not to cancel the Subscription after all. This removes the property from the Stripe subscription cancel_at_period_end
and the Subscription will remain in its current state: `
`
You may wish to use logic to only show the button when it can be used.
Both buttons could be combined in the logic as follows:
The option to cancel a Subscription item immediately is available on the Stripe Dashboard.
When the actual change of status to canceled
takes place on Stripe, either because of an action on the Dashboard, or because Siteglide queued it to happen at the end of the billing period, Stripe will send a customer.subscription.deleted
event to Siteglide. We'll then also remove the database object from your Site, and stop provisioning the Secure Zone Access.
Some layouts have a wrapper and an item file, while other layouts have a single Liquid file.
Checkout and Quote Forms use ordinary Form Layouts, despite using a different Liquid tag to output them. The marketplace_builder/views/partials/layouts/modules/module_14/checkout directory doesn't store a Checkout layout, instead it stores an "empty" file which will be displayed instead of Checkout if the Cart is empty.