📍 Bolt / Developers / Developer Guides / Checkout Setup / Custom API Checkout / Set Up SSO Commerce For Custom API Integrations

Set Up SSO Commerce For Custom API Integrations

Use this guide to set up Bolt’s SSO Commerce on your Custom Cart store.

Login Workflow

When a shopper selects your Login or Register button, the Bolt modal is displayed for them to input their account credentials. This triggers the following series of actions:

  1. Bolt sends an authorization code to an endpoint in your system from the shopper’s browser.
  2. Your system sends a POST request to Bolt, using the authorization code provided.
  3. Bolt sends your system an ID token containing:
    • ✓ Shopper’s External ID
    • ✓ Shopper’s Bolt Account Email Address
  4. Your system then must make one of the following decisions:
    • ID is recognized: Log the shopper into your store.
    • ID not recognized: Create a new account, log the shopper in, and record the ID.
    • Email Recognized & Verified: Log the shopper in and record the ID.
    • Email Recognized & Not Verified: Throw an error.
  5. If logged in, your system then redirects the shopper to the My Account page.

How to Integrate with SSO Commerce

You must validate the ID Token and the Signing Secrets used in all of your interactions with Bolt. See Environment Details for a full list of keys and URLs.

1. Export Accounts

You must export your existing shopper accounts in the following xml format:

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:element name="Customers">
    <xs:complexType>
      <xs:sequence>
        <xs:element minOccurs="0" maxOccurs="unbounded" name="Customer">
          <xs:complexType>
            <xs:sequence>
              <xs:element name="Customer_ID" type="xs:string" />
              <xs:element name="First_Name" type="xs:string" />
              <xs:element name="Last_Name" type="xs:string" />
              <xs:element name="Email" type="xs:string" />
              <xs:element name="Phone" type="xs:string" />
              <xs:element name="Date_Joined" type="xs:string" />
              <xs:element name="Addresses">
                <xs:complexType>
                  <xs:sequence>
                    <xs:element minOccurs="0" maxOccurs="unbounded" name="Item">
                      <xs:complexType>
                        <xs:sequence>
                          <xs:element name="Address_First_Name" type="xs:string" />
                          <xs:element name="Address_Last_Name" type="xs:string" />
                          <xs:element name="Address_Line_1" type="xs:string" />
                          <xs:element name="Address_Line_2" type="xs:string" />
                          <xs:element name="City" type="xs:string" />
                          <xs:element name="State" type="xs:string" />
                          <xs:element name="Zip" type="xs:string" />
                          <xs:element name="Country_Code" type="xs:string" />
                          <xs:element name="Address_Phone" type="xs:string" />
                        </xs:sequence>
                      </xs:complexType>
                    </xs:element>
                  </xs:sequence>
                </xs:complexType>
              </xs:element>
            </xs:sequence>
          </xs:complexType>
        </xs:element>
      </xs:sequence>
    </xs:complexType>
  </xs:element>
</xs:schema>

Important

  • Date_Joined must be provided in RFC 3339 format (e.g. 2021-08-15T19:16:21.0Z).
  • Country_Code must be a two-letter country code as indicated by ISO 3166-1’s alpha-2 codes.

Example

Example

