Skip to main content
interface PrimerSettings {
  paymentHandling?: 'AUTO' | 'MANUAL';
  localeData?: IPrimerLocaleData;
  paymentMethodOptions?: IPrimerPaymentMethodOptions;
  uiOptions?: IPrimerUIOptions;
  debugOptions?: IPrimerDebugOptions;
  clientSessionCachingEnabled?: boolean;
  apiVersion?: PrimerApiVersion;

  // Dropin UI
  onBeforeClientSessionUpdate?: () => void;
  onClientSessionUpdate?: (clientSession: PrimerClientSession) => void;
  onBeforePaymentCreate?: (checkoutPaymentMethodData: PrimerCheckoutPaymentMethodData, handler: PrimerPaymentCreationHandler) => void;
  onCheckoutComplete?: (checkoutData: PrimerCheckoutData) => void;
  onTokenizeSuccess?: (paymentMethodTokenData: PrimerPaymentMethodTokenData, handler: PrimerTokenizationHandler) => void;
  onResumeSuccess?: (resumeToken: string, handler: PrimerResumeHandler) => void;
  onResumePending?: (additionalInfo: PrimerCheckoutAdditionalInfo) => void;
  onCheckoutReceivedAdditionalInfo?: (additionalInfo: PrimerCheckoutAdditionalInfo) => void;
  onError?: (error: PrimerError, checkoutData: PrimerCheckoutData | null, handler: PrimerErrorHandler | undefined) => void;
  onDismiss?: () => void;

  headlessUniversalCheckoutCallbacks?: {
    onAvailablePaymentMethodsLoad?: (availablePaymentMethods: any[]) => void;
    onTokenizationStart?: (paymentMethodType: string) => void;
    onTokenizationSuccess?: (paymentMethodTokenData: PrimerPaymentMethodTokenData, handler: PrimerHeadlessUniversalCheckoutResumeHandler) => void;

    onCheckoutResume?: (resumeToken: string, handler: PrimerHeadlessUniversalCheckoutResumeHandler) => void;
    onCheckoutPending?: (additionalInfo: PrimerCheckoutAdditionalInfo) => void;
    onCheckoutAdditionalInfo?: (additionalInfo: PrimerCheckoutAdditionalInfo) => void;

    onError?: (error: PrimerError, checkoutData: PrimerCheckoutData | null) => void;
    onCheckoutComplete?: (checkoutData: PrimerCheckoutData) => void;
    onBeforeClientSessionUpdate?: () => void;

    onClientSessionUpdate?: (clientSession: PrimerClientSession) => void;
    onBeforePaymentCreate?: (checkoutPaymentMethodData: PrimerCheckoutPaymentMethodData, handler: PrimerPaymentCreationHandler) => void;
    onPreparationStart?: (paymentMethodType: string) => void;

    onPaymentMethodShow?: (paymentMethodType: string) => void;
  }
}

interface IPrimerLocaleData {
  languageCode?: string
  localeCode?: string
}

interface IPrimerPaymentMethodOptions {
  iOS?: {
    urlScheme?: string;
  }
  android?: {
    redirectScheme?: string;
  },
  apayaOptions?: IPrimerApayaOptions;
  applePayOptions?: IPrimerApplePayOptions;

  /**
  * @obsoleted The IPrimerCardPaymentOptions is obsoleted on v.2.14.0
  */
  cardPaymentOptions?: IPrimerCardPaymentOptions;

  goCardlessOptions?: IPrimerGoCardlessOptions;
  googlePayOptions?: IPrimerGooglePayOptions;
  klarnaOptions?: IPrimerKlarnaOptions;
  threeDsOptions?: IPrimerThreeDsOptions;
  stripeOptions?: IPrimerStripeOptions;
}

interface IPrimerApayaOptions {
  webViewTitle: string;
}

interface IPrimerApplePayOptions {
  merchantIdentifier: string;
  merchantName?: string;
  isCaptureBillingAddressEnabled?: boolean;
  showApplePayForUnsupportedDevice?: boolean;
  checkProvidedNetworks?: boolean;
  shippingOptions?: {
    shippingContactFields?: RequiredContactField[];
    requireShippingMethod: boolean;
  };
  billingOptions?: {
    requiredBillingContactFields?: RequiredContactField[];
  };
}

type RequiredContactField = 'name' | 'emailAddress' | 'phoneNumber' | 'postalAddress';

interface IPrimerCardPaymentOptions {
  is3DSOnVaultingEnabled: boolean;
}

interface IPrimerGoCardlessOptions {
  businessName?: string;
  businessAddress?: string;
}

interface IPrimerGooglePayOptions {
  merchantName?: string;
  allowedCardNetworks?: string[];
  isCaptureBillingAddressEnabled?: boolean;
  isExistingPaymentMethodRequired?: boolean;
  shippingAddressParameters?: IPrimerGoogleShippingAddressParameters;
  requireShippingMethod?: boolean;
  emailAddressRequired?: boolean;
  buttonOptions?: IPrimerGooglePayButtonOptions;
}

interface IPrimerGooglePayButtonOptions {
  buttonType?: number;
  buttonTheme?: number;
}

interface IPrimerGoogleShippingAddressParameters {
  isPhoneNumberRequired?: boolean;
}

interface IPrimerKlarnaOptions {
  recurringPaymentDescription?: string;
  webViewTitle?: string;
}

interface IPrimerUIOptions {
  isInitScreenEnabled?: boolean;
  isSuccessScreenEnabled?: boolean;
  isErrorScreenEnabled?: boolean;
  dismissalMechanism?: DismissalMechanism[];
  appearanceMode?: PrimerAppearanceMode;
  theme?: IPrimerTheme;
}

export type DismissalMechanism = 'gestures' | 'closeButton';

export type PrimerAppearanceMode = 'SYSTEM' | 'LIGHT' | 'DARK';

interface IPrimerDebugOptions {
  is3DSSanityCheckEnabled?: boolean;
}

export type PrimerApiVersion = '2.4' | 'latest'

interface IPrimerThreeDsOptions {
  iOS?: {
    threeDsAppRequestorUrl?: string;
  };
  android?: {
    threeDsAppRequestorUrl?: string;
  };
}

Appearance Mode Configuration

You can control the SDK’s appearance mode independently of the system setting using the appearanceMode property in uiOptions. This is particularly useful for apps that implement their own theme management.

Example

import { Primer, PrimerSettings } from '@primer-io/react-native';

const settings: PrimerSettings = {
  paymentHandling: 'AUTO',
  uiOptions: {
    appearanceMode: 'LIGHT', // Options: 'SYSTEM' (default), 'LIGHT', 'DARK'
    isInitScreenEnabled: true,
    isSuccessScreenEnabled: true,
    isErrorScreenEnabled: true
  }
};

// Configure Primer with the settings
await Primer.configure(settings);
This feature is especially helpful when:
  • Your app has an “Always Light” or “Always Dark” mode setting
  • You want to maintain consistent appearance across the payment flow
  • You need to override the system’s dark mode setting for specific user preferences
⚠️ If no settings are provided, the SDK will initialize with its default settings.
Use PrimerSettings to provide different options based on your use case.