Android API: Payment tutorial

United States

With Clover Android Payments API, your app can process payments on a Clover device, without the need to be device aware, using a simple Android Intent. The following sections explore using the Clover Android Payments API in a small sample app with a single button that processes a sale for $10.00.

Add Clover Android Payments API dependencies

The Clover Android Payments API library is published on Maven Central and therefore, you must add that repository and the dependencies to your build configurations by performing the following steps:

  1. Open your project's build.gradle file.
  2. In the repositories block, add mavenCentral() as the first repository.
repositories {
  mavenCentral()
  google()
}
  1. Open your module's build.gradle file.
  2. In the dependencies block, add the following implementation statements:
dependencies {
  ...
  implementation "com.clover.sdk:clover-android-sdk:293"
}

Create a payment request

Next, create a simple payment request with the PaymentRequestIntentBuilder class. For testing purposes, the payment amount is set to $10.00.

Example of a Simple Payment Request:

fun buildPaymentRequestIntent() : Intent {
        val externalPaymentId = "<posPaymentId>" // should be unique for each request
        val amount = 1000L
        val context = this

        val builder = PaymentRequestIntentBuilder(externalPaymentId, amount)
        return builder.build(context)

    }
private Intent buildPaymentRequestIntent() {
   String externalPaymentId = "<posPaymentId>"; // should be unique for each request
   long amount = 1000;
   Context context = this;

   PaymentRequestIntentBuilder builder = new PaymentRequestIntentBuilder(externalPaymentId, amount);
   return builder.build(context);
}

Use the newly built payment request Intent

In your activity, add code for the following:

  • Set the layout to use the activity_main.xml file.
  • Add the button widget that can be tapped to initiate the payment.

Create Activity example:

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        val payButton = findViewById<Button>(R.id.paymentButton)
        payButton.setOnClickListener(object : OnClickListener() {
            fun onClick(v: View?) {
                val intent: Intent = buildPaymentRequestIntent()
                startActivityForResult(intent, PAYMENT_REQUEST_CODE)
            }
        })
    }
@Override
    protected void onCreate(Bundle savedInstanceState) {
       super.onCreate(savedInstanceState);
       setContentView(R.layout.activity_main);
       Button payButton = findViewById(R.id.paymentButton);
       payButton.setOnClickListener(new View.OnClickListener() {
           @Override
           public void onClick(View v) {
               Intent intent = buildPaymentRequestIntent();	
               startActivityForResult(intent, PAYMENT_REQUEST_CODE);
           }
       });
    }

Handle the result

Set up for ActivityResult

Upon completion of the payments flow, the response will come through the ActivityResultLauncher callback. The following example shows how to set up the ActivityResultLauncher to process the payment result.

var paymentLauncher: ActivityResultLauncher<Intent> = registerForActivityResult(StartActivityForResult()) { result -> 
    if (result.resultCode == RESULT_OK) {
        val payment: Payment = result.data.getParcelableExtra<Parcelable>(Intents.EXTRA_PAYMENT) as Payment
        // TODO: verify payment is as expected (e.g. partial amount, signature, offline, tippable, etc.)
    } else {
        // payment failed, check for error
        val failureMessage = result.data.getStringExtra(Intents.EXTRA_FAILURE_MESSAGE)
    }
}

Set up the onActivityResult()

Upon completion of the payments flow, the response will come through onActivityResult(). The following example shows how to set up the onActivityResult() and how to extract the resulting Payment object.

Example onActivityResult()

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<Parcelable>(Intents.EXTRA_PAYMENT) as Payment
                // TODO: verify payment is as expected (e.g. partial amount, signature, offline, tippable, etc.)
            } else {
                // payment failed, check for error
                val failureMessage = data.getStringExtra(Intents.EXTRA_FAILURE_MESSAGE)
            }
        }
    }
@Override
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 = (Payment) data.getParcelableExtra(Intents.EXTRA_PAYMENT);
       // TODO: verify payment is as expected (e.g. partial amount, signature, offline, tippable, etc.)
     } else {
       // payment failed, check for error
       String failureMessage = data.getStringExtra(Intents.EXTRA_FAILURE_MESSAGE);
     }
   }
}