We’ve introduced a new way to integrate our Checkout for Web
Learn how to build a fully customizable checkout using modular components through our documentation here
The simplest way to integrate Universal Checkout is with our drop-in UI. With just a few lines of code, you can display a fully in-context checkout UI with all your payment methods.
Not all payment methods are currently compatible with Drop-in Checkout.Please refer to this table to learn more about the payment methods available for Drop-in Checkout.
A client session is the starting point for integrating payments at Primer. You can attach any data associated with the order 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
Requests to our API are authenticated using an API key in the X-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:
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.
Our Web SDK is available on npm under the name @primer-io/checkout-web.This package includes TypeScript definitions.
BASH
# With yarnyarn add @primer-io/checkout-web# With npmnpm install --save @primer-io/checkout-web
Typescript
import { Primer } from "@primer-io/checkout-web";Primer.showUniversalCheckout(clientToken, { /* Options */});
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.
Include the Primer.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.
Use the generated client token on the client-side to show Universal Checkout by calling Primer.showUniversalCheckout(clientToken, options). Make sure to pass a selector to your container in the options.
Javascript
const universalCheckout = await Primer.showUniversalCheckout(clientToken, { // Specify the selector of the container element container: "#checkout-container", /** * When the checkout flow has been completed, you'll receive * the successful payment via `onCheckoutComplete`. * Implement this callback to redirect the user to an order confirmation page. */ onCheckoutComplete({ payment }) { console.log("Checkout Complete!", payment); }, /** * When the checkout flow has been fail, you'll receive * the error via `onCheckoutFail` */ onCheckoutFail(error, { payment }, handler) { console.log("Checkout Fail!", error, payment); },});
On the client-side, listen to the onCheckoutComplete callback to be notified when the payment has been successfully completed. Use it to show an order confirmation screen.
To receive updates about the status of your payments you’ll need to listen to webhooks. This is particularly useful for updating an order or any other data stored server-side.Head to the Developers section of the Primer Dashboard to setup and test a webhook for PAYMENT.STATUS event.If you are not yet ready to receive webhooks, you can use https://webhook.site to test your implementation.
Some payment methods require redirecting to another web page in order to capture payment details.Drop-in checkout automatically renders that web page in a popup window in order to maintain the current context.
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.
Any errors, cancelled payment interactions or failed payments will trigger the onCheckoutFail callback with a PrimerClientError
Javascript
onCheckoutFail(error, { payment }, handler) { // Notifies you that the checkout flow has failed and a payment could not be created // This callback can also be used to display an error state within your own UI. // ⚠️ `handler` is undefined if the SDK does not expect anything from you if (!handler) { return; } // ⚠️ If `handler` exists, you MUST call one of the functions of the handler // Show a default error message return handler.showErrorMessage(); // Show a custom error message return handler.showErrorMessage('This is my custom error message');}
Not all failures are retryable. A client-side error doesn’t always mean the payment failed, and decline reasons are intentionally generic. Verify the payment status server-side before asking the user to pay again.
Backend API V2.4 enhances reliability and minimizes synchronization issues with external processors by significantly extending payment timeouts. This longer timeout accommodates external processor limits and internal operations, ensuring more reliable transaction handling. These improvements are fully supported starting with Primer iOS SDK 2.34.0, so upgrading your app to use the newest SDK version is highly recommended when creating client sessions with API V2.4.
use_frameworks!target 'MyApp' do # 👇 Add this line pod 'PrimerSDK' # ...end
Then run pod install to install PrimerSDK on your workspace.
In case you encounter an error that the bundle needs signing on Xcode 14, add the following post-install script in your podfile.
post_install do |installer| installer.pods_project.targets.each do |target| if target.respond_to?(:product_type) and target.product_type == "com.apple.product-type.bundle" target.build_configurations.each do |config| config.build_settings['CODE_SIGNING_ALLOWED'] = 'NO' end end endend
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
At this step you should have a client token available - see Manage Client Sessions for more.Call the showUniversalCheckout(clientToken:) function (as shown below) to present Universal Checkout.
You should now be able to see Universal Checkout! The user can now interact with Universal Checkout, and the SDK will create the payment. The payment’s data will be returned on primerDidCompleteCheckoutWithData(_:) configured in the previous step.
When the user interacts with the checkout and clicks to pay, the Universal Checkout:
Listen to the primerDidCompleteCheckoutWithData(_:) delegate functionThis function will notify you of a successful payment.
SWIFT
class MyViewController: UIViewController { // ... func primerDidCompleteCheckoutWithData(_ data: PrimerCheckoutData) { // Primer checkout completed with data // Do something with the data, e.g. show the payment id }}
To receive updates about the status of your payments you’ll need to listen to webhooks. This is particularly useful for updating an order or any other data stored server-side.Head to the Developers section of the Primer Dashboard to setup and test a webhook for PAYMENT.STATUS event.If you are not yet ready to receive webhooks, you can use https://webhook.site to test your implementation.
Any errors, cancelled payment interactions or failed payments will trigger the primerDidFailWithError(_:data:decisionHandler:) delegate function.
SWIFT
class MyViewController: UIViewController, PrimerDelegate { // ... func primerDidFailWithError(_ error: Error, data: PrimerCheckoutData?, decisionHandler: @escaping ((PrimerErrorDecision) -> Void)) { // 👇 Call the decision handler to show a failure message decisionHandler(.fail(withErrorMessage: message)) }}
Not all failures are retryable. A client-side error doesn’t always mean the payment failed, and decline reasons are intentionally generic. Verify the payment status server-side — through payment webhooks or the Payments API — before asking the user to pay again.
Backend API V2.4 enhances reliability and minimizes synchronization issues with external processors by significantly extending payment timeouts. This longer timeout accommodates external processor limits and internal operations, ensuring more reliable transaction handling. These improvements are fully supported starting with Primer Android SDK 2.35.0, so upgrading your app to use the newest SDK version is highly recommended when creating client sessions with API V2.4.
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:
Kotlin
class CheckoutActivity : AppCompatActivity() { private val listener = object : PrimerCheckoutListener { // 👇 [Required] This function is called when the checkout has been completed override fun onCheckoutCompleted(checkoutData: PrimerCheckoutData) { // Show an order confirmation screen... // checkoutData contains the payment that has been created } } override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) configureCheckout() } private fun configureCheckout() { // 👇 Initialize the SDK with the default settings. Primer.instance.configure(settings = PrimerSettings(), listener = listener) }}
At this step you should have a client token available - see Manage Client Sessions for more.When the client token is retrieved, show Universal Checkout by calling showUniversalCheckout method:
Kotlin
class CheckoutActivity : AppCompatActivity() { // other code goes here private lateinit var viewModel: CheckoutViewModel override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) setContentView(R.layout.activity_main) setupViewModel() setupObservers() fetchClientToken() } private fun setupViewModel() { viewModel = ViewModelProvider(this).get(CheckoutViewModel::class.java) } private fun fetchClientToken() = viewModel.fetchClientToken() private fun setupObservers() { viewModel.clientToken.observe(this) { clientToken -> showUniversalCheckout(clientToken) } } private fun showUniversalCheckout(clientToken: String) { Primer.instance.showUniversalCheckout(this, clientToken) }}
You should now be able to see Universal Checkout! The user can now interact with Universal Checkout, and the SDK will create the payment. The payment’s data will be returned on onCheckoutCompleted() configured in the previous step.
When the user interacts with the checkout and clicks to pay, the Universal Checkout:
Listen to onCheckoutCompleted callbackThis function will notify you of a successful payment
Kotlin
private val listener = object : PrimerCheckoutListener { override fun onCheckoutCompleted(checkoutData: PrimerCheckoutData) { // Show an order confirmation screen... // checkoutData contains the payment that has been created }}
To receive updates about the status of your payments you’ll need to listen to webhooks. This is particularly useful for updating an order or any other data stored server-side.Head to the Developers section of the Primer Dashboard to setup and test a webhook for PAYMENT.STATUS event.If you are not yet ready to receive webhooks, you can use https://webhook.site to test your implementation.
Any errors, cancelled payment interactions or failed payments will trigger the onFailed callback
Kotlin
private val listener = object : PrimerCheckoutListener { override fun onFailed( error: PrimerError, checkoutData: PrimerCheckoutData?, errorHandler: PrimerErrorDecisionHandler? ) { // Notifies you that the checkout flow has failed and a payment could not be created // This callback can also be used to display an error state within your own UI. // Show a default error message errorHandler?.showErrorMessage(null) // Show a custom error message errorHandler?.showErrorMessage("This is my custom error message") }}
Not all failures are retryable. A client-side error doesn’t always mean the payment failed, and decline reasons are intentionally generic. Verify the payment status server-side — through payment webhooks or the Payments API — before asking the user to pay again.
Backend API V2.4 enhances reliability and minimizes synchronization issues with external processors by significantly extending payment timeouts. This longer timeout accommodates external processor limits and internal operations, ensuring more reliable transaction handling. These improvements are fully supported starting with Primer React Native SDK 2.35.0, so upgrading your app to use the newest SDK version is highly recommended when creating client sessions with API V2.4.
First, 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 component. Once successful store your client token for future use.
You should now be able to see Universal Checkout! The user can now interact with Universal Checkout, and the SDK will create the payment. The payment’s data will be returned on primerDidCompleteCheckoutWithData(_:) configured in the previous step.
When the user interacts with the checkout and clicks to pay, the Universal Checkout:
To receive updates about the status of your payments you’ll need to listen to webhooks. This is particularly useful for updating an order or any other data stored server-side.Head to the Developers section of the Primer Dashboard to setup and test a webhook for PAYMENT.STATUS event.If you are not yet ready to receive webhooks, you can use https://webhook.site to test your implementation.
Any errors, cancelled payment interactions or failed payments will trigger the onError callback
Typescript
const onError = ( error: PrimerError, checkoutData: PrimerCheckoutData | null, handler: PrimerErrorHandler | undefined,) => { // Notifies you that the checkout flow has failed and a payment could not be created // This callback can also be used to display an error state within your own UI. // ⚠️ `handler` is undefined if the SDK does not expect anything from you if (!handler) { return; } // ⚠️ If `handler` exists, you MUST call one of the functions of the handler // Show a default error message handler.showErrorMessage(); // Show a custom error message handler.showErrorMessage('This is my custom error message');
Not all failures are retryable. A client-side error doesn’t always mean the payment failed, and decline reasons are intentionally generic. Verify the payment status server-side — through payment webhooks or the Payments API — before asking the user to pay again.
Assistant
Responses are generated using AI and may contain mistakes.