Skip to content

Repository files navigation

CrossmintCheckout

A Swift Package for embedding Crossmint's checkout experience in iOS apps.

Installation

Add the package via Swift Package Manager:

In Xcode: File > Add Package Dependencies, paste the URL below, and select Up to Next Major Version from 1.0.0.

https://github.com/Crossmint/crossmint-checkout-swift.git

Or add it to your Package.swift:

dependencies: [
    .package(url: "https://github.com/Crossmint/crossmint-checkout-swift.git", from: "1.0.0")
]

Then add "CrossmintCheckout" to your target's dependencies.

Quick Start

1. Create an order server-side

Use the Crossmint Orders API to create an order from your backend. The response includes an orderId and clientSecret.

POST https://www.crossmint.com/api/2022-06-09/orders

2. Render the checkout client-side

Pass your client-side API key (ck_...) — the same key used by the Orders API's client-side counterpart. It is required; without it the hosted checkout renders an "Invalid input" configuration error.

import SwiftUI
import CrossmintCheckout

struct CheckoutView: View {
    let orderId: String
    let clientSecret: String

    var body: some View {
        CrossmintEmbeddedCheckout(
            apiKey: "ck_production_...",
            orderId: orderId,
            clientSecret: clientSecret
        )
    }
}

Properties

Property Type Required Description
apiKey String Yes Your client-side API key (ck_...)
orderId String? Yes* The order ID returned by the Orders API
clientSecret String? Yes* The client secret returned by the Orders API
payment CheckoutPayment? No Payment configuration (fiat/crypto, allowed methods)
appearance CheckoutAppearance? No UI customization (colors, fonts, border radius)
lineItems CheckoutLineItems? No Line item configuration (not yet implemented)
recipient CheckoutRecipient? No Recipient configuration (not yet implemented)
identityVerificationHandling IdentityVerificationHandling? No .external renders no KYC step inside checkout; you present it yourself (see below)
controller CrossmintCheckoutController? No Observable order state (order, client secret, KYC credentials)

Payment Configuration

CrossmintEmbeddedCheckout(
    apiKey: "ck_production_...",
    orderId: orderId,
    clientSecret: clientSecret,
    payment: CheckoutPayment(
        crypto: CheckoutCryptoPayment(enabled: true, defaultChain: "base"),
        fiat: CheckoutFiatPayment(
            enabled: true,
            defaultCurrency: "usd",
            allowedMethods: CheckoutAllowedMethods(applePay: true, card: true)
        ),
        defaultMethod: .fiat
    )
)

Appearance Customization

CrossmintEmbeddedCheckout(
    apiKey: "ck_production_...",
    orderId: orderId,
    clientSecret: clientSecret,
    appearance: CheckoutAppearance(
        variables: CheckoutAppearanceVariables(
            colors: CheckoutVariablesColorStyle(
                textPrimary: "#000000",
                textSecondary: "#606060",
                backgroundPrimary: "#FFFFFF",
                borderPrimary: "#E0E0E0"
            )
        ),
        rules: CheckoutAppearanceRules(
            primaryButton: CheckoutPrimaryButtonRule(
                borderRadius: "8px",
                colors: CheckoutColorStyle(background: "#6C5CE7", text: "#FFFFFF")
            )
        )
    )
)

Note: lineItems and recipient are accepted as parameters but not yet implemented. Passing either will display an error.

Order Updates

Pass a CrossmintCheckoutController to observe the order as the buyer progresses. The controller exposes the latest order, the orderClientSecret, and derived identityVerificationCredentials.

struct CheckoutView: View {
    @StateObject private var controller = CrossmintCheckoutController()

    var body: some View {
        CrossmintEmbeddedCheckout(
            apiKey: "ck_production_...",
            orderId: orderId,
            clientSecret: clientSecret,
            controller: controller
        )
        .onReceive(controller.$order) { order in
            print("Order phase: \(String(describing: order?.phase))")
        }
    }
}

Order events are also available as chained methods: .onOrderUpdated { update in } and .onOrderCreationFailed { message in }.

Reusing a controller across checkout sessions requires calling clear() first.

Identity Verification (KYC)

Some orders require identity verification before payment. By default checkout renders that step inline and you do nothing.

To show the step in your own layout instead, pass identityVerificationHandling: .external to checkout. Then watch the controller for credentials and present CrossmintIdentityVerification with them. A sheet works well: the credentials appear when the order needs verification, and they go away when the backend confirms it.

struct CheckoutView: View {
    @StateObject private var controller = CrossmintCheckoutController()
    @State private var kycCredentials: IdentityVerificationCredentials?

    var body: some View {
        CrossmintEmbeddedCheckout(
            apiKey: "ck_production_...",
            orderId: orderId,
            clientSecret: clientSecret,
            identityVerificationHandling: .external,
            controller: controller
        )
        .onReceive(controller.$order) { order in
            kycCredentials = order?.identityVerificationCredentials
        }
        .sheet(item: $kycCredentials) { credentials in
            CrossmintIdentityVerification(
                apiKey: "ck_production_...",
                credentials: credentials
            )
            .onComplete { status in print("KYC finished: \(status)") }
            .onError { error in print("KYC error: \(error.message)") }
        }
    }
}

Checkout does not wait for a signal from your component. It polls the order until the backend confirms the verification, then continues on its own.

CrossmintIdentityVerification can also be used standalone, without embedded checkout, if you obtain the credentials from your backend's order response (payment.preparation.kyc).

CrossmintIdentityVerification Properties

Property Type Required Description
apiKey String Yes Your client-side API key (ck_...)
credentials IdentityVerificationCredentials Yes From the controller or your backend's order response
locale CheckoutLocale? No UI language of the verification flow

Event handlers

Attach handlers with chained methods, all optional:

  • .onReady { } — the verification UI finished loading
  • .onComplete { status in } — the buyer finished; the status carries the outcome
  • .onCancel { } — the buyer dismissed the flow
  • .onError { error in } — something failed; retriable says whether showing the view again can work

The view fills the space you give it, and the verification content scrolls inside the view. Use onReady to drive your own loading indicator.

Note: Document capture needs camera access. Add NSCameraUsageDescription to your app's Info.plist or the capture step fails.

Note: identityVerificationHandling requires a current Crossmint deployment. Older deployments ignore the flag and render the verification step inline as well.

Example App

See a full working example at crossmint-swift-checkout-demo.

Documentation

License

See LICENSE for details.

About

No description, website, or topics provided.

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages