Accept a payment

United States

Use the PaymentRequestIntentBuilder class to build an Intent to start an activity to guide a user through the payment steps. Depending on the merchant configuration and Intent options set, a successful payment may be either a finalized payment or a tip-adjustable payment. The steps may include tip selection, signature collection, payment confirmation, and receipt selection. You can configure the options through the merchant settings or on the PaymentRequestIntentBuilder.

Prerequisites

Build a payment request

You can build a payment request with a few lines of code.

val externalPaymentId = "<posPaymentId>" // should be unique for each request
val amount = 1000L
val context = this

val builder = PaymentRequestIntentBuilder(externalPaymentId, amount)
val intent = builder.build(context)
String externalPaymentId = "<posPaymentId>";
Long amount = 1000L;   
Context context = this;
 
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder(externalPaymentId, amount);
Intent intent = builder.build(context);

Use the Intent to start the activity to process the payment request.

Options set on the builder to provide additional processing instructions include:

  • TipOptions—Settings for tips (if tips are enabled for merchant) and settings for signature requirements
  • CardOptions—Settings for supported card entry methods and card confirmations
  • ReceiptOptions—Settings for receipt screen
  • OfflineOptions—Settings to control offline payment options
  • TokenizeOptions—Settings for pay and tokenize cards for use in Ecommerce services
  • TenderOptions—Settings for Cash and Custom Tenders on a transaction level

TipOptions & SignatureOptions

TipOptions & SignatureOptions are independent options that can be excluded; however, they share the same “location” value (on screen/on paper).

TipOptions

Prerequisite: Configure the merchant’s payment gateway settings to create a tippable payment for a tip-adjustable payment.
Note: On some devices, tips are taken prior to the payment and can be supported without merchant payment gateway settings, as the payment is finalized by the gateway.

The TipOptions class provides static helper methods to simplify the creation of TipOptions.

MethodDescription
Disable()Sets the options so that no tip is requested. Creates a final payment that is not tip-adjustable.
Provided(tipAmount: Long)If the tip amount is known before the payment request, this method adds the tip amount to the payment and the payment is finalized.
PromptCustomer(baseAmount: Long, tipSuggestions: List<TipSuggestion>)Sets the amount to calculate the percentage-based tips or overrides the tip suggestions with fixed amounts or custom percentages.

SignatureOptions

The SignatureOptions class provides static helper methods to simplify the creation of SignatureOptions.

MethodDescription
Disable()Sets the options so that no signature is requested.
PromptCustomer()Overrides the merchant settings for when, and if, to prompt for a signature.

Example—Disable tip and signature for a payment

val builder = PaymentRequestIntentBuilder("<posPaymentId>", 1500)
builder.tipAndSignatureOptions(
   PaymentRequestIntentBuilder.TipOptions.Disable(),
   PaymentRequestIntentBuilder.SignatureOptions.Disable(),
   null) // preferOnScreen

val intent = builder.build(context)
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
builder.tipAndSignatureOptions(
            PaymentRequestIntentBuilder.TipOptions.Disable(),
            PaymentRequestIntentBuilder.SignatureOptions.Disable(),
            null);  //preferOnScreen
Intent intent = builder.build(context);

CardOptions

The CardOptions class provides a static method to set the supported card entry methods. It also includes options to auto-accept duplicate payment challenges that bypass the challenge prompts, and a cardNotPresent flag. When the cardNotPresent flag is false it results in manual card entry only.

MethodDescription
Instance( cardEntryMethods : Set<CardEntryMethod>, cardNotPresent : Boolean, autoAcceptDuplicates : Boolean)Optionally sets any of these flags to create a CardOptions instance. If null is passed, the default settings for the merchant are used.
Instance( cardEntryMethods : Set<CardEntryMethod>, cardNotPresent : Boolean, autoAcceptDuplicates : Boolean,

cashbackOptions: CashbackOptions)
Optionally, sets any of these flags to create a CardOptions instance. If null is passed, the default settings for the merchant are used.

Example—Set the card entry method to Manual only and to auto-accept duplicate challenges

val builder = PaymentRequestIntentBuilder("<posPaymentId>", 1500)

builder.cardOptions(
   PaymentRequestIntentBuilder.CardOptions.Instance(
       CardEntryMethod.Manual(), // manual only
       null, // card not present
       true)) // auto-accept duplicates

val intent = builder.build(context)
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
builder.cardOptions(PaymentRequestIntentBuilder.CardOptions.Instance(
            CardEntryMethod.Manual(),   // manual only
            null,                       // card not present
            true));                     // auto-accept duplicates
 
Intent intent = builder.build(context);

ReceiptOptions

The ReceiptOptions class provides the following options:

