Overview
With version 2 of our Web SDK, Universal Checkout automatically creates and handles Payments by default. This greatly reduces the complexity and amount of boilerplate required to integrate Primer.
For backward compatibility reasons, it is still possible to manually create and resume payments. Follow this guide to setup Universal Checkout so that you handle the payment lifecycle.
Flow

Manual payment creation flow
- Generate a
clientToken
on your backend by creating a Client Session with - Initialize Universal Checkout with the
clientToken
to render the UI. - Universal Checkout will generate a
paymentMethodToken
when the customer submits their payment data, or when they select particular payment methods. - Create a payment using the
paymentMethodToken
via the Payments API - If the response indicates a
requiredAction
, you’ll get a newclientToken
. - Pass the
clientToken
back to Universal Checkout to render next steps, like 3DS, and get aresumeToken
. - Call with the
resumeToken
to resume the payment and wrap things up. (If a newrequiredAction
is returned, you’ll have to go back to step 5.)
Generate a Client Token
Get an API Key
Ensure you have an API key configured. Make sure to set the following scopes for your API Key:
client_tokens:write
transactions:authorize
Generate a Client Session
Follow the instructions here to create a client session, which will be used to initialize the checkout.
Set up Universal Checkout
Step 1. Turn off automatic payment creation
The Universal Checkout option paymentHandling
defines how the SDK should handle payment creation and resume.
Set paymentHandling
to MANUAL
to turn off automatic payment handling.
This disables the callbacks onBeforePayment
and onCheckoutComplete
.
Step 2. Handle callbacks for creating and resuming payments
Two callbacks must be implemented:
onTokenizeSuccess()
to create payments withpaymentMethodToken
onResumeSuccess()
to resume payments withresumeToken
Handle onTokenizeSuccess()
callback
- When a customer submits their payment data, the payment details are tokenized and you’ll receive a
paymentMethodToken
inonTokenizeSuccess()
- Create a payment request with the
paymentMethodToken
- If the payment is successful, call
handler.handleSuccess()
in order to display a success screen. - If the payment is unsuccessful, call
handler.handleFailure(errorMessage)
to display an error / failed message. - Payments API may return a new
clientToken
for additional steps (in therequiredActions
on the response). In this case, callhandler.continueWithNewClientToken(clientToken)
to the checkout.
Handle onResumeSuccess()
callback
Handling onResumeSuccess()
is required to fully support 3DS and the majority of payment methods.
- You will receive a
resumeToken
via theonResumeSuccess()
callback if applicable - Send a resume payment request with the
resumeToken
- If the payment is successful, call
handler.handleSuccess()
in order to display a success screen. - If the payment is unsuccessful, call
handler.handleFailure(errorMessage)
to display an error / failed message. - Payments API may again return a new
clientToken
for additional steps. In this case, callhandler.continueWithNewClientToken(clientToken)
again.
Step 1. Turn off automatic payment creation
The Universal Checkout option paymentHandling
defines how the SDK should handle payment creation and resume.
Set paymentHandling
to MANUAL
to turn off automatic payment handling.
This disables the callbacks onBeforePayment
and onCheckoutComplete
.
Step 2. Handle callbacks for creating and resuming payments
Two callbacks must be implemented:
onTokenizeSuccess()
to create payments withpaymentMethodToken
onResumeSuccess()
to resume payments withresumeToken
Handle onTokenizeSuccess()
callback
- When a customer submits their payment data, the payment details are tokenized and you’ll receive a
paymentMethodToken
inonTokenizeSuccess()
- Create a payment request with the
paymentMethodToken
- If the payment is successful, call
handler.handleSuccess()
in order to display a success screen. - If the payment is unsuccessful, call
handler.handleFailure(errorMessage)
to display an error / failed message. - Payments API may return a new
clientToken
for additional steps (in therequiredActions
on the response). In this case, callhandler.continueWithNewClientToken(clientToken)
to the checkout.
Handle onResumeSuccess()
callback
Handling onResumeSuccess()
is required to fully support 3DS and the majority of payment methods.
- You will receive a
resumeToken
via theonResumeSuccess()
callback if applicable - Send a resume payment request with the
resumeToken
- If the payment is successful, call
handler.handleSuccess()
in order to display a success screen. - If the payment is unsuccessful, call
handler.handleFailure(errorMessage)
to display an error / failed message. - Payments API may again return a new
clientToken
for additional steps. In this case, callhandler.continueWithNewClientToken(clientToken)
again.
Step 1. Install
Add the following to your app/build.gradle
file
For more details about SDK versions, please see our changelog.
It is highly recommended to add following settings to your app/build.gradle
file:
Step 2. Initialize the SDK
Prepare the PrimerCheckoutListener
that will handle the callbacks that happen during the lifecycle.
Import the Primer SDK and set its listener as shown in the following example.
In order to use manual payment handling, you have to set paymentHandling
to **PrimerPaymentHandling.MANUAL**
in the PrimerSettings
.
Check the SDK API here to customize your SDK settings.
Step 3. Generate a client token
For more information on generating a client token, take a look at our client session guide.
Make an API call to your backend to fetch a Client Token. Here is a simple example of how it can be done from your activity:
Your view model code may look something like this:
Step 4. Show Universal Checkout
When the client token is retrieved, show Universal Checkout.
You should now be able to see Universal Checkout! The user can now interact with Universal Checkout.
Step 5. Handle callbacks for creating and resuming payments
Once the payment method data has been securely captured, Primer will return a uniform paymentMethodToken
via onTokenizeSuccess
that can be safely passed to your server to create a payment with the Payments API.
Handle onTokenizeSuccess
callback
-
When a customer submits their payment data, the payment details are tokenized and you’ll receive a
paymentMethodToken
inonTokenizeSuccess
. -
Create a payment request with the payment method token data.
-
If the payment is successful, call
decisionHandler.handleSuccess()
in order to display a success screen. -
If the payment is unsuccessful, call
decisionHandler.handleFailure("Your error message")
to display an error / failed message. -
Payments API may return a
requiredAction
with a newclientToken
for additional steps. In this case, calldecisionHandler.continueWithNewClientToken(clientToken)
.
Handle onResumeSuccess
callback
Once the required actions are completed, Primer will return resumeToken
via onResumeSuccess
that can be safely passed to your server to resume a payment with the Payments API.
-
You will receive a
resumeToken
via theonResumeSuccess()
callback if applicable. -
Send a resume payment request with
resumeToken
-
If the payment is successful, call
decisionHandler.handleSuccess()
in order to display a success screen. -
If the payment is unsuccessful, call
decisionHandler.handleFailure("Your error message")
to display an error / failed message. -
Payments API may return a
requiredAction
with a newclientToken
for additional steps. In this case, calldecisionHandler.continueWithNewClientToken(clientToken)
.
Step 1. Install
Add the following to your app/build.gradle
file
For more details about SDK versions, please see our changelog.
Step 2. Initialize the SDK
Prepare the PrimerCheckoutListener
that will handle the callbacks that happen during the lifecycle.
Import the Primer SDK and set its listener as shown in the following example.
In order to use manual payment handling, you have to set paymentHandling
to **PrimerPaymentHandling.MANUAL**
in the PrimerSettings
.
Check the SDK API here to customize your SDK settings.
Step 3. Generate a client token
For more information on generating a client token, take a look at our client session guide.
Make an API call to your backend to fetch a client token. Here is a simple example of how it can be done from your activity:
Your view model code may look something like this:
Step 4. Show Universal Checkout
When the client token is retrieved, show Universal Checkout.
You should now be able to see Universal Checkout! The user can now interact with Universal Checkout.
Step 5. Handle callbacks for creating and resuming payments
Once the payment method data has been securely captured, Primer will return a uniform paymentMethodToken
via onTokenizeSuccess
that can be safely passed to your server to create a payment with the Payments API.
Handle onTokenizeSuccess
callback
-
When a customer submits their payment data, the payment details are tokenized and you’ll receive a
paymentMethodToken
inonTokenizeSuccess
. -
Create a payment request with the payment method token data.
-
If the payment is successful, call
decisionHandler.handleSuccess()
in order to display a success screen. -
If the payment is unsuccessful, call
decisionHandler.handleFailure("Your error message")
to display an error / failed message. -
Payments API may return a
requiredAction
with a newclientToken
for additional steps. In this case, calldecisionHandler.continueWithNewClientToken(clientToken)
.
Handle onResumeSuccess
callback
Once the required actions are completed, Primer will return resumeToken
via onResumeSuccess
that can be safely passed to your server to resume a payment with the Payments API.
-
You will receive a
resumeToken
via theonResumeSuccess()
callback if applicable. -
Send a resume payment request with
resumeToken
-
If the payment is successful, call
decisionHandler.handleSuccess()
in order to display a success screen. -
If the payment is unsuccessful, call
decisionHandler.handleFailure("Your error message")
to display an error / failed message. -
Payments API may return a
requiredAction
with a newclientToken
for additional steps. In this case, calldecisionHandler.continueWithNewClientToken(clientToken)
.
Step 1. Install the SDK
With CocoaPods
The iOS SDK is available with Cocoapods. Just add the PrimerSDK pod and run pod install
.
Then run pod install
to install PrimerSDK
on your workspace.
For specific versions of the SDK, please refer to the changelog.
In case you encounter an error that the bundle needs signing on Xcode 14, add the following post-install script in your podfile.
With Swift Package Manager
The Swift Package Manager is a tool for automating the distribution of Swift code and is integrated into Xcode. In order to add PrimerSDK with Swift Package Manager;
- Select your project, and then navigate to
Package Dependencies
- Click on the + button at the bottom-left of the
Packages
section - Paste https://github.com/primer-io/primer-sdk-ios.git into the Search Bar
- Press Add Package
- Let Xcode download the package and set everything up

