Accessing Library from Javascript

Last modified March 24, 2017

An advanced alternative to using HTML Markup directives is to access the Store Builder Library directly from Javascript utilizing available public methods.

The Flow

Store Builder Library is a wrapper around a set of private APIs allowing vendors to manipulate the cart contents for a given visitor. All calls made to the Library will be converted into API requests and published to the backend expecting a response with current cart contents and order parameters – the "order object". Given sophisticated cart population logic, various cross-sell and up-sell scenarios, and other features of the platform, each request might result in significant changes to the order object. Therefore, we recommend that you rely on the most current data after each request and avoid caching responses. 

All requests to the Library are made in the form of the "Session Object" which will be converted to the internal API directives. The Session Object can be used for passing order details to the Store without requiring the use of a secure payload.

Understanding the Session Object

The Session Object is a standard Javascript object which contains directives for the Library. 

The Session object might contain the following fields:

  • coupon – String, must contain a valid coupon. If empty string is passed coupon (if any was previously applied) will be removed from the cart. 
  • products – Array of objects, each object representing a valid product. Must contain at least product ID and quantity. To place product in the cart pass any non-zero quantity, to remove product from the cart pass quantity as 0. Example: {'path' : 'arkanoid', 'quantity': 1}. The product object might also contain a complete product definition when used as part of the secure payload. See Passing sensitive data with Secure Requests for more information.
  • checkout – Accepts "true" or SessionID string which you have obtained after pre-creating a session using the server API. If "true" is passed the visitor will be redirected to checkout after performing other operations. If Session ID is passed as a parameter all other fields will be ignored and visitor will be redirected to checkout.
  • clean – Boolean. If set to "true" the session will be cleaned for the visitor after redirecting to checkout. This parameter only makes sense if "data-continuous" is set to "true" when initializing the Library. The intention of this behavior is to make sure that the customer will return to the "clean" cart after attempting a checkout. 
  • reset – Boolean. If set to "true" resets the session, but does this immediately when called, before all other actions.
  • secure – String (for Live storefronts) OR Object (for test storefronts). Contains secure payload, see "Passing sensitive data with Secure Requests for details. 
  • tags – Any valid Javascript object. Any data can be passed using tags and it will be made available to vendor via webhooks and server events. For example, tags can be used in secure payloads if you want to change a product's price for a specific customer or for price A/B testing. For more information on tags see Passing and capturing custom order tags and product attributes.
  • language – A string representing two-letter language code to force a different checkout language
  • country – A string representing two-letter country code to force a different checkout country
  • paymentContact – object representing "tentatively" known visitor details. Applies "tentatively" known (unconfirmed) customer information to the order but won't hide input fields during checkout process. To pass "known" and "confirmed" information refer to Passing sensitive data with Secure Requests. The structure of this object is: 

    {'email': email,'firstName': firstName,'lastName': lastName, 'company': company, 'addressLine1': addressLine1, 'addressLine2': addressLine2, 'city': city, 'region': region, 'country': country, 'postalCode': postalCode, 'phoneNumber': phoneNumber}

Once created, the Session Object is usually passed to the Library by utilizing generic fastspring.builder.push() method:

var s = {
	'reset': true, // reset the cart and session (will remove everything added to the cart or passed to the session prior to this)
	'products' : [
					{
						'path':'arkanoid',
						'quantity': 1 // add product "arkanoid" to the cart with quantity "1".
					}
	],
	'coupon': 'YOUR10OFF', // apply coupon to the order
	'checkout': true // once all of the above is done redirect to checkout
}

fastspring.builder.push(s); // call Library "Push" method to apply the Session Object. 

Initializing the Library with the Session Object

The Library will make a first request to the FastSpring backend immediately when initialized. Sometimes your website flow requires you to pass data to the Library before the first request is even made. 

To allow this behavior you can place a Session Object into the variable named "fscSession" before initializing the Library:

<script>
var fscSession = {
	'reset': true,
	'products' : [
					{
						'path':'arkanoid',
						'quantity': 1
					}
	],
	'coupon': 'YOUR10OFF'
}
</script>
<script
	id="fsc-api"
	src="https://d1f8f9xcsvx3ha.cloudfront.net/sbl/0.7.1/fastspring-builder.min.js" type="text/javascript" 
...

If you define the "fscSession" variable before the API is loaded, its contents are executed with the first priority. In this example, the session will be reset (breaking continuous mode), the "arkanoid" product will be added to cart, and a coupon will be applied immediately when loading the API.

Public methods exposed by the Library

After the Library is loaded, your webpage can access it using public methods.

The core method is called fastspring.builder.push(payload);

fastspring.builder.push takes a Session Object payload as input and applies data to the session. 

