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

# Floa

> Let customers securely make payments using Floa Pay on your website or mobile application via Primer's direct integration.

export const paymentMethodType_2 = "FLOA_PAY"

export const displayName_2 = "Floa Pay"

export const paymentMethodType_1 = "FLOA_PAY"

export const displayName_1 = "Floa Pay"

export const paymentMethodType_0 = "FLOA_PAY"

export const displayName_0 = "Floa Pay"

Primer's direct integration to Floa Pay enables you to accept BNPL payments across Web, iOS & Android.

## Get started with Floa Pay

### Before you begin

If this is your first payment method, make sure to follow the [Get started guide](/docs/get-started/overview) to begin processing payments with Primer.

### Configure in the Dashboard

1. **Add Floa Pay payment method to your Dashboard** Go to the [integrations](https://dashboard.primer.io/integrations) section of the Dashboard, click on the 'New Integration' button and search for Floa Pay. Follow the instructions to connect your Floa Pay account to your Primer Dashboard.
2. **Activate Floa Pay on the Checkout** Go to the [Checkout](https://dashboard.primer.io/checkout) section of the Dashboard and activate the `FLOA_PAY` payment method.
3. **Configure a Workflow to process payments made with Floa Pay** Go to [Workflows](/docs/workflows), and ensure there is a workflow with the **Authorization** action configured to process APMs.

### Prepare the client session

Floa Pay leverages the following parameters to process a payment. Pass them when creating the client session.

| Parameter Name | Example value | Required | Description |
| - | - | - | - |
| orderId | `FLOAORDE6` | ✓ | A unique transaction reference. Do not reuse it for another Floa Pay payment. |
| currencyCode | `EUR` | ✓ | The three-letter ISO 4217 currency code of the payment. |
| amount | `45600` | ✓ | The financed amount in minor units. Must match the amount you authorize. |
| customerId | `floa-customer-002` | | Your identifier for the customer. |
| order ↳ countryCode | `FR` | | The country of the order. |
| paymentMethod ↳ paymentType | `ECOMMERCE` | ✓ | Set to `ECOMMERCE`. |
| customer ↳ firstName | `Carlos` | | Recommended. If missing, Floa Pay may request it in its customer information form. |
| customer ↳ lastName | `Garcia` | | Recommended. If missing, Floa Pay may request it in its customer information form. |
| customer ↳ emailAddress | `carlos.garcia@example.com` | | Recommended. Validate the email format before creating the client session. |
| customer ↳ mobileNumber | `+33624122644` | | Recommended. Mobile number in international format, including the country code. |
| customer ↳ nationalDocumentId | `26351648L` | | Conditional. Tax or national identity document number, required in some countries. |
| customer ↳ billingAddress.firstName | `Carlos` | | Conditional. First name on the billing address. |
| customer ↳ billingAddress.lastName | `Garcia` | | Conditional. Last name on the billing address. |
| customer ↳ billingAddress.addressLine1 | `12 Rue de Rivoli` | | Recommended. Send if available, or if required for the country or product. |
| customer ↳ billingAddress.addressLine2 | `Apt 4B` | | Additional address information. |
| customer ↳ billingAddress.city | `Paris` | | Recommended. Send if you provide a billing address. |
| customer ↳ billingAddress.postalCode | `75001` | | Recommended. Used for address and risk checks. Validate the format for the country. |
| customer ↳ billingAddress.countryCode | `FR` | ✓ | Two-letter ISO country code. Determines eligibility for the selected Floa Pay product. |
| customer ↳ shippingAddress.firstName | `Carlos` | | First name of the recipient. |
| customer ↳ shippingAddress.lastName | `Garcia` | | Last name of the recipient. |
| customer ↳ shippingAddress.addressLine1 | `8 Avenue Montaigne` | | Conditional. Required when the order is not a virtual delivery. |
| customer ↳ shippingAddress.addressLine2 | `Floor 2` | | Additional address information. |
| customer ↳ shippingAddress.city | `Paris` | | Conditional. Required when you send a shipping address. |
| customer ↳ shippingAddress.postalCode | `75008` | | Conditional. Required when you send a shipping address. Validate the format for the country. |
| customer ↳ shippingAddress.countryCode | `FR` | | Conditional. Two-letter ISO country code, for example `FR`, `ES`, `IT`, `PT`, `NL`, `DE` or `BE`. |
| metadata ↳ bnplPlan | `BC3XF` | ✓ | The Floa Pay product code, which sets the installment plan (for example 3x or 4x) and country. See Floa Pay's [product codes](https://floapay.readme.io/reference/testing#products-testing-values). |
| metadata ↳ shippingMethod | `VIR` | ✓ | The delivery method: `STD` standard, `EXP` express, `TRK` tracked, `REL` pickup point, `MAG` in store, `LCK` lockers, `VIR` virtual (digital sales). |
| metadata ↳ itemCount | `2` | ✓ | Total number of items. Must match the number of entries in `metadata.itemsMetadata`. |
| metadata ↳ reportDelayInDays | `30` | | Conditional. Number of days the payment is deferred. Required for 1x Pay Later products. |
| metadata ↳ birthDate | `1985-04-12` | | Conditional. Customer date of birth in `YYYY-MM-DD` format, used for eligibility and risk checks. |
| metadata ↳ birthCity | `Paris` | | Customer place of birth. May be required by some local checks. |
| metadata ↳ birthDepartment | `75` | | Customer department of birth, used in some countries. |
| metadata ↳ birthCountryCode | `FR` | | Customer country of birth as a two-letter ISO country code. |
| metadata ↳ secondLastName | `Fernandez` | | Customer second surname, for markets where one is used. |
| metadata ↳ createdDate | `2021-03-01` | | Date the customer account was created, in `YYYY-MM-DD` format. |
| metadata ↳ firstOrderDate | `2021-03-05` | | Date of the customer's first order, in `YYYY-MM-DD` format. |
| metadata ↳ lastOrderDate | `2026-07-14` | | Date of the customer's most recent order, in `YYYY-MM-DD` format. |
| metadata ↳ itemsMetadata\[].name | `Return Flight MAD-BCN` | | Recommended. Product name or short description that identifies the financed item. |
| metadata ↳ itemsMetadata\[].amount | `45000` | | Recommended. Item amount in minor units. |
| metadata ↳ itemsMetadata\[].category | `Travel` | | Recommended. Product category, used for risk analysis and reporting. |
| metadata ↳ itemsMetadata\[].subCategory | `Flight` | | Recommended. Product subcategory. |
| metadata ↳ floaMetadata\[].key | `travelType` | | Recommended. Additional transaction data key, as agreed with Floa Pay during onboarding. |
| metadata ↳ floaMetadata\[].value | `TwoWay` | | Recommended. The value for the key, sent as a string. |

## Prepare the SDK for payments

<Tabs>
  <Tab title="Web">
    <Info>
      Use the payment method type <code>{paymentMethodType_0}</code> wherever the code below references `YOUR_PAYMENT_METHOD_TYPE`.
    </Info>

    <Tabs>
      <Tab title="Primer Checkout (recommended)">
        Primer Checkout is our latest web SDK, built around declarative web components. Once {displayName_0} is enabled in your [Dashboard](https://dashboard.primer.io/checkout), the default `<primer-checkout>` layout renders it automatically alongside your other methods — no payment-method-specific markup is required.

        ```html theme={"dark"}
        <primer-checkout client-token="your-client-token"></primer-checkout>
        ```

        #### Custom layouts

        Only reach for [primer-payment-method](/docs/sdk/primer-checkout-web/components/primer-payment-method) if you're building a custom layout and need to place {displayName_0} at a specific position. The element only renders when the type is enabled in your Dashboard and returned by the server for this checkout.

        ```html theme={"dark"}
        <primer-checkout client-token="your-client-token">
          <primer-main slot="main">
            <div slot="payments">
              <primer-payment-method type="YOUR_PAYMENT_METHOD_TYPE"></primer-payment-method>
            </div>
          </primer-main>
        </primer-checkout>
        ```

        For dynamic rendering based on what the server returns, listen to [primer:methods-update](/docs/sdk/primer-checkout-web/events-reference) or use [primer-payment-method-container](/docs/sdk/primer-checkout-web/components/primer-payment-method-container) for declarative filtering.
      </Tab>

      <Tab title="Universal Checkout (legacy)">
        ##### Set up redirects

        If {displayName_0} can't be shown in a popup, Universal Checkout redirects the customer back to your site using the `returnUrl` passed in the `redirect` options. See [Handle redirects & deep links](/docs/sdk/web/v2.x.x/handle-redirects-and-deeplinks#set-up-redirects) for the full flow.

        ```typescript theme={"dark"}
        const options = {
          container: "#checkout-container",
          redirect: {
            returnUrl: "https://mystore.com/checkout",
          },
          onCheckoutComplete({ payment }) {
            console.log("Checkout complete.", payment);
          },
        };
        ```

        ##### Show Universal Checkout

        {displayName_0} is automatically presented when calling [Primer.showUniversalCheckout](/docs/sdk/web/v2.x.x/primer/methods/showUniversalCheckout).

        ```typescript theme={"dark"}
        import { Primer } from "@primer-io/checkout-web";

        try {
          await Primer.showUniversalCheckout(clientToken, options);
        } catch (e) {
          // handle error
        }
        ```

        Check the [customization guide](/docs/checkout/drop-in/customization#styling-payment-method-button) to learn how to customize payment method buttons.
      </Tab>

      <Tab title="Headless Universal Checkout (legacy)">
        Create a `RedirectPaymentMethodManager` for {displayName_0} using [createPaymentMethodManager](/docs/sdk/web/v2.x.x/primer-headless-checkout/methods/createPaymentMethodManager#redirect), then call `start()` to begin the redirect flow.

        ```typescript theme={"dark"}
        const manager = await headless.createPaymentMethodManager("YOUR_PAYMENT_METHOD_TYPE");

        if (manager) {
          manager.addEventListener("click", () => {
            // Optional: run custom logic before the redirect flow starts.
          });

          await manager.start();
        }
        ```

        Refer to the full guide for [handling payment methods with redirect](/docs/checkout/headless/#step-4c-handle-payment-methods-with-redirect).
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="iOS">
    <Info>
      Use the payment method type <code>{paymentMethodType_1}</code> wherever the code below references `YOUR_PAYMENT_METHOD_TYPE`.
    </Info>

    #### Set up redirects

    Redirect-based payment methods present a webpage or open a third-party app for the customer to authorize the payment. To return to your app once the customer has authorized the payment, include the `urlScheme` parameter when configuring `PrimerPaymentMethodOptions`.

    ```swift theme={"dark"}
    let settings = PrimerSettings(
      // ...
      paymentMethodOptions: PrimerPaymentMethodOptions(
        urlScheme: "your-url-scheme://" // e.g. primer://, yourscheme://
      )
      // ...
    )
    ```

    When the customer is redirected back to your app, iOS calls `application(_:continue:restorationHandler:)`. Forward the call to the Primer SDK so the checkout can continue the flow.

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

    @UIApplicationMain
    class AppDelegate: UIResponder, UIApplicationDelegate {
      // ...
      func application(
        _ application: UIApplication,
        continue userActivity: NSUserActivity,
        restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
      ) -> Bool {
        return Primer.shared.application(
          application,
          continue: userActivity,
          restorationHandler: restorationHandler
        )
      }
    }
    ```

    #### Show the payment method

    <Tabs>
      <Tab title="Universal Checkout (drop-in)">
        {displayName_1} is automatically presented when calling [Primer.shared.showUniversalCheckout](/docs/sdk/ios/v2.x.x/primer/methods/showUniversalCheckout).

        ```swift theme={"dark"}
        class MyViewController: UIViewController {
          func startUniversalCheckout() {
            Primer.shared.showUniversalCheckout(clientToken: self.clientToken)
          }
        }
        ```

        Check the [customization guide](/docs/checkout/drop-in/customization#styling-payment-method-button) to learn how to customize payment method buttons.
      </Tab>

      <Tab title="Headless Universal Checkout">
        {displayName_1} requires a [Native UI Manager](/docs/checkout/headless/#native-ui-manager) to be presented to the customer.

        ```swift theme={"dark"}
        // 👇 Create the payment method manager
        let nativeUIPaymentMethodManager = try PrimerHeadlessUniversalCheckout.NativeUIManager(
          paymentMethodType: "YOUR_PAYMENT_METHOD_TYPE"
        )

        // 👇 Show the payment method
        try nativeUIPaymentMethodManager.showPaymentMethod(intent: .checkout)
        ```

        See [NativeUIManager.init](/docs/sdk/ios/v2.x.x/primer-headless-checkout/native-ui-manager/init) for the full API. As many redirect-based payment methods share this approach, we recommend centralizing the implementation — see the worked example in the [Native UI Manager guide](/docs/checkout/headless/#native-ui-manager).
      </Tab>
    </Tabs>
  </Tab>

  <Tab title="Android">
    <Info>
      Use the payment method type <code>{paymentMethodType_2}</code> wherever the code below references `YOUR_PAYMENT_METHOD_TYPE`.
    </Info>

    <Tabs>
      <Tab title="Universal Checkout (drop-in)">
        {displayName_2} is automatically presented when calling [Primer.instance.showUniversalCheckout](/docs/sdk/android/v2.x.x/primer/methods/showUniversalCheckout).

        ```kotlin theme={"dark"}
        class CheckoutActivity : AppCompatActivity() {
          private fun setupObservers() {
            viewModel.clientToken.observe(this) { clientToken ->
              showUniversalCheckout(clientToken)
            }
          }

          private fun showUniversalCheckout(clientToken: String) {
            Primer.instance.showUniversalCheckout(this, clientToken)
          }
        }
        ```

        Check the [customization guide](/docs/checkout/drop-in/customization#styling-payment-method-button) to learn how to customize payment method buttons.
      </Tab>

      <Tab title="Headless Universal Checkout">
        {displayName_2} requires a [Native UI Manager](/docs/checkout/headless/#native-ui-manager) to be presented to the customer.

        ```kotlin theme={"dark"}
        // 👇 Create the payment method manager
        val nativeUiManager = PrimerHeadlessUniversalCheckoutNativeUiManager.newInstance("YOUR_PAYMENT_METHOD_TYPE")

        // 👇 Show the payment method
        nativeUiManager.showPaymentMethod(this, PrimerSessionIntent.CHECKOUT)
        ```

        See [NativeUiManager.newInstance](/docs/sdk/android/v2.x.x/primer-headless-checkout/native-ui-manager/newInstance) for the full API. As many redirect-based payment methods share this approach, we recommend centralizing the implementation — see the worked example in the [Native UI Manager guide](/docs/checkout/headless/#native-ui-manager).
      </Tab>
    </Tabs>
  </Tab>
</Tabs>

## Go live


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.