đź“Ť Bolt Help / Add-Ons / Account Linking
Account Linking
Connect your existing store accounts to Bolt accounts and register new shoppers to your account system with a simple checkbox.

Account Linking enables merchants to tap into Bolt Shopper Accounts and link them with your own store’s accounts using the shopper’s email address. This ensures shoppers can use the Bolt Accounts to check out without needing to log in on your site multiple times.

Availability

SSO vs. Account Linking

What is the difference between SSO and Account Linking?

With SSO:

  • Bolt fully takes over the shopper’s login experience.
  • Bolt provides social login, biometrics authentication, and other innovations for secure and quick login.
  • All shoppers log into and out of their merchant accounts via the Bolt-hosted surfaces.

With Account Linking:

  • The merchant retains control of the login experience, allowing for maximum customization via our direct API design.
  • The merchant decides when to leverage Bolt’s passwordless login or rely on the merchant’s native login experience.

Before You Start

Before you start, you must have successfully implemented Bolt Ignite.

Sequence Diagram

Click to expand.

Step 1: Fetch an ID Token

Use the OAuth Endpoint (v1/oauth/token) to fetch shopper account information, as noted in the Accounts setup guide, but with the following specifications to exchange an authorization code (authorization_code) for an ID token (id_token).

Parameter Requirements
state Must be an 8-character string.
scope Must include openid.

Example

client_id=PUBLISHABLE_KEY_PLACEHOLDER&client_secret=API_KEY_PLACEHOLDER&code=AUTH_CODE_PLACEHOLDER&grant_type=authorization_code&scope=bolt.account.manage%2Bopenid&state=EIGHT_CS
{
  "access_token": "$ACCESS_TOKEN",
  "expires_in": 3600,
  "id_token": "$ID_TOKEN",
  "refresh_token": "$REFRESH_TOKEN",
  "refresh_token_scope": "bolt.account.view",
  "scope": "bolt.account.manage",
  "token_type": "bearer"
}

Step 2: Fetch Bolt’s RSA Public Key

Fetch Bolt’s RSA public key using our Open ID Configuration authentication protocol via our /.well-known/openid-configuration endpoint.

  • Sandbox: https://api-sandbox.bolt.com/.well-known/openid-configuration
  • Production: https://api.bolt.com/.well-known/openid-configuration

The RSA key is exposed in response as jwks_uri:

{
  "issuer": "https://api-sandbox.bolt.com", // production: `https://api.bolt.com/.well-known/openid-configuration`
  "authorization_endpoint": "https://api-sandbox.bolt.com/v1/oauth/authorize",
  "token_endpoint": "https://api-sandbox.bolt.com/v1/oauth/token",
  "jwks_uri": "https://api-sandbox.bolt.com/v1/oauth/jwks.json",
  "response_types_supported": [
    "id_token",
    "code",
    "token",
    "id_token token",
    "code id_token",
    "code token",
    "code id_token token"
  ],
  "grant_types_supported": ["authorization_code", "refresh_token"],
  "subject_types_supported": ["public"],
  "id_token_signing_alg_values_supported": ["RS256"],
  "scopes_supported": ["openid", "bolt.account.manage", "bolt.account.view"]
}

Step 3: Parse the ID Token

TIP

When you set up Bolt Accounts, require a shopper to input their email address when logging into your store account.

You must parse the ID token using the RSA Public Key to retrieve the Bolt Account email address to validate it against your own store’s account email addresses.

You can use any standard JWT validation library to do this.

Step 4: Write Logic to Trigger a Successful Store Account Login

Ensure your store site has logic that determines whether the Bolt email address parsed from the ID token matches one of your store accounts. If there is a validated match, the shopper should experience a successful store account login.

// Sample list of ecommerce store accounts
const storeAccounts = ['john@example.com', 'jane@example.com', 'mark@example.com'];

function login(email) {
  // Check if the email matches any of the store accounts
  const isValidEmail = storeAccounts.includes(email);

  if (isValidEmail) {
    // Successful login, perform further actions
    console.log('Successfully logged in!');
    // Perform additional operations like setting cookies, redirecting, etc.
  } else {
    // Invalid email address, display an error or take appropriate action
    console.log('Invalid email address');
  }
}

// Example usage:
const emailFromToken = 'john@example.com'; // Replace with the parsed email from ID token
login(emailFromToken);
import React, { useState } from 'react';

// Sample list of ecommerce store accounts
const storeAccounts = ['john@example.com', 'jane@example.com', 'mark@example.com'];

const LoginForm = () => {
  const [email, setEmail] = useState('');
  const [loggedIn, setLoggedIn] = useState(false);

  const handleEmailChange = (e) => {
    setEmail(e.target.value);
  };

  const handleLoginFormSubmit = (e) => {
    e.preventDefault();

    // Check if the email matches any of the store accounts
    const isValidEmail = storeAccounts.includes(email);

    if (isValidEmail) {
      // Set the logged in state to true
      setLoggedIn(true);
    } else {
      // Invalid email address, display an error or take appropriate action
      console.log('Invalid email address');
    }
  };

  return (
    <div>
      {loggedIn ? (
        <div>
          <h2>Successfully logged in!</h2>
          {/* Display logged-in user information */}
        </div>
      ) : (
        <form onSubmit={handleLoginFormSubmit}>
          <h2>Login</h2>
          <input
            type="email"
            value={email}
            onChange={handleEmailChange}
            placeholder="Email address"
            required
          />
          <button type="submit">Login</button>
        </form>
      )}
    </div>
  );
};

export default LoginForm;