Applies to: Mobile Payments SDK - Android | Payments API | Orders API
Learn how to use the Mobile Payments SDK for Android to take a payment with a Square Reader.
Applies to: Mobile Payments SDK - Android | Payments API | Orders API
Learn how to use the Mobile Payments SDK for Android to take a payment with a Square Reader.
Payments in the Mobile Payments SDK are handled by the PaymentManager
. Prior to starting a payment, you create PaymentParameters
to represent details of an individual payment and PromptParameters
indicating how the payment prompts are presented to the buyer.
Before taking a payment with the SDK in a production environment, ensure that you have done the following:
Additionally, before taking a payment in production, you can use the Square Sandbox and mock readers to test your application.
To begin a payment with the Mobile Payments SDK, you need to create a PaymentParameters
object, which includes attributes describing the payment you want to take. For example, there are parameters for the payment amount, idempotency key, optional tip, application fee (if applicable), and the processing mode, which is ONLINE_ONLY
by default but can be changed if you want to take payments while offline. For the complete list of payment parameter values and details, see the Android technical reference.
The PaymentParameters
must include an idempotency key. An idempotency key is a unique string identifier that accompanies an API operation, allowing Square to recognize potential duplicate calls. Using an idempotency key in each payment request ensures that a payment can only occur once, protecting against unintended outcomes like charging a customer twice for the same transaction.
Along with an idempotency key, include a unique referenceID
value in your PaymentParameters
for each payment. This persists with the payment and can be used to identify the payment if you need to reference it later. The idempotency key and reference ID aren't interchangeable. You shouldn't use the same value for both parameters because sometimes a payment requires multiple attempts (for example, if the first is declined for expiration or insufficient funds, you can retry the payment with the same referenceID
and a new idempotency key). Typically, the referenceID
is used to match Square payments to an external system, but it can also be used to identify payments within Square.
If you don't receive a server response from a payment made with the Mobile Payments SDK, you should check the status of the payment to determine whether to retry the payment. Use the ListPayments endpoint and query by location ID, total payment amount, or other fields to filter the list. You can use your unique referenceID
to identify the correct payment and check its status. You might need to retry the payment with a new idempotency key if the prior payment exists, but cannot be completed. In this situation, you can cancel the original incomplete payment by using CancelPaymentByIdempotencyKey.
Each payment also requires PromptParameters
, consisting of a mode
and a list of additionalPaymentMethods
. PromptParameters.mode
determines whether your application uses the DEFAULT
Square payment prompt UI or a CUSTOM
payment prompt where you build your own UI. The default UI provided by Square presents buyers with the payment options available from paymentManager.availableCardInputMethods()
. While PaymentParameters
are unique to each payment, you can likely reuse the same PromptParameters
for most payments in your application.
PromptParameters.additionalPaymentMethods
specifies a list of additional payment methods available to use for this payment. The only current option is KEYED
(a manually entered credit card payment). When used with the DEFAULT
promptMode
, the Square payment prompt includes these alternative payment methods as options presented to buyers. If you create your own CUSTOM
promptMode
, you should use the additionalPaymentMethods
available from the PaymentHandle
to display these options to buyers in your own payment prompt UI.
After the callbacks have been written, you can begin processing a payment by calling paymentManager.startPaymentActivity()
with the PaymentParameters
and PromptParameters
you created previously and calling a callback
to notify your application of results or errors from the payment flow.
During the payment:
PaymentHandle
as a way for you to interact with the ongoing payment (for example, if you need to cancel the payment).When the payment completes, regardless of whether it completed successfully, control is returned to the user interface and the callback
is invoked with the result. Your application can then display receipt or error information to the user.
Only one payment can be in process at a time. If you make a second call to startPaymentActivity
before the first call completes, the second call fails immediately with a USAGE_ERROR
, triggering the payment callbacks. The first payment call continues.
fun startPaymentActivity() {
val paymentManager = MobilePaymentsSdk.paymentManager()
val idempotencyKey = UUID.randomUUID().toString()
// write your own code to save the idempotency key for recovery
...
// Configure the payment parameters
val paymentParams = PaymentParameters.Builder(
amount = Money(100, CurrencyCode.USD),
idempotencyKey = idempotencyKey
)
.referenceId("1234")
.note("Chocolate Cookies and Lemonade")
.autocomplete(true)
.build()
// Configure the prompt parameters
val promptParams = PromptParameters(
mode = PromptMode.DEFAULT,
additionalPaymentMethods = listOf(AdditionalPaymentMethod
.Type.KEYED)
)
// Start the payment activity
paymentHandle = paymentManager.startPaymentActivity(paymentParams, promptParams) { result ->
// Handle the payment result
when (result) {
is Success -> // show payment details
is Failure -> // show error message
}
}
}
override fun onDestroy() {
paymentHandle?.cancel()
}
As part of your application workflow, you might want to authorize a customer's transaction but delay the capture of the payment (the transfer of funds from the customer to the seller) for a period of time. For example, in a restaurant with a kiosk ordering system, you might want to authorize a customer's credit card when they order, but not complete the payment until they receive their food.
While creating PaymentParameters
for a payment, set the autocomplete
value to false
if you want to delay the capture of a payment. By default, autocomplete
is true
, meaning the payment is authorized and captured immediately.
Only one of the autocomplete
and acceptPartialAuthorization
values can be true
. If you're accepting multiple payment methods for a single purchase (such as a gift card and credit card), you must set autocomplete
to false
and manage the delayed capture of the payment.
When autocomplete
is false
, there are two more PaymentParameter
values that handle the delayed payment:
delayDuration
- The number of milliseconds to wait before canceling the payment or taking another delayAction
, in RFC 3339 format. By default, this is 36 hours for card reader payments and 7 days for manually entered payments.delayAction
- The action to take after the delayDuration
passes with no other action on the payment. The possible options are CANCEL
(which is the default) or COMPLETE
.You can add a tip to the delayed payment by calling the UpdatePayment endpoint and setting tip_money
prior to completing the payment. If you don't set the delayAction
to automatically complete the payment, you can manually complete it by calling paymentManager.completePayment
.
For more information about delayed payment capture using the Square Payments API, see Delayed Capture of a Card Payment.
If you need to cancel a payment in progress for any reason, use paymentHandle.cancel()
. The CancelResult
returned is CANCELED
, NO_PAYMENT_IN_PROGRESS
if there is no payment in progress to be canceled, or NOT_CANCELABLE
if the payment in progress cannot be canceled. This can happen when the payment is actively being sent to Square servers or has already been completed.
During any payment flow, if the application is backgrounded or the application activity is interrupted, the payment in progress is canceled.
Your application must provide buyers with the option to receive a digital or printed receipt. These receipts aren't sent directly by Square. Therefore, to remain compliant with EMV-certification requirements, you must generate receipts including the following fields found in the cardDetails
of the successful payment response object from startPaymentActivity()
:
card.cardholderName
(example: James Smith)card.brand
and card.last4digits
(example: Visa 0094)authorizationCode
(example: Authorization 262921) (not available for offline payments)emvApplicationName
(example: AMERICAN EXPRESS)emvApplicationId
(example: AID: A0 00 00 00 25 01 09 01)entryMethod
(example: Contactless)private fun showPaymentDetails(payment: Payment, receiptScreen: ReceiptScreen) {
val cardDetails = (payment as OnlinePayment).cardDetails
val card = cardDetails!!.card
receiptScreen.setCardInformation(
card.cardholderName,
card.brand,
card.lastFourDigits
)
receiptScreen.setEmvInformation(
cardDetails.authorizationCode,
cardDetails.applicationName,
cardDetails.applicationId
)
receiptScreen.setEntryMethod(cardDetails.entryMethod)
}
If you need more assistance, contact Developer and App Marketplace Support or ask for help in the Developer Forums.