Stripe Integration in Android - Kotlin

Stripe is one of the simplest payment gateway to be used. It enables us to process payments in minutes. Let's see how to integrate Stripe in Android using Kotlin.

Operational Flow:



            1. App should provide order details to Stripe server and the order total will be returned to App.
            2. Then the user will enter the payment/card details. That will be sent to Stripe server and the result of the request will be sent back to the App.

Create Stripe Account:

(a) Go to https://dashboard.stripe.com/register and enter all your details and create account. 


 (b) Click API in side tab. Make sure that the Account is in Test mode. And make a note of         Publishable Key and Secret Key for use.



Code:

build.gradle:

 compile 'com.stripe:stripe-android:5.1.0'

Layout files:

main_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent">

    <TextView
        android:id="@+id/price"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Price : $10"
        android:padding="10dp"
        android:textAppearance="@android:style/TextAppearance.Medium"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent" />

    <TextView
        android:id="@+id/pay"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="Pay Now"
        android:background="@color/colorPrimary"
        android:padding="15dp"
        android:gravity="center"
        android:textColor="@color/white"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"/>

</android.support.constraint.ConstraintLayout>

stripe_layout.xml:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout
    xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical"
    android:padding="10dp">

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.design.widget.TextInputEditText
            android:id="@+id/cardNo"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:maxLength="16"
            android:hint="Card Number"/>
    </android.support.design.widget.TextInputLayout>

    <android.support.design.widget.TextInputLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content">

        <android.support.design.widget.TextInputEditText
            android:id="@+id/cvv"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:maxLength="4"
            android:hint="CVV"/>
    </android.support.design.widget.TextInputLayout>

    <LinearLayout
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal">

    <android.support.design.widget.TextInputLayout
        android:layout_width="0dp"
        android:layout_height="wrap_content"
        android:layout_marginRight="3dp"
        android:layout_weight="1">

        <android.support.design.widget.TextInputEditText
            android:id="@+id/month"
            android:layout_width="match_parent"
            android:layout_height="wrap_content"
            android:maxLength="2"
            android:hint="Month"/>
    </android.support.design.widget.TextInputLayout>

        <android.support.design.widget.TextInputLayout
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_marginLeft="3dp"
            android:layout_weight="1">

            <android.support.design.widget.TextInputEditText
                android:id="@+id/year"
                android:layout_width="match_parent"
                android:layout_height="wrap_content"
                android:maxLength="2"
                android:hint="Year"/>
        </android.support.design.widget.TextInputLayout>

    </LinearLayout>

    <TextView
        android:id="@+id/submit"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:text="PAY NOW"
        android:padding="15dp"
        android:layout_marginTop="10dp"
        android:gravity="center"
        android:background="@color/colorPrimary"
        android:textColor="@color/white"/>

</LinearLayout>

StripeActivity.kt 

class StripeActivity : AppCompatActivity() {

    lateinit var stripe: Stripe
    val publishKey: String = "pk_test_xxxxxxxxxxxxxxxxxxx"

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.main_layout)

        stripe = Stripe(this, publishKey)

        pay.setOnClickListener { OpenDialog() }
    }

    private fun OpenDialog() {

        var dialog = Dialog(this)
        dialog.setContentView(R.layout.stripe_layout)
        var lp : WindowManager.LayoutParams = WindowManager.LayoutParams().apply {
            copyFrom(dialog.window.attributes)
            width = WindowManager.LayoutParams.MATCH_PARENT
            height = WindowManager.LayoutParams.WRAP_CONTENT
        }

        val submit = dialog.findViewById<View>(R.id.submit) as TextView
        val cardNo = dialog.findViewById<View>(R.id.cardNo) as EditText
        val month = dialog.findViewById<View>(R.id.month) as EditText
        val year = dialog.findViewById<View>(R.id.year) as EditText
        val cvv = dialog.findViewById<View>(R.id.cvv) as EditText

        submit.setOnClickListener {
            when {
                cardNo.length() == 0 || month.length() == 0 || year.length() == 0 || cvv.length() == 0 ->
                    Toast.makeText(this@StripeActivity, "Please fill all the fields"
                            , Toast.LENGTH_SHORT).show()
                cardNo.length() < 16 -> Toast.makeText(this@StripeActivity, "Please enter" +
                        " valid Card No.", Toast.LENGTH_SHORT).show()
                else -> {
                    validateCard(cardNo.text.toString(), month.text.toString(), year.text.toString(), cvv.text.toString())
                    dialog.dismiss()
                }
            }
        }
        dialog.show()
        dialog.getWindow().setAttributes(lp)
    }

    private fun validateCard(card: String?, month: String?, year: String?, cvv: String?) {
        val card = Card(card, Integer.valueOf(month), Integer.valueOf(year), cvv)
        card.currency = "USD"
        stripe.createToken(card, object : TokenCallback {
            override fun onSuccess(token: Token?) {
                Log.v("Token!","Token Created!!"+ token!!.getId())
                Toast.makeText(this@StripeActivity, "Token Created!!", Toast.LENGTH_SHORT).show()
                chargeCard(token.id);
            }

            override fun onError(error: Exception?) {
                Toast.makeText(this@StripeActivity, error!!.message, Toast.LENGTH_SHORT).show()
                error.printStackTrace()
            }

        })

    }

    private fun chargeCard(token: String?) {
        // Pass that token, amount to your server using API to process payment.

    }
}

Run Application:

 
 


Comments

Post a Comment

Popular posts from this blog

SOAP Client using ksoap2 in Android - Kotlin

Databinding in RecyclerView - Android - Kotlin

RecyclerView with different number of columns using SpanSizeLookup

Using Camera in Android - Kotlin

Using RxJava, Retrofit in Android - Kotlin

Map, Location update and AutoComplete Places - Kotlin

Braintree Integration in Android - Kotlin

Exploring Android Slices - JetPack

Room with LiveData, ViewModel - Android Architecture Components - Kotlin