Static MethodDescription
Default(cloverShouldHandleReceipts: Boolean)Sets whether Clover handles printing or sending SMS/Email receipts.
SkipReceiptSelection()Configures the flow to skip the receipt selection.
Instance ( cloverShouldHandleReceipts : Boolean, smsReceiptOption : SmsReceiptOption, emailReceiptOption : EmailReceiptOption, printReceiptOption : PrintReceiptOption, noReceiptOption : NoReceiptOption)- Enables or disables every receipt selection
button on the receipt screen.

- Sets whether Clover handles the printing or sending of SMS/Email receipts.

Example—Disable the SMS and email receipt buttons and set cloverShouldHandleReceipts to true.

val externalPaymentId = "<posPaymentId>" // should be unique for each request
val amount = 1000L
val builder = PaymentRequestIntentBuilder(externalPaymentId, amount)
val receiptOptions = PaymentRequestIntentBuilder.ReceiptOptions.Instance(
                true,                                                                       //cloverShouldHandleReceipts = true
                PaymentRequestIntentBuilder.ReceiptOptions.SmsReceiptOption.Disable(),      //disable SMS receipt button
                PaymentRequestIntentBuilder.ReceiptOptions.EmailReceiptOption.Disable(),    //disable Email receipt button
                PaymentRequestIntentBuilder.ReceiptOptions.PrintReceiptOption.Enable(),     //enable Print receipt button
                PaymentRequestIntentBuilder.ReceiptOptions.NoReceiptOption.Enable())        //enable No Receipt button
val paymentRequestIntent = builder.receiptOptions(receiptOptions).build(context)
String externalPaymentId = "<posPaymentId>";
Long amount = 1000L;
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder(externalPaymentId, amount);
PaymentRequestIntentBuilder.ReceiptOptions receiptOptions = PaymentRequestIntentBuilder.ReceiptOptions.Instance(
            true,                                                                       //cloverShouldHandleReceipts = true
            PaymentRequestIntentBuilder.ReceiptOptions.SmsReceiptOption.Disable(),      //disable SMS receipt button
            PaymentRequestIntentBuilder.ReceiptOptions.EmailReceiptOption.Disable(),    //disable Email receipt button
            PaymentRequestIntentBuilder.ReceiptOptions.PrintReceiptOption.Enable(),     //enable Print receipt button
            PaymentRequestIntentBuilder.ReceiptOptions.NoReceiptOption.Enable());       //enable No Receipt button
Intent intent = builder.receiptOptions(receiptOptions).build(context);

Result on the device

1280

Accept a payment: Receipt screen

OfflineOptions

Prerequisite: Configure the Merchant's payment gateway for offline payments.

The OfflineOptions class provides a static method to configure three flags for offline payment settings.

Static MethodsDescription
Instance( allowOfflinePayment : Boolean, allowOfflinePaymentWithoutPrompt : Boolean, forceOfflinePayment : Boolean)Creates an OfflineOptions instance that is configured to take the payment offline. If needed, the system can take the payment offline and enforce offline payment processing without notifying the merchant. The resulting payment returns a value of offline=true, if the payment was taken offline.

Offline payments are processed as soon as network connectivity is available.

Example—Allow an offline payment and disable the allow offline prompt

val builder = PaymentRequestIntentBuilder("<posPaymentId>", 1500)
builder.offlineOptions(
   PaymentRequestIntentBuilder.OfflineOptions.Instance(
       true, // allow offline
       true,  // approveOfflineWithoutPrompt
       null)) // forceOffline

val intent = builder.build(context)
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
builder.offlineOptions(
      PaymentRequestIntentBuilder.OfflineOptions.Instance(
          true,     //allow offline
          true,     //approveOfflineWithoutPrompt
          null));   //forceOffline
Intent intent = builder.build(context);

Tokenize options

Prerequisite: Your device must have core-payments installed. If your device does not have core-payments installed, please contact Developer Support if you would like to utilize this feature.

The TokenizeOptions class contains a single property—suppressConfirmation. The presence of TokenizeOptions, regardless of the suppressConfirmation value, indicates that a token must be generated for the payment card. The tokenize option is secondary to the payment, so a failed tokenization can result in a successful payment, but a failed payment cannot result in a successful tokenization.

ValueDescription
Instance(suppressConfirmation:Boolean)Creates a TokenizeOptions instance with or without the confirmation required.

Default: Confirmation is required and is requested.

Example—Request a payment token with a payment

val builder = PaymentRequestIntentBuilder("<posPaymentId>", 1500)

builder.tokenizeOptions(PaymentRequestIntentBuilder.TokenizeOptions.Instance(
   false // suppressConfirmation
));

val intent = builder.build(context)
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
builder.tokenizeOptions(
         PaymentRequestIntentBuilder.TokenizeOptions.Instance(
             false));  //suppressConfirmation
Intent intent = builder.build(context);

TenderOptions

