Git Product home page Git Product logo

paystack-android's Introduction

Maven Central Min API SonarCloud

Paystack Android

This is a library for easy integration of Paystack with your Android application. Use this library in your Android app so we shoulder the burden of PCI compliance by helping you avoid the need to send card data directly to your server. Instead, this library sends credit card data directly to our servers.

Summarized flow

  1. Collect user's card details

  2. Initialize the transaction

    • App prompts your backend to initialize a transaction
    • Your backend returns access_code we return when it calls the Initialize Transaction endpoint
    • App provides the access_code and card details to our SDK's chargeCard function via Charge object
  3. SDK prompts user for PIN, OTP or Bank authentication as required

  4. Once successful, we'll send an event to your webhook URL and call onSuccess callback. You should give value via webhook.

Requirements

  • Android SDKv16 (Android 4.1 "Jelly Bean") - This is the first SDK version that includes TLSv1.2 which is required by our servers. Native app support for user devices older than API 16 will not be available.

Installation

Android Studio (using Gradle)

You do not need to clone this repository or download the files. The latest build is available on Maven Central Add the following lines to your app's build.gradle:

dependencies {
    implementation 'co.paystack.android:paystack:3.1.3'
}

From version 3.0.18, the Pinpad library comes as part of this library and does not need to be explicitly included in your dependencies.

You should also add Java 8 support in your build.gradle:

android { 
    // ... Other configuration code 
    compileOptions {   
        sourceCompatibility JavaVersion.VERSION_1_8 
        targetCompatibility JavaVersion.VERSION_1_8 
    } 

    // For kotlin codebases, include
    kotlinOptions {
         jvmTarget = "1.8" 
    }
}

Eclipse

To use this library with Eclipse, you need to:

  1. Clone the repository.
  2. Import the paystack folder into your Eclipse project
  3. In your project settings, add the paystack project under the Libraries section of the Android category.

Usage

0) Prepare for use

To prepare for use, you must ensure that your app has internet permissions by making sure the uses-permission line below is present in the AndroidManifest.xml.

<uses-permission android:name="android.permission.INTERNET" />

1) Initialize SDK

To use the Paystack Android SDK, you need to first initialize it using the PaystackSdk class.

public class App extends Application{
    @Override
    public void onCreate() {
        super.onCreate();

        PaystackSdk.initialize(getApplicationContext());
    }
}

Make sure to call this method in the onCreate method of your Fragment or Activity or Application.

2) Set your Public Key

Before you can charge a card with the PaystackSdk class, you need to set your public key. The library provides two approaches:

a) Add the following lines to the <application></application> tag of your AndroidManifest.xml

<meta-data
    android:name="co.paystack.android.PublicKey"
    android:value="pk_your_public_key"/>

You can obtain your public key from your Paystack dashboard.

b) Set the public key by code

This can be done anytime in your code. Just be sure to initialize before calling chargeCard.

class Bootstrap {
    public static void setPaystackKey(String publicKey) {
        PaystackSdk.setPublicKey(publicKey);
    }
}

3) Collect and validate card details

At this time, we expect you to provide fields on your activity that collect the card details. Our Card class allows you collect and verify these. The library provides validation methods to validate the fields of the card.

card.validNumber

This method helps to perform a check if the card number is valid.

card.validCVC

Method that checks if the card security code is valid.

card.validExpiryDate

Method checks if the expiry date (combination of year and month) is valid.

card.isValid

Method to check if the card is valid. Always do this check, before charging the card.

card.getType

This method returns an estimate of the string representation of the card type.

public class MainActivity extends AppCompatActivity {

  // This sets up the card and check for validity
  // This is a test card from paystack
   String cardNumber = "4084084084084081";
   int expiryMonth = 11; //any month in the future
   int expiryYear = 18; // any year in the future. '2018' would work also! 
   String cvv = "408";  // cvv of the test card
   
   Card card = new Card(cardNumber, expiryMonth, expiryYear, cvv);
    if (card.isValid()) {
       // charge card
    } else {
      //do something
    }
}

4) Charge Card

Charging with the PaystackSdk is quite straightforward.

Parameters for the chargeCard function

  • Activity - The first argument to the PaystackSdk.chargeCard is the calling Activity object. Always give an Activity that will stay open till the end of the transaction. The currently open Activity is just fine.

  • Charge - This object allows you provide information about the transaction to be made. Before calling chargeCard, you should do a charge.setCard(card). The charge can then be used in either of 2 ways

    • Resume an initialized transaction: If employing this flow, you would send all required parameters for the transaction from your backend to the Paystack API via the transaction/initialize call - documented here. The response of the call includes an access_code. This can be used to charge the card by doing charge.setAccessCode({value from backend}). Once an access code is set, the only other parameter relevant to the transaction is the card. Others will be ignored.
    • Initiate a fresh transaction on Paystack: Using the functions: setCurrency, setPlan, setSubaccount, setTransactionCharge, setAmount, setEmail, setReference, setBearer, putMetadata, putCustomField, you can set up a fresh transaction directly from the SDK. Documentation for these parameters are same as for transaction/initialize.
  • Transaction Callback - When an error occurs or transaction concludes successfully, we will call the methods available in the callback you provided.

    • OnSuccess will be called once the charge succeeds.
    • beforeValidate is called every time the SDK needs to request user input. This function currently only allows the app know that the SDK is requesting further user input.
    • OnError is called if an error occurred during processing. Some Exception types that you should watch include
      • ExpiredAccessCodeException: This would be thrown if the access code has already been used to attempt a charge.
      • ChargeException: This would be thrown if the charge failed. It would hold the message from the server.
