> ## 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.

# SDK v1 to v2

export const ApiEndpoint = ({method, path}) => {
  const getMethodColor = method => {
    switch (method?.toUpperCase()) {
      case "GET":
        return "#0285c7";
      case "POST":
        return "#008d71";
      case "PUT":
        return "#16a34a";
      case "PATCH":
        return "#808080";
      case "DELETE":
        return "#dc2626";
      default:
        return "#6b7280";
    }
  };
  const getEndpointUrl = (method, path) => {
    const endpoints = {
      "POST /client-session": "/api-reference/v2.4/api-reference/client-session-api/create-a-client-session",
      "PATCH /client-session": "/api-reference/v2.4/api-reference/client-session-api/update-client-session",
      "POST /payments": "/api-reference/v2.4/api-reference/payments-api/create-a-payment",
      "POST /payments/<YOUR-PAYMENT-ID>/resume": "/api-reference/v2.4/api-reference/payments-api/resume-payment",
      "POST /payments/<YOUR-PAYMENT-ID>/adjust-authorization": "/api-reference/v2.4/api-reference/payments-api/adjust-authorized-amount",
      "POST /payments/<PAYMENT_ID>/cancel": "/api-reference/v2.4/api-reference/payments-api/cancel-payment",
      "POST /payments/<PAYMENT_ID>/refund": "/api-reference/v2.4/api-reference/payments-api/refund-payment",
      "GET /payments/<PAYMENT_ID>": "/api-reference/v2.4/api-reference/payments-api/get-a-payment",
      "GET /payment-instruments": "/api-reference/v2.4/api-reference/payment-methods-api/list-saved-payment-methods",
      "DELETE /payment-instruments/<PAYMENT_METHOD_TOKEN>": "/api-reference/v2.4/api-reference/payment-methods-api/delete-payment-method-payment-methods-token-delete"
    };
    const key = `${method?.toUpperCase()} ${path}`;
    return endpoints[key] || "#";
  };
  const getPrettyPath = (method, path) => {
    const pathMapping = {
      "POST /payments/<YOUR-PAYMENT-ID>/resume": "/payments/{paymentId}/resume",
      "POST /payments/<YOUR-PAYMENT-ID>/adjust-authorization": "/payments/{paymentId}/adjust-authorization",
      "POST /payments/<PAYMENT_ID>/cancel": "/payments/{paymentId}/cancel",
      "POST /payments/<PAYMENT_ID>/refund": "/payments/{paymentId}/refund",
      "GET /payments/<PAYMENT_ID>": "/payments/{paymentId}",
      "DELETE /payment-instruments/<PAYMENT_METHOD_TOKEN>": "/payment-instruments/{paymentMethodToken}"
    };
    const key = `${method?.toUpperCase()} ${path}`;
    return pathMapping[key] || path;
  };
  const methodColor = getMethodColor(method);
  const url = getEndpointUrl(method, path);
  const displayPath = getPrettyPath(method, path);
  return <div style={{
    display: "inline-flex",
    alignItems: "center",
    cursor: "pointer",
    margin: "2px 0",
    padding: "4px",
    paddingRight: "6px",
    background: "rgb(245, 245, 245)",
    borderRadius: "6px",
    whiteSpace: "nowrap",
    textDecoration: "none"
  }}>
      <a href={url} target="_blank" rel="noopener noreferrer" style={{
    textDecoration: "none",
    border: "none"
  }}>
        <span style={{
    display: "inline-block",
    whiteSpace: "nowrap",
    padding: "0 8px",
    fontSize: "13px",
    lineHeight: "23px",
    borderRadius: "6px",
    fontWeight: 400,
    backgroundColor: methodColor,
    color: "white",
    border: "none"
  }}>
          {method.toUpperCase()}
        </span>
        <code style={{
    padding: "0",
    marginLeft: "4px",
    fontFamily: "monospace",
    color: methodColor,
    border: "none",
    textDecorationColor: methodColor
  }}>
          {displayPath}
        </code>
      </a>
    </div>;
};

