Headless Universal Checkout has changed to solidify the integration experience and make the interfaces clearer and more consistent.

Below is a summary of the changes and examples of how to migrate to this new integration, however we recommend you consult the full documentation during integration.

🚀 Starting Headless Universal Checkout

As before, you still set Headless Universal Checkout callbacks to handle events during the checkout’s lifecycle.

Previously you passed all the individual callbacks in PrimerSettings, like below:

12345678910
const settings: PrimerSettings = {    // Any other settings & callbacks (see the Quick Start Guide    // and the SDK API reference)     onAvailablePaymentMethodsLoad: onAvailablePaymentMethodsLoad,    onPrepareStart: onPrepareStart,    onPaymentMethodShow: onPaymentMethodShow,    onTokenizeStart: onTokenizeStart,    onCheckoutComplete: onCheckoutComplete,}
tsx
copy

Now these callbacks can be set on the headlessUniversalCheckoutCallbacks property of PrimerSettings:

12345678910111213141516171819
import { HeadlessUniversalCheckout } from '@primer-io/react-native'; export const HeadlessUniversalCheckoutScreen = () => {         useEffect(() => {                const settings: PrimerSettings = {                        //...                        headlessUniversalCheckoutCallbacks: {                                onCheckoutComplete: (checkoutData) => {                              // Here you will receive the checkout data of the payment.                        }                        }                }             const availablePaymentMethods = await HeadlessUniversalCheckout.startWithClientToken(clientToken, settings);              // Store the available payment methods for the session.         }, [clientToken]);})
tsx
copy

In addition, for the availablePaymentMethods returned when headless universal checkout is created, the payload will change.

Instead of just a string, each payment method returned contains the following:

  • paymentMethodType
    a unique string identifier for the payment method.
  • paymentMethodManagerCategories
    an array which defines the payment method managers that can be used with this payment method (i.e. NATIVE_UI or RAW_DATA). Use this to know which payment method managers to create.
  • [Optional] requiredInputDataClass
    this is provided with the RAW_DATA payment method manager and indicates the type of data that should be captured for the payment method.
  • supportedPrimerSessionIntents
    an array of SessionIntent which defines what intents can be used with this payment method (i.e. .checkout or .vault).

Building your UI

You can build your UI by using the AssetsManager. You can access the payment methods’ assets like below:

12345
const getPaymentMethodAssets = (): Promise<Asset[]> => {    const assetsManager = new AssetsManager()    const assets: Asset[] = await assetsManager.getPaymentMethodAssets()    return assets}
tsx
copy

The payment method asset contains the following:

  • paymentMethodType: a unique string identifier for the payment method.
  • paymentMethodLogo which contains the logos’ local URLs
    • colored?: string: Local URL for the colored value of the logo
    • dark?: string: Local URL for the dark value of the logo
    • light?: string: Local URL for the light value of the logo
  • paymentMethodBackgroundColor which contains the background colors hex values
    • colored?: string: Color hex value for the colored background color
    • dark?: string: Color hex value for the dark mode background color
    • light?: string: Color hex value for the light mode background color

With the above images and colors, you can build your own payment method buttons 💪

Handling Payment Methods

Before you had to call showPaymentMethod directly for some payment methods while having managers for others. Now each payment method belongs to a payment method manager, as indicated by paymentMethodManagerCategories on the list of available payment methods.

Native UI Manager

Used for any payment method that needs to present its own UI, like Apple Pay. See example integration below:

12345
const payWithPaymentMethod = async (paymentMethodType: string) => {    const nativeUIManager = new NativeUIManager()    await nativeUIManager.initialize({ paymentMethodType: paymentMethod.paymentMethodType })    await nativeUIManager.showPaymentMethod(SessionIntent.CHECKOUT)}
tsx
copy

Raw Data Manager

Used for payment methods that require you to pass data to the SDK, for example for cards. As before, you have to render your own input elements and capture the required data before finally calling submit on the raw data manager. See an example integration below:

123456789101112131415161718192021222324
const rawDataManager = new RawDataManager(); const initialize = async (paymentMethod: PaymentMethod) => {    await rawDataManager.initialize({        paymentMethodType: paymentMethod.paymentMethodType,        onMetadataChange: (data => {            // For example card number detected to be Visa        }),        onValidation: ((isVallid, errors) => {            // Show on your UI if the card data aren't valid        })    });     const requiredInputElementTypes = await rawDataManager.getRequiredInputElementTypes();    setRequiredInputElementTypes(requiredInputElementTypes);} // .... // Build your own Pay button and call "submit"const pay = async () => {    await rawDataManager.submit();}    ```
tsx
copy

Other changes

Callback updates

Some callbacks have been renamed:

Before v2.17.0After 2.17.0

onHUCAvailablePaymentMethodsLoaded

Renamed to onAvailablePaymentMethodsLoad

onHUCPrepareStart

Renamed to onPreparationStart

onHUCTokenizeStart

Renamed to onTokenizationStart

onHUCPaymentMethodShow

Renamed to onPaymentMethodShow

onResumePending

Renamed to onCheckoutPending

onCheckoutReceivedAdditionalInfo

Renamed to onCheckoutAdditionalInfo

Resume handler updates

Some listener functions provide a decision handler that you can call with the relevant decision to continue the flow.

The handler class name and signature of the following functions have changed:

Before v2.17.0After 2.17.0
1234
onTokenizationSuccess?: (    paymentMethodTokenData: PrimerPaymentMethodTokenData,    handler: PrimerTokenizationHandler) => void;
tsx
copy
1234
onTokenizeSuccess?: (    paymentMethodTokenData: PrimerPaymentMethodTokenData,    handler: PrimerHeadlessUniversalCheckoutResumeHandler) => void;
tsx
copy
1234
onResumeSuccess?: (    resumeToken: string,    handler: PrimerResumeHandler) => void;
tsx
copy
1234
onCheckoutResume?: (    resumeToken: string,    handler: PrimerHeadlessUniversalCheckoutResumeHandler) => void;
tsx
copy

Miscellaneous changes

The interfaces that need to be passed to the SDK when using Raw Data Managers have changed structures and names:

Before v2.17.0After 2.17.0
1234567
interface PrimerRawCardData {    cardNumber: string    expiryMonth: string    expiryYear: string    cvv: string    cardholderName?: string}
tsx
copy
123456
interface CardData {    cardNumber: string    expiryDate: string    cvv: string    cardholderName?: string}
tsx
copy
123456
interface PrimerBancontactCardRedirectData {    cardNumber: string    expiryMonth: string    expiryYear: string    cardholderName: string}
tsx
copy
12345
interface BancontactCardData {    cardNumber: string    expiryDate: string    cardholderName: string}
tsx
copy
123
interface PrimerRawPhoneNumberData {    phoneNumber: string}
tsx
copy
123
interface PhoneNumberData {    phoneNumber: string}
tsx
copy
123
interface PrimerRawRetailerData {    id: string}
tsx
copy
123
interface RetailerData {    id: string}
tsx
copy