public class MainActivity extends AppCompatActivity {


  // This is the subroutine you will call after creating the charge
  // adding a card and setting the access_code
   public void performCharge(){
         //create a Charge object
         Charge charge = new Charge(); 
         charge.setCard(card); //sets the card to charge
   
       PaystackSdk.chargeCard(MainActivity.this, charge, new Paystack.TransactionCallback() {
           @Override
           public void onSuccess(Transaction transaction) {
               // This is called only after transaction is deemed successful.
               // Retrieve the transaction, and send its reference to your server
               // for verification.
           }

           @Override
           public void beforeValidate(Transaction transaction) {
               // This is called only before requesting OTP.
               // Save reference so you may send to server. If
               // error occurs with OTP, you should still verify on server.
           }
           
           @Override
           public void showLoading(Boolean isProcessing) {
               // This is called whenever the SDK makes network requests.
               // Use this to display loading indicators in your application UI
           }

           @Override
           public void onError(Throwable error, Transaction transaction) {
             //handle error here
           }

       });
   }
}

Note that once chargeCard is called, the SDK may prompt the user to provide their PIN, an OTP or conclude Bank Authentication. These are currently being managed entirely by the SDK. Your app will only be notified via the beforeValidate function of the callback when OTP or Bank Authentication is about to start.

5) Verifying the transaction

Send the reference to your backend and verify by calling our REST API. An authorization will be returned which will let you know if its code is reusable. You can learn more about our Verify Transaction endpoint.

Below is a sample authorization object returned along with the transaction details:

   {
     "status": true,
     "message": "Verification successful",
     "data": {
       "amount": 10000,
       "currency": "NGN",
       "transaction_date": "2017-04-06T21:28:41.000Z",
       "status": "success",
       "reference": "d68rbovh4a",
       "domain": "live",
       "metadata": {
         "custom_fields": [
           {
             "display_name": "Started From",
             "variable_name": "started_from",
             "value": "sample charge card backend"
           },
           {
             "display_name": "Requested by",
             "variable_name": "requested_by",
             "value": "some person"
           },
           {
             "display_name": "Server",
             "variable_name": "server",
             "value": "some.herokuapp.com"
           }
         ]
       },
       "gateway_response": "Approved",
       "message": "Approved",
       "channel": "card",
       "ip_address": "41.31.21.11",
       "log": null,
       "fees": 150,
       "authorization": {
         "authorization_code": "AUTH_blahblah",
         "bin": "412345",
         "last4": "6789",
         "exp_month": "10",
         "exp_year": "2345",
         "channel": "card",
         "card_type": "mastercard debit",
         "bank": "Some Bank",
         "country_code": "NG",
         "brand": "mastercard",
         "reusable": true,
         "signature": "SIG_IJOJidkpd0293undjd"
       },
       "customer": {
         "id": 22421,
         "first_name": "Guava",
         "last_name": "Juice",
         "email": "[email protected]",
         "customer_code": "CUS_6t6che6w8hmt",
         "phone": "",
         "metadata": {},
         "risk_action": "default"
       },
       "plan": null
     }
   }

To reuse the authorization gotten from charging this customer in future, you need to do 2 tests:

  1. In the sample JSON above, you can conclude that the transaction was successful because data.status="success". This means the authorization is active.
  2. Confirm that the authorization is reusable by checking data.authorization.reusable which is true in this case. Once both pass, you can save the authorization code against the customer's email.

6) Charging a card authorization from your server in future

To charge an authorization saved from concluding chargeCard, you need its authorization code and the customer's email. Our Recurring Charge documentation provides more information about charging an authorization.

Testing your implementation

You can (and should) test your implementation of the Paystack Android library in your Android app. You need the details of an actual debit/credit card to do this, so we provide ##test cards## for your use instead of using your own debit/credit cards. Kindly reference our Test Payments documentation for test cards.

To try out the OTP flow, we have provided a test "verve" card:

50606 66666 66666 6666
CVV: 123
PIN: 1234
TOKEN: 123456

Remember to use all test cards only with test keys. Also note that all bank issued cards will be declined in test mode.

Building the example project

  1. Clone the repository.
  2. Import the project either using Android Studio or Eclipse
  3. Deploy a sample backend from PaystackJS-Sample-Backend (PHP) or Sample charge card backend (NodeJS heroku single click deploy)
  4. Copy the endpoints from the deployed backend to your MainActivity.java file. In the case of verify, only copy up to the / before the :
  5. Add your public key to your MainActivity.java file
    • Note that the public key must match the secret key, else none of the transactions will be attempted
  6. Build and run the project on your device or emulator

FAQs

