Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sezzle.com/llms.txt

Use this file to discover all available pages before exploring further.

This guide walks you through integrating the Sezzle iOS SDK into your app. By the end, your app will display Sezzle promotional messaging on product pages and launch Sezzle checkout.

Prerequisites

  • iOS 15.0+ deployment target
  • Swift 5.9+
  • A Sezzle merchant account with your Public API Key
  • A backend server to capture payments after checkout
A working example app is included in the SDK repo at Example/SezzleCheckoutExample. It demonstrates all widget variants and both checkout modes.

1. Installation

  1. In Xcode, go to File > Add Package Dependencies
  2. Enter the repository URL:
https://github.com/sezzle/sezzle-merchant-sdk-ios.git
  1. Select Up to Next Major Version from the latest release
  2. Add SezzleMerchantSDK to your target
Requirements: iOS 15.0+, Swift 5.9+

2. Configuration

Initialize the SDK once at app startup in your AppDelegate:
import SezzleMerchantSDK

@main
class AppDelegate: UIResponder, UIApplicationDelegate {
    func application(
        _ application: UIApplication,
        didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
    ) -> Bool {
        SezzleSDK.shared.configure(
            publicKey: "sz_pub_your_key_here",
            environment: .production  // use .sandbox for testing
        )
        return true
    }
}
ParameterTypeDefaultDescription
publicKeyStringRequiredYour Sezzle public API key
environmentSezzleEnvironment.production.sandbox for testing, .production for live
Never include your private API key in the app. The SDK only uses the public key. Use your private key server-side to capture payments.

3. Promotional Messaging

Add a SezzlePromotionalView to your product page to display installment pricing:
import SezzleMerchantSDK

let promoView = SezzlePromotionalView(
    amountInCents: 9999,  // $99.99
    presentingFrom: self   // UIViewController for modal presentation
)
view.addSubview(promoView)
The widget automatically shows the correct message based on the price and updates when you call:
promoView.update(amountInCents: 14999)  // price changed to $149.99
iOS Widgets

All Parameters

SezzlePromotionalView(
    amountInCents: Int,
    currency: String = "USD",
    style: SezzlePromotionalStyle = .light,
    widgetConfig: SezzleWidgetConfig = .default,
    presentingFrom viewController: UIViewController
)
ParameterTypeDefaultDescription
amountInCentsIntRequiredProduct price in cents (e.g., 4999 = $49.99)
currencyString"USD"ISO 4217 currency code (e.g., "USD", "CAD")
styleSezzlePromotionalStyle.light.light for light backgrounds, .dark for dark
widgetConfigSezzleWidgetConfig.defaultControls pricing thresholds and Pay-in-5
presentingFromUIViewControllerRequiredView controller to present the info modal from
The widget auto-detects dark mode and switches styles via traitCollectionDidChange. If you want to force a specific style, pass .light or .dark explicitly.

Widget Configuration

All config parameters are optional — the widget works out of the box with sensible defaults:
ParameterDefaultDescription
minPriceInCents3500 ($35)Minimum price to show the widget
maxPriceInCents250000 ($2,500)Maximum price for short-term (PI4/PI5)
enablePayIn5trueShow “5 payments” for prices at or above the PI5 threshold
pi5MinPriceInCents5000 ($50)Price threshold for Pay-in-5
longTermConfignil (disabled)Enable long-term monthly payments — set to a SezzleLongTermConfig to activate
To customize, pass only the values you want to override:
let config = SezzleWidgetConfig(
    longTermConfig: SezzleLongTermConfig(
        minPriceInCents: 25_000  // $250+ shows monthly payments
    )
)

let promoView = SezzlePromotionalView(
    amountInCents: 79900,
    widgetConfig: config,
    presentingFrom: self
)

Custom Promotional Text

If you need full control over the UI, use SezzlePromoDataHandler to get a styled NSAttributedString with the Sezzle logo inline:
SezzlePromoDataHandler.getMessage(amountInCents: 9999) { attributedString in
    myLabel.attributedText = attributedString
}

4. Checkout

Build the Checkout Object

let checkout = SezzleCheckout(
    customer: SezzleCustomer(
        email: "customer@example.com",
        firstName: "Jane",
        lastName: "Doe",
        phone: "+15551234567",
        billingAddress: SezzleAddress(
            street: "123 Main St",
            city: "Minneapolis",
            state: "MN",
            postalCode: "55401",
            countryCode: "US"
        )
    ),
    order: SezzleOrder(
        referenceId: "order-12345",
        description: "Wireless Earbuds",
        amount: SezzleAmount(amountInCents: 4599, currency: "USD"),
        items: [
            SezzleItem(
                name: "Wireless Earbuds",
                sku: "WE-001",
                quantity: 1,
                price: SezzleAmount(amountInCents: 3999, currency: "USD")
            )
        ],
        taxAmount: SezzleAmount(amountInCents: 350, currency: "USD"),
        shippingAmount: SezzleAmount(amountInCents: 250, currency: "USD")
    )
)

