
Hello there, my name is Peterstev Uremgba, but my friends simply call me Peters or Light or Peters Light however they like. well, this is my first time trying out this Blogging thingy so you all can already forgive my future errors and be kind to me :XD. Now to the business at hand.
I am yet to come across any sound/complete Paystack integration tutorial online asides the official GitHub readMe page and Segun Famisa’s blog post, albeit an abridged post, so I’m here to throw my hat into the ring.
What is Paystack?
According to their official page, they are simply a fintech company that helps businesses in Africa get paid by anyone, anywhere in the world, well there you go, but I don’t think you’ll be searching for a way to integrate Paystack into an Android app if you didn’t know what Paystack does.
I’ll make a series of assumptions here.
- You are an Android Programmer.
- You program using Android Studio.
- You know how to add libraries to your project using Gradle.
Now that we have that out of the way lets roll.
Firstly follow this link to create a Paystack account if you don’t have one or login, when done, complete your profile, head over to settings, click on the API KEYS & WEBHOOK tab to reveal your Test API Key (Note: leave your account in test mode, so you can easily test all the features of Paystack without incurring any charges.)
Next, we have to head over to the official Paystack github page and grab the Paystack android library link, copy the implementation link and paste in your app.gradle file’s dependency block and SYNC GRADLE
dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation 'co.paystack.android:paystack:3.0.12' }
This version (3.0.12) of the library may be outdated by the time you’re reading this, so make sure to grab the latest version from the official GitHub page.
NOTE: you have to be targeting Android 4.1 “Jelly Bean” and above to be able to use this Library.
Next, add the internet permission to your Manifest file (Ignore the other code for now, just focus on the highlighted code block).
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.your.packagename"> <uses-permission android:name="android.permission.INTERNET" /> <application android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Next, create a class that extends Application and initialize the Paystack SDK there
public class App extends Application{ @Override public void onCreate() { super.onCreate(); PaystackSdk.initialize(getApplicationContext()); } }
Now add this new class to the as a name attribute in the application tag of your manifest file
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.your.packagename"> <uses-permission android:name="android.permission.INTERNET" /> <application android:name=".App" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
Now add the following meta tag to the application tag of your manifest file
<?xml version="1.0" encoding="utf-8"?> <manifest xmlns:android="http://schemas.android.com/apk/res/android" package="com.your.packagename"> <uses-permission android:name="android.permission.INTERNET" /> <application android:name=".App" android:allowBackup="true" android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher_round" android:supportsRtl="true" android:theme="@style/AppTheme"> <meta-data android:name="co.paystack.android.PublicKey" android:value="your test public key"/> <activity android:name=".MainActivity"> <intent-filter> <action android:name="android.intent.action.MAIN" /> <category android:name="android.intent.category.LAUNCHER" /> </intent-filter> </activity> </application> </manifest>
The test (As in test environment) public key can be gotten from the API KEYS & WEBHOOK tab in the settings page of your Paystack account