Is authorization_code (https://developers.paystack.co/reference#charging-returning-customers) the same as the access_code)?

No

Where do I get an access_code?

Initialize a transaction : https://developers.paystack.co/reference#initialize-a-transaction

Where do I get an authorization_code?

Verify a successful transaction : https://developers.paystack.co/reference#verify-transaction

If I’m trying to use the Android SDK to charge someone who we’ve previously charged, can I use the authorization_code?

You don't need the SDK to charge an authorization code. It doesn't even know of its existence. Rather, use our charge endpoint: https://developers.paystack.co/reference#charge-authorization

Security

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Contact

For more enquiries and technical questions regarding the Android PaystackSdk, please post on our issue tracker: https://github.com/PaystackHQ/paystack-android/issues.

Change log

Please see CHANGELOG for more information what has changed recently.

paystack-android's People

Contributors

ahmed-paystack avatar blundell avatar damilola-paystack avatar dependabot[bot] avatar donpaul120 avatar efemoney avatar ibrahimlawal avatar ibrahimlawal-paystack avatar ifiok avatar ighotouch avatar ikhiloya avatar jubril-paystack avatar lukman008 avatar michael-paystack avatar nsikaktopdown avatar peter-john-paystack avatar segunfamisa avatar steveamaza avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

paystack-android's Issues

Error while PaystackSdk.chargeCard

While processing transaction in live mode, getting the following error during chargeCard method

Error occurred while processing your request... Please contact merchant

OTP Dialog disappears when you leave the app to retrieve your OTP

Problem/Motivation

Problem: You cannot succeed in entering the OTP if you leave the app.

Steps to repeat:

  1. Using the Android SDK, specify "enforce_otp": true on the Charge object, e.g.
    Charge charge = new Charge();
    charge.setCard(card);
    charge.setEmail(email);
    charge.setAmount((int) (amount * 100.0f));
    charge.setReference(reference);
    charge.addParameter("enforce_otp", "true");
  1. Execute PaystackSdk.chargeCard() using the Charge object created in step 1.
  2. When the OTP dialog appears and you receive the OTP via SMS or email, leave the app to get retrieve the OTP.
  3. Return to the app and see that the OTP dialog is gone.

Repeatable

Always

Expected Results:

The OTP dialog should persist.
Bonus: The OTP window shrinks when the keyboard is shown. Even when it hasn't shrunk, window tends to cut off some text on the edges. Perhaps include an option to show a full Activity instead of a small window?

Pin and OTP Verification dialog doesn't popup(show) at the right time

Problem

I've been working on implementing the paystack-android SDK on an app, but I noticed that sometimes the pin and the OTP verification dialog doesn't popup at the right time after the chargeCard() method has been called. This is so annoying that end-users can likely tap on the pay-button on the app twice thereby initiating two transactions. I managed to resolve the double-tapping error though by disabling the pay-button while a transaction is in progress. But it will be so nice if the paystack-android team can look into this issue and propose a solution or fix the bug in the SDK.

Collection and validation of card details

Problem/Motivation

In your documentation on the above topic, you said the developer needs to provide the fields on our apps activity that collect the card details. this I think is dangerous and customer might feel uncomfortable supplying their card details within an app. knowing the developer can compromise the details.

Proposed resolution

I propose that you provide an interface from you end that apps can connect to for payment and the apps get a callback when the transaction is over.

Problem building project with paystack sdk and retrofit

Problem/Motivation

I keep getting errors building my project when i use this sdk with retrofit, How can i resolve this problem?

Steps to repeat:

Add retrofit dependency
Add paystack sdk
build project

Actual Results:

Error: Program type already present: okhttp3.Challenge

SDK doesn't sync in project

I included the library in my build.gradle file and my project has since stopped syncing. This is the error I get

Error:/xxx/app/build/intermediates/incremental/mergeDebugResources/merged.dir/values/values.xml:473 resource android:attr/foregroundInsidePadding is private

Error:java.util.concurrent.ExecutionException: com.android.builder.internal.aapt.AaptException: AAPT2 link failed:

Error:com.android.builder.internal.aapt.AaptException: AAPT2 link failed:

Error:Execution failed for task ':app:processDebugResources'.
> Failed to execute aapt

When I remove the compile line, my project syncs up fine again.

This is how my build looks like:

compileSdkVersion 25
buildToolsVersion "25.0.2"
minSdkVersion 21
targetSdkVersion 25

Please how do i set the currency string

Problem/Motivation

(Why the issue was filed, steps to reproduce the problem, etc.)

Proposed resolution

(Description of the proposed solution, the rationale behind it, and workarounds for people who cannot use the patch.)

Repeatable

Always|Sometimes|Specific conditions|Specific times

(If it is a bug, you are reporting lease specify:)

Steps to repeat: (Describe how the issue can be repeated by someone who is to work on it)

  1. Step 1
  2. Step 2
  3. ...

Expected Results:

(What you expected steps 1, 2 and 3 to give)

Actual Results:

(What is gave including any error messages, memory dump etc that can help)

public static boolean isExpired(int year, int month) always return true on active cards

The cause of the problem for now is in the "CardUtils class" of the android SDK and needs to be fixed asap.
The method isExpired always returns true for a valid card given valid dates  ,this leads to valid cards always not passing the verification stage.

How to recreate it is to pass valid date of card to it and it will return true which implies expired.I also attached screenshots. I have lso added my CardUtils class i modified that worked.
CardUtils.zip

alwaysreturntrue
cardutilsissues
codeexpired
screenshot_2017-02-18-10-54-25

Is there any way to customize PinActivity and OtpActivity?

it's not an issue, but question.

Case: when user add new card in our app, PaystackSdk request for pin/OTP (PinActivity/OtpActivity is run).
Obvious this inner activities are not in our app style.
Is there any way to change it's layouts?

Failing Transaction

Problem/Motivation

I am trying to make a charge, and after setting up the card and validation(card validation and OTP), the App crashes base on an error from the sdk

Proposed resolution

Check the TransactionManager. The error points here:

    if (transactionApiResponse.status.equalsIgnoreCase("1") ||transactionApiResponse.status.equalsIgnoreCase("success")){
        setProcessingOff();
        transactionCallback.onSuccess(transaction);
        return;
    }

Repeatable

Always

(If it is a bug, you are reporting lease specify:)

Steps to repeat: (Describe how the issue can be repeated by someone who is to work on it)

  1. Create card
  2. Create charge by attaching card
  3. Add amount
  4. Add email

Expected Results:

Return transaction object

Actual Results:

    java.lang.NullPointerException: Attempt to invoke virtual method 'boolean java.lang.String.equalsIgnoreCase java.lang.String)' on a null object reference
            at co.paystack.android.TransactionManager.handleApiResponse(TransactionManager.java:170)
            at co.paystack.android.TransactionManager.access$000(TransactionManager.java:37)
            at co.paystack.android.TransactionManager$AuthAsyncTask.onPostExecute(TransactionManager.java:361)
            at co.paystack.android.TransactionManager$AuthAsyncTask.onPostExecute(TransactionManager.java:339)
            at android.os.AsyncTask.finish(AsyncTask.java:651)
            at android.os.AsyncTask.access$500(AsyncTask.java:180)
            at android.os.AsyncTask$InternalHandler.handleMessage(AsyncTask.java:668)
            at android.os.Handler.dispatchMessage(Handler.java:102)
            at android.os.Looper.loop(Looper.java:158)
            at android.app.ActivityThread.main(ActivityThread.java:7225)
            at java.lang.reflect.Method.invoke(Native Method)
            at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1230)
            at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1120)

