Applies to: Mobile Payments SDK - Android | Payments API
Learn how to take offline payments with the Mobile Payments SDK for Android.
The Mobile Payments SDK supports taking payments in offline mode, which allows you to take payments when a reader is used in a location with weak network connection or the application momentarily loses connection to Square servers. Offline payments are stored (queued) locally on the mobile device running the Mobile Payments SDK application and processed by Square the next time the device successfully connects to the Internet and Square servers.
Warning
Before upgrading the Mobile Payments SDK or your application, confirm that no offline payment has a QUEUED status. Query the offline payment queue and check each payment's status. Uploaded payments stay on the device for 14 days, so don't use an empty list as the signal that all payments have uploaded. See Payment IDs.
- Offline payments aren't supported in the Square Sandbox.
- Interac debit cards don't work in Offline mode. Any offline transaction attempted with an Interac debit card results in a payment failure.
- Offline Payments support is limited to the two most recent versions of Square Reader for contactless and chip and Square Reader for magstripe. To learn whether your reader device is supported, see Hardware devices and capabilities.
- If you're using the Mobile Payments SDK with a Square Reader for contactless and chip, both a bluetooth connection and a secure connection are required to take offline payments.
- Bluetooth connection relies on device settings and physical distance. A reader must maintain a Bluetooth connection with a mobile device's POS application to take payments.
- A secure connection is established when a reader is connected to a mobile device that has its POS application open and online.
To take offline payments with the Mobile Payments SDK and a bluetooth Square reader:
- The reader must be connected to a device that was online and had its POS application opened within the last 24 hours.
- The POS device must have a bluetooth connection to the reader and have offline processing enabled before going offline.
- The reader must maintain a bluetooth connection to your device throughout the offline payment.
Important
Sellers must contact Square and opt-in to accept offline payments with the Mobile Payments SDK. The seller is responsible for any expired, declined, or disputed payments accepted while offline. By providing their merchant ID and using Offline Payments, the seller is aware of and accepting this risk.
At this time, the Offline Payments feature for the Mobile Payments SDK is in Beta, and requires Square sellers to opt in to this feature. If a seller using your application is interested in taking payments offline with the Mobile Payments SDK, send an email to [email protected]. In your message, include:
- The seller's business name.
- The seller's email address (this should be the owner or administrator for the seller's Square account).
- Your application ID.
Square contacts the seller directly and provides them with a seller onboarding form for this Beta feature. After the seller is successfully onboarded, Square sends you (the developer) a confirmation email letting you know that you can accept offline payments for the seller.
At any time, you can check the isOfflineProcessingAllowed value within the PaymentSettings to determine whether the seller that is authorized with your application can take payments offline. If your application tries to take an offline payment for a seller who doesn't have access to this feature, you receive a USAGE_ERROR.
Each seller taking payments offline with the Mobile Payments SDK has a limit on each offline payment and a limit to the total amount they can store offline on their mobile device. These limits vary by seller. If your application attempts to take an offline payment that exceeds one of these limits, the Mobile Payments SDK returns a USAGE_ERROR.
Each device running the Mobile Payments SDK can take up to 1000 payments for up to 24 hours before reconnecting to the network. If this limit is reached, the reader fails to connect and your mobile device must connect to a network to process and upload these payments before accepting more.
offlineTransactionAmountLimit and offlineTotalStoredAmountLimit are null when offline processing isn't allowed for the authorized seller, so check isOfflineProcessingAllowed before reading them.
val paymentSettings = MobilePaymentsSdk.settingsManager().getPaymentSettings() val isOfflineProcessingAllowed = paymentSettings.isOfflineProcessingAllowed val offlineTransactionAmountLimit = paymentSettings.offlineTransactionAmountLimit val offlineTotalStoredAmountLimit = paymentSettings.offlineTotalStoredAmountLimit
The payment methods available to customers are limited while offline, and not all readers support every card entry method. PaymentManager.getAvailableCardEntryMethods() returns the card entry methods currently available from connected readers. It doesn't report additional payment methods such as CASH or KEYED. Manually keyed card payments aren't available offline, but you can record cash payments by adding CASH to PromptParameters.additionalPaymentMethods.
If you're using the DEFAULT payment prompt, the SDK automatically displays the available card entry methods and any supported additional methods you configured.
When you're ready to take a payment with the Mobile Payments SDK, you create PaymentParameters with details about the payment. The processingMode field is required, and determines whether the payment should be taken offline. You can choose from ONLINE_ONLY, OFFLINE_ONLY, or AUTO_DETECT.
It's recommended to set the processingMode to AUTO_DETECT to improve your application reliability. In this mode, the SDK checks the status of the local network connection and the performance of Square's servers to route the payment online or offline for the highest chance of success. For example, if a seller hasn't opted in to offline processing, AUTO_DETECT attempts the payment online. If online processing isn't available, the payment fails with PaymentErrorCode.CANCELED rather than falling back to offline processing. Don't treat CANCELED as a buyer or seller cancellation without first checking connectivity. If you're using the AUTO_DETECT processing mode, the Payment object returned by startPaymentActivity() might be an OnlinePayment or OfflinePayment, and your application should account for both possibilities.
In some situations, such as when a location has a sporadic or weak internet connection, sellers might want to take all payments offline during a period of time. To do so, set the processingMode for payments to OFFLINE_ONLY. All payments made with this mode are initially queued on the mobile device, even if there is a network connection.
val paymentManager = MobilePaymentsSdk.paymentManager() val paymentParameters = PaymentParameters.Builder( amount = Money(100L, CurrencyCode.USD), processingMode = ProcessingMode.AUTO_DETECT, allowCardSurcharge = false, paymentAttemptId = UUID.randomUUID().toString() ) .build() val promptParameters = PromptParameters( mode = PromptMode.DEFAULT, additionalPaymentMethods = listOf(AdditionalPaymentMethod.Type.CASH) ) val paymentHandle = paymentManager.startPaymentActivity( paymentParameters, promptParameters ) { result -> when (result) { is Result.Success -> { val payment = result.value // Handle an OnlinePayment or OfflinePayment. } is Result.Failure -> { val errorMessage = result.errorMessage // Update your UI with the payment error. } } }
Important
When an offline payment is queued, it hasn't yet been processed by Square. The transaction isn't returned from the ListPayments endpoint and doesn't have a Square payment ID value. If your application's workflow involves delayed payment capture or syncing Square payments with an outside transaction database, you must write logic to query Square for the completed payment and its details and then perform that sync. For more information, see Payment IDs.
Use PaymentManager.getOfflinePaymentQueue() to access payments taken offline by the application on the current device. This includes payments waiting to upload and payments that have already uploaded or finished processing. Only payments that have a locationId matching the current application user's location ID are returned. This prevents two Square sellers logging in to your application on the same mobile device from viewing each other's payments.
The status of an OfflinePayment indicates its current point in the payment workflow and whether it failed to upload or process. The status can be one of the following:
QUEUED- The payment is stored locally on the device running the Mobile Payments SDK application. The SDK attempts to upload the payment to Square after the network connection is restored.UPLOADED- The payment has been uploaded to the Square server, but hasn't yet been processed.FAILED_TO_UPLOAD- The payment couldn't be uploaded due to an unrecoverable error.FAILED_TO_PROCESS- The connection was restored, but Square couldn't process this specific offline payment. This might be because of a declined card or another error with the card-issuing bank. An offline payment with this status cannot be recovered, and the seller doesn't receive funds from the transaction.PROCESSED- Square processed your offline payment successfully. It can now be seen in the Square Dashboard.
private var getPaymentsCallbackReference: CallbackReference? = null fun loadOfflinePayments() { val offlineQueue = MobilePaymentsSdk.paymentManager().getOfflinePaymentQueue() when (val amountResult = offlineQueue.getTotalStoredPaymentAmount()) { is Result.Success -> { val totalStoredAmount = amountResult.value // Update your UI with the amount waiting to upload. } is Result.Failure -> { val errorMessage = amountResult.errorMessage // Update your UI with the error. } } getPaymentsCallbackReference?.clear() getPaymentsCallbackReference = offlineQueue.getPayments { result -> when (result) { is Result.Success -> { result.value.forEach { offlinePayment -> when (offlinePayment.status) { OfflineStatus.QUEUED -> { /* Waiting to upload. */ } OfflineStatus.UPLOADED -> { /* Uploaded, awaiting processing. */ } OfflineStatus.FAILED_TO_UPLOAD -> { /* Upload couldn't be recovered. */ } OfflineStatus.FAILED_TO_PROCESS -> { /* Square couldn't process it. */ } OfflineStatus.PROCESSED -> { /* Processing completed. */ } } } } is Result.Failure -> { val errorMessage = result.errorMessage // Update your UI with the error. } } } } override fun onDestroy() { getPaymentsCallbackReference?.clear() super.onDestroy() }
A payment taken offline with the Mobile Payments SDK has two identification values: localId, used to identify the payment on your mobile device before it's uploaded, and id, which represents the Square payment id value. The id value is null until the SDK uploads the payment and Square assigns its server-side ID.
When a payment's status changes to PROCESSED, you can access its id value from the device and match it to the id returned by the ListPayments endpoint. You can then continue your payment workflow and use other Square APIs to manage the payment. The SDK removes uploaded payment records during initialization once they are more than 14 days old.
paymentManager.startPaymentActivity(paymentParams, promptParams) { result -> when (result) { is Result.Success -> { when (val payment = result.value) { is Payment.OnlinePayment -> { val paymentId = payment.id } is Payment.OfflinePayment -> { val paymentId = payment.id // Null until Square assigns an ID. val localPaymentId = payment.localId val status = payment.status } } } is Result.Failure -> { val errorMessage = result.errorMessage // Update your UI with the error. } } }
While your application process is running, the Mobile Payments SDK checks for connectivity and attempts to upload queued payments when it can connect to Square. The SDK doesn't schedule uploads after your application process terminates. Assuming that there are no errors in the PaymentParameters or issues like cards being declined, the funds are available to the seller in the Square Dashboard and the payment can be accessed and managed by the Payments API after this processing is complete.
Important
The following actions result in queued payments being removed from the device. If this happens before the payment is uploaded and processed, it cannot be processed and the seller doesn't receive funds from the transaction:
- Wiping the device cache
- Authenticating the Mobile Payments SDK with a different application ID on the same device
- Uninstalling the application from the device using the Mobile Payments SDK
Queued payments remain on the device when a user force-quits your application, switches to another application, or a seller logs out of your application. Query for QUEUED payments before calling authorizationManager.deauthorize(). After deauthorization, getPayments() returns NOT_AUTHORIZED because no current location is available to scope the query. Stored payments aren't deleted and resume uploading after the same location is authorized again.