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

# PrimerFormRedirectScope

> API reference for form-based redirect payment method scopes

`PrimerFormRedirectScope` manages payment methods that collect user input (OTP code or phone number) before completing payment in an external app (e.g., BLIK, MBWay).

## Declaration

```swift theme={"dark"}
@MainActor
public protocol PrimerFormRedirectScope: PrimerPaymentMethodScope where State == PrimerFormRedirectState
```

## Properties

| Property            | Type                                   | Description                                           |
| ------------------- | -------------------------------------- | ----------------------------------------------------- |
| `paymentMethodType` | `String`                               | Payment method type identifier (e.g., `"ADYEN_BLIK"`) |
| `state`             | `AsyncStream<PrimerFormRedirectState>` | Stream of form redirect state changes                 |

### Customization

| Property           | Type                                | Description                                                                                                              |
| ------------------ | ----------------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `screen`           | `FormRedirectScreenComponent?`      | Full screen replacement (replaces both form and pending screens). Signature: `(any PrimerFormRedirectScope) -> any View` |
| `formSection`      | `FormRedirectFormSectionComponent?` | Custom form fields area. Signature: `(any PrimerFormRedirectScope) -> any View`                                          |
| `submitButton`     | `FormRedirectButtonComponent?`      | Custom submit button. Signature: `(any PrimerFormRedirectScope) -> any View`                                             |
| `submitButtonText` | `String?`                           | Submit button label (default: payment method specific)                                                                   |

## Methods

| Method                  | Description                             |
| ----------------------- | --------------------------------------- |
| `updateField(_:value:)` | Update a form field value by field type |

<Info>
  This scope inherits `start()`, `submit()`, `cancel()`, `onBack()`, `presentationContext`, and `dismissalMechanism` from [PrimerPaymentMethodScope](/sdk/ios-checkout/v3.0.0-beta/configuration/scopes-overview#base-protocol).
</Info>

## PrimerFormRedirectState

```swift theme={"dark"}
public struct PrimerFormRedirectState: Equatable {
  public enum Status: Equatable {
    case ready
    case submitting
    case awaitingExternalCompletion
    case success
    case failure(String)
  }

  var status: Status
  var fields: [PrimerFormFieldState]
  var isSubmitEnabled: Bool        // Computed: all fields valid
  var pendingMessage: String?
  var surchargeAmount: String?

  // Convenience
  var otpField: PrimerFormFieldState?
  var phoneField: PrimerFormFieldState?
  var isLoading: Bool
  var isTerminal: Bool
}
```

### Flow

```mermaid theme={"dark"}
stateDiagram-v2
    [*] --> ready
    ready --> submitting
    submitting --> awaitingExternalCompletion
    awaitingExternalCompletion --> success
    awaitingExternalCompletion --> failure
```

| Property          | Type                     | Description                                |
| ----------------- | ------------------------ | ------------------------------------------ |
| `status`          | `Status`                 | Current payment status                     |
| `fields`          | `[PrimerFormFieldState]` | Form fields for user input                 |
| `isSubmitEnabled` | `Bool`                   | Whether all fields are valid (computed)    |
| `pendingMessage`  | `String?`                | Message while awaiting external completion |
| `surchargeAmount` | `String?`                | Formatted surcharge amount                 |
| `otpField`        | `PrimerFormFieldState?`  | Convenience accessor for OTP field         |
| `phoneField`      | `PrimerFormFieldState?`  | Convenience accessor for phone field       |
| `isLoading`       | `Bool`                   | Whether payment is submitting              |
| `isTerminal`      | `Bool`                   | Whether payment reached terminal state     |

## PrimerFormFieldState

```swift theme={"dark"}
public struct PrimerFormFieldState: Equatable, Identifiable {
  public enum FieldType: String, Equatable, Sendable {
    case otpCode       // BLIK 6-digit code
    case phoneNumber   // MBWay phone number
  }

  public enum KeyboardType: Equatable, Sendable {
    case numberPad
    case phonePad
    case `default`
  }

  var id: String { fieldType.rawValue }
  let fieldType: FieldType
  var value: String
  var isValid: Bool
  var errorMessage: String?
  let placeholder: String
  let label: String
  let helperText: String?
  let keyboardType: KeyboardType
  let maxLength: Int?
  var countryCodePrefix: String?
  var dialCode: String?
}
```

| Property            | Type           | Description                         |
| ------------------- | -------------- | ----------------------------------- |
| `fieldType`         | `FieldType`    | `.otpCode` or `.phoneNumber`        |
| `value`             | `String`       | Current text value                  |
| `isValid`           | `Bool`         | Whether the value passes validation |
| `errorMessage`      | `String?`      | Validation error message            |
| `placeholder`       | `String`       | Placeholder text                    |
| `label`             | `String`       | Display label                       |
| `helperText`        | `String?`      | Helper text below field             |
| `keyboardType`      | `KeyboardType` | Keyboard type for input             |
| `maxLength`         | `Int?`         | Max length (`nil` = unlimited)      |
| `countryCodePrefix` | `String?`      | Display prefix for phone fields     |
| `dialCode`          | `String?`      | Dial code for session info          |

## Payment methods

| Payment Method | Type String     | Field Type          |
| -------------- | --------------- | ------------------- |
| BLIK           | `"ADYEN_BLIK"`  | OTP code (6 digits) |
| MBWay          | `"ADYEN_MBWAY"` | Phone number        |

## See also

<CardGroup cols={2}>
  <Card title="Scopes overview" icon="diagram-project" href="/sdk/ios-checkout/v3.0.0-beta/configuration/scopes-overview">
    All available scopes
  </Card>
</CardGroup>