SDK Does Not Validate Cards with PAN > 16 digits

Problem/Motivation

When customer is trying to pay with a Verve card which is longer than 16 digits, SDK does not allow this.

Proposed resolution

Update validation to accept Verve cards or other cards with PAN longer than 16 digits.

App crashes when trying to initiate transaction locally

Problem/Motivation

When I try to initiate a transaction locally, the app crashes with the error "Could not find class 'co.paystack.android.TransactionManager$1', referenced from method co.paystack.android.TransactionManager." My android studio version is 3.0.

Pin or OTP Verification dialog closes

So... I put in card details (Visa card) submit, it bring up some dialog to verify i suppose and then it closes by it self. Maybe I am implementing it the wrong way. Is there a working example i can use to see how to verify a visa card on paystack?

Error in initializing paystack android sdk

Problem/Motivation

I'm using the paystack version "co.paystack.android:paystack:3.0.7". When i try to initialize the paystack sdk in fragment via: PaystackSdk.initialize(getApplicationContext()), I get the error "cannot resolve the symbol PaystackSdk. And i'm using android studio 3.1.2.

Compatiablity issue with api and sdk

Problem

I have tried to hit api
https://api.paystack.co/charge/tokenize

(Header)
Authorization: Bearer sk_test_2f823212029d3b97db05da735b43ab4d1f97815f

(Request)
{"card":{"cvc":"408","expiryMonth":11,"expiryYear":18,"last4digits":"4081","number":"4084084084084081","type":"Visa"},"card.cvv":"408","email":"[email protected]","card.expiry_month":"11","card.expiry_year":"18","card.number":"4084084084084081"}

So, above request CARD created from SDK.
Issue is api needs,

{"card":{"cvv":"408","expiry_month":11,"expiry_year":18,"last4digits":"4081","number":"4084084084084081","type":"Visa"},"card.cvv":"408","email":"[email protected]","card.expiry_month":"11","card.expiry_year":"18","card.number":"4084084084084081"}

Proposed resolution

I have seen there is need to change above 3 parameters on sdk too.

(If it is a bug, you are reporting lease specify:)

Expected Results:

{
"card": {
"cvv": "408",
"expiry_month": 11,
"expiry_year": 18,
"last4digits": "4081",
"number": "4084084084084081",
"type": "Visa"
},
"card.cvv": "408",
"email": "[email protected]",
"card.expiry_month": "11",
"card.expiry_year": "18",
"card.number": "4084084084084081"
}

Our CARD class from sdk should return, below parameters.
"cvv": "408",
"expiry_month": 11,
"expiry_year": 18

Not this one.
"cvc": "408",
"expiryMonth": 11,
"expiryYear": 18

Thankyou

Proguard rules

Building with proguard enabled fails. How do I write proguard rules to solve this?

I am trying to compile stack but I am getting this error, Error:In <declare-styleable> ForegroundView, unable to find attribute foreground. Any help will be highly appreciated.

Problem/Motivation

(Why the issue was filed, steps to reproduce the problem, etc.)

Proposed resolution

(Description of the proposed solution, the rationale behind it, and workarounds for people who cannot use the patch.)

Repeatable

Always|Sometimes|Specific conditions|Specific times

(If it is a bug, you are reporting lease specify:)