Now here comes the fun part :XD
By now you should head over to your main layout file and create a layout to collect data like Card Number, CVV, Expiry date
These are the compulsory details before you can charge the card, other details include Name, Email, Phone Number etc see the documentation for more details to collect.
Therefore create a simple layout with 2 EditText for Card Number and CVV then 2 Spinners for Expiry Month and year.
<?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" tools:context=".MainActivity"> <android.support.v7.widget.AppCompatEditText android:id="@+id/et_main_card" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginStart="10dp" android:layout_marginTop="30dp" android:layout_marginEnd="10dp" android:hint="Card Number" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toTopOf="parent" /> <android.support.v7.widget.AppCompatEditText android:id="@+id/et_main_cvv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:hint="Card CVV" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/et_main_card" /> <android.support.v7.widget.LinearLayoutCompat android:id="@+id/sp_container" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:animateLayoutChanges="true" android:orientation="horizontal" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@id/et_main_cvv"> <android.support.v7.widget.AppCompatSpinner android:id="@+id/sp_main_month" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:entries="@array/months" android:spinnerMode="dropdown" /> <android.support.v7.widget.AppCompatSpinner android:id="@+id/sp_main_year" android:layout_width="0dp" android:layout_height="wrap_content" android:layout_weight="1" android:spinnerMode="dropdown" /> </android.support.v7.widget.LinearLayoutCompat> <android.support.v7.widget.AppCompatButton android:id="@+id/bt_main_proceed" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_margin="10dp" android:text="Process Payment" android:textColor="#ffffff" app:backgroundTint="@color/colorPrimary" app:layout_constraintEnd_toEndOf="parent" app:layout_constraintStart_toStartOf="parent" app:layout_constraintTop_toBottomOf="@+id/sp_container" /> </android.support.constraint.ConstraintLayout>
android:entries=”@array/months” should pop an error in your screen, copy the string array of months and add to your strings.xml file.
You’ll also notice that no entry was defined for the year spinner, that is because we want it to be dynamic and change on its own every year. So we’ll set it in our Java code.
<resources> <string name="app_name">Peterstev Blog</string> <string-array name="months"> <item>Month</item> <item>01</item> <item>02</item> <item>03</item> <item>04</item> <item>05</item> <item>06</item> <item>07</item> <item>08</item> <item>09</item> <item>10</item> <item>11</item> <item>12</item> </string-array> </resources>
Now to our Java Code
First, we have to get references to our XML elements (I expect you to reference them yourself) and name them etCard, etCvv, spMonth, spYear, also get a reference to the button and call it btProceed.
Make them global variables outside onCreate() so we can access them later.
Next, we create a new method that’ll enable us get the year dynamically at all times.
private String[] getYears() { String[] years = new String[10]; Integer year = Calendar.getInstance().get(Calendar.YEAR); years[0] = "Year"; for (int x = 1; x < years.length; x++) { String currentYear = String.valueOf(year++); years[x] = currentYear; } return years; }
Now we set the year spinner adapter to show these new values we are getting from the getYears() method.
ArrayAdapter<String> adapter = new ArrayAdapter<>(context, android.R.layout.simple_list_item_1, getYears()); //here we set the adapter to the year spinner spYear.setAdapter(adapter);
Next, we create a chargeCard() method that takes care of collecting card details and passing it over to Paystack through the Paystack Card class.
private void chargeCard(int amountInKobo) { String cardCvv = etCvv.getText().toString().trim(); String cardNumber = etCard.getText().toString().trim(); String month, year; if (spMonth.getSelectedItemPosition() > 0 && spYear.getSelectedItemPosition() > 0) { month = spMonth.getSelectedItem().toString(); year = spYear.getSelectedItem().toString(); if (cardName.isEmpty()) { snackBar("Please enter the name on the card"); } else { if (!cardNumber.isEmpty() && !cardCvv.isEmpty()) { //here we pass the details to the card object Card card = new Card(cardNumber, Integer.valueOf(month), Integer.valueOf(year), cardCvv, cardName); //check if the card is valid before attempting to charge the card if (card.isValid()) { //we disable the button so the user doesn't tap multiple times and create a duplicate transaction btProceed.setEnabled(false); //every transaction requires you to send along a unique reference String customRef = generateReference(); //setup a charge object to set values like amount, reference etc Charge charge = new Charge(); //the amount(in KOBO eg 1000 kobo = 10 Naira) the customer is to pay for the product or service // basically add 2 extra zeros at the end of your amount to convert from kobo to naira. charge.setAmount(amountInKobo); charge.setReference(customRef); charge.setCurrency("NGN"); charge.setCard(card); //Charge the card PaystackSdk.chargeCard(this, charge, new Paystack.TransactionCallback() { @Override public void onSuccess(Transaction transaction) { btProceed.setEnabled(true); snackBar("onSuccess"); } @Override public void beforeValidate(Transaction transaction) { snackBar("beforeValidate"); } @Override public void onError(Throwable error, Transaction transaction) { btProceed.setEnabled(true); snackBar(error.getMessage()); } }); } else { snackBar("Invalid Card"); } } } } else { snackBar("Select Card Expiry Date"); } }
btProceed.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { chargeCard(100000); } });
NOTE: Paystack handles the network calls for you under the hood using Retrofit, this is what most posts fail to tell you and so you may spend time wondering how to pass the data on your own. So if its solely charging of user cards your app handles, then there is no need for a lib like Retrofit or Volley etc.
After the request hits Paystack servers you’ll be prompted to enter your card pin and then your OTP then the transaction is validated and processed
Use TEST CARDS to test in the Test Environment, you can find more test cards here or simply use…
Card Number: 5060 6666 6666 6666 666 (Verve)
Expiry Date: any date in the future
CVV: 123
PIN: 1234
OTP: 123456
You can check your dashboard to confirm receipt of the funds or if you hit onError() method, you can log the messages to analyse the cause of the error.
some utility method used like snackBar(“…”), generateReference() are setup below.
private void snackBar(String message) { Snackbar.make(etCvv, message, Snackbar.LENGTH_LONG).show(); }
private String generateReference() { String keys = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" + "0123456789" + "abcdefghijklmnopqrstuvxyz"; StringBuilder sb = new StringBuilder(10); for (int i = 0; i < 10; i++) { int index = (int)(keys.length() * Math.random()); sb.append(keys.charAt(index)); } return sb.toString(); }
So here you go with integrating Paystack into an android Application.
Do like and share this post on Twitter, Facebook and LinkedIn or other social media platforms if you found it helpful.
if you have any issues don’t fail to reach out to me in the comments box and i’ll do well to promptly reply you.
Thanks.
If you still experience “invalid email address passed” check that you have charge.setEmail(“customer_email@abc.com”) when setting up the charge object. This solved it for me
In this SDK , can I make a payment integration on mobile money channel? , I required mobile money from paystack.
I can’t say for sure right now, but you’ll have to take a look at the latest documentation
Error: invalid email passed
email is not required in this project, what you need is CVV, card number and card expiry date
Thanks bro, this is on point. How can you be reached?
hello, you can reach me on linkedIn https://linkedin.com/in/peterstev-uremgba
Nice post!
How do I show transaction history or details to user after on successful transaction in android?
you would have to pull that detail from the Paystack API. check out the docs to see other meaningful endpoints you can use to make your app more fluid
https://developers.paystack.co/
Nice post,very helpful.
thanks
Hi, I followed your tutorial but i keep getting this error; java.lang.NoClassDefFoundError: Failed resolution of: Lretrofit2/Callback;
probably you imported the wrong libs, ensure your paystack version is updated and you are adding the dependency to your build.gradle file
implementation ‘co.paystack.android:paystack:$latest_version’
I got the same error. I mean the retrofit error
I got the sane error. And what about how to implement the secret key
I think this is the most precise and easy to follow paystack tutorial out there. Thanks.
Nice post. Excellent explanation
Thank you Hector 😁
Hi, Thanks for this great tutorial, i have followed all your guide bu I Always get error please try again while running the code
Hello, what exactly is the error you are getting Christain
Nice i think you should make that amount to be passed in as parameters in the charge card method so it would be like :
chargeCard(1000);
Nice tutorial
Thanks 🙂
Thanks for the tutorial! Looking forward to more.
🙂
Nice post
thanks Chizoba 🙂
Good one bro
Thanks Franklin