Options
All
  • Public
  • Public/Protected
  • All
Menu

@arc/sdk

@arc-publishing/sdks

Getting Started

sdk-identity

This package is responsible for interacting with the Identity API. It will handle managing the JWT, sign-in, sign-out, registration and any other self-service account management functions.

Built w/ TypeScript and bundled with webpack and published to npm.

The sdk-identity can be loaded using the sdk-loader by passing the id identity.

sdk-sales

This package is responsible for interacting with the Sales API. It will handle creating orders and processing payments.

Built w/ TypeScript and bundled w/ webpack and published to npm.

The sdk-sales can be loaded using the sdk-loader by passing the id sales.

sdk-groups

This package is responsible for interacting with the group packages features of the Sales API. It will handle joining & leaving group subscriptions.

Built w/ TypeScript and bundled w/ webpack and published to npm.

sdk-amp

This package is responsible for interacting with AMP. It will handle taking an AMP READER_ID, storing it in localStorage or cookies, and interacting with the Sales API to associate a READER_ID to a logged in user.

Built w/ TypeScript and bundled w/ webpack and published to npm.

Error Handling

A note about errors: All errors listed below will be returned as a JSON object in this shape:

{
  "code": "string",
  "message": "string"
}

If an error is not listed, you can assume that generic errors will be used (with a code of 0) to denote a connection problem unrelated to the API's functions.

Getting Started

Pre-requisites

  • NodeJS & NPM
  • window.Promise & window.Fetch, or equivalent polyfills

Installation

The Arc Identity & Sales SDKs are published to NPM.

Once you have npm installed, to install the Arc SDKs, simply execute the following in your npm project:

> npm i @arc-publishing/sdk-identity @arc-publishing/sdk-sales

Once you have them installed, include the SDKs in your code:

import Identity from '@arc-identity/sdk-identity';
import Sales from '@arc-identity/sdk-sales';

Set-up

In order for the Arc SDKs to hit the right API endpoints, you should specify an API Origin before calling any other SDK methods. This is done by calling Identity.options and Sales.options:

Identity.options({
  apiOrigin: '{your api origin here}'
});

Sales.options({
  apiOrigin: '{your api origin here}'
});

Examples

How to implement Login

Once you have the Identity SDK installed & your API Origin is set up, you can use login to login your user & create an authenticated session.

The following demonstrates how this is done in a typical React component, using hooks:

import React, { useState } from 'react';
import Identity from '@arc-publishing/sdk-identity';

export const Login = () => {
  const [username, setUsername] = useState();
  const [password, setPassword] = useState();

  return (
    <section>
      <form
        onSubmit={e => {
          e.preventDefault();
          return Identity.login(username, password)
            .then(userIdentity => {
              console.log('success!', userIdentity);
              // send the user to an authenticated route
            })
            .catch(e => {
              console.error(e);
              // handle your error here
            });
        }}
      >
        <label htmlFor="username">Username</label>
        <input
          name="username"
          id="username"
          type="text"
          onChange={e => setUsername(e.target.value)}
          value={username}
        />
        <label htmlFor="password">Password</label>
        <input
          name="password"
          id="password"
          type="password"
          onChange={e => setPassword(e.target.value)}
          value={password}
        />
        <button>Login</button>
      </form>
    </section>
  );
};

If Identity.login is successful, the SDK will receive an auth & refresh token and save them to the browser. These tokens can be accessed at Identity.userIdentity.

Identity.login takes an optional options object as its third parameter.

When logging in without specifying an options object or {rememberMe: false} as the options object, the SDK will save the user's tokens to the browser SessionStorage & will clear these tokens at the end of the browser session.

If you pass in {rememberMe: true}, the SDK will save the user's tokens to the browser's LocalStorage & persist tokens between browser sessions.

To check if a user is currently logged in, call Identity.isLoggedIn() isLoggedIn

How to add items to cart & checkout

