If you’re looking for a simpler way of integrating Universal Checkout, consider integrating our Drop-In checkout.
Not all payment methods are currently compatible with Headless Checkout.Please refer to this table to learn more about the payment methods available for Headless Checkout.
Before you start
Before you start, make sure:- you are ready to process a payment
- Universal Checkout is properly configured in the dashboard
Create a client session
A client session is the starting point for integrating payments at Primer. You can attach any data associated with theorder
to your client session.
Creating a client session provides you with a client token, a temporary key used to initialize the Universal Checkout.
The information you include in the client session is used in the Dashboard:
- to conditionally route payments with Workflows
- to activate payment methods and other features in Universal Checkout
Generate an API key
Requests to our API are authenticated using an API key in theX-Api-Key
header. Create an API key by visiting the developer page of the Primer Dashboard.
Make sure to set the following scopes for your API Key:
client_tokens:write
transactions:authorize
Make a client session request
On your server, create a client session with . Make sure to pass at least the following data:Field | Description |
---|---|
orderId | Your reference for the payment. Make sure to keep track of orderId - you will later receive updates to the payment via Webhooks. The payment will contain the orderId specified in the client session. |
currencyCode | The three-letter currency code in ISO 4217 format. e.g. use USD for US dollars. |
order ↳ lineItems | The details of the line items of the order. |
The body of a successful response contains a clientToken that you will use to initialize the Universal Checkout.
BASH
Get Started
Primer Headless Universal Checkout works in a simple way:- Get a
clientToken
from your server - Start Primer Headless Universal Checkout with the client token
- Primer Headless Universal Checkout will then return the
available payment methods
for the session initiated. Those payment methods that have been configured in the Dashboard and whose conditions match the current client session will be returned. - You show the user the list of available payment methods.
- When the user selects a payment method, show its UI to enable the user to enter their credentials. Depending on the payment method, you will have to either ask the SDK to render it, or build the UI yourself.
- Primer’s Headless Universal Checkout will then create a payment for you and manage its lifecycle. You will receive a confirmation of payment with a callback to indicate the checkout flow has completed.
This documentation is only relevant for v2.21.0 and upward.
Step 1. Install the SDK
Please review the Content Security Policy (CSP) recommendations before installing.
With npm
Our Web SDK is available on npm under the name@primer-io/checkout-web
.This package includes TypeScript definitions.BASH
Typescript
- The npm package only works if used alongside a bundler such as Webpack or Parcel. If you’re directly writing JavaScript using
script
tag, please use our CDN instead. - As of today, the npm package does not work in a server environment. If you are using Next.js, Gatsby, or a similar framework, make sure the
Primer
functions are called on the client side, or use our CDN instead.
With our CDN
Include thePrimer.min.js
script and the Checkout.css
stylesheet on the page where you want to render the Checkout.
Make sure to pass the proper version in the URL.HTML
Primer.min.js
will add the Primer
object to the global scope:Typescript
Step 2: Initialize Primer’s Headless Universal Checkout
Generate a client token
Request a client token from your backend by creating a client session.Check our guide on how to create a client session here.
Remember that based on your client token different payment methods will be available for display.
Configure Headless Universal Checkout
Once you have a client token, initialize Primer’s headless checkout withPrimer.createHeadless(clientToken, options)
.Typescript
onAvailablePaymentMethodsLoad(paymentMethodTypes)
returns the available payment methods for the client session. Use it to render a list of payment methods.onCheckoutComplete(data)
is called when the payment has been successfully completed. It returns a reference to the payment.onCheckoutFail(error, data, handler)
is called if the payment fails to be created or processed.
Payment methods are added and configured through your Primer Dashboard.
onAvailablePaymentMethodsLoad
will return the payment methods
whose conditions match the current client session.headless.start()
to retrieve the list of payment methods, and start the checkout flow.Typescript
Typescript
See more options and events in the SDK API Reference
Step 3: Show available payment methods
When the checkout is done initializing, the callbackonAvailablePaymentMethodsLoad
is invoked. Use this event to show the list of payment methods to the user:- Some payment methods such as Google Pay, Apple Pay, and PayPal require Primer to manage their payment method button.
-
For the others, you have full control over how the payment method button should be presented. To assist you, Primer exposes the
AssetsManager
that enables you to retrieve the logo and main colors attached to each payment method.
Typescript
The assets manager is only available once
onAvailablePaymentMethodsLoad
has been called.Step 4: Handle payment method selection
Headless Universal Checkout enables you to create any UI that suits your needs, using the components and data we provide.Step 4.a: Handle cards
WhenPAYMENT_CARD
is available as a payment method and provided via onAvailablePaymentMethodsLoad
, build your card form using Primer input elements.Get started by creating a payment method manager for cards.Typescript
Show card fields
Headless Universal Checkout securely captures payment method data while fully embedded in your app. By communicating
directly with Primer’s PCI-L1 tokenization service, Universal Checkout transforms sensitive customer data into a
secure uniform string called a payment method token.
Typescript
Typescript
Typescript
Customize card fields
Card fields are rendered with individual iframes in order to remain PCI-L1 compliant. One key consequence is that the CSS of your page will not be propagated to the card fields.
This includes color, and font.
style
object to the render
function to configure colors and font options.Typescript
Check the “Styling Inputs” section of the Customize Universal Checkout guide to learn how to adapt the style to your requirements.
Reset card form
If needed, the card form can be cleared by callingreset()
:Typescript
Remove card elements
CallremoveHostedInputs()
to remove the hosted card input fields from the DOM:Typescript
Detect card type
When the user enters the card credentials, Headless Universal Checkout automatically detects the possible types of the card.Listen to the callbackonCardNetworksChange
on the card manager to receive the type of card.Typescript
Learn more about
onCardNetworksChange
in the API reference.Capture cardholder name
You are free to render the cardholder name input however you want.As the user enters their cardholder name, callsetCardholderName(cardholderName)
to pass the cardholder name to the cardManager
:Typescript
Typescript
Handle input errors
The eventchange
, available on each input, reacts to input changes. This returns if the input is valid or not, and the error type.Typescript
Validate and Submit
When the user submits the card information, follow the following flow:- First, validate all the inputs using the
validate()
function that does basic validations on the hosted inputs. - Then, submit the validated data using the
submit()
function. This triggers the payment creation.
Typescript
submit()
triggers the creation and handling of the payment.- If
onCheckoutComplete
is called, show a success message and reset the inputs. - If
onCheckoutFail
is called, show a failure message and allow the customer to try again with the same details.
Prepare 3DS
When the user pays by card, the Workflow will decide whether a 3DS challenge is required or not. If so, Headless Universal Checkout will automatically render the 3DS challenge in context.To improve 3DS success rates, it is recommended to pass the following elements in the Client Session:customer.emailAddress
customer.billingAddress
Integration example snippet
Below is an example code snippet of how it all fits together.Typescript
See more options and events in the SDK API Reference
Step 4.b: Handle payment methods with native buttons
This applies to PayPal, Apple Pay and Google Pay.
PAYPAL
, APPLE_PAY
or GOOGLE_PAY
is available as a payment method and provided via onAvailablePaymentMethodsLoad
.Render the button
Get started by creating the payment method manager:Typescript
Typescript
See additional style options in the SDK API Reference.
Handle button clicks (optional)
When the payment method button is clicked, Headless Universal Checkout automatically handles the rendering of the payment method screen and the payment. Based on the result of the payment, you should handle different callbacks.- If
onCheckoutComplete
is called, show a success message and hide the button. - If
onCheckoutFail
is called, show a failure message and allow the customer to try again.
Typescript
Other button methods
The button object also supports other methods:Typescript
Integration example snippet
Below is an example code snippet of how it all fits together.Typescript
Step 4.c: Handle payment methods with redirect
Some payment methods require redirecting to another web page in order to capture payment details.Headless checkout automatically renders that web page in a popup window in order to maintain the current context.Get started by creating a payment method manager:Typescript
start
function. This function automatically:- opens a popup to present a loading indicator, then the payment method web page
- shows an overlay on top of your page that prompts the user to focus on the popup
Typescript
Make sure
start
is called synchronously after a clickstart
opens a popup. However, most browsers have strict popup-blocking rules to protect the user. One such rule is to only allow popups that result from a direct user action.Therefore, to ensure that the popup is properly rendered, make sure to call this function immediately after a user click.If the browser cannot open popup windows, the current window will be redirected instead.To ensure maximum compatibility, read the guide on how to handle redirects.
Step 4.d: Handle Klarna
The Klarna payment method requires selecting a payment category before redirecting to capture payment details and finalize the payment.You can create the interface for selecting a payment category before the redirect. Using an api function exposed by the payment method manager you canstart
the checkout, after the payment category has been selected and confirmed, and it will automatically render the payment web page in a popup window.Get started by creating a payment method manager. You need to provide a callback function, onPaymentMethodCategoriesChange
, in the options parameter of the createPaymentMethodManager
function:Typescript
onPaymentMethodCategoriesChange
callback and use it to render a custom user interface for the user to be able to select payment categories. More details about the callback can be found hereTypescript
containerId
, that belongs to a container in the DOM, which will later be used to render payment details about the selected payment method category.
When a payment method category has been selected call the renderCategory
function from the payment method manager. The renderCategory
function uses the id of the selected payment method category, a containerId
and an onHeightChange
callback in order to render more details about the category in the selected container.The onHeightChange
callback will return a new height based on the selected payment method category. Use the new height to change the height of the container in which Klarna will render the payment category details. More details about the callback can be found hereTypescript
start
function. This function automatically:- opens a popup to present a loading indicator, then the payment method web page
- shows an overlay on top of your page that prompts the user to focus on the popup
Typescript
Step 4.e: Handle Stripe ACH
The Stripe ACH payment method requires filling in a form with the customer’s first name, last name, and email, and then going through the Stripe interface to collect the bank account details. Once the bank details are collected, the mandate should be displayed together with a button so the customer can click to confirm it.Optionally, if it’s an existing customer, the existing customer details can be used to pre-populate the input fields.You can grab the details from theonClientSessionUpdate
callback and store them on a variable, example:Typescript
The
customer
client session property can be undefined
.onClientSessionUpdate
is always called once before the onAvailablePaymentMethodsLoad
, so the payment method manager can be created as usual.When creating the ACH payment method manager, the stripePublishableKey
needs to be provided, and optionally, the onCollectBankAccountDetailsComplete
callback.Typescript
collectBankAccountDetails
method can be called to start the Stripe flow.Typescript
collectBankAccountDetails
promise to be resolved, the onCollectBankAccountDetailsComplete
callback can be set up to display the mandate screen.Typescript
confirm
button, the confirmMandate
method can be called.Typescript