Steps to repeat: (Describe how the issue can be repeated by someone who is to work on it)

  1. Step 1
  2. Step 2
  3. ...

Expected Results:

(What you expected steps 1, 2 and 3 to give)

Actual Results:

(What is gave including any error messages, memory dump etc that can help)

So many requests.

I have been testing on this project but I noticed one big problem. The app fails and gives an error 'card can not be null'. then it starts posting wildly on my backed.

ChargeException Error! Please try again

LoginAddCreditCardFragment.java.zip

Problem/Motivation

(Why the issue was filed, steps to reproduce the problem, etc.)
Actually, I am trying to execute fresh charge (transaction) with the test card (4084084084084081) provided on Paystack site. I am getting this exception ##ChargeException Error! Please try again.

Proposed resolution

(Description of the proposed solution, the rationale behind it, and workarounds for people who cannot use the patch.)

Repeatable

Always|Sometimes|Specific conditions|Specific times
Always
(If it is a bug, you are reporting lease specify:)
I don' know if its a bug or not. But I am getting this exception every time I try to run the flow of fresh transaction by executing chargeCard method.

Steps to repeat: (Describe how the issue can be repeated by someone who is to work on it)

  1. Step 1

  2. Step 2

  3. ...

  4. Step 1
    Created a card object with the dummy test card provided on Paystack site.

  5. Step 2
    Card.isValid method is also returning "False" for the test card.

  6. Step 3
    Executing "chargeCard" method by providing the test card details, I am getting the above-mentioned exception every time.

Expected Results:

(What you expected steps 1, 2 and 3 to give)
Step 2.
"card.IsValid" should return "true".
Step 3.
"chargeCard" should return an "Authorization Code".

Actual Results:

(What is gave including any error messages, memory dump etc that can help)

It should create a transaction and return the transaction object along with the "Authorization Code" details.

Action not yet supported for mastercard by this app.

Android - Action not yet supported for mastercard by this app.

Facing issue in android while performing credit card authentication in paystack using visa/master credit/debit cards

Caught co.paystack.android.exceptions.ChargeException: Action not yet supported for mastercard by this app.

Unable to Charge card in test mode.

Am getting this error when I try to charge card in test mode:

An error occurred while charging card: BadTokenException Unable to add window -- token null is not for an application

Kindly make some static final Strings public

Kindly make the below statics public to aid us not to recreate a job u have done twice in the class "Card".
I had to recreate it so that my edittext text-watcher can update card type in realtime and to verify if card belongs to acceptable cards in Nigeria.
publicstatic

static final String PATTERN_VISA = "^4[0-9]{6,}$";
static final String PATTERN_MASTERCARD = "^5[1-5][0-9]{5,}$";
static final String PATTERN_AMERICAN_EXPRESS = "^3[47][0-9]{5,}$";
static final String PATTERN_DINERS_CLUB = "^3(?:0[0-5]|[68][0-9])[0-9]{4,}$";
static final String PATTERN_DISCOVER = "^6(?:011|5[0-9]{2})[0-9]{3,}$";
static final String PATTERN_JCB = "^(?:2131|1800|35[0-9]{3})[0-9]{3,}$";
static final String PATTERN_VERVE = "^506[0-9]{6,}$";

I dont want my customers to enter card details within my app. Is there a payment page which does not contain firstname and lastname spaces Just card details only?

Problem/Motivation

(Why the issue was filed, steps to reproduce the problem, etc.)

Proposed resolution

(Description of the proposed solution, the rationale behind it, and workarounds for people who cannot use the patch.)

Repeatable

Always|Sometimes|Specific conditions|Specific times

(If it is a bug, you are reporting lease specify:)

Steps to repeat: (Describe how the issue can be repeated by someone who is to work on it)

  1. Step 1
  2. Step 2
  3. ...

Expected Results:

(What you expected steps 1, 2 and 3 to give)

Actual Results:

(What is gave including any error messages, memory dump etc that can help)

Android "Unspecified Failure" with Visa cards

Problem/Motivation

I always get this error "Unspecified Failure" each time i charge with Visa card on android native application.

Proposed resolution

(Description of the proposed solution, the rationale behind it, and workarounds for people who cannot use the patch.)

Repeatable

Always|Sometimes|Specific conditions|Specific times

(If it is a bug, you are reporting lease specify:)

Steps to repeat: (Describe how the issue can be repeated by someone who is to work on it)

  1. Step 1
  2. Step 2
  3. ...

Expected Results:

(What you expected steps 1, 2 and 3 to give)

Actual Results:

(What is gave including any error messages, memory dump etc that can help)

Unable to install Library for Paystack:3.0.9

Each time I try to install Paystack:3.0.9 using the dependency: compile 'co.paystack.android:paystack:3.0.9' .
I am getting the error below:

Error:Execution failed for task ':app:processDebugResources'.

com.android.ide.common.process.ProcessException: Failed to execute aapt.

I am using android studio 2.3

"Please send Pin" error after I switched to the Live Key and Made a payment

Problem

Hello, I used the example codes to build my payment activity in such a way that once a payment is successful, it sends details to my server, the server verifies the payment and provides an input to my app, which uses that to perform some functions, That way I don't need to verify the payment on the app, that can be done on the server all I need to do is wait for the response after making a payment. This work perfectly with the test Key the test card gets charged, Both PIN and OTP are requested, and a payment notification is sent to my mail. But once I used a live key (I made a test account to develop the app. the live key is from another account currently running on a web platform and working) I still get the request for my card PIN and OTP and after I input that, i get an error saying "Please Send Pin" (also the live key is in both my codes and manifest) Below are my codes