The end-to-end checkout flow involves these steps, in this order:

  1. Add an item to the cart
  2. Create an order
  3. Initialize a payment with a payment provider
  4. Present a payment form to the user to collect payment details (credit card #, billing info, etc.)
  5. Finalize the payment & record the transaction in Arc

We also provide an Express Checkout flow which allows users to checkout without being logged-in (anonymous user), following the above steps with some small differences & the addition of a final step:

  1. Add an item to the cart
  2. Create an order, collecting the user's email address
  3. Initialize a payment with a payment provider
  4. Present a payment form to the user to collect payment details (credit card #, billing info, etc.)
  5. Finalize the payment & record the transaction in Arc
  6. Present a login or registration form to the user. If the email address in step 2 is associated with an existing account, the order is added to that account & the user should log in to that account to enjoy the subscription. If the email is not already registered in Arc Identity, the user should register a new account with that email to enjoy the order.

Note that when checking out with an anonymous user during an express checkout, a browser cookie is used to associate the browser session to the cart tracked in Arc Sales.

Adding an item to your cart

Simply call addItemToCart with your items like so:

Sales.addItemToCart([
  {
    sku: 'item01',
    priceCode: 'your-price-code',
    quantity: 1
  },
  {
    sku: 'item02',
    priceCode: 'other-price-code',
    quantity: 1
  }
]);

These values can be queried from the Arc Retail API.

You can call Sales.cart to get the user's current cart.

Calling Sales.getCart (getCart) will return the latest version of the cart available from the server.

Sales.removeItemFromCart (removeItemFromCart) will remove the item (by sku) from the cart & Sales.clearCart (clearCart) will empty the user's cart.

Creating an Order

Once the user has filled their cart with the items they wish to purchase, call Sales.createNewOrder See createNewOrder for a full list of accepted parameters.

If this is an express checkout, an email address must be provided.

  Sales.createNewOrder(
    {
      line1: "123 Main St.",
      line2: "Unit 1",
      ...
    },
    "express-checkout-user@example.com" // required if this is an express checkout
  );

This will create an order based on the user's current cart, and prepare it for payment. Note that once you call createNewOrder the user's cart will be cleared out.

You can access the user's current order via Sales.currentOrder.

Initializing & Finalizing payment

Before you can initialize a payment, you should render a list of available payment options to the user. To get a list of configured payment providers, call Sales.getPaymentOptions getPaymentOptions, which resolves to a list of payment providers configured & available for use in your system.

Sales.getPaymentOptions().then(paymentOptions => {
  // show the options to the user here.
});

Once you have created an order for the user and once they have selected one of the above payment options, you can initialize a payment by calling Sales.initializePayment. See initializePayment for a full list of accepted parameters.

Sales.initializePayment will create a payment session with the chosen payment provider & the billing details for the order.

const orderNumber = Sales.currentOrder.orderNumber;
const paymentProvider = chosenPaymentOption; // chosen by the user
Sales.initializePayment(orderNumber, paymentProvider.paymentMethodID);

If successful, Sales.initializePayment will resolve to an object with parameter1, parameter2, parameter3, ... etc. properties. These parameters are needed for rendering the chosen provider's payment form to the user.

For example, using the Stripe payment provider & their payment form React component library, you can set up & display a payment form.

import React, { useEffect, useState } from 'react';
import Sales from '@arc-publishing/sdk-sales';

import {
  StripeProvider,
  Elements,
  injectStripe,
} from 'react-stripe-elements';

export const StripeCheckout = (props) => {
  const {
    order,
    stripePaymentMethodID,
    stripe // injected as a prop by `injectStripe`
  }
  const [payment, setPayment] = useState();

  useEffect(() => {
    // initialize our payment & save the result to component state;
    const initializePayment = async () => {
      const payment = Sales.initializePayment(order.orderNumber, stripePaymentMethodID);
      setPayment(payment);
    };
    initializePayment();
  }, []);

  const handleSubmit = async (e) => {
    e.preventDefault();
    const result = await stripe.createToken({name: `${order.firstName} ${order.lastName}`});

    if (result.error) {
      // handle your payment error here
      throw result.error;
    }
    if (result.token) {
      // successful payment tokenization, finalize our payment
      await Sales.finalizePayment(order.orderNumber, stripePaymentMethodID, result.token.id);
    }
  };

  if (payment) {
    // render a credit card collection form
    return (
      <StripeProvider apiKey={payment.parameter1}>
        <Elements>
          <h1>Checkout with Stripe</h1>
          <form onSubmit={handleSubmit}>
            <CardElement />
            <button>
              Finish Checkout
            </button>
          </form>
        </Elements>
      </StripeProvider>
    )
  } else {
    return "Loading...";
  }
};

export default injectStripe(StripeCheckout);

Once the user submits the form, the submit handler tokenizes the Stripe transaction, and passes the token to Arc Sales by calling Sales.finalizePayment (finalizePayment).

This will convert the order from a pending state to a paid state. Any subscriptions on the order will now be considered active.

You can get a list of active subscriptions belonging to the user by calling Sales.getAllActiveSubscriptions (getAllActiveSubscriptions).