Customer Fields

FieldRequiredDescription
emailYesCustomer email address
firstNameNoCustomer first name
lastNameNoCustomer last name
phoneNoCustomer phone number
dobNoDate of birth ("YYYY-MM-DD")
billingAddressNoBilling address (SezzleAddress)
shippingAddressNoShipping address (SezzleAddress)
tokenizeNoTokenize customer for future orders

Order Fields

FieldRequiredDescription
referenceIdYesYour internal order/reference ID
descriptionNoOrder description
amountYesTotal order amount in cents + currency
intentNo.auth (default, capture later from your backend) or .capture (auto-capture at checkout completion)
itemsNoLine item details
discountsNoDiscount line items ([SezzleDiscount])
taxAmountNoTax amount breakdown
shippingAmountNoShipping amount breakdown
metadataNoCustom key-value pairs. The SDK automatically includes _sdk_platform, _sdk_version, _device_model, and _os_version — avoid using keys prefixed with _.
localeNoCheckout locale (.enUS, .enCA, .frCA)
checkoutFinancingOptionsNoRestrict to specific plans: .fourPayBiweekly, .fourPayMonthly, .sixPayMonthly. Optional — omit to let Sezzle show all eligible plans.

Address Fields (SezzleAddress)

FieldDescription
nameFull name
streetStreet address line 1
street2Street address line 2
cityCity
stateState or province
postalCodePostal/ZIP code
countryCodeISO country code (e.g., "US")
phonePhone number

Start Checkout

SezzleSDK.shared.startCheckout(
    checkout,
    from: self,            // presenting UIViewController
    delegate: self,        // SezzleCheckoutDelegate
    mode: .systemBrowser   // or .webView
)

Handle the Result

Conform to SezzleCheckoutDelegate:
extension ProductViewController: SezzleCheckoutDelegate {

    func checkoutDidComplete(orderUUID: String) {
        // Send orderUUID to your backend to capture payment
        // POST /v2/order/{orderUUID}/capture
        print("Order completed: \(orderUUID)")
    }

    func checkoutDidCancel() {
        // Customer closed checkout without completing
        print("Checkout cancelled")
    }

    func checkoutDidFail(error: SezzleError) {
        // Handle the error
        switch error {
        case .networkError(let underlying):
            print("Network error: \(underlying)")
        case .apiError(let statusCode, let message):
            print("API error \(statusCode): \(message)")
        case .browserDismissed:
            print("Browser dismissed")
        case .notConfigured:
            print("SDK not configured")
        case .invalidResponse:
            print("Invalid response")
        }
    }
}
After checkoutDidComplete, send the orderUUID to your backend server. Your server should call POST /v2/order/{orderUUID}/capture using your private API key to capture the payment. See the Orders API for details.

5. WebView Mode

By default, checkout opens in ASWebAuthenticationSession (system browser). To keep the user inside your app, use WebView mode:
SezzleSDK.shared.startCheckout(
    checkout,
    from: self,
    delegate: self,
    mode: .webView
)
System Browser
ModeProsCons
.systemBrowserSecure, shares Safari cookies, recommendedBrief context switch
.webViewStays in-appNo cookie sharing, user logs in every time

6. Dark Mode

The SDK automatically adapts to the device’s appearance setting. The promotional widget, installment modal, and checkout modal all support dark mode.
Light Mode
If you need to force a specific style (e.g., your app doesn’t follow the system setting):
let promoView = SezzlePromotionalView(
    amountInCents: 9999,
    style: .dark,  // force dark style
    presentingFrom: self
)

7. Error Handling

All errors are delivered via SezzleCheckoutDelegate.checkoutDidFail(error:):
ErrorWhenSuggested Action
.notConfiguredSezzleSDK.shared.configure() was not calledCall configure() in AppDelegate
.networkErrorNo internet, timeout, DNS failureShow retry option
.apiError(statusCode, message)Sezzle API returned an errorCheck status code and message
.browserDismissedUser closed the browser/WebViewReturn to product page
.invalidResponseUnexpected response formatContact Sezzle support

8. Testing

Use the sandbox environment for testing:
SezzleSDK.shared.configure(
    publicKey: "sz_pub_your_sandbox_key",
    environment: .sandbox
)
Use the test data to complete test checkouts in sandbox.
Switch to .production and your live public key before releasing to the App Store.