This guide walks you through the process of setting up a new Flutter project with Mobile Payments SDK. See the Flutter Mobile Payments SDK Technical Reference for more detailed information about types and methods.
- You will need a Square account enabled for payment processing. If you have not enabled payment processing on your account (or you are not sure), visit squareup.com/activate.
- Set-up your Flutter environment by following the official guide.
- Use Flutter 3.44 or later. The iOS plugin is distributed as a Swift package and the sample app adopts the
UIScenelifecycle, both of which require this version.
Install the Mobile Payments SDK package with pub:
flutter pub add square_mobile_payments_sdkFor iOS:
- Open your iOS project
Runner.xcodeprojwith Xcode. - Set the
iOS Deployment Targetto 16.0 or above. Projects created withflutter createdefault to a lower target and fail to resolve the SDK. - Add a Mobile Payments SDK build phase:
- In the Build Phases tab for your application target, click the + button at the top of the pane.
- Select New Run Script Phase.
- Paste the following into the editor panel of the new run script:
FRAMEWORKS="${BUILT_PRODUCTS_DIR}/${FRAMEWORKS_FOLDER_PATH}" "${FRAMEWORKS}/SquareMobilePaymentsSDK.framework/setup"
The iOS dependencies are resolved through Swift Package Manager, which Flutter enables by default. There is no pod install step and no Podfile in the sample app.
If your project still relies on CocoaPods, the plugin ships a podspec as a fallback. Opt out of Swift Package Manager in your application's pubspec.yaml:
flutter:
config:
enable-swift-package-manager: falseThis setting is scoped to the project, so it does not change your global Flutter configuration. Run flutter pub get afterwards and Flutter will generate a Podfile and run pod install on the next build.
For Android:
- Modify your
/android/app/build.gradle.kts- Add
val squareSdkVersion = "2.6.1"at the top of the file - Add
maven { url = uri("https://sdk.squareup.com/public/android/") }inside the module'srepositories {...}block - Add
implementation("com.squareup.sdk:mobile-payments-sdk:$squareSdkVersion")inside thedependencies {...}block
- Add
- Disable Proguard by adding the following to your
/android/app/build.gradle.kts. The Mobile Payments SDK does not support code shrinking, which may strip bytecode the SDK needs at runtime:
android {
buildTypes {
release {
isMinifyEnabled = false
isShrinkResources = false
}
}
}- Make sure your
/android/gradle.propertiesenables AndroidX and Jetifier. The SDK bundles a dependency that still references the legacy support library:
android.useAndroidX=true
android.enableJetifier=trueThe plugin targets Java 17 and requires Android Gradle Plugin 8.9.1 or later. The sample app is built with Android Gradle Plugin 8.12.1 and Gradle 8.14.
You can also refer to MPSDK Android Quickstart's SDK installation section.
- Visit the Square Developer Console and sign in or create an account.
- Create a new Square application.
- Open the Credentials page and make note of your Application ID and Access token. Note at the top there's a switch to choose Sandbox or Production environment.
- Open the Locations page, and make note of the Location ID of the location you'd like to use.
- For iOS: update your application delegate as follows.
import Flutter
import UIKit
import SquareMobilePaymentsSDK
@main
@objc class AppDelegate: FlutterAppDelegate, FlutterImplicitEngineDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
let applicationId = "REPLACE ME!"
MobilePaymentsSDK.initialize(squareApplicationID: applicationId)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
func didInitializeImplicitFlutterEngine(_ engineBridge: FlutterImplicitEngineBridge) {
GeneratedPluginRegistrant.register(with: engineBridge.pluginRegistry)
}
}Under the UIScene lifecycle, plugins are registered from didInitializeImplicitFlutterEngine instead of didFinishLaunchingWithOptions. Registering in both places raises an assertion in FlutterEngine and terminates the app at launch.
You also need a SceneDelegate that subclasses FlutterSceneDelegate:
import Flutter
import UIKit
class SceneDelegate: FlutterSceneDelegate {}And a UIApplicationSceneManifest entry in your Info.plist pointing to it:
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<false/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneClassName</key>
<string>UIWindowScene</string>
<key>UISceneConfigurationName</key>
<string>flutter</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).SceneDelegate</string>
<key>UISceneStoryboardFile</key>
<string>Main</string>
</dict>
</array>
</dict>
</dict>Verify that SceneDelegate.swift is listed in the target's Compile Sources. If the class is missing at runtime, the scene starts without a root view controller and the app shows a black screen with no error. See the sample app's AppDelegate.swift, SceneDelegate.swift and Info.plist for a complete setup, and Flutter's UIScene adoption guide for background.
- For Android: update your
MainApplication.ktfile as follows:
import android.app.Application
import com.squareup.sdk.mobilepayments.MobilePaymentsSdk
class MainApplication : Application() {
override fun onCreate() {
super.onCreate()
MobilePaymentsSdk.initialize("Your Square Application ID", this)
}
}To authorize the SDK, you'll need the Access token and Location ID noted before. Then, in your Flutter application:
import 'package:square_mobile_payments_sdk/square_mobile_payments_sdk.dart';
//...
final _squareMobilePaymentsSdkPlugin = SquareMobilePaymentsSdk();
try {
response = await _squareMobilePaymentsSdkPlugin.authorize("accessToken", "locationId")
print('Successful authorization: $response');
} catch (e) {
print('Authorization error: $e');
}You can use the getAuthorizedLocation() and getAuthorizationState() methods to retrieve the location and authorization status on any screen.
Finally, you can deauthorize a client by calling deauthorize().
In order to pair a reader, you can show the settings screen, which allows reader pairing, checking reader status, and unpairing. To do this, simply call showSettings(), and to hide the settings page, the user can dismiss it by tapping on the close button. If you try to present settings while it's already being displayed, you will get an error, so make sure to use a try/catch block to handle this.
To take a payment, you must pass it a PaymentParameters object, which includes payment-specific values such as amount, tip, location; and a PromptParameters, which includes the payment methods offered to the customer, and the display mode (which for now only supports the default mode of presenting over a given view). This will look like this:
import 'package:square_mobile_payments_sdk/square_mobile_payments_sdk.dart';
//...
final _squareMobilePaymentsSdkPlugin = SquareMobilePaymentsSdk();
try {
String idempotencyKey = uuid.v4();
Payment payment = await _squareMobilePaymentsSdkPlugin.startPayment(
PaymentParameters(
amountMoney: Money(amount: 100, currencyCode: CurrencyCode.eur),
idempotencyKey: idempotencyKey
),
PromptParameters(additionalPaymentMethods: List.empty(), mode: PromptMode.defaultMode));
print('Payment successful:: $payment');
} catch (e) {
print('Payment error: $e');
}Payment parameters supports a number of additional attributes, which can be seen in the PaymentParameters definition. For error descriptions, visit the respective pages for iOS, and Android.
You can use mock readers to take payments in Sandbox, which allows you to test the payment flow without moving real money. To do this, make sure you're using a Sandbox Application ID, access token, and location ID, available in the Developer console (see Step 3: Square Application ID and Access Token).
iOS + Swift Package Manager:
MockReaderUIis not bundled by default and must be added to your app's Runner target. See Using MockReaderUI with Swift Package Manager for the setup steps and the important version/Release-build caveats.
Once you've configured your application to start in Sandbox, you can show or hide the mock reader as follows:
import 'package:square_mobile_payments_sdk/square_mobile_payments_sdk.dart';
//...
final _squareMobilePaymentsSdkPlugin = SquareMobilePaymentsSdk();
try {
await _squareMobilePaymentsSdkPlugin.showMockReaderUI();
} catch (e) {
print('Mock Reader UI error: $e');
}
//...
await _squareMobilePaymentsSdkPlugin.hideMockReaderUI();Note that you might get an error if you try to call these methods outside of Sandbox, so you can handle the errors by using a try/catch block.
For iOS devices, you can manage Tap to Pay settings using the tapToPaySettings property. The following methods are available:
Before using Tap to Pay on iPhone, you need to link an Apple account:
import 'package:square_mobile_payments_sdk/square_mobile_payments_sdk.dart';
//...
final _squareMobilePaymentsSdkPlugin = SquareMobilePaymentsSdk();
//...
try {
await _squareMobilePaymentsSdkPlugin.tapToPaySettings
.linkAppleAccount();
} catch (e, stackTrace) {
print("Exception reader: $e");
}If the Apple account needs to be relinked, use:
try {
await _squareMobilePaymentsSdkPlugin.tapToPaySettings
.relinkAppleAccount();
} catch (e, stackTrace) {
print("Exception reader: $e");
}You can check if an Apple account is already linked:
try {
bool isAppleAccountLinked = await _squareMobilePaymentsSdkPlugin.tapToPaySettings.isAppleAccountLinked();
} catch (e, stackTrace) {
print("Exception reader: $e");
}To verify if the device supports Tap to Pay on iPhone:
const isCapable = await _squareMobilePaymentsSdkPlugin.tapToPaySettings.isDeviceCapable();
Note: These methods are only available on iOS. Calling them on Android will result in an error.
This is currently a Beta feature in the SDK. Additionally, use of offline payments requires Square sellers to opt in and agree to the terms of the feature.
You can manage offline payment capabilities using the SquareMobilePaymentsSdk singleton instance. The relevant namespaces are:
settingsManager.paymentSettings– for checking offline availability and limits.paymentManager.offlinePaymentQueue– for accessing stored offline payments.
import 'package:square_mobile_payments_sdk/square_mobile_payments_sdk.dart';
final sdk = SquareMobilePaymentsSdk();
// Check if offline payments are allowed
final isAllowed = await sdk.settingsManager.paymentSettings.isOfflineProcessingAllowed();
// Get storage limits
final totalLimit = await sdk.settingsManager.paymentSettings.getOfflineTotalStoredAmountLimit();
final transactionLimit = await sdk.settingsManager.paymentSettings.getOfflineTransactionAmountLimit();
// Retrieve stored offline payments
final offlinePayments = await sdk.paymentManager.offlinePaymentQueue.getPayments();
final storedTotal = await sdk.paymentManager.offlinePaymentQueue.getTotalStoredPaymentAmount();Offline Payments support is Beta-only and requires seller opt-in.
To onboard a seller:
- Send an email to: developerbetas@squareup.com
- Include the following:
- The seller's business name
- The seller's email address (owner/admin of their Square account)
- Your application ID
Square will contact the seller and provide an onboarding form. Once completed, Square will notify you when the seller is ready to process offline payments.
ℹ️ You can always check whether offline payments are allowed by calling
isOfflineProcessingAllowed().
If you try to process an offline payment for a seller who hasn’t been onboarded, the SDK will return a USAGE_ERROR.
For more details, refer to: Square Android Offline Payments Docs