var s = {
	'products' : [
					{
						'path':'arkanoid',
						'quantity': 1
					}
	],
	'coupon': 'YOUR10OFF',
	'checkout': true
}

fastspring.builder.push(s);

Each call to fastspring.builder.push() method will usually result in an updated order data obtained from FastSpring backend. If you registered callback functions when initializing the Library your functions will be called with corresponding data on each request made allowing you to create a tight integration between platforms. See Getting Started with Store Builder Library for more information.

Additional public methods

In addition to fastspring.builder.push() Library exposes a number of public methods. All of them are easy-to-use wrappers around fastspring.builder.push(). 

  • fastspring.builder.checkout() – Expects either no input or a session ID obtained after pre-creating a session using the server API. 
  • fastspring.builder.promo(code) – Takes coupon code as input, applies it to the cart. 
  • fastspring.builder.update(productId,qty) – Takes product ID and quantity as input, updates specified product's quantity in the cart. Example: ('product-path',1)
  • fastspring.builder.add(productId) – Takes product ID as input, adds product to cart.
  • fastspring.builder.remove(productId) – Takes product ID as input, removes product from the cart.
  • fastspring.builder.tag(key,value) – Takes key and value as input, applies tag to the session.
    Note:  The sum of the number of characters supplied for the key and the value must not exceed approximately 4,000 characters. 
  • fastspring.builder.reset() – No input, resets the cart immediately.
  • fastspring.builder.clean() – No input, resets the cart after redirecting to checkout.
  • fastspring.builder.secure(securePayload, secureKey) – Takes secure payload (encrypted or plain text, depending on the storefront state) and secure key as input, applies secure payload to the current session. See Passing sensitive data with Secure Requests.
  • fastspring.builder.authenticate(securePayload, secureKey) – Takes secure payload (encrypted or plain text, depending on the storefront state) and secure key as input and if payload contains customer id redirects customer to the account/subscription management page.
  • fastspring.builder.recognize({paymentContact object}) – Applies "tentatively" known (unconfirmed) customer information to the order but won't hide input fields during checkout process. See paymentContact object above for object definition.
    To pass "known" and "confirmed" information refer to Passing sensitive data with Secure Requests.
  • fastspring.builder.country(countryCode) – Change checkout country to the "countryCode" (where countryCode is a two-letter country code – "US", "DE", ...)
  • fastspring.builder.language(language) – Change checkout language to "language" (where language is a two-letter language code – "es", "de", ...)

Public methods callback function

All public methods accept an additional parameter – callback function. This function will be called after the specific request was made. Unlike generic "data-data-callback" which is called once for a request chain (meaning that if multiple consequent requests are made only last request will return order object) callback functions passed to public methods will be called with the order object resulted from the call giving you more flexibility around integration. 

 fastspring.builder.add("arkanoid", function(data){
 
	console.log("Added 'arkanoid' and it resulted in the following order object", data);
 
});

Callback function is always passed as the last parameter. 

fastspring.builder.checkout() method does not accept callback function as a parameter due to its "finite" nature.

Errors

Some requests might result in errors received from server. All errors are fatal – if an error is encountered processing stops and error is returned. The easiest way to handle errors is to declare "error callback" function when initializing the Library.

In case of an error the body of the response will contain one of the following "codes":

General session related

  • session-payload-invalid – Couldn't understand the data in the "session" parameter.
  • session-expired – Serialized session data has expired.
  • empty-session – Tried to finalize / checkout a session with no items.
  • path-not-found – Couldn't find the product variation referenced in session data.
  • envelope-invalid – Error parsing secure payload

Adding a product

  • quantity-invalid – Passed a bad quantity value.
  • not-removable – Product is not allowed to be removed from the session.
  • path-not-found – Couldn't find the product variation.

