> ## Documentation Index
> Fetch the complete documentation index at: https://primer.io/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# PrimerSettings

Primer's SDK will need to be configured with a `PrimerSettings` object, no matter whether you're
using the drop-in or headless integration, auto or manual flow. This object greatly depends on your
payment methods configuration.

## Parameters

<Expandable title="Properties" defaultOpen>
  <ResponseField name="paymentHandling" type="enum PrimerPaymentHandling">
    Use this to set you payment handling flow. Defaults to `.auto`.

    <Expandable title="Cases" defaultOpen>
      <ResponseField name="auto" type="default">
        Primer SDK will create the payment and handle the flow.
      </ResponseField>

      <ResponseField name="manual">
        If you use the manual flow, make sure you add the `primerDidTokenizePaymentMethod(_:decisionHandler:)` delegate function of `PrimerDelegate`, create a payment on your backend and call the `decisionHandler` of the delegate function once you receive your backend's response.
      </ResponseField>
    </Expandable>
  </ResponseField>

  <ResponseField name="localeData" type="PrimerLocaleData">
    Forces some payment methods' locale.

    <Expandable title="Properties" defaultOpen>
      <ResponseField name="languageCode" type="String" required>
        Forces the language code (e.g. `en`). Defaults on your app's language code if available.
      </ResponseField>

      <ResponseField name="regionCode" type="String">
        Forces the language code (e.g. `US`). Defaults on your app's region code if available.
      </ResponseField>
    </Expandable>
  </ResponseField>

  <ResponseField name="paymentMethodOptions" type="PrimerPaymentMethodOptions">
    <Expandable title="Properties" defaultOpen>
      <ResponseField name="urlScheme" type="String">
        ⚠️ Required for some payment methods (e.g. PayPal). <br /><br />This option sets the deeplink schema used when redirecting back from 3rd party applications to your app.
      </ResponseField>

      <ResponseField name="applePayOptions" type="PrimerApplePayOptions">
        ⚠️ Required when using Apple Pay in your integration.

        <Expandable title="Properties" defaultOpen>
          <ResponseField name="merchantIdentifier" type="String" required>
            Set it to the merchant identifier as it is shown in your Apple Pay
            certificate.
          </ResponseField>

          <ResponseField name="merchantName" type="String" deprecated>
            Set it to the merchant name that you want to be shown on the Apple Pay screen. Deprecated, use [ClientSession](/api-reference/v2.4/api-reference/client-session-api/create-a-client-session) instead.
          </ResponseField>

          <ResponseField name="isCaptureBillingAddressEnabled" type="Bool">
            Defaults to `false`. Set to `true` to let Apple Pay capture the customer's billing address.

            Use BillingOptions to configure required billing fields.
          </ResponseField>

          <ResponseField name="showApplePayForUnsupportedDevice" type="Bool">
            If in some cases you don't want to present ApplePay option if the device is not supporting it set this to `false`. The default value is `true`.

            Default value is `true`. Set to `false` if you do not want to present
            Apple Pay option on unsupported devices.
          </ResponseField>

          <ResponseField name="checkProvidedNetworks" type="Bool">
            Flag introduced to enable the initiation of the ApplePay flow even when no cards are present in the Wallet. To enable the feature, set this to `false`. The default value `true`.

            Default value is `true`. This flag supports the old behavior where Apple
            Pay flow might not present if there are no cards in the Wallet.
          </ResponseField>

          <ResponseField name="shippingOptions" type="ShippingOptions">
            Configure shipping options for Apple Pay.

            <Expandable title="Properties" defaultOpen>
              <ResponseField name="shippingContactFields" type="Array of RequiredContactField">
                Specify which contact fields are required for shipping.
              </ResponseField>

              <ResponseField name="requireShippingMethod" type="Bool">
                Indicate if a shipping method is required.
              </ResponseField>
            </Expandable>
          </ResponseField>

          <ResponseField name="billingOptions" type="BillingOptions">
            Configure billing options for Apple Pay.

            <Expandable title="Properties" defaultOpen>
              <ResponseField name="requiredBillingContactFields" type="Array of RequiredContactField">
                Specify which contact fields are required for billing.
              </ResponseField>
            </Expandable>
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="klarnaOptions" type="PrimerKlarnaOptions">
        ⚠️ Required when using Klarna in your integration.

        <Expandable title="Properties" defaultOpen>
          <ResponseField name="recurringPaymentDescription" type="String" required>
            Set the payment description that will be shown on the Klarna screen.
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="threeDsOptions" type="PrimerThreeDsOptions">
        <Expandable title="Properties" defaultOpen>
          <ResponseField name="threeDsAppRequestorUrl" type="String">
            Set the [iOS Universal Link](https://developer.apple.com/ios/universal-links/) that's used to call your app after an **out-of-band (OOB)** authentication.
            Supported in 3D Secure protocol versions 2.2.0 and after.
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="stripeOptions" type="PrimerStripeOptions">
        ⚠️ Required when using Stripe ACH in your integration.

        <Expandable title="Properties" defaultOpen>
          <ResponseField name="publishableKey" type="String?">
            Set the [Stripe publishable key](https://docs.stripe.com/keys#obtain-api-keys/).
          </ResponseField>

          <ResponseField name="mandateData" type="MandateData?">
            One of:

            <Expandable title="Options" defaultOpen>
              <ResponseField name="fullMandate(text:)" type="MandateData">
                The full `text` that you would like to be displayed to the user before
                they accept/decline the mandate.
              </ResponseField>

              <ResponseField name="templateMandate(merchantName:)" type="MandateData">
                A `merchantName` that will be used as part of our predefined mandate template.
              </ResponseField>
            </Expandable>
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Expandable>
  </ResponseField>

  <ResponseField name="uiOptions" type="PrimerUIOptions">
    Set the `uiOptions` for custom UI options of the Primer SDK.

    <Expandable title="Properties" defaultOpen>
      <ResponseField name="isInitScreenEnabled" type="Bool">
        Set to `false` to hide the loading screen before the Universal Checkout or the Vault Manager. Defaults to `true`.
      </ResponseField>

      <ResponseField name="isSuccessScreenEnabled" type="Bool">
        Set to `false` to hide the screen after a successful payment, or tokenization on the vault flow. Defaults to `true`.
      </ResponseField>

      <ResponseField name="isErrorScreenEnabled" type="Bool">
        Set to `false` to hide the error screen when an error occurs. Defaults to `true`.
      </ResponseField>

      <ResponseField name="dismissalMechanism" type="enum DismissalMechanism">
        Set the mechanism for dismissing Universal Checkout. Options are:

        * `gestures`: The dialog can be dismissed by tapping outside or by swiping down.
        * `closeButton`: A close button is provided, allowing users to dismiss the dialog manually.
      </ResponseField>

      <ResponseField name="theme" type="PrimerTheme">
        Set a custom theme for Primer SDK.
      </ResponseField>

      <ResponseField name="appearanceMode" type="enum PrimerAppearanceMode">
        Control the SDK's appearance mode independently of the system setting. This allows apps to force light or dark mode regardless of the device's appearance setting.

        <Expandable title="Cases" defaultOpen>
          <ResponseField name="system" type="default">
            Follow the system's appearance setting (default behavior).
          </ResponseField>

          <ResponseField name="light">
            Force light mode appearance regardless of system setting.
          </ResponseField>

          <ResponseField name="dark">
            Force dark mode appearance regardless of system setting.
          </ResponseField>
        </Expandable>
      </ResponseField>

      <ResponseField name="cardFormUIOptions" type="PrimerCardFormUIOptions?">
        Configure the card form UI options.

        <Expandable title="Properties" defaultOpen>
          <ResponseField name="payButtonAddNewCard" type="Bool">
            When set to true, the Drop-In's card form pay button will show "Add new card"; otherwise it will show "Pay \$x.xx".
          </ResponseField>
        </Expandable>
      </ResponseField>
    </Expandable>
  </ResponseField>

  <ResponseField name="debugOptions" type="PrimerDebugOptions">
    <Expandable title="Properties" defaultOpen>
      <ResponseField name="is3DSSanityCheckEnabled" type="Bool" required />
    </Expandable>
  </ResponseField>

  <ResponseField name="clientSessionCachingEnabled" type="Bool" post={["Default: false"]}>
    <Warning>
      Before enabling the flag to true it's recommended to reach out to Primer
      support for additional verification since there are edge cases where it's not
      advised.
    </Warning>

    Indicates whether client session caching is enabled.

    When set to `true`, responses from the server will be cached on the client side, allowing for faster subsequent
    access to the same data within the cache duration. When set to `false`, every request to the server will be
    processed without utilizing any client-side cache, ensuring that the client always receives the most up-to-date data.
  </ResponseField>

  <ResponseField name="apiVersion" type="PrimerApiVersion" post={["Default: PrimerApiVersion.V2_4"]}>
    Indicates the API version to use when interacting with the Primer backend. Options are:

    * `PrimerApiVersion.V2_4` - will use ApiVersion 2.4

    Note that this is optional, if a value is not supplied, ApiVersion `V2.4` will be used by default.
  </ResponseField>
</Expandable>

## Example

Create a `settings` object.

```swift SWIFT theme={"dark"}
// 👇 Add this
import PrimerSDK

class MyViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        // 👇 Create your settings
        let settings = PrimerSettings(
            paymentHandling: .auto,
            localeData: PrimerLocaleData(
                languageCode: "en",
                regionCode: "US"),
            paymentMethodOptions: PrimerPaymentMethodOptions(
                urlScheme: "URL_SCHEME://",
                applePayOptions: PrimerApplePayOptions(
                    merchantIdentifier: "MERCHANT_IDENTIFIER",
                    merchantName: "MERCHANT_NAME",
                    isCaptureBillingAddressEnabled: true,
                    showApplePayForUnsupportedDevice: true,
                    checkProvidedNetworks: true,
                    shippingOptions: PrimerApplePayOptions.ShippingOptions(
                        shippingContactFields: [.name, .emailAddress],
                        requireShippingMethod: true
                    ),
                    billingOptions: PrimerApplePayOptions.BillingOptions(
                        requiredBillingContactFields: [.postalAddress]
                    )
                ),
                klarnaOptions: PrimerKlarnaOptions(
                    recurringPaymentDescription: "RECURRING_PAYMENT_DESCRIPTION"),
                stripeOptions: PrimerStripeOptions(
                    publishableKey: "STRIPE_PUBLISHABLE_KEY")),
            uiOptions: PrimerUIOptions(
                isInitScreenEnabled: false,
                isSuccessScreenEnabled: false,
                isErrorScreenEnabled: false,
                appearanceMode: .light), // Force light mode regardless of system setting
            debugOptions: PrimerDebugOptions(is3DSSanityCheckEnabled: false),
            clientSessionCachingEnabled: false)
    }
}
```

### Appearance Mode Configuration

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

```swift SWIFT theme={"dark"}
// Force light mode regardless of system setting
let uiOptions = PrimerUIOptions(
    appearanceMode: .light  // Options: .system (default), .light, .dark
)

let settings = PrimerSettings(
    paymentHandling: .auto,
    uiOptions: uiOptions
)

// Configure Primer with the settings
Primer.shared.configure(settings: settings, delegate: self)
```

This feature is especially helpful when:

* Your app has a "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