The TenderOptions class allows Integrators to control Cash and Custom Tenders on a per-transaction level. With TenderOptions, you have the option to disable the Cash or Custom Tender. When both tenders are not enabled, the system bypasses the selection and automatically asks for a card payment.

ValueDescription
Disable(disableCash: Boolean, disableCustom: Boolean)Creates a TenderOptions instance where Cash, Custom Tender, or both can be disabled.
Disable()Creates a TenderOptions instance where both Cash and Custom Tender are disabled.
val builder = PaymentRequestIntentBuilder("<posPaymentId>", 1500)

builder.tenderOptions(PaymentRequestIntentBuilder.TenderOptions.Disable(
   true // disable Cash
   false //keep Custom Tender enabled
));
val intent = builder.build(context)

Additional fields

Additional fields on the PaymentRequestIntentBuilder include:

FieldDescription
externalPaymentId: StringCustom external payment identifier (Id) to identify the transaction.
amount: LongTotal amount paid.
taxAmount: LongAmount paid in taxes. This amount must display in the taxAmount field as this is used for reporting purposes.
externalReferenceId: StringReference identifier (Id) is passed to the merchant's gateway and displays in settlement records as the Invoice Number.

Response details

When the payment flow completes, the response comes through onActivityResult().

  • When the request is successful, you can retrieve the resulting Payment object with Intents.EXTRA_PAYMENT. You can also retrieve the receipt option selected with Intents.EXTRA_RECEIPT_DELIVERY_TYPE if it was processed or requested using Intents.EXTRA_RECEIPT_DELIVERY_STATUS.
  • If an email or SMS value is entered, that value is retrieved using Intents.EXTRA_ENTERED_RECEIPT_VALUE.
  • If you tokenized the card used, the card is retrieved using Intents.EXTRA_CARD.
  • When the request is unsuccessful, you can retrieve the failure message with Intents.EXTRA_FAILURE_MESSAGE.
fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent) {
        super.onActivityResult(requestCode, resultCode, data)
        if (requestCode == PAYMENT_REQUEST_CODE) {
            if (resultCode == RESULT_OK) {
                val payment: Payment = data.getParcelableExtra(Intents.EXTRA_PAYMENT)
                val receiptDeliveryStatus = data.getStringExtra(Intents.EXTRA_RECEIPT_DELIVERY_STATUS)
                val receiptDeliveryType = data.getStringExtra(Intents.EXTRA_RECEIPT_DELIVERY_TYPE)
                val enteredReceiptValue = data.getStringExtra(Intents.EXTRA_ENTERED_RECEIPT_VALUE)
                val card:Card = data.getParcelableExtra(Intents.EXTRA_CARD) //if card was tokenized
            } else {
                // payment failed, check for error
                val failureMessage = data.getStringExtra(Intents.EXTRA_FAILURE_MESSAGE)
            }
        }
    }
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (requestCode == PAYMENT_REQUEST_CODE) {
      if (resultCode == RESULT_OK) {
        Payment payment = data.getParcelableExtra(Intents.EXTRA_PAYMENT);
        String receiptDeliveryStatus = data.getStringExtra(Intents.EXTRA_RECEIPT_DELIVERY_STATUS);
        String receiptDeliveryType = data.getStringExtra(Intents.EXTRA_RECEIPT_DELIVERY_TYPE);
        String enteredReceiptValue = data.getStringExtra(Intents.EXTRA_ENTERED_RECEIPT_VALUE);
        Card card = data.getParcelableExtra(Intents.EXTRA_CARD); //if card was tokenized
      } else {
       // payment failed, check for error
        String failureMessage = data.getStringExtra(Intents.EXTRA_FAILURE_MESSAGE);
      }
    }
  }

Examples

Custom tips

Example—Create custom tip options of $1.00, $2.00, and 20% and prefer onScreen tips.

val builder = PaymentRequestIntentBuilder("<posPaymentId>", 1500)

var tipSuggestions = listOf<TipSuggestion>(
   TipSuggestion.Amount("Thanks!", 100),
   TipSuggestion.Amount("Good Job!", 200),
   TipSuggestion.Percentage("Great!", 20)
)
var tipOptions = PaymentRequestIntentBuilder.TipOptions.PromptCustomer(null, tipSuggestions)

builder.tipAndSignatureOptions(
   tipOptions,
   null, // signature options
   true) // preferOnScreen

val intent = builder.build(context)
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
List<TipSuggestion> tipSuggestions = Arrays.asList(
            TipSuggestion.Amount("Thanks!", 100L),
            TipSuggestion.Amount("Good Job!", 200L),
            TipSuggestion.Percentage("Great!", 20L));
PaymentRequestIntentBuilder.TipOptions tipOptions = PaymentRequestIntentBuilder.TipOptions.PromptCustomer(null, tipSuggestions);
builder.tipAndSignatureOptions(tipOptions,
            null,
            true);