Order object response fields

 {
  "order": {
    "currency": "EUR",
    "total": "€115.99", // order total, this will be charged
    "totalValue": 115.99, // order total value without the currency sign
    "tax": "€18.52", // tax (usually included in the order total)
    "taxValue": 18.52,
    "totalWithTax": "€115.99",
    "totalWithTaxValue": 115.99,
    "discountTotal": "€0.00", // total discount for the order
    "discountTotalValue": 0.0, 
    "taxPriceType": "included", // if tax is included in total or not
    "taxType": "EU",
    "taxRate": "19%",
    "groups": [ // product items, can be multiple groups with multiple items
      {
        "items": [
          {
            "selected": true, // if the item is in the order. 
            "path": "example-product-id", // item id and path
            "pid": "JSON Example Product", // item title in the dashboard, do not present it to visitors
            "quantity": 1, // quantity
            "price": "€115.99", // unit price
            "priceValue": 115.99, 
            "priceTotal": "€115.99", // unit price multiplied by quantity
            "priceTotalValue": 115.99,
            "unitPrice": "€115.99",
            "unitPriceValue": 115.99,
            "unitDiscountValue": 0.0,
            "discountPercentValue": 0.0,
            "discountTotal": "€0.00",
            "discountTotalValue": 0.0,
            "total": "€115.99", // this price will be charged. it accounts for quantity, discounts and unit price. 
            "totalValue": 115.99,
            "removable": false, // if visitor is allowed to remove product from cart
            "image": "https://d8y8nchqlnmka.cloudfront.net/zf316iSbRww/HrRE7Ao7SFo/tumblr_mldolkbFor1qb6e3ao1_500.png", // product image
            "display": "Example Product", // product display name
            "description": {
              "summary": "<p>Description of an example product</p>",
              "full": "<p>Long description of an example product</p>",
              "action": "<p>Add to Cart</p>"
            },
            "pricing": {
              "quantity": "allow" // allow: visitor is allowed to change quantity. lock: visitor is shown quantity, but can't change. hide: visitor can't see quantity
            },
            "groups": [ // if item contains up-sells, options, choose-one and choose-many configuration parameters they will appear here. the format is the same as the parent item.
            ]
          }
        ],
        "selections": true // if this group of items contains selected items
      },
      {
        "display": "You might also be interested in...", // some group items will have their own display names. It means that items in the group have a header.
        "driver": "example-product-id", // if group lists the "driver" it means that it's present because it is defined as a cross-sell group for a specific item or storefront
        "type": "add", // type: add means that this is a group of "additions" – cross-sells
        "selections": false, 
        "items": [
          {
            "selected": false, // items is not in the order
            "path": "example-cross-sell",
            "pid": "JSON Example Product",
            "quantity": 1,
            "price": "€115.99",
            "priceValue": 115.99,
            "priceTotal": "€115.99",
            "priceTotalValue": 115.99,
            "unitPrice": "€115.99",
            "unitPriceValue": 115.99,
            "unitDiscountValue": 0.0,
            "discountPercentValue": 0.0,
            "discountTotal": "€0.00",
            "discountTotalValue": 0.0,
            "total": "€115.99",
            "totalValue": 115.99,
            "removable": true,
            "image": "https://d8y8nchqlnmka.cloudfront.net/zf316iSbRww/HrRE7Ao7SFo/tumblr_mldolkbFor1qb6e3ao1_500.png",
            "display": "Example Cross-sell Product",
            "description": {
              "summary": "<p>Example Cross-sell Product Description</p>",
              "full": "<p>Long Example Cross-sell Product description</p>",
              "action": "<p>Add to Order</p>"
            },
            "pricing": {
              "quantity": "allow"
            },
            "groups": [
            ]
          }
        ]
      }
    ],
    "coupons": [ // coupons applied to the order
    ],
    "selections": true
  },
  "paymentOptions": [ // list of payment options available for this order. vendors can/should only list supported payment methods without trying to implement them. vendors cannot and should not pass selected payment method to FastSpring as of now.
    {
      "type": "card",
      "variants": [
        {
          "type": "visa"
        },
        {
          "type": "mastercard"
        },
        {
          "type": "amex"
        },
        {
          "type": "jcb"
        }
      ],
      "requireContact": true,
      "requireBillingPostal": false,
      "requireCard": true,
      "requireShipping": false,
      "currency": "EUR",
      "match": true
    },
    {
      "type": "paypal",
      "variants": [
      ],
      "requireContact": false,
      "requireBillingPostal": false,
      "requireCard": false,
      "requireShipping": false,
      "currency": "EUR",
      "match": true
    },
    {
      "type": "sofort",
      "variants": [
      ],
      "requireContact": true,
      "requireBillingPostal": false,
      "requireCard": false,
      "requireShipping": false,
      "currency": "EUR",
      "match": true
    },
    {
      "type": "giropay",
      "variants": [
      ],
      "requireContact": true,
      "requireBillingPostal": false,
      "requireCard": false,
      "requireShipping": false,
      "currency": "EUR",
      "match": true
    },
    {
      "type": "wire",
      "variants": [
      ],
      "requireContact": true,
      "requireBillingPostal": false,
      "requireCard": false,
      "requireShipping": false,
      "currency": "EUR",
      "match": true
    }
  ],
  "session": {
// information in this object should be ignored
  },
  "country": "DE", // visitor defined country
  "countryDisplay": "Germany",
  "countryRequiresPostalCode": false,
  "countryRequiresRegion": false,
  "language": "en", // language used for theme display
  "languageDisplay": "English",
  "defaultLanguage": false,
  "live": false // if the storefront is live
}