Codes

public class BuyPowerActivity extends AppCompatActivity {


    private EditText mEditCardNum;
    private EditText mEditCVC;
    private EditText mEditExpiryAll;


    private Charge charge;
    private Transaction transaction;


    private CircularProgressButton mButtonPerformLocalTransaction;

    private static String newPid;
    private FirebaseDatabase mdata;
    private DocumentReference mDocRef;
    private int selectedprice;
    private String myFormattedPrice;
    private String selectedemail,date_created,time_created,uuid,phone,meternumber,location,acct_name,address;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_buy_power);

        //initialize sdk
        PaystackSdk.initialize(getApplicationContext());


        TextView priceget = findViewById(R.id.priceget);
        TextView getemail = findViewById(R.id.emailget);

        mButtonPerformLocalTransaction = findViewById(R.id.chargeid);
        mdata = FirebaseDatabase.getInstance();



        Intent receivedIntent = getIntent();
        selectedprice = receivedIntent.getIntExtra("price",0);
        selectedemail = receivedIntent.getStringExtra("email");
        date_created = receivedIntent.getStringExtra("date_created");
        time_created = receivedIntent.getStringExtra("time_created");
        uuid = receivedIntent.getStringExtra("uuid");
        phone = receivedIntent.getStringExtra("phone");
        meternumber = receivedIntent.getStringExtra("meternumber");
        location = receivedIntent.getStringExtra("location");
        acct_name = receivedIntent.getStringExtra("account_name");
        address = receivedIntent.getStringExtra("address");
        String defaultcNa = BuyPowerActivity.this.getResources().getString(R.string.currency);



        DecimalFormat decimalFormat = new DecimalFormat("#,###,###");


        myFormattedPrice = decimalFormat.format(selectedprice);
        String pricewithCurrency = defaultcNa+myFormattedPrice;
        priceget.setText(pricewithCurrency);
        getemail.setText(selectedemail);

        //Backend Url is only used for build Used but saved for test purposes
        String backend_url = "Backend URl is saved here";
        if (BuildConfig.DEBUG && (backend_url.equals(""))) {
            throw new AssertionError("Please set a backend url before running the sample");
        }
        String paystack_public_key = "My public key is saved here";
        if (BuildConfig.DEBUG && (paystack_public_key.equals(""))) {
            throw new AssertionError("Please set a public key before running the sample");
        }



        PaystackSdk.setPublicKey(paystack_public_key);

        mEditCardNum = findViewById(R.id.cardnum);
        mEditCVC = findViewById(R.id.cvcid);

        mEditExpiryAll = findViewById(R.id.date);

        mEditCardNum.addTextChangedListener(new CreditCardFormattingTextWatcher(mEditCardNum));


        mEditExpiryAll.addTextChangedListener(new CreditCardExpiryTextWatcher(mEditExpiryAll));






        mButtonPerformLocalTransaction.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View view) {


                if (!validateForm()) {
                    return;
                }else{
                    mButtonPerformLocalTransaction.startAnimation();
                    startAFreshCharge(true);
                }
            }
        });

    }

    private void startAFreshCharge(boolean local) {
        // initialize the charge

        if(loadCardFromForm().isValid()) {

            charge = new Charge();
            charge.setCard(loadCardFromForm());
        }



        if (local) {

            Intent receivedIntent = getIntent();

            int selectedprice = receivedIntent.getIntExtra("price", 0);
            String selectedemail = receivedIntent.getStringExtra("email");
            int selectedPriceWkobo = selectedprice*100;


            charge.setAmount(selectedPriceWkobo);
            charge.setEmail(selectedemail);
            //TODO: Intent now

            // charge.setReference("0MA0P" + Calendar.getInstance().getTimeInMillis());

            // this generates a transaction reference for me
            final DatabaseReference ref = mdata.getReference("firebase-generated-reference");
            final DatabaseReference outs = ref.push();
            String s = outs.getKey();

            newPid = s;
            charge.setReference(s);
            try {
                charge.putCustomField("Charged From", "Mobile App");
            } catch (JSONException e) {
                e.printStackTrace();
            }
            chargeCard();
        }
    }

    private Card loadCardFromForm() {
        //validate fields
        Card card;
        String cardNum = mEditCardNum.getText().toString().replaceAll("\\D", "");

        //build card object with ONLY the number, update the other fields later
        //card = new Card.Builder(cardNum, 0, 0, "").build();
        String cvc = mEditCVC.getText().toString().trim();
        //update the cvc field of the card
        // card.setCvc(cvc);

        //validate expiry month;
//        String sMonth = mEditExpiryMonth.getText().toString().trim();
        int month = 0;
        String n = mEditExpiryAll.getText().toString();
        String[] split = n.split("/");
        String firstsub = split[0];
        String secondsub = split[1];
        try {
            month = Integer.parseInt(firstsub);
        } catch (Exception ignored) {
        }

        // card.setExpiryMonth(month);

        //    String sYear = mEditExpiryYear.getText().toString().trim();
        int year = 0;
        try {
            year = Integer.parseInt(secondsub);
        } catch (Exception ignored) {
        }
        //  card.setExpiryYear(20+year);

        card = new Card(cardNum, month, 20+year, cvc);

        return card;
    }

    @Override
    public void onPause() {
        super.onPause();

    }

    private void chargeCard() {
        transaction = null;
        PaystackSdk.chargeCard(BuyPowerActivity.this, charge, new Paystack.TransactionCallback() {
            // This is called only after transaction is successful
            @Override
            public void onSuccess(Transaction transaction) {


                // Move to the other activity, to send reference of
                // Successful payment that will be verified on the server
                // and response received

            }


            @Override
            public void beforeValidate(Transaction transaction) {
                Toast.makeText(BuyPowerActivity.this, "before OTP: "+transaction.getReference(), Toast.LENGTH_LONG).show();
            }

            @Override
            public void onError(Throwable error, Transaction transaction) {


                if (error instanceof ExpiredAccessCodeException) {
                    BuyPowerActivity.this.startAFreshCharge(false);
                    BuyPowerActivity.this.chargeCard();
                    return;
                }

                mButtonPerformLocalTransaction.revertAnimation();

                if (transaction.getReference() != null) {
                    //
                    // This is where I get the "Please send Pin" error
                    //
                } else {
                    Toast.makeText(BuyPowerActivity.this, error.getMessage(), Toast.LENGTH_LONG).show();
                }
            }

        });
    }

    private boolean validateForm() {
        boolean valid = true;

        String cardnum = mEditCardNum.getText().toString();
        if (TextUtils.isEmpty(cardnum)) {
            mEditCardNum.setError("Required.");
            valid = false;
        } else {
            mEditCardNum.setError(null);
        }

        String cardcvc = mEditCVC.getText().toString();
        if (TextUtils.isEmpty(cardcvc)) {
            mEditCVC.setError("Required.");
            valid = false;
        } else {
            mEditCVC.setError(null);
        }

        String password = mEditExpiryAll.getText().toString();
        if (TextUtils.isEmpty(password)) {
            mEditExpiryAll.setError("Required.");
            valid = false;
        } else {
            mEditExpiryAll.setError(null);
        }


        return valid;
    }
}

