Skip to content

Latest commit

 

History

History
334 lines (252 loc) · 13.8 KB

File metadata and controls

334 lines (252 loc) · 13.8 KB

Getting Started with the Flutter plug-in for Mobile Payments SDK

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.

Before you start

  • 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 UIScene lifecycle, both of which require this version.

Step 1: Install Flutter plugin for Mobile Payments SDK

Install the Mobile Payments SDK package with pub:

flutter pub add square_mobile_payments_sdk

For iOS:

  1. Open your iOS project Runner.xcodeproj with Xcode.
  2. Set the iOS Deployment Target to 16.0 or above. Projects created with flutter create default to a lower target and fail to resolve the SDK.
  3. Add a Mobile Payments SDK build phase:
    1. In the Build Phases tab for your application target, click the + button at the top of the pane.
    2. Select New Run Script Phase.
    3. 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: false

This 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:

  1. 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's repositories {...} block
    • Add implementation("com.squareup.sdk:mobile-payments-sdk:$squareSdkVersion") inside the dependencies {...} block
  2. 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
        }
    }
}
  1. Make sure your /android/gradle.properties enables AndroidX and Jetifier. The SDK bundles a dependency that still references the legacy support library:
android.useAndroidX=true
android.enableJetifier=true

The 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.

Step 2: Square Application ID and Access Token

  1. Visit the Square Developer Console and sign in or create an account.
  2. Create a new Square application.
  3. 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.
  4. Open the Locations page, and make note of the Location ID of the location you'd like to use.

Step 3: Additional Platform Setup

  1. 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.

  1. For Android: update your MainApplication.kt file 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)
    }
}

Step 4: Implement Authorization

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().

Step 5: Show the settings screen

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.

Step 6: Take a payment

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.

Optional: Use Mock Readers in Sandbox

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: MockReaderUI is 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.

Tap to Pay Settings on iPhone

For iOS devices, you can manage Tap to Pay settings using the tapToPaySettings property. The following methods are available:

Link Apple Account

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");
    }

Relink Apple Account

If the Apple account needs to be relinked, use:

try {
      await _squareMobilePaymentsSdkPlugin.tapToPaySettings
          .relinkAppleAccount();
    } catch (e, stackTrace) {
      print("Exception reader: $e");
    }

Check if Apple Account is Linked

You can check if an Apple account is already linked:

try {
      bool isAppleAccountLinked =  await _squareMobilePaymentsSdkPlugin.tapToPaySettings.isAppleAccountLinked();

    } catch (e, stackTrace) {
      print("Exception reader: $e");
    }

Check Device Capability

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.


📡 Offline Payments (Beta)

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.

🔧 Accessing Offline Features

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.

Example Usage

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();

🧾 Seller Onboarding

Offline Payments support is Beta-only and requires seller opt-in.

To onboard a seller:

  1. Send an email to: developerbetas@squareup.com
  2. 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