Step 2. Initialize the SDK
Import the Primer SDK and set its delegate as shown in the following example. You have to set paymentHandling: .manual
in the PrimerSettings
.
Check the SDK API here to customize your SDK settings.
Step 3. Generate a client token
Check our guide on how to set up the client session here.
Make an API call to your backend to fetch a client token. Here is a simple example of how it can be done from your view controller. Once successful store your client token for future use.
Step 4. Show Universal Checkout
At this step you should have a client token available. Call the showUniversalCheckout(clientToken:)
function (as shown below) to present the Universal Checkout.
Step 5. Handle callbacks for creating and resuming payments
Once the payment method data has been securely captured, Primer will return a uniform paymentMethodTokenData
via primerDidTokenizePaymentMethod(:decisionHandler:)
. This can be safely passed to your server to create a payment with the Payments API.
Handle primerDidTokenizePaymentMethod(:decisionHandler:)
-
When a customer submits their payment data, the payment details are tokenized and you’ll receive a
paymentMethodTokenData
inprimerDidTokenizePaymentMethod
. -
Create a payment request with the payment method token data.
-
If the payment is successful, call
decisionHandler(.succeed())
in order to display a success screen. -
If the payment is unsuccessful, call
decisionHandler(.fail(withErrorMessage: "YOUR_ERROR_MESSAGE"))
to display an error / failed message. -
Payments API may return a
requiredAction
with a newclientToken
for additional steps. In this case, calldecisionHandler(.continueWithNewClientToken(clientToken))
.
Once the the above operation has finished, the SDK will return an error or a new token through its delegate. You can use this token to resume the payment, i.e. send this token to your backend.
Handle primerDidResumeWith(:decisionHandler:)
-
You will receive a
resumeToken
via theprimerDidResumeWith(:decisionHandler:)
callback if applicable. -
Send a resume payment request with
resumeToken
-
If the payment is successful, call
decisionHandler(.succeed())
in order to display a success screen. -
If the payment is unsuccessful, call
decisionHandler(.fail(withErrorMessage: "YOUR_ERROR_MESSAGE"))
to display an error / failed message. -
Payments API may return a
requiredAction
with a newclientToken
for additional steps. In this case, calldecisionHandler(.continueWithNewClientToken(clientToken))
.
You should now be able to see Universal Checkout! The user can now interact with Universal Checkout, and you can create the payment.
Step 1. Turn off automatic payment creation
The Universal Checkout option paymentHandling
defines how the SDK should handle payment creation.
Set paymentHandling
to MANUAL
to turn off automatic payment handling. This will allow you to create the payment yourself (via your backend).
This disables the callback onCheckoutComplete
.
See our SDK API Reference for more info on available settings.
Step 2. Handle callbacks for creating and resuming payments
There are two required callbacks:
onTokenizeSuccess
to create payments withpaymentMethodToken
onResumeSuccess
to resume payments withresumeToken
See our SDK API Reference for the full list of callbacks.
Handle onTokenizeSuccess()
callback
- When a customer submits their payment data, the payment details are tokenized and you’ll receive a
PrimerPaymentMethodTokenData
object inonTokenizeSuccess()
- Create a payment request with the
token
of thePrimerPaymentMethodTokenData
received. - If the payment is successful, call
handler.handleSuccess()
in order to display a success screen. - If the payment is unsuccessful, call
handler.handleFailure(errorMessage)
to display an error / failed message. - Payments API may return a new
clientToken
for additional steps (in therequiredActions
on the response). In this case, callhandler.continueWithNewClientToken(clientToken)
to the checkout.
See below for an example integration:
Handle onResumeSuccess()
callback
Handling onResumeSuccess()
is required to fully support 3DS and the majority of payment methods.
- You will receive a
resumeToken
via theonResumeSuccess()
callback if applicable - Send a resume payment request with the
resumeToken
- If the payment is successful, call
handler.handleSuccess()
in order to display a success screen. - If the payment is unsuccessful, call
handler.handleFailure(errorMessage)
to display an error / failed message. - Payments API may again return a new
clientToken
for additional steps. In this case, callhandler.continueWithNewClientToken(clientToken)
to the checkout.
Step 3. Generate a client token
Make an API call to your backend to generate a Client Session. The Client Session request returns a client token, which you will need to initialize the checkout.
Here is an example of how it can be done from your component. Once successful, store your client token for future use.
Step 4. Show Universal Checkout
At this point, you should have a client token available. To present Universal Checkout, call showUniversalCheckout(clientToken)
as shown below.
You should now be able to see Universal Checkout, and the user can now interact with it. When the user tries to pay, we will tokenize the payment method and invoke onTokenizeSuccess
. You can then create the payment as mentioned in Step 4.