> For clean Markdown of any page, append .md to the page URL. > For a complete documentation index, see https://docs.coinflow.cash/guides/checkout/implementation-overview/mobile-app-payments/swift-sdk/llms.txt. > For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.coinflow.cash/_mcp/server. # Swift SDK ## Overview `CoinflowCardForm` is a SwiftUI SDK that embeds Coinflow's card tokenization form directly into iOS apps. The user enters their card inside your app, the SDK returns a payment token, and your backend charges the card via the standard Coinflow checkout API. * **Package:** [`coinflow-swift`](https://github.com/coinflow-labs-us/coinflow-swift) * **Distribution:** Swift Package Manager * **Current version:** `0.2.0` ## Requirements * iOS 15+ * Swift 5.9+ * Xcode 15+ ## Installation #### Xcode UI In Xcode: **File → Add Package Dependencies…** and enter: ``` https://github.com/coinflow-labs-us/coinflow-swift ``` Select version **0.2.0** (or "Up to Next Major"), then add the `CoinflowCardForm` library product to your app target. #### Package.swift ```swift dependencies: [ .package( url: "https://github.com/coinflow-labs-us/coinflow-swift", from: "0.2.0" ) ], targets: [ .target( name: "YourApp", dependencies: [ .product(name: "CoinflowCardForm", package: "coinflow-swift") ] ) ] ``` ## Integration #### Add the card form view Drop `CoinflowCardFormView` into your SwiftUI layout and pass a `CardFormCoordinator` you'll use to trigger tokenization. ```swift import SwiftUI import CoinflowCardForm struct PaymentView: View { @StateObject private var coordinator = CardFormCoordinator() var body: some View { VStack { CoinflowCardFormView( variant: .cardForm, merchantId: "your-merchant-id", env: .sandbox, coordinator: coordinator ) .frame(height: 52) Button("Pay") { Task { await tokenize() } } } } private func tokenize() async { do { let response = try await coordinator.tokenize() print("Token: \(response.token)") } catch { // surface error to user } } } ``` > **Info** > > `your-merchant-id` is an **example placeholder**. Use your actual merchant ID from the merchant dashboard, or contact the Coinflow integrations team. Typically you'd inject it via a build setting or environment variable rather than hard-coding it. #### Configure the environment Switch `env` based on build configuration: ```swift #if DEBUG let env: CoinflowEnv = .sandbox #else let env: CoinflowEnv = .prod #endif ``` * `.sandbox` — test cards, no real money * `.prod` — live cards, real money #### Charge the token server-side `coordinator.tokenize()` returns a `TokenizeResponse`: * `token: String` — payment token to send to your backend * `expMonth: String?`, `expYear: String?` — populated only for variants that collect expiry Send the token to your server and call Coinflow's checkout API to charge it. See the [Checkout API reference](/api-reference/api-reference/checkout/card-checkout) for the full request shape. ## Variants ```swift CoinflowCardFormView(variant: .cardForm, ...) // full card entry CoinflowCardFormView(variant: .cardNumberForm, ...) // number + expiry only CoinflowCardFormView(variant: .cvvForm, token: "...", ...) // CVV only for saved card ``` | Variant | Captures | Use case | | ----------------- | ------------------- | ------------------------------------------ | | `.cardForm` | Number, expiry, CVV | Standard one-shot capture | | `.cardNumberForm` | Number + expiry | First step of a two-step flow | | `.cvvForm` | CVV only | Re-collecting CVV for a card-on-file token | ## Theming `MerchantTheme` styles the rendered form. All fields optional. ```swift let theme = MerchantTheme( primary: "#165DFB", background: "#ffffff", textColor: "#05092E", ctaColor: "#165DFB", font: "Red Hat Display", style: .rounded ) CoinflowCardFormView(theme: theme, /* ... */) ``` #### All theme fields | Field | Purpose | | ------------------------------------------------------------------ | --------------------------------------------------- | | `primary`, `ctaColor` | Accent / action colors (hex strings) | | `background`, `backgroundAccent`, `backgroundAccent2` | Form background tones | | `textColor`, `textColorAccent`, `textColorAction` | Input and label text colors | | `font`, `fontSize`, `fontWeight` | Typography. `font` must be available on the device. | | `style` | Input shape: `.rounded`, `.sharp`, `.pill` | | `cardNumberPlaceholder`, `cvvPlaceholder`, `expirationPlaceholder` | Override input placeholder text | | `showCardIcon` | Toggle the card brand icon (Visa/Mastercard/Amex) | ## Dynamic height The hosted form reflows responsively — at narrow widths the inputs wrap to multiple rows. To keep your SwiftUI container fitted, observe `coordinator.contentHeight` and bind it to your frame: ```swift CoinflowCardFormView( merchantId: "your-merchant-id", coordinator: coordinator ) .frame(height: coordinator.contentHeight ?? 52) ``` `contentHeight` is `@Published` on `CardFormCoordinator` and updates whenever the form reflows. Without this wiring the form may be clipped if it wraps. ## Resources * **Source:** [github.com/coinflow-labs-us/coinflow-swift](https://github.com/coinflow-labs-us/coinflow-swift) * **License:** Apache 2.0 * **Checkout API:** [Card Checkout endpoint](/api-reference/api-reference/checkout/card-checkout)