<?xml version="1.0" encoding="UTF-8"?>
	<Customers>
		<Customer>
			<Customer_ID><![CDATA[1]]></Customer_ID>
			<First_Name><![CDATA[Amanda]]></First_Name>
			<Last_Name><![CDATA[Andersen]]></Last_Name>
			<Email><![CDATA[amanda@example.com]]></Email>
			<Phone><![CDATA[2125551111]]></Phone>
			<Date_Joined><![CDATA[2020-08-29T19:16:21.0Z]]></Date_Joined>
			<Addresses>
				<Item>
					<Address_First_Name><![CDATA[Amanda]]></Address_First_Name>
					<Address_Last_Name><![CDATA[Andersen]]></Address_Last_Name>
					<Address_Company><![CDATA[Amanda's Surfboards]]></Address_Company>
					<Address_Line_1><![CDATA[5000 Wilshire Blvd]]></Address_Line_1>
					<Address_Line_2><![CDATA[Ste 300]]></Address_Line_2>
					<City><![CDATA[San Diego]]></City>
					<State><![CDATA[CA]]></State>
					<Zip><![CDATA[91950]]></Zip>
					<Country_Code><![CDATA[US]]></Country_Code>
					<Address_Phone><![CDATA[2125551111]]></Address_Phone>
				</Item>
                <Item>
					<Address_First_Name><![CDATA[Amanda]]></Address_First_Name>
					<Address_Last_Name><![CDATA[Andersen]]></Address_Last_Name>
					<Address_Company><![CDATA[Amanda's Snowboards]]></Address_Company>
					<Address_Line_1><![CDATA[600 Jefferson Ave]]></Address_Line_1>
					<Address_Line_2><![CDATA[]]></Address_Line_2>
					<City><![CDATA[Surrey]]></City>
					<State><![CDATA[BC]]></State>
					<Zip><![CDATA[V1M 3B5]]></Zip>
					<Country_Code><![CDATA[CA]]></Country_Code>
					<Address_Phone><![CDATA[2125551111]]></Address_Phone>
				</Item>
			</Addresses>
		</Customer>
		<Customer>
			<Customer_ID><![CDATA[2]]></Customer_ID>
			<First_Name><![CDATA[Buster]]></First_Name>
			<Last_Name><![CDATA[Baker]]></Last_Name>
			<Email><![CDATA[buster@example.com]]></Email>
			<Phone><![CDATA[8885558888]]></Phone>
			<Date_Joined><![CDATA[2019-11-24T14:00:00.0Z]]></Date_Joined>
			<Addresses>
				<Item>
					<Address_First_Name><![CDATA[Buster]]></Address_First_Name>
					<Address_Last_Name><![CDATA[Baker]]></Address_Last_Name>
					<Address_Company><![CDATA[]]></Address_Company>
					<Address_Line_1><![CDATA[3330 North 13th Street]]></Address_Line_1>
					<Address_Line_2><![CDATA[]]></Address_Line_2>
					<City><![CDATA[Independence]]></City>
					<State><![CDATA[KS]]></State>
					<Zip><![CDATA[67301]]></Zip>
					<Country_Code><![CDATA[US]]></Country_Code>
					<Address_Phone><![CDATA[8885558888]]></Address_Phone>
				</Item>
			</Addresses>
		</Customer>
	</Customers>

2. Import Accounts

Reach out to Bolt for assistance with uploading your exported accounts.

3. Create Database Table

You must create a new database table used to link external IDs Bolt provides with the accounts found in your existing account management system. This table is updated in Step 4 of the Login Workflow.

Example External_Account Database Table
External Ids (Bolt) Internal Ids
<external-bolt-id#1> <internal-id#1>

4. Install Login/Register Button

The following steps must be completed on every page where shoppers can log in or register an account.

  1. Add a div element with the class name bolt-account-sso.
    <div class="bolt-account-sso" />
    
  2. Add the following account.js script:
    <script>
         var insertAccountScript = function () {
             var scriptTag = document.getElementById('bolt-account');
             if (scriptTag) {
                 return;
             }
             scriptTag = document.createElement('script');
             scriptTag.setAttribute('type', 'text/javascript');
             scriptTag.setAttribute('async', '');
             scriptTag.setAttribute('src', 'https://account.bolt.com/account.js');
             scriptTag.setAttribute('id', 'bolt-account');
             scriptTag.setAttribute('data-publishable-key', <insert publishable key>);
             document.head.appendChild(scriptTag);
         }
         function insertButtons() {
             if (typeof BoltAccount === 'undefined') {
                 window.setTimeout(insertButtons, 100);
                 return;
             }
             BoltAccount.injectButtons();
         }
         insertAccountScript();
         insertButtons();
     </script>
    

Custom Buttons: To create your own button with custom styling, simply add the bolt-sso-custom class to your element. This enables the account.js script to inject an onClick event, which opens Bolt’s login/registration modal.

5. Build Endpoints

Refer to the Merchant API spec for schema information, authentication, and query parameters.

GetAccount Endpoint

Bolt calls your /api-merchant/#operation/account.get endpoint when checking for a shopper’s account. This endpoint should accept POST requests that are signed with Bolt’s Signing Secret and contain the shopper’s email address.

Example JSON Request
{ email: <the email address> }
  • Success: HTTP OK
  • Failure: 404 Not Found

Build an OAuth Login Endpoint

Bolt calls your /oauth/login endpoint when attempting to log a shopper into your system. This endpoint should accept GET requests that contain all of the following query parameters:

  • Authorization Code
  • State
  • Scope
  • Order ID (optional)
Example URL with Parameters
https://website.com/bolt-login?code=A&state=B&scope=C&order\_id=D

How to Handle the Request

  1. Validate the query params.
    • State: must be an 8 character string.
    • Scope: must be openid.
  2. Exchange the authorization code for an ID token with Bolt’s /v1/oauth/token endpoint.
  3. Fetch Bolt’s RSA public key:
    1. Fetch Bolt’s Open ID configuration from Bolt’s /.well-known/configuration endpoint.
    2. Fetch Bolt’s RSA public key from the jwks_uri indicated in the Open ID configuration.
  4. Parse and validate the ID token using Bolt’s RSA public key.
    • You can use any standard JWT validation library to do this.
  5. Use the ID token to determine if an account already exists for the shopper.
    • ID is recognized: Log the shopper into your store.
    • ID not recognized:
      • If Email Recognized & Bolt Verified: Create a new account, log the shopper in, and record the external-id by creating a new entry in the External_Account table.
      • If Email Recognized & Not Bolt Verified: Throw an error.
  6. Link the Order ID, if provided, to the logged-in account.
👎

How did we do?

📖On This Page