Error trying to upgrade Paystack SDK 3.0.1 to 3.0.9.

Please i need help. I still see this error upgrading to paystack SDK 3.0.9. Even in 3.0.7.
Error:Execution failed for task ':app:processDebugResources'.

com.android.ide.common.process.ProcessException: Failed to execute aapt.

My app config:
minSdkVersion 16
targetSdkVersion 27
compileSdkVersion 27
buildToolsVersion "27.0.3"

Reasons for trying to upgrade

  1. card.validNumber() for card number always return false on any card number that is less than 19digits.
  2. When trying to test with 'PIN+PHONE+OTP validation', SDK doesn't show input screen for OTP on beforeValidate(Transaction transaction) after showing input screen for PIN and PHONE.
  3. Also what about PAY-BY-BANK if implemented in any SDK. I wish i can get this as it's in Paystack payment web pluggin.

Please i need help as soon as possible.
Thank you.

New SDK Update has no clear changelog and SDK breaks the application.

Problem/Motivation

(Why the issue was filed, steps to reproduce the problem, etc.)

Proposed resolution

(Description of the proposed solution, the rationale behind it, and workarounds for people who cannot use the patch.)

Transaction Class was moved out of a whole namespace and was not stated in the Changelog.Its really sad.

Project doesn't synch with build gradle dependency

Hi, please my project on Android studio has refused to sync when I added co.paystack.android:paystack:3.0.10...
The error is could not find common.jar
Am new to Android studio please assist.
Thanks

java.lang.NullPointerException:

Problem/Motivation

(Why the issue was filed, steps to reproduce the problem, etc.)

Proposed resolution

(Description of the proposed solution, the rationale behind it, and workarounds for people who cannot use the patch.)

Repeatable

Always|Sometimes|Specific conditions|Specific times

(If it is a bug, you are reporting lease specify:)

Steps to repeat: (Describe how the issue can be repeated by someone who is to work on it)

  1. Step 1
  2. Step 2
  3. ...

Expected Results:

(What you expected steps 1, 2 and 3 to give)

Actual Results:

(What is gave including any error messages, memory dump etc that can help)

How to make payment to Sub accounts using the Android SDK

Problem/Motivation

I have checked the android SDK doc, i cant see where Sub account payment is captured in it, does it mean it is not possible with the android SDK

Proposed resolution

I think the SDK should offer support for SubAccount payment.

Adding meta data to Charge

Problem

I can't currently add meta data to Charge details.

Proposed Solution

charge.setKey("key","value");

Usage

charge.setKey("cartId","123abc");

Compiling errors

I am presently having five error integrating the dependency. Number one is this and what is the solution
Error:In ForegroundView, unable to find attribute foreground

ExpiredAccessCodeException on all Verve test cards

Problem/Motivation

(Why the issue was filed, steps to reproduce the problem, etc.)
The card addition always throws an error of ExpiredAccessCodeException in the test environment.
I have gotten the access code from the http call to initiate a transaction from the server
Created a charge object like so:

