# Upgrade from Frames for iOS Follow this guide to upgrade your Frames for iOS integration to Flow for mobile. --- ## Before you start Create a [public key and a secret key](https://www.checkout.com/docs/resources/api-authentication/api-keys.md) from the [Dashboard](https://dashboard.checkout.com), with the following key scopes: - Public key – `payment-sessions:pay` and `vault-tokenization` - Secret key – `payment-sessions` To receive webhooks for the [payment events](https://www.checkout.com/docs/developer-resources/event-notifications/event-types.md#Gateway), [configure your webhook server](https://www.checkout.com/docs/developer-resources/event-notifications/receive-webhooks/configure-your-webhook-server.md). --- ## Remove existing Frames code To prepare for the upgrade to Flow, remove all Frames code from your client-side and server-side integrations. ### Remove Frames dependency `Client side` Remove the SDK: **CocoaPods** Run the following command in the terminal: ``` pod deintegrate ``` **Swift Package Manager** In Xcode, go to _Project_ > _Package Dependencies_ and remove the dependency. ### Remove Frames initialization `Client side` Remove any Swift code where you initialize Frames. For example: ```swift import Frames let framesViewController = PaymentFormFactory.buildViewController( configuration: configuration, style: style, completionHandler: completion ) navigationController?.pushViewController(framesViewController, animated: true) ``` ### Remove payment logic `Server side` Remove all server-side API calls to the following endpoints: **Production** `POST` `https://api.checkout.com/payments` **Sandbox** `POST` `https://api.sandbox.checkout.com/payments` --- ## Create a Flow Payment Session `Server side` Update your server to create a `PaymentSession` for the Flow integration: ```javascript const createPaymentSession = async (req, res) => { const response = await fetch("https://{prefix}.api.checkout.com/payment-sessions", { method: "POST", headers: { Authorization: `Bearer ${secretKey}`, "Content-Type": "application/json", }, body: JSON.stringify({ amount: 1000, currency: "GBP", reference: "ORD-123A", display_name: "Online Shop", billing: { address: { country: "GB" }, }, customer: { name: "Jia Tsang", email: "jia.tsang@example.com", }, success_url: "https://example.com/payments/success", failure_url: "https://example.com/payments/failure", }), }); const paymentSession = await response.json(); res.json(paymentSession); }; ``` --- ## Initialize and mount Flow `Client side` ### Add Flow dependency In Xcode, go to _Project_ > _Package Dependencies_ and add `https://github.com/checkout/checkout-ios-components`. ### Initialize Flow Configure Flow with your public key and the payment session data returned from the server: ```swift import CheckoutComponentsSDK let configuration = try await CheckoutComponents.Configuration( paymentSession: paymentSession, publicKey: publicKey, environment: environment, callbacks: .init( onSuccess: { paymentMethod, paymentID in // Handle success }, onError: { error in // Handle error } ) ) // Initialize the Flow for mobile payment component: try checkoutComponentsSDK.create(.flow()) ``` ### Render Flow Check if the Flow component is available and render it: ```swift // Check if component is available if component.isAvailable { return component.render() } else { return nil } ``` --- ## Handle payment responses You can use Flow to handle payment methods that require a redirect (asynchronous payments) and those that do not (synchronous payments). ### Asynchronous payments Depending on the payment outcome, customers are redirected to the `success_url` or `failure_url` you specified when you created the `PaymentSession`. We send a webhook to your server notifying you of changes to the payment's status. Wait for the webhook callback before you start your order fulfillment process. For payments submitted with Flow, the `PaymentSession` ID is returned in the webhook payload's `data.metadata.cko_payment_session_id` field. Optionally, you can retrieve the payment result using the callbacks provided by Flow: - `onSuccess` for successful payments - `onError` for unsuccessful payments ### Synchronous payments For payment methods that do not require a redirect, use the `onSuccess` callback to handle payments. You can use this to notify the customer of the payment status. ```swift let callbacks = CheckoutComponents.Callbacks(onSuccess: { paymentMethod, paymentID in // Payment with ID: paymentID has gone through successfully } let configuration = CheckoutComponents.Configuration(callbacks: callbacks) ``` --- ## Test the Flow integration Use our [test cards](https://www.checkout.com/docs/developer-resources/testing/test-cards.md) to simulate different payment flows, to ensure your integration is set up correctly and behaving as expected. > **Information** > > Ensure that you test each payment method that you plan to offer to your customers. You can check the status of a payment from the _Payments_ > _Processing_ > _All payments_ page in the [Dashboard](https://dashboard.checkout.com). --- ## Upgrade your Apple Pay integration You can use Flow for mobile to natively offer Apple Pay payments. To upgrade from your Apple Pay Frames integration: 1. Remove any `PKPayment` related code from your Frames implementation. For Example: ```swift func handle(payment: PKPayment) { // Create a CheckoutAPIClient instance with your public key. let checkoutAPIClient = CheckoutAPIClient( publicKey: "PUBLIC_KEY", environment: .sandbox) // Get the data containing the encrypted payment information. let paymentData = payment.token.paymentData // Request an Apple Pay token. checkoutAPIClient.createApplePayToken(paymentData: paymentData) { result in switch result { case .success(let response): print(response) case .failure(let error): print(error.localizedDescription) } } } ``` 2. Follow the [Flow for mobile instructions](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-mobile-app/get-started-with-flow-for-mobile.md#Apple_Pay) to accept Apple Pay payments. --- ## Next steps **[Customize your Flow for mobile integration](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-mobile-app/customize-flow-for-mobile.md)** Learn how to customize your Flow for mobile integration. **[Flow for mobile library reference](https://www.checkout.com/docs/payments/accept-payments/accept-a-payment-on-your-mobile-app/flow-for-mobile-library-reference/ios.md)** See the configuration options and error handling steps for Flow for mobile. **[Tokenize credentials](https://www.checkout.com/docs/payments/store-and-manage-credentials/tokenize-credentials.md)** Securely collect and tokenize credentials with Flow for mobile.