Overview
The lite Flutter SDK lets customers pay without leaving your app. It provides three integration options:- Payment Sheet: a complete checkout presented over your existing interface.
- Embeddable payment form: the same lite-managed checkout UI placed inside your Flutter layout.
- Individual card fields: secure card number, expiry, CVV, and cardholder name inputs that you place in your own layout. You provide the pay button.
How it works
- Your server creates a checkout session with the lite API and receives a session secret.
- Your app gives the session secret to the SDK.
- The SDK loads the session and displays the payment methods enabled for it.
- The customer enters a new card or selects a saved card.
- The SDK encrypts new card data, tokenizes it, and submits the payment.
- If required, the SDK presents and completes 3D Secure automatically.
- Your server confirms the final payment result before fulfilling the order.
Before you begin
You need:- A lite account with a configured channel.
- Valid lite API keys on your server.
- A backend endpoint that creates lite checkout sessions.
- Flutter 3.44.2 or later, and a Dart SDK compatible with
^3.12.2. - For iOS: Xcode 15 or later and an app targeting iOS 15 or later.
- For Android: an app with
minSdk26 or later,compileSdk35 or later, and Java 17.
Integrate the SDK
1. Install the SDK
Add the plugin to your app:flutter pub get.
Install this plugin only. It brings in the native SDKs itself: sa.lite:lite-android from Maven Central, and LiteSDK from the lite-sa/lite-ios Swift package. Do not add those packages to your app again.
On iOS the SDK is distributed through Swift Package Manager only. CocoaPods is not supported.
- iOS
- Android
Flutter 3.44 enables Swift Package Manager by default, and nothing goes in your
Podfile. If the app turned Swift Package Manager off, remove enable-swift-package-manager: false from flutter: config: in pubspec.yaml and run flutter pub get again.2. Create a checkout session
Your server must create a checkout session using your lite API credentials and return its session secret to the app.Response
Response
client_secret to your app, where the SDK takes it as clientSecret. Keep the session id on your server so you can confirm the payment afterwards.
The session determines the amount, currency, enabled payment methods, available card networks, and eligible saved cards. Create a new session for each checkout attempt.
3. Modes of integration
The Payment Sheet and the embeddable form take the session secret and deliver aPayResult when the payment attempt finishes. Pick the one that fits your checkout screen. For a checkout you draw yourself, use Individual card fields.
- Payment Sheet
- Embeddable form
The Payment Sheet is the recommended integration. The sheet shows the payment result until the customer dismisses it.
present() returns a future that completes with a PayResult carrying the payment status once the sheet is consumed:Only one Payment Sheet can be presented at a time. A second call throws a
PlatformException with the code already_presenting.LitePaymentConfiguration. Its only setting, cardLayout, selects how the card fields are laid out:
4. Individual card fields
Use individual card fields when you draw the checkout yourself. You placeLiteCardNumberField, LiteExpiryField, LiteCvvField, and LiteCardholderNameField, and you provide the pay button. The SDK opens the session and hosts those fields in the native iOS and Android SDKs. It encrypts a new card, tokenizes it, and presents 3D Secure when required.
Your Dart code receives a LiteCardFieldChange and a PayResult. The change describes the field. It does not include the card number, expiry, CVV, or cardholder name.
On Android the host activity must be a FlutterFragmentActivity, the same requirement as the embeddable form.
LiteCheckout constructor, then await start(). It completes when the session is ready. An expired or rejected secret throws LiteCheckoutException, and a later start() retries. The fields can sit in the tree before start() finishes, and they stay empty until it succeeds. Keep that LiteCheckout alive until the fields leave the tree, then call dispose(). Disposal clears the collected card data.
onPayResult receives the result of pay(), including Apple Pay. The pay button awaits pay() and does not handle that result again.
Mount at most one field of each type on a checkout. A second field of the same type is not shown. The fields stay alive when a ListView scrolls them off screen, so the typed card is not cleared.
onChange reports:
LiteFieldStyle is optional. It styles the native field text, placeholder, border, and colors. It does not style your pay button, and it does not draw message. Pass the same style to each field you want to match. Any property you omit keeps the default shown here. Sizes are logical pixels.
isReadyToPay is true when a new card is complete, or an enabled saved card is selected, and pay is not locked. pay() authorizes that selection and returns a PayResult. Pass storeForFuture: true to save a new card for a later checkout. That flag does nothing when a saved card is already selected. The fields do not draw the save switch. You draw it and pass its value. Handle the result with the same statuses as the Payment Sheet and embeddable form, and confirm the payment on your server before fulfilling the order.
LiteCheckout notifies listeners when the session updates. After start():
instrumentslists the saved cards on the session.titleandexpiryare safe to display.getStoredInstruments(enabledOnly: true)returns only cards the session can charge.selectStoredInstrumentselects an enabled saved card and returns false when the id is missing or disabled.selectNewCardreturns the nextpay()to a newly entered card.
LiteApplePayButton draws the native Apple Pay button on iOS when Apple Pay is available for the session. It takes no space on Android. Set onPayResult on the checkout to receive its result. Apple Pay setup is the same as for the Payment Sheet. Follow Enable Apple Pay.
A card number that is format-valid stays valid even when that scheme is turned off for the session. pay() then returns failure with errorCode PAYMENT_METHOD_NOT_SUPPORTED. isPayLocked becomes true and payLockMessage is the text to show above your button. Leave the customer on your form. Editing the card number clears the lock.
A dismissed 3D Secure challenge returns cancelled with errorCode THREE_DS_CHALLENGE_DISMISSED. Leave the customer on your form.
Keep the checkout and its fields mounted until pay() finishes. Removing them disposes the native checkout.
5. Save and reuse cards
When the session contains eligible saved cards, the Payment Sheet and embeddable form display them automatically. The customer can select a saved card or enter a new one. Individual card fields do not draw that list. Readinstruments on the checkout and call selectStoredInstrument or selectNewCard.
For a new card, the Payment Sheet and embeddable form include a Save card for future purchase control. Individual card fields do not. Call pay(storeForFuture: true) when your own switch is on. Saved cards are available only when the customer and checkout session are eligible for them. Your server remains responsible for creating the session with the correct customer context.
6. Handle the result
The sheet future, the form callback, andLiteCheckout.onPayResult all receive a PayResult:
The built-in form disables its pay button while a payment is in progress. Keep the checkout screen mounted until the result arrives.
7. Confirm the payment on your server
Always retrieve the checkout session or payment from your server and verify its final state before fulfilling the order.Enable Apple Pay
Apple Pay is available on iOS when the checkout session enables it. Android does not show Apple Pay. The plugin presents Apple Pay through the native iOS SDK, so the setup is the same as for a native iOS app. Follow Enable Apple Pay in the iOS SDK guide and apply the Xcode steps to theRunner target of your Flutter project.
Clean up
The Payment Sheet clears card fields when it closes. For an embeddable integration, removeLitePaymentForm from the tree when the customer abandons checkout. Disposal clears the collected card data and detaches the native checkout. To start again with a new session, mount a new LitePaymentForm with a new ValueKey.
For individual card fields, call dispose() on the LiteCheckout when the customer leaves. That clears the collected card data and detaches the native session.
Integration checklist before going live
Run through this checklist in the lite sandbox environment with a sandbox API key before you switch to live keys. See Sandbox testing for enabling test mode, creating the key, and configuring a channel, and Test cards for the cards to use.- Successful card payments.
- Declined and unsupported cards.
- 3D Secure success, failure, and cancellation.
- Processing payments.
- Saved-card display and payment.
- Saving a new card for future use.
- Payment Sheet dismissal.
- A second sheet presentation while one is already open.
- Replacing the embeddable form when the session secret changes.
- Rotation, with the Android host as a
FlutterFragmentActivity. - Reopening a completed session.
- Apple Pay on a correctly provisioned physical iOS device.
- Individual card fields: a completed new card, a scheme the session does not accept, and a dismissed 3D Secure challenge.