@Override
    public void paystackAddCard(CreditCard card, String access_code) {
        Charge charge = new Charge();
        charge.setCard(new co.paystack.android.model.Card.Builder(
                card.getCardNumber(),
                card.getExpMonth(),
                card.getExpYear(),
                card.getSecurityCode()
        ).build());
        charge.setAccessCode(access_code);
        charge.setEmail(MyApplication.getUser().getEmail());
        view.callPaystackSdk(charge);

    }

Repeatable

Specific conditions: Happens just on Verve test cards

(If it is a bug, you are reporting lease specify:)
Bug

Steps to repeat

  1. Get access code from server
  2. Add card details in add card textfield 5060 6666 6666 6666 666
  3. Add the CVV and expiry as stated in https://developers.paystack.co/v1.0/docs/test-cards
  4. Call PaystackSdk.chargeCard

Expected Results:

Expected a success with transaction ID

Actual Results:

Error! Please try again: a894ea34063d41fcacb6a9d617318d1393922c7c

Code snippet to initiate transaction locally on Android

Problem/Motivation

I need a code snippet or sample project to initiate transaction on the SDK. The example on the repo only does the transaction on a backend server.

Proposed resolution

Some App may not have a backend server and the may only be one programmer who does not write web languages

Expected Results:

  1. A second Activity class within the example(sample) project that initiate a transaction on the SDK.
    That is a class within here: https://github.com/PaystackHQ/paystack-android/tree/master/example/src/main/java/co/paystack/example

Error: "Expected ':status' header not present" while processing CC payment.

Problem/Motivation

We faced an issue with PayStack integration into our Android app.
When we trying to make a payment using a credit card we see error "Expected ':status' header not present".

Processing of international Credit Cards is turned on for our account, we already processed several similar payments before.

SDK version used is 3.0.9

Proposed resolution

Help needed.

Repeatable

Always.
Appeared during last several days.

Steps to repeat: (Describe how the issue can be repeated by someone who is to work on it)

  1. We initialize a transaction at our backend, backend returns access_code - this is working without issues.
  2. We collecting information about user's Credit Card in the application.
  3. We using PayStack SDK's chargeCard function to process payment (with access_code and Credit Card information), but here we receiving an error "Expected ':status' header not present"

Expected Results:

Expectation to have processed payment.

Actual Results:

Error: "Expected ':status' header not present" while processing CC payment, in onError of function chargeCard.

unable to charge VISA card

Problem

When charge card is called by the sdk,it takes me to a webview then it fails with the below error .
Also note that i use this same card for pos,uber etc.
I attached an image of me intercepting the transaction and you can see that the values where sent correctly---its a shame it wasnt encrypted when i decided to pull it.....

I had to manually mask the card details since i am sharing it here!!!!
horridexperiece

"{"status":"error","message":"Transaction was blocked by the Payment Server because it did not pass all risk checks.","bank":"Access Bank"}"

Proposed resolution

why must a webview be used?
My app would be better off with a straight forward implementation.

Repeatable

Always

(If it is a bug, you are reporting lease specify:)

Steps to repeat: (Describe how the issue can be repeated by someone who is to work on it)

just a normal transaction with a visa card.(i will also come up with the verve card issue aswell.)

Expected Results:

Transaction should succeed or fail in a straight forward manner.
I had to dig too deep to find the issue,not good at all.

Actual Results:

I/System.out: what do we have here :: Transaction was blocked by the Payment Server because it did not pass all risk checks.
10-21 11:51:09.006 11138-11138/ng.com.sourcecard.aiki I/System.out: what do we have here22 :: {"status":"error","message":"Transaction was blocked by the Payment Server because it did not pass all risk checks.","bank":"Access Bank"}

**createToken method not found anymore** I need to send a token to the server as usually done with PaystackSdk.createToken(card, new Paystack.TokenCallback() { @Override public void onCreate(Token token) {} I guess it has been deprecated. Please is there a workaround for this?

Problem/Motivation

(Why the issue was filed, steps to reproduce the problem, etc.)

Proposed resolution

(Description of the proposed solution, the rationale behind it, and workarounds for people who cannot use the patch.)

Repeatable

Always|Sometimes|Specific conditions|Specific times

(If it is a bug, you are reporting lease specify:)

Steps to repeat: (Describe how the issue can be repeated by someone who is to work on it)

  1. Step 1
  2. Step 2
  3. ...

Expected Results:

(What you expected steps 1, 2 and 3 to give)

Actual Results:

(What is gave including any error messages, memory dump etc that can help)

Paystack Transaction Amount Conversion

We have successfully integrated Paystack sdk in Web, Android and iOS application. We are able to do successful transactions also. But we are getting one problem during transactions is that when we are sending the transaction amount it is getting divided by 100 for Nigerian currency ( Naira )

eg.
If we assign transaction amount as 3500 /-
then it is converted to 35 ₦

How to solve this? Any help will be appreciated.

SSL Error

I'm getting this error on android 4.4 devices:

javax.net.ssl.SSLHandshakeException: javax.net.ssl.SSLProtocolException: SSL handshake aborted: ssl=0x6241ddf0: Failure in SSL library, usually a protocol error
error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure (external/openssl/ssl/s23_clnt.c:741 0x5dfcf6fd:0x00000000)

I noticed the the transaction was logged on my paystack dashboard but I could not get response from the server due to the error.
I tested the app on 5.0 and above and it worked fine.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.