Intent intent = builder.build(context);

Custom card entry methods

Example—Set the card entry methods to Manual and near-field communication (NFC) only.

val builder = PaymentRequestIntentBuilder("<posPaymentId>", 1500)

var cardEntryMethods = setOf<CardEntryMethod>(
   CardEntryMethod.MANUAL, 
   CardEntryMethod.NFC)

var cardOptions = PaymentRequestIntentBuilder.CardOptions.Instance(
   cardEntryMethods,
   null, // card not present
   null) // auto accept duplicates

builder.cardOptions(cardOptions)


val intent = builder.build(context)
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
Set<CardEntryMethod> cardEntryMethods = new HashSet<>();
cardEntryMethods.add(CardEntryMethod.MANUAL);
cardEntryMethods.add(CardEntryMethod.NFC);
PaymentRequestIntentBuilder.CardOptions cardOptions = CardOptions.Instance(
     cardEntryMethods,
     null,      //card not present
     null);                  //auto accept duplicates
builder.cardOptions(cardOptions);
Intent intent = builder.build(context);

Minimal interaction

Example—Reduce the screens to only the payment screen. This example disables tips, signatures, and payment confirmations, and skips the receipt screen.

val builder = PaymentRequestIntentBuilder("<posPaymentId>", 1500)
builder.tipAndSignatureOptions(
	 PaymentRequestIntentBuilder.TipOptions.Disable(),
 	 PaymentRequestIntentBuilder.SignatureOptions.Disable(),
	 true)
builder.cardOptions(
	 PaymentRequestIntentBuilder.CardOptions.Instance(
       null,
       null,
       true))
builder.receiptOptions(PaymentRequestIntentBuilder.ReceiptOptions.SkipReceiptSelection())
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
builder.tipAndSignatureOptions(
            PaymentRequestIntentBuilder.TipOptions.Disable(),
            PaymentRequestIntentBuilder.SignatureOptions.Disable(),
            true);
builder.cardOptions(
            PaymentRequestIntentBuilder.CardOptions.Instance(
                    null,
                    null,
                    true));
builder.receiptOptions(PaymentRequestIntentBuilder.ReceiptOptions.SkipReceiptSelection());
Intent intent = builder.build(context);

Custom cashback options

Example—Set the CashbackOptions to $10, $15, $20, $25.

val builder = PaymentRequestIntentBuilder("<posPaymentId>", 1500)
val cashbackSuggestions: List<Long> = mutableListOf(10, 15, 20, 25)
val cashbackOptions = PaymentRequestIntentBuilder.CardOptions.CashbackOptions.Suggestions(cashbackSuggestions)
builder.cardOptions(
   PaymentRequestIntentBuilder.CardOptions.Instance(
       null,
       null,
       false,
       cashbackOptions))
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
List<Long> cashbackSuggestions = Arrays.asList(10L, 15L, 20L, 25L);
PaymentRequestIntentBuilder.CardOptions.CashbackOptions cashbackOptions = PaymentRequestIntentBuilder.CardOptions.CashbackOptions.Suggestions(cashbackSuggestions);
builder.cardOptions(
            PaymentRequestIntentBuilder.CardOptions.Instance(
                    null,       //cardEntryMethods
                    null,                       //cardNotPresent
                    false,                      //autoAcceptDuplicates
                    cashbackOptions));
Intent intent = builder.build(context);

Example—Disable the cashback options screen.

val builder = PaymentRequestIntentBuilder("<posPaymentId>", 1500)
val cashbackOptions = PaymentRequestIntentBuilder.CardOptions.CashbackOptions.Disable()
builder.cardOptions(
   PaymentRequestIntentBuilder.CardOptions.Instance(
       null,
       null,
       false,
       cashbackOptions))
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
PaymentRequestIntentBuilder.CardOptions.CashbackOptions cashbackOptions = PaymentRequestIntentBuilder.CardOptions.CashbackOptions.Disable();
builder.cardOptions(
        PaymentRequestIntentBuilder.CardOptions.Instance(
              null,     //cardEntryMethods
              null,     //cardNotPresent
              false,    //autoAcceptDuplicates
              cashbackOptions));
Intent intent = builder.build(context);

Example—Bypass tenders and go straight to card payment

PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
builder.tenderOptions(PaymentRequestIntentBuilder.TenderOptions.Disable());
Intent intent = builder.build(context);
PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder("<posPaymentId>", 1500);
PaymentRequestIntentBuilder.CardOptions.CashbackOptions cashbackOptions = PaymentRequestIntentBuilder.CardOptions.CashbackOptions.Disable();
builder.cardOptions(
        PaymentRequestIntentBuilder.CardOptions.Instance(
              null,     //cardEntryMethods
              null,     //cardNotPresent
              false,    //autoAcceptDuplicates
              cashbackOptions));
Intent intent = builder.build(context);