<Tabs>
  <Tab title="Web">
    ## Migrating from v1 to v2

    The latest Web SDK has evolved significantly from the previous release SDK v1. This guide describes what is new in v2, what has changed from v1 and what you need to do to migrate to the latest Universal Checkout SDK v2.

    <Note>
      The latest version v2 of Universal Checkout Web SDK introduces a few breaking changes.
    </Note>

    <Note>
      Universal Checkout v2 SDK is super efficient and simpler to integrate. Going forward, the prior Primer Checkout SDK v1.x.x will be no longer supported.
    </Note>

    ## Key Highlights

    * There is a brand new way to [initialize checkout](#initializing-universal-checkout)
    * Universal Checkout now [creates payments automatically](#automatic-payment-creation) in a more secure manner.
    * Some of the earlier payment method options and methods are no longer required, therefore removed or addressed via other calls or functions.
    * The way to [customize merchant branding through styling](/docs/checkout/drop-in/customization/web) has changed.

    For more details about the new features and to see specific code examples, refer to the other sections of this guide.

    ## Initializing Universal Checkout

    In the new Primer Universal Checkout Web SDK, you’ll find that the boilerplate for initializing is reduced to just one line of code!

    ```typescript theme={"dark"}
    /* v2 */
    // To initialize Universal Checkout
    const universalCheckout = await Primer.showUniversalCheckout(clientToken, options)
    ```

    Compare with previous v1 SDK that required you to write more code:

    ```typescript theme={"dark"}
    /* v1 */
    const Primer = await loadPrimer()                   // If the package is loaded from npm
    const primer = new Primer({ credentials: clientToken })
    const checkout = await primer.checkout(options)
    ```

    ## Initialize Vault Manager

    In the v2 SDK, you can initialize the vault manager using the following function:

    ```typescript theme={"dark"}
    /* v2 */
    // to initialize Vault Manager
    const vaultManager = await Primer.showVaultManager(clientToken, options)
    ```

    ## Other Initialization Changes

    The new Universal Checkout initialization makes integration much simpler and easier. As a result, developers are no longer required to construct the Primer object using `new Primer()` call. Instead, you need to use `Primer.showUniversalCheckout()` or `Primer.showVaultManager()`.

    Another set of changes that you need to take into account is when the package is loaded from npm:

    * The `loadPrimer()` call is now removed from the latest SDK. When the user approaches checkout, if you need to preload Primer Universal Checkout SDK, use `preloadPrimer()` instead. Under the hood, `loadPrimer()` is automatically called by `Primer.showUniversalCheckout()` so you do not need to call `loadPrimer()` explicitly anymore.
    * It is no longer required to import the CSS file anymore. `Primer.showUniversalCheckout()` will automatically load it.

    To find out more about Universal Checkout initialization process, checkout the [Web Get Started Guide](/docs/checkout/drop-in/overview#web).

    ## Automatic Payment Creation

    Universal Checkout Web SDK v2 now creates, resumes and handles payments under the hood 🎉

    The automatic payment flow is activated by default.

    When migrating to Web SDK v2, you need to use the following simpler code for payment creation:

    ```typescript theme={"dark"}
    /* v2 */
    Primer.showUniversalCheckout(token, {
        onCheckoutComplete({ payment }) {
            // e.g. Show a success message
        },
    })
    ```

    Earlier, the payment creation code was more complex:

    ```typescript theme={"dark"}
    /* v1 */
    primer.checkout({
        onTokenizeSuccess(paymentMethodTokenData) {
            // Create a payment
            // If payment fails: show error message
            // If payment succeeds: show a success message
            // If payment has a required action: return the new client token
        },
        onResumeSuccess(resumeTokenData) {
            // Resume the payment
            // If payment fails: show error message
            // If payment succeeds: show a success message
            // If payment has a required action: return the new client token
        },
    })
    ```

    In the earlier versions, you had to manually create and resume payments using `onTokenizeSuccess` and `onResumeSuccess`. **Not anymore.**

    The functions `onTokenizeSuccess` and `onResumeSuccess` are no longer required to be used. This essentially means that you do not need to make any API calls for creating and resuming payments.

    Those can be edited out of your integration code.

    *No complex integrations to maintain anymore!*

    With the new SDK, you can simply listen to the `PAYMENT.STATUS` webhook and the callback `onCheckoutComplete` to process successful and even more secure payments as compared to the earlier versions.

    <Frame>
      <img src="https://mintcdn.com/primer-cc826789/dM-udzSll5kL79ou/images/changelogs/sdk-v1-to-v2/web/automatic-payment-flow.png?fit=max&auto=format&n=dM-udzSll5kL79ou&q=85&s=299b523dd997bdbe66475c1507d78e56" width="1440" height="813" data-path="images/changelogs/sdk-v1-to-v2/web/automatic-payment-flow.png" />
    </Frame>

    <Note>
      Should you wish to go back to the manual flow of v1, pass the option `paymentHandling: "MANUAL"`. See [Manual Payment Creation Guide](/docs/checkout/advanced/manual-payment-creation#web) for details.

      ```typescript theme={"dark"}
      /* v2 */
      Primer.showUniversalCheckout({
          paymentHandling: 'MANUAL',

          onTokenizeSuccess(data, handler) {
              // To implement
          },

          onResumeSuccess(data, handler) {
              // To implement
          },

          /* Other options */
      })
      ```
    </Note>

    ## onTokenizeSuccess and onResumeSuccess change

    In the earlier version, `onTokenizeSuccess` and `onResumeSuccess` had to return specific data to trigger various scenarios. This proved to be quite error-prone and not self-explanatory.

    ```typescript theme={"dark"}
    /* v2 */
    async function onTokenizeSuccess(paymentMethodTokenData) {
      return true;                               // Handle success
      // or
      throw new Error("Error message");          // Handle error message
      // or
      return { clientToken: "..." }              // Continue the flow with a new client token
    }

    // Same for onResumeSuccess
    ```

    This logic has been greatly improved in v2 by introducing a `handler` argument that contains the functions to continue.

    ```typescript theme={"dark"}
    /* v2 */
    async function onTokenizeSuccess(paymentMethodTokenData, handler) {
      return handler.handleSuccess();                    // Handle success
      // or
      return handler.handleFailure("Error message");     // Handle failure with a custom error message
      // or
      return handler.continueWithNewClientToken("...");  // Continue the flow with a new client token
    }

    async function onResumeSuccess(paymentMethodTokenData, handler) {
      return handler.handleSuccess();                    // Handle success
      // or
      return handler.handleFailure("Error message");     // Handle failure with a custom error message
      // or
      return handler.continueWithNewClientToken("...");  // Continue the flow with a new client token
    }
    ```

    ## Improved 3DS

    <Note>
      In Web SDK v2 the `threeDSecure` option is now completely removed from the Universal Checkout. Earlier, this option was provided to trigger 3DS at the time of tokenization.
    </Note>

    In the latest SDK, the 3DS feature can be accessed without writing a single line of integration code by simply using workflows. You can be fully SCA-ready with a unified checkout across all your payment services including 3D Secure 2.0.

    Once you add a 3DS pre-authorization Primer Connection to your Workflow, the [Universal Checkout](/docs/checkout/drop-in/overview#web) feature will just do the right thing for you. It will present to your customer a fully in-context workflow that is optimized with 3D Secure flow on both web or mobile.

    ### Payment Options Updates

    The following payment method options in Primer Checkout SDK v1.x.x are no longer available in the latest Universal Checkout SDK v2. Developers must now specify the order and customer details when creating the client session with <ApiEndpoint method="POST" path="/client-session" />.

    | Earlier v1.x.x                                 | Latest v2 SDK                                                                           |
    | ---------------------------------------------- | --------------------------------------------------------------------------------------- |
    | `purchaseInfo` and `orderDetails` (in the SDK) | Pass the order details through the client-session API call.                             |
    | `customerDetails` (in the SDK)                 | Pass the customer information through the client-session API call.                      |
    | `customerId` (in the SDK)                      | Specify the `customerId` through the client-session API call.                           |
    | `countryCode` (in the SDK)                     | Pass `order.countryCode` through the client-session API call.                           |
    | `businessDetails` (in the SDK)                 | Only needed for tax calculation using TaxJar. Removed. In the future, business details… |

    ## Setters Removed

    The Setters in Web SDK v1.x.x listed below have been removed. Now this information is retrieved by Universal Checkout through the client session.

    Developers need to migrate their integration backend to use the latest Universal Checkout SDK v2 and update order details using <ApiEndpoint method="PATCH" path="/client-session" />. The token obtained through the client-session API needs to be passed to the SDK with `setClientToken(newClientToken)` API call.

    | Earlier v1.x.x                                       | Latest v2 SDK                                                               |
    | ---------------------------------------------------- | --------------------------------------------------------------------------- |
    | `setPurchaseInfo` and `setOrderDetails` (in the SDK) | Update the order in the client session, then call `setClientToken(...)`.    |
    | `setCustomerDetails` (in the SDK)                    | Update the customer in the client session, then call `setClientToken(...)`. |
    | `setBusinessDetails` (in the SDK)                    | This has been completely removed                                            |

    ```typescript theme={"dark"}
    const universalCheckout = await Primer.showUniversalCheckout(clientToken, options)

    // Update client token
    universalCheckout.setClientToken('...')
    ```

    <Note>
      Once you migrate your merchant backend, all your implementations will be able to properly display payment methods through the Primer Universal Checkout, regardless of the platform!
    </Note>

    ### allowedPaymentMethods Removed

    In the previous Primer Checkout v1.x.x, the option `allowedPaymentMethods` was used to filter and display the payment methods as required by a specific merchant integration. This is no longer necessary and has been completely removed in the latest SDK v2.

    The recently introduced **Checkout** section in the Dashboard enables display of merchant-specific payment methods, based on the conditions defined by them.

    <Note>
      With Universal Checkout, Primer can now dynamically show payment methods in the user interface. It uses the conditions set up by you on the dashboard, along with the data passed in the client session call, to dynamically display only those payment methods that are applicable as per your selection and inputs.
    </Note>

    *All of this happens without a single line of code as part of merchant integration!*

    See [How Universal Checkout works](/docs/checkout/overview) for details.

    ## Client Session Actions Automation

    Earlier versions of Primer Checkout SDK required you to integrate using `onClientSessionActions`.

    Now, with the latest SDK v2, as the customer interacts with the UI, Universal Checkout takes care of setting up "client session actions" via `onClientsessionActions()`.

    <Note>
      Developers are no longer required to call this function anymore and it has been removed from the SDK. Instead, now you need to set up the following callbacks:

      * `onClientSessionUpdate`
      * `onClientSessionUpdateStart`
    </Note>

    As a side effect of this usage change, the following callbacks have also been removed from the SDK in addition to `onClientSessionActions`. These callbacks are now replaced by the client session update call.

    * `onAmountChange`
    * `onAmountChanging`
    * `onAmountChangeError`

    <Note>
      The previous SDK version had Primer Checkout functionality that was sending you `Client session actions` in order to enable you to update the client session according to the merchant checkout requirements. This is now completely managed automatically by the Primer Universal Web SDK v2.

      The latest SDK can now collect various customer data such as the `billing address`, `customer contact` details and update the client session by itself. It no longer requires any explicit developer initiated actions or function calls to update these details while integrating with Primer.
    </Note>

    For more details, refer to the [Universal Checkout Guide](/docs/checkout/checkout-builder).

    ## Submit Button Updates

    If you have setup a custom submit button in the checkout user interface here is what you need to do in order to migrate from previous Primer Checkout Web SDK:

    * Use the function `submit()` to implement a custom submit button. For details, see [Universal Checkout Submit button usage guide](https://www.npmjs.com/package/@primer-io/checkout-web?activeTab=readme).

    - The option `submitButton.visible` is now renamed to `submitButton.useBuiltInButton`.

    ## Styling Customization Changes

    Earlier, the card input fields could be customized as per merchant checkout requirements using `card.css`.

    Now, you can instead use the `style` option to customize the style 🎨 for the entire Universal Checkout SDK and align with the merchant branding in a more cohesive and unified way!

    For more details, refer to the [Primer Universal Checkout Web SDK Styling Guide](/docs/checkout/drop-in/customization/web).

    ## Miscellaneous Updates

    * **Card holder name display option**
      The option `card.cardholderName.visible` available in the previous version of Primer Checkout SDK has been removed altogether. You can continue to configure this setting through the Dashboard in the forthcoming release. Stay tuned!

      In the meantime, if you need to show or hide the cardholder name field, please get in touch with us.

    * **Renamed `CheckoutOptions`**
      The TypeScript `CheckoutOptions` is now renamed to `UniversalCheckoutOptions`.

    * **Checkout object updates**
      The checkout object functions `tokenize()` and `validate()` are no longer available in Universal Checkout SDK v2.

    ## Deprecated Items

    * **Checkout Components**
      Checkout Components are now sunset and no longer supported. The new Universal Checkout SDK does not contain the `primer.render()` function. Make sure you clean that up!

    <Note>
      At Primer, we are all working hard towards a fully customisable payment framework that enables you to build any checkout that you want!

      Stay tuned for more updates!
    </Note>
  </Tab>

  <Tab title="Android">
    ## Migrating from v1 to v2

    The latest Android SDK has evolved significantly from the previous release SDK v1. This guide describes what is new in v2, what has changed from v1 and what you need to do to migrate to the latest Universal Checkout SDK v2.

    <Note>
      The latest version v2 of Universal Checkout Android SDK introduces a few breaking changes.
    </Note>

    <Note>
      Universal Checkout v2 SDK is super efficient and simpler to integrate. Going forward, the prior Primer Checkout SDK v1.x.x will be no longer supported.
    </Note>

    ## Key Highlights

    * Universal Checkout now [creates payments automatically](#automatic-payment-creation) in a more secure manner
    * Some of the earlier [payment method options](#payment-options-updates) are no longer required, therefore removed or addressed via other calls or functions
    * We’ve made major improvements to Universal Checkout’s [listener](#primer-listener-changes)

    For more details about the new features and to see specific code examples, refer to the other sections of this guide.

    ## Automatic Payment Creation

    Universal Checkout Android SDK v2 now creates, resumes and handles payments under the hood 🎉

    The automatic payment flow is activated by default.

    When migrating to Android SDK v2, you need to use the following simpler code for payment creation:

    ```kotlin theme={"dark"}
    private val listener = object : PrimerCheckoutListener {

    override fun onCheckoutCompleted(checkoutData: PrimerCheckoutData) {
       // show an order confirmation screen
    }
    }

    Primer.instance.configure(listener = listener)

    Primer.instance.showUniversalCheckout(context, clientToken)
    ```

    Earlier, the payment creation code was more complex:

    ```kotlin theme={"dark"}
    private val listener = object : CheckoutEventListener {

       override fun onCheckoutEvent(e: CheckoutEvent) {

          when (e) {

             is CheckoutEvent.TokenizationSuccess -> {
                // Create a payment
                // If payment fails: show error message
                // If payment succeeds: show a success message
                // If payment has a required action: return the new client token
             }

             is CheckoutEvent.ResumeSuccess -> {
                // Resume the payment
                // If payment fails: show error message
                // If payment succeeds: show a success message
                // If payment has a required action: return the new client token
             }
          }
       }
    }

    Primer.instance.configure(listener = listener)

    Primer.instance.showUniversalCheckout(context, clientToken)
    ```

    In the earlier versions, you had to manually create and resume payments when receiving `CheckoutEvent.TokenizationSuccess` and `CheckoutEvent.ResumeSuccess`. **Not anymore.**

    We have redesigned and changed this callback and you will no longer have to listen to different events but rather to different callbacks. But even now, you are no longer required to use `onTokenizeSuccess` and `onResumeSuccess` callbacks. This essentially means that you do not need to make any API calls for creating and resuming payments.

    Those can be edited out of your integration code.

    *All this results in an even simpler integration to maintain!*

    With the new SDK, you can simply listen to the `PAYMENT.STATUS` webhook and the callback `onCheckoutCompleted` to process successful and even more secure payments as compared to the earlier versions.

    <Frame>
      <img src="https://mintcdn.com/primer-cc826789/dM-udzSll5kL79ou/images/changelogs/sdk-v1-to-v2/android/flow.png?fit=max&auto=format&n=dM-udzSll5kL79ou&q=85&s=6266f6fb6f260695fa27c996ba502add" width="1440" height="813" data-path="images/changelogs/sdk-v1-to-v2/android/flow.png" />
    </Frame>

    ## Primer listener changes

    We have completely changed how you are receiving events/callbacks from Android SDK.

    Previously you had to use `onCheckoutEvent` callback that was receiving different events from the SDK. We have updated it to a more natural approach and now all events are translated to different callbacks:

    | Earlier v1.x.x                      | Latest v2 SDK          |
    | ----------------------------------- | ---------------------- |
    | `CheckoutEvent.TokenizationSuccess` | `onTokenizeSuccess` \* |
    | `CheckoutEvent.ResumeSuccess`       | `onResumeSuccess` \*   |
    | `CheckoutEvent.Exit`                | `onDismissed`          |
    | `CheckoutEvent.TokenizationError`   | `onFailed`             |
    | `CheckoutEvent.APIError`            | `onFailed`             |
    | `CheckoutEvent.ResumeError`         | `onFailed`             |

    *Only relevant on the `manual` flow. Won’t be called if `paymentHandling` is `AUTO`, which is the default value*

    Moreover, we have renamed `CheckoutEventListener` → `PrimerCheckoutListener`

    ## Client Session Actions Automation

    Earlier versions of Primer Checkout SDK required you to integrate using `onClientSessionActions`.

    Now, with the latest SDK v2, as the customer interacts with the UI, Universal Checkout takes care of setting up "client session actions" via `onClientsessionActions()`.

    <Note>
      Developers are no longer required to call this function anymore and it has been removed from the SDK. Instead, now you can set up the following callbacks:

      * `onClientSessionUpdated`
      * `onBeforeClientSessionUpdated`
    </Note>

    <Note>
      Earlier release of SDK had Primer Checkout functionality that was sending you `Client session actions` in order to enable you to update the client session according to the merchant checkout requirements. This is now completely managed automatically by the Primer Universal Android SDK v2.

      The latest SDK can now collect various customer data such as the `billing address`, `customer contact` details and update the client session by itself. It no longer requires any explicit developer initiated actions or function calls to update these details while integrating with Primer.
    </Note>

    For more details, refer to the [Universal Checkout Guide](/docs/checkout/checkout-builder).

    ## Payment Options Updates

    The following payment method options in Primer Checkout SDK v1.x.x are no longer available in the latest Universal Checkout SDK v2:

    * `Order`
    * `Customer`

    Developers must now specify the `order` and `customer` details when creating the client session with <ApiEndpoint method="POST" path="/client-session" />.

    We have completely restructured how you are passing your local settings to SDK. Earlier, you would be passing `PrimerConfig` object to the SDK with various options:

    ```kotlin theme={"dark"}
    Primer.instance.configure(PrimerConfig(...))
    ```

    Now, you should be passing `PrimerSettings`:

    ```kotlin theme={"dark"}
    Primer.instance.configure(PrimerSettings(...))
    ```

    ## **Miscellaneous Updates**

    * `PrimerSettings` structure has been refactored and `PrimerTheme` has been integrated within it. Check the [PrimerSettings API Reference](https://www.notion.so/primerio/API-Reference-e58ee6d184ff4cd7ae2f90c6b28aaaba) for details.

    | Earlier v1.x.x       | Latest v2 SDK                 |
    | -------------------- | ----------------------------- |
    | `PaymentMethodToken` | `PrimerPaymentMethodToken`    |
    | `ResumeHandler`      | `PrimerResumeDecisionHandler` |

    ## Resume handler updates

    * `handler.handleError(error: Error)` → `handler.handleFailure(message: String?)`
    * `handler.handleNewClientToken(clientToken: String)` → `handler.continueWithNewClientToken(clientToken: String)`

    ## Removed Items

    All the deprecated methods in v1 have been removed and replaced with other methods where applicable:

    ### Class `Primer`:

    | Earlier v1.x.x          | Latest v2 SDK           |
    | ----------------------- | ----------------------- |
    | `initialize`            | `configure`             |
    | `showCheckout`          | `showUniversalCheckout` |
    | `showVault`             | `showVaultManager`      |
    | `showSuccess`           | Removed                 |
    | `showError`             | Removed                 |
    | `showProgressIndicator` | Removed                 |

    ### Interface `PrimerCheckoutListener`:

    * `onClientSessionActions` *→ **Removed***
    * `onTokenAddedToVault` → *Removed*

    ### Class `PrimerSettings`:

    All the deprecated classes in v1 have been removed:

    * `Order`
    * `Customer`

    Also, we have removed:

    * `PrimerConfig`
    * `Business`
    * `Address`
  </Tab>

  <Tab title="iOS">
    ## Migrating from v1 to v2

    The latest iOS SDK has evolved significantly from the previous release SDK v1. This guide describes what is new in v2, what has changed from v1 and what you need to do to migrate to the latest Universal Checkout SDK v2.

    <Note>
      The latest version v2 of Universal Checkout iOS SDK introduces a few breaking changes.
    </Note>

    <Note>
      Universal Checkout v2 SDK is super efficient and simpler to integrate. Going forward, the prior Primer Checkout SDK v1.x.x will be no longer supported.
    </Note>

    ## Key Highlights

    * Universal Checkout now [creates payments automatically](#automatic-payment-creation) in a more secure manner
    * Some of the earlier [payment method options](#payment-options-updates) are no longer required, therefore removed or addressed via other calls or functions
    * We’ve made major improvements to the SDK’s delegate and settings

    For more details about the new features and to see specific code examples, refer to the other sections of this guide.

    ## Automatic Payment Creation

    Universal Checkout iOS SDK v2 now creates, resumes and handles payments under the hood 🎉

    The automatic payment flow is activated by default.

    When migrating to iOS SDK v2, you need to use the following simpler code for payment creation:

    ```swift theme={"dark"}
    import PrimerSDK

    class MyViewController: UIViewController {

       override func viewDidLoad() {
          super.viewDidLoad()
          // Initialize the SDK with the default settings.
          Primer.shared.configure(delegate: self)
       }

       func startUniversalCheckout() {
          Primer.shared.showUniversalCheckout(clientToken: self.clientToken)
       }
    }

    extension MyViewController: PrimerDelegate {
       func primerDidCompleteCheckoutWithData(_ data: CheckoutData) {
          // Primer checkout completed with data
       }
    }
    ```

    Earlier, the payment creation code was more complex:

    ```swift theme={"dark"}
    import PrimerSDK

    class MyViewController: UIViewController {

       override func viewDidLoad() {
          super.viewDidLoad()
          // Initialize the SDK with the default settings.
          let settings = PrimerSettings(
             amount: amount,
             currency: currency
          )

          Primer.shared.configure(settings: settings)
          Primer.shared.delegate = self
       }

       func startUniversalCheckout() {
          Primer.shared.showUniversalCheckout(on: self)
       }
    }

    extension MyViewController: PrimerDelegate {

       func clientTokenCallback(_ completion: @escaping (String?, Error?) -> Void) {
          // API call to fetch client token from your backend.
          fetchClientToken() { (token, err) in
             completion(token, err)
          }
       }

       func onTokenizeSuccess(_ paymentMethodToken: PaymentMethodToken, resumeHandler: ResumeHandlerProtocol) {
          // Send the payment method token to your server to create a payment
          sendPaymentMethodToken(token: paymentMethodToken) { (res, err) in
             if let err = err {
                resumeHandler.handle(error: err)
             } else if let res = res {
                guard let requiredActionDic = res["requiredAction"] as? [String: Any],
                      let clientToken = requiredActionDic["clientToken"] as? String
                else {
                   resumeHandler.handleSuccess()
                   return
                }
                resumeHandler.handle(newClientToken: clientToken)
             }
          }
       }

       func onResumeSuccess(_ resumeToken: String, resumeHandler: ResumeHandlerProtocol) {
          // Resume the payment
          sendResumeToken(resumeToken) { (res, err) in
             if let err = err {
                resumeHandler.handle(error: err)
             } else if let res = res {
                resumeHandler.handleSuccess()
             }
          }
       }
    }
    ```

    In the earlier versions, you had to manually create and resume payments when receiving `CheckoutEvent.TokenizationSuccess` and `CheckoutEvent.ResumeSuccess`. **Not anymore.**

    We have redesigned and changed this callback and you will no longer have to listen to different events but rather to different callbacks.  But even now, you are no longer required to use `onTokenizeSuccess` and `onResumeSuccess` callbacks. This essentially means that you do not need to make any API calls for creating and resuming payments.

    Those can be edited out of your integration code.

    *All this results in an even simpler integration to maintain!*

    With the new SDK, you can simply listen to the `PAYMENT.STATUS` webhook and the callback `onCheckoutCompleted` to process successful and even more secure payments as compared to the earlier versions.

    <Frame>
      <img src="https://mintcdn.com/primer-cc826789/dM-udzSll5kL79ou/images/changelogs/sdk-v1-to-v2/ios/flow.png?fit=max&auto=format&n=dM-udzSll5kL79ou&q=85&s=da5edb526e0a52b7e2eab1b98edc19ab" width="1440" height="813" data-path="images/changelogs/sdk-v1-to-v2/ios/flow.png" />
    </Frame>

    ## Primer listener changes

    We have completely changed how you are receiving events via the `PrimerDelegate`.

    Previously you had to use the delegate functions that were returning different SDK events. We have updated it to a more natural approach and now all events are translated to different callbacks:

    | Earlier v1.x.x      | Latest v2 SDK                       |
    | ------------------- | ----------------------------------- |
    | `onTokenizeSuccess` | `primerDidTokenizePaymentMethod` \* |
    | `onResumeSuccess`   | `primerDidResumeWith` \*            |
    | `onDismiss`         | `primerDidDismiss`                  |
    | `checkoutFailed`    | `primerDidFailWithError`            |
    | `onResumeError`     | `primerDidFailWithError`            |

    *Only relevant on the `manual` flow. Won’t be called if `paymentHandling` is `AUTO`, which is the default value*

    ## Client Session Actions Automation

    Earlier versions of Primer Checkout SDK required you to integrate using `onClientSessionActions`.

    Now, with the latest SDK v2, as the customer interacts with the UI, Universal Checkout takes care of setting up the "client session actions".

    <Note>
      🛑 Developers are no longer required to call this function and it has been removed from the SDK. Instead, now you can set up the following callbacks:

      * `primerClientSessionDidUpdate`
      * `primerClientSessionWillUpdate`
    </Note>

    <Note>
      Earlier release of SDK had Primer Checkout functionality that was sending you `Client session actions` in order to enable you to update the client session according to the merchant checkout requirements. This is now completely managed automatically by the Primer Universal iOS SDK v2.

      The latest SDK can now collect various customer data such as the `billing address`, `customer contact` details and update the client session by itself. It no longer requires any explicit developer initiated actions or function calls to update these details while integrating with Primer.
    </Note>

    For more details, refer to the [Universal Checkout Guide](/docs/checkout/checkout-builder).

    ## Payment Options Updates

    The following payment method options in Primer Checkout SDK v1.x.x are no longer available in the latest Universal Checkout SDK v2:

    * `Order`
    * `OrderItem`
    * `Customer`
    * `Address`

    Instead, developers must now specify the `order` and `customer` details when creating the client session with <ApiEndpoint method="POST" path="/client-session" />.

    We have completely restructured how you are passing your local settings to SDK. Earlier, you would be passing `PrimerSettings` and a `PrimerTheme` object to the SDK with various options:

    ```swift theme={"dark"}
    Primer.shared.configure(settings: settings, theme: theme)
    ```

    Now, you should be passing PrimerSettings and set the delegate, as per the [Quick Start Guide](/docs/checkout/drop-in/overview#ios). In case you need more customization, you can find the PrimerSettings API reference [here](https://www.notion.so/primerio/API-Reference-f62b4be8f24642989e63c25a8fb5f0ba).

    ```swift theme={"dark"}
    Primer.shared.configure(settings: settings, delegate: self)
    ```

    ## **Miscellaneous Updates**

    * `PrimerSettings` structure has been refactored and `PrimerTheme` has been integrated within it. Check the [PrimerSettings API Reference](https://www.notion.so/primerio/API-Reference-f62b4be8f24642989e63c25a8fb5f0ba) for details.
    * Renamed `PaymentMethodToken` → `PrimerPaymentMethodTokenData`
    * Renamed `ResumeHandler` → `PrimerResumeDecisionHandler`
    * `showUniversalCheckout` and `showVaultManager` receive different arguments. You can find documentation on them in the [SDK API reference](https://www.notion.so/primerio/API-Reference-f62b4be8f24642989e63c25a8fb5f0ba).

    ## Resume handler updates

    Some delegate functions provide a decision handler, e.g. `primerWillCreatePaymentWithData(:decisionHandler:)`. You can process the data provided and once you’re ready you can call the decision handler with your relevant decision. Once you do, the SDK will continue the flow.

    | Earlier v1.x.x                                      | Latest v2 SDK                                                         |
    | --------------------------------------------------- | --------------------------------------------------------------------- |
    | `handler.handleError(error: Error)`                 | `decisionHandler(.fail(withErrorMessage: String?))`                   |
    | `handler.handleNewClientToken(clientToken: String)` | `decisionHandler(.continueWithNewClientToken(_ clientToken: String))` |
    | `handler.handleSuccess()`                           | `decisionHandler(.succeed())`                                         |

    ## Removed Items

    All the deprecated methods in v1 have been removed and replaced with other methods where applicable:

    * `tokenAddedToVault` → Removed
    * `onClientSessionActions` → Removed

    All the deprecated classes in v1 have been removed. They are instead set on the backend when creating the [client session]():

    * `Order`
    * `OrderItem`
    * `Customer`
    * `Address`
  </Tab>

  <Tab title="React Native">
    ## Migrating from v1 to v2

    The latest React Native (RN) SDK has evolved significantly from the previous release SDK v1. This guide describes what is new in v2, what has changed from v1 and what you need to do to migrate to the latest Universal Checkout SDK v2.

    <Note>
      The latest version v2 of Universal Checkout RN SDK introduces a few breaking changes.
    </Note>

    <Note>
      Universal Checkout v2 SDK is super efficient and simpler to integrate. Going forward, the prior Primer Checkout SDK v1.x.x will be deprecated.
    </Note>

    ## Key Highlights

    * Universal Checkout now [creates payments automatically](#automatic-payment-creation) in a more secure manner
    * Some of the earlier [payment method options](#payment-options-updates) are no longer required, therefore removed or addressed via other calls or functions
    * We’ve made major improvements to Universal Checkout’s [listener](#primer-listener-changes)

    For more details about the new features and to see specific code examples, refer to the sections below.

    ## Automatic Payment Creation

    Universal Checkout React Native SDK v2 now creates, resumes and handles payments under the hood 🎉

    The automatic payment flow is activated by default.

    When migrating to React Native SDK v2, you need to use the following simpler code for payment creation:

    ```js theme={"dark"}
    import {
       Primer,
       PrimerSettings,
       PrimerCheckoutData
    } from '@primer-io/react-native';

    const CheckoutScreen = async (props: any) => {

       const onCheckoutComplete = (checkoutData: PrimerCheckoutData) => {
          // Show a success screen
       }

       const onUniversalCheckoutButtonTapped = async () => {
          const settings: PrimerSettings = {
                onCheckoutComplete: onCheckoutComplete
          }

          // Configure the SDK
          await Primer.configure(settings)

          // Ask your backend to create a client session
          const clientToken = await createClientSession(clientSessionRequestParams)

          // Present Universal Checkout
          await Primer.showUniversalCheckout(clientToken)
       }
    }
    ```

    Earlier, the payment creation code was more complex:

    ```js theme={"dark"}
    import { Primer } from '@primer-io/react-native';

    const CheckoutScreen = (props: any) => {

       const onTokenizeSuccess = (req, res) => {
          createPayment({
             paymentMethod: req.token
          })
          .then((payment) => {
             // handle required actions if present.
             if (payment.requiredAction?.name) {
                // ensure the result id is stored somewhere.
                setPaymentId(result.id)
                // resume the SDK with the result clientToken.
                res.handleNewClientToken(result.requiredAction?.clientToken);
             } else {
                // resume the SDK passing a null object.
                res.handleSuccess();
             }
          })
          .catch(() => res.resumeWithError(errorMessage));
       }

       const onResumeSuccess = (req, res) => {
          resumeSession({
             id: paymentId,
             resumeToken: req
          })
          .then((payment) => {
             if (payment.status in ['FAILED', 'DECLINED', 'CANCELLED', 'PENDING']) {
                res.handleError(errorMessage);
             } else {
                res.handleSuccess();
             }
          })
          .catch(() => res.handleError(errorMessage));
       }

       const onUniversalCheckoutButtonTapped = async () => {
          try {
             const clientToken = await createClientSession(clientSessionRequestParams);

             // Present Universal Checkout
             Primer.showUniversalCheckout(clientToken, {
                onTokenizeSuccess,
                onResumeSuccess
             });
          } catch (err) {
             // Handle error
          }
       }
    }
    ```

    In the earlier versions, you had to manually create and resume payments when the delegate functions `onTokenizeSuccess` and `onResumeSuccess` were called. **Not anymore**.

    We have redesigned and changed this callback and you will no longer have to listen to different events but rather to different callbacks.  But even now, you are no longer required to use `onTokenizeSuccess` and `onResumeSuccess` callbacks. This essentially means that you do not need to make any API calls for creating and resuming payments.

    Those can be edited out of your integration code.

    *All this results in an even simpler integration to maintain!*

    With the new SDK, you can simply listen to the `PAYMENT.STATUS` webhook and the callback `onCheckoutCompleted` callback will be called.

    <Frame>
      <img src="https://mintcdn.com/primer-cc826789/dM-udzSll5kL79ou/images/changelogs/sdk-v1-to-v2/react-native/flow.png?fit=max&auto=format&n=dM-udzSll5kL79ou&q=85&s=a76a9b18894e95b8eb6aee5893177d9e" width="1440" height="813" data-path="images/changelogs/sdk-v1-to-v2/react-native/flow.png" />
    </Frame>

    ## Primer listener changes

    We have completely changed how you are receiving events, now you can add your callbacks in the SDK’s settings when you configure the SDK.

    Previously you had to separately add callbacks in the `showUniversalCheckout` function.

    We have updated it to a more natural approach and now all events are translated to different callbacks:

    | Earlier v1.x.x      | Latest v2 SDK          |
    | ------------------- | ---------------------- |
    | `onTokenizeSuccess` | `onTokenizeSuccess` \* |
    | `onResumeSuccess`   | `onResumeSuccess` \*   |
    | `Exit`              | `onDismissed`          |
    | `onDismiss`         | `onDismiss`            |
    | `checkoutFailed`    | `onFailed`             |
    | `onResumeError`     | `onFailed`             |

    *Only relevant on the `manual` flow. Won’t be called if `paymentHandling` is `AUTO`, which is the default value*

    ## Client Session Actions Automation

    Earlier versions of Primer Checkout SDK required you to integrate using `onClientSessionActions`.

    Now, with the latest SDK v2, as the customer interacts with the UI, Universal Checkout takes care of setting up the "client session actions".

    <Note>
      Developers are no longer required to call this function and it has been removed from the SDK. Instead, now you can set up the following callbacks:

      * `onClientSessionUpdate`
      * `onBeforeClientSessionUpdate`
    </Note>

    <Note>
      Earlier release of SDK had Primer Checkout functionality that was sending you `Client session actions` in order to enable you to update the client session according to the merchant checkout requirements. This is now completely managed automatically by the Primer Universal React Native SDK v2.

      The latest SDK can now collect various customer data such as the `billing address`, `customer contact` details and update the client session by itself. It no longer requires any explicit developer initiated actions or function calls to update these details while integrating with Primer.
    </Note>

    For more details, refer to the [Universal Checkout Guide](/docs/checkout/overview).

    ## Payment Options Updates

    The following payment method options in Primer Checkout SDK v1.x.x are no longer available in the latest Universal Checkout SDK v2.

    * `Order`
    * `OrderItem`
    * `Customer`
    * `Address`

    Instead, developers must now specify the `order` and `customer` details when creating the client session with <ApiEndpoint method="POST" path="/client-session" />.

    We have completely restructured how you are passing your local settings to SDK. Earlier, you would be passing a `PrimerConfig` object—that contained the SDK settings and callbacks—to the SDK in the `showUniversalCheckout` function.

    ```js theme={"dark"}
    Primer.configure(settings);
    ```

    Now, you should be passing `PrimerSettings` on the `configure` function, as per the [Quick Start Guide](/docs/checkout/drop-in/overview#react-native). In case you need more customization, you can find the `PrimerSettings` API reference [here](https://www.notion.so/primerio/API-Reference-1ce697cf1de6425794df9feeb831f3c3).

    ```js theme={"dark"}
    Primer.showUniversalCheckout(clientToken);
    ```

    ## Miscellaneous Updates

    * `PrimerSettings` structure has been refactored and `PrimerTheme` has been integrated within it. Check the [PrimerSettings API Reference](https://www.notion.so/primerio/API-Reference-1ce697cf1de6425794df9feeb831f3c3) for details.
    * Renamed `PaymentMethodToken` → `PrimerPaymentMethodTokenData`
    * Renamed `ResumeHandler` → `PrimerResumeDecisionHandler`
    * `showUniversalCheckout` and `showVaultManager` receive different arguments. You can find documentation on them in the [SDK API reference](https://www.notion.so/primerio/API-Reference-1ce697cf1de6425794df9feeb831f3c3).

    ## Removed Items

    All the deprecated methods in v1 have been removed and replaced with other methods where applicable:

    * `onVaultSuccess` → Removed
    * `onClientSessionActions` → Removed

    All the deprecated classes in v1 have been removed. They are instead set on the backend when creating the [client session](/docs/checkout/client-session).

    * `Order`
    * `OrderItem`
    * `Customer`
    * `Address`
  </Tab>
</Tabs>
