Stripe is one of the most widely used payment gateways currently. It is also one of the best for developers because it allows very easy and smooth integration of code in multiple languages. Here we are going to look at accepting stripe payments in an Android app.
It is assumed that there is already a stripe account available for integration. If not then you can sign up for a free Stripe account and use it in test mode.
CONCEPTS
Before we look at the code, a few concepts need to be understood .
API Keys
Stripe can run in two modes – Live and Test mode. Test mode is useful while testing integration or for any scenario which allows you to test payment integration without actually charging live credit cards. When in test mode, Stripe has some predefined card numbers to use, as shown below. You can use these numbers with any CVC/CVV number and any expiry month/year set in the future.

For API integration, Stripe provides two keys – one Public and one Private. These can be found in your Stripe account settings. The Public key will have the prefix of pk and the Private Key will have the prefix of sk . You will have different pairs of Public/Private keys for Test mode and Live Mode.
So if you are going to use the Stripe gateway in Test mode then use the Test keys , otherwise use the Live keys.
Customer
A Customer Entity in Stripe is the person who makes payments into the account.
Card
A Card entity contains the credit card details of a Customer. A Customer may have multiple Cards.
Charge
An actual payment made in Stripe is called a Charge. A Charge is always linked to a Card and a Customer.
There are more entities in Stripe like Subscription, Plans, Coupons etc. but here we are just dealing with a simple payment, so we will not look into the advanced concepts.
PROCESS
In the sample code, the following logic is in place.
1.Create a Card entity in Stripe
2.Create a Customer entity
3.Create a Charge entity and link it with the Card and Customer entity.
Each of these entities returns a unique id which has to be handled by your backend code. For instance, in your database you should store the Stripe customer id, so that the next time this customer does a payment you can retrieve the Customer Entity from Stripe and then do a Charge, instead of creating a duplicate Customer entity again.
You can do a similar thing for the Card. A Card entity returns a Card token which can be stored and reused in your code. The advantage of this is that the actual card details are stored securely in Stripe and you can use the card token to tell Stripe which card to use.
Note that amounts are to be sent in the lowest currency denomination. Eg. if you are using USD and the amount to be charged is $50.00 then the amount should not be sent to Stripe as 50.00 but 50*100 cents which is 5000 .
THE APPLICATION
For your app to use the Stripe Android library, you need to link
'com.stripe:stripe-android'
This is shown in the build.gradle listing below.
We have a single Activity screen which takes in the payment details, validates the data and then updates Stripe with the transaction details.
LISTINGS
build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.3"
defaultConfig {
applicationId "stripe.test.com.stripetest"
minSdkVersion 19
targetSdkVersion 23
versionCode 1
versionName "1.0"
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
}
}
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
testCompile 'junit:junit:4.12'
compile 'com.android.support:appcompat-v7:23.4.0'
compile 'com.android.support:design:23.4.0'
compile 'com.stripe:stripe-android:+'
}
Android.Manifest
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="stripe.test.com.stripetest">
<uses-sdk
android:minSdkVersion="19"
android:targetSdkVersion="23" />
<uses-permission android:name="android.permission.INTERNET" />
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:theme="@style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout 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"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
app:layout_behavior="@string/appbar_scrolling_view_behavior"
android:orientation="vertical"
tools:context="stripe.test.com.stripetest.MainActivity"
>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="10dp">
<TextView
android:id="@+id/textStripeLabel"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
android:text="Transaction Details"
android:textAllCaps="false"
android:textAlignment="center"
android:textSize="@dimen/font_size_medium"
android:textStyle="bold"
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/sharp_rectangle_border"
android:layout_marginBottom="20dp">
<EditText
android:id="@+id/editStripeCardNumber1"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.20"
android:padding="5dp"
android:singleLine="true"
android:hint="XXXX"
android:inputType="number"
android:maxLength="4"
android:textColor="#000000"
android:textCursorDrawable="@null"/>
<EditText
android:id="@+id/editStripeCardNumber2"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.20"
android:padding="5dp"
android:singleLine="true"
android:hint="XXXX"
android:inputType="number"
android:maxLength="4"
android:textColor="#000000"
android:textCursorDrawable="@null"/>
<EditText
android:id="@+id/editStripeCardNumber3"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.20"
android:padding="5dp"
android:singleLine="true"
android:hint="XXXX"
android:inputType="number"
android:maxLength="4"
android:textColor="#000000"
android:textCursorDrawable="@null"/>
<EditText
android:id="@+id/editStripeCardNumber4"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.20"
android:padding="5dp"
android:singleLine="true"
android:hint="XXXX"
android:inputType="number"
android:maxLength="4"
android:textColor="#000000"
android:textCursorDrawable="@null"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="20dp">
<EditText
android:id="@+id/editStripeCVV"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.15"
android:padding="5dp"
android:hint="CVC"
android:maxLength="3"
android:singleLine="true"
android:inputType="number"
android:background="@drawable/sharp_rectangle_border"
android:textColor="#000000"
android:layout_marginRight="10dp"
android:textCursorDrawable="@null"/>
<LinearLayout
android:layout_width="0dp"
android:layout_weight="0.80"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:padding="5dp"
android:background="@drawable/sharp_rectangle_border"
>
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.20"
android:text="MM/YYYY"
android:textAllCaps="true"
android:textSize="@dimen/font_size_small"
/>
<Spinner
android:layout_width="0dp"
android:padding="2dp"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:id="@+id/spinnerStripeExpMonth"
android:layout_marginRight="5dp"
/>
<Spinner
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.25"
android:padding="2dp"
android:id="@+id/spinnerStripeExpYear"
/>
</LinearLayout>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="10dp">
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:background="@drawable/sharp_rectangle_border"
android:layout_marginBottom="10dp">
<TextView
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.60"
android:text="$"
android:layout_gravity="end"
android:textAlignment="textEnd"
android:textSize="@dimen/font_size_medium"
android:textAllCaps="true"
/>
<EditText
android:id="@+id/editStripeAmount"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="0.35"
android:padding="2dp"
android:editable="true"
android:inputType="numberDecimal"
android:singleLine="true"
android:textAlignment="textEnd"
android:textSize="@dimen/font_size_medium"
android:textColor="#000000"
android:textCursorDrawable="@null"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="10dp">
<EditText
android:id="@+id/editCustName"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:editable="true"
android:singleLine="true"
android:hint="Customer Name"
android:textSize="@dimen/font_size_small"
android:textColor="#000000"
android:textCursorDrawable="@null"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="10dp">
<EditText
android:id="@+id/editCustEmail"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:editable="true"
android:inputType="textEmailAddress"
android:singleLine="true"
android:hint="Customer Email"
android:textSize="@dimen/font_size_small"
android:textColor="#000000"
android:textCursorDrawable="@null"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="10dp">
<EditText
android:id="@+id/editCustAddress"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:editable="true"
android:singleLine="true"
android:hint="Customer Address"
android:textSize="@dimen/font_size_small"
android:textColor="#000000"
android:textCursorDrawable="@null"/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="10dp">
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginTop="5dp">
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Cancel"
android:id="@+id/btnStripeCancel"
android:layout_weight="0.45"
android:onClick="showInvoices"
/>
<View
android:layout_width="0dp"
android:layout_height="0dp"
android:layout_weight="0.10" />
<Button
style="?android:attr/buttonStyleSmall"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Save"
android:id="@+id/btnStripeSave"
android:layout_weight="0.45"
android:onClick="doPayment"
/>
</LinearLayout>
<LinearLayout
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:layout_marginBottom="10dp">
<TextView
android:id="@+id/textStripeMode"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_weight="1"
android:layout_gravity="center_horizontal"
android:text=""
android:textAllCaps="true"
android:textAlignment="center"
android:textSize="@dimen/font_size_small"
/>
</LinearLayout>
</LinearLayout>
drawable/sharp_rectangle_border.xml
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<shape android:shape="rectangle">
<solid android:color="#d4d4d4"/>
<corners android:radius="0dp" />
</shape>
</item>
<item
android:left="1dp"
android:right="1dp"
android:top="1dp"
android:bottom="1dp">
<shape android:shape="rectangle">
<solid android:color="@android:color/white"/>
<corners android:radius="0dp" />
</shape>
</item>
</layer-list>
values/dimens.xml
<resources>
<!-- Default screen margins, per the Android Design guidelines. -->
<dimen name="activity_horizontal_margin">16dp</dimen>
<dimen name="activity_vertical_margin">16dp</dimen>
<!-- Per the design guidelines, navigation drawers should be between 240dp and 320dp:
https://developer.android.com/design/patterns/navigation-drawer.html -->
<dimen name="navigation_drawer_width">240dp</dimen>
<dimen name="font_size_verysmall">10sp</dimen>
<dimen name="font_size_small">12sp</dimen>
<dimen name="font_size_average">14sp</dimen>
<dimen name="font_size_medium">20sp</dimen>
<dimen name="font_size_large">30sp</dimen>
<dimen name="font_size_verylarge">50sp</dimen>
</resources>
MainActivity.java
package stripe.test.com.stripetest;
import android.app.ProgressDialog;
import android.os.AsyncTask;
import android.os.Bundle;
import android.support.design.widget.FloatingActionButton;
import android.support.design.widget.Snackbar;
import android.support.v7.app.AppCompatActivity;
import android.support.v7.widget.Toolbar;
import android.text.Editable;
import android.text.TextWatcher;
import android.view.View;
import android.view.Menu;
import android.view.MenuItem;
import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.Spinner;
import android.widget.Toast;
import com.stripe.android.Stripe;
import com.stripe.android.TokenCallback;
import com.stripe.android.model.Card;
import com.stripe.android.model.Token;
import com.stripe.exception.AuthenticationException;
import com.stripe.exception.CardException;
import com.stripe.model.Charge;
import com.stripe.model.Customer;
import com.stripe.net.RequestOptions;
import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.Map;
public class MainActivity extends AppCompatActivity {
ProgressDialog mProgressBar;
private String mStripeCardToken;
private String mPublicKey = "";
private String mPrivateKey = "";
private Token mToken;
private Stripe mStripe = null;
private String mStripeCustId;
private boolean mCustWasAdded = false;
private String mCustomerName;
private String mCustomerEmail;
private String mCustomerAddress;
private BigDecimal mAmount;
private String mTxnRef;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mProgressBar = new ProgressDialog(this);
// populate spinners
String []months = new String[12];
for (int i =1; i <=12; i++) {
String val = "";
if (i < 10)
val = "0";
months[i-1] = val + String.valueOf(i);
}
Spinner s = (Spinner) findViewById(R.id.spinnerStripeExpMonth);
ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, months);
s.setAdapter(adapter);
String []years = new String[12];
for (int i =1; i <=12; i++) {
years[i-1] = String.valueOf(i+2015);
}
Spinner s2 = (Spinner) findViewById(R.id.spinnerStripeExpYear);
ArrayAdapter<String> adapter2 = new ArrayAdapter<String>(this,
android.R.layout.simple_spinner_item, years);
s2.setAdapter(adapter2);
// set auto jump to next field for CC entry
EditText card1 = (EditText)findViewById(R.id.editStripeCardNumber1);
card1.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
EditText card1 = (EditText) findViewById(R.id.editStripeCardNumber1);
if (card1.getText().toString().length() == 4) {
EditText card2 = (EditText) findViewById(R.id.editStripeCardNumber2);
card2.requestFocus();
}
}
});
EditText card2 = (EditText)findViewById(R.id.editStripeCardNumber2);
card2.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
EditText card2 = (EditText)findViewById(R.id.editStripeCardNumber2);
if (card2.getText().toString().length() == 4) {
EditText card3 = (EditText)findViewById(R.id.editStripeCardNumber3);
card3.requestFocus();
}
}
});
EditText card3 = (EditText)findViewById(R.id.editStripeCardNumber3);
card3.addTextChangedListener(new TextWatcher() {
@Override
public void beforeTextChanged(CharSequence s, int start, int count, int after) {
}
@Override
public void onTextChanged(CharSequence s, int start, int before, int count) {
}
@Override
public void afterTextChanged(Editable s) {
EditText card3 = (EditText) findViewById(R.id.editStripeCardNumber3);
if (card3.getText().toString().length() == 4) {
EditText card4 = (EditText) findViewById(R.id.editStripeCardNumber4);
card4.requestFocus();
}
}
});
// set stripe key values
// this info would actually come from another place in the app or from the backend. I am just putting hardcoded values here
mPublicKey = "pk_test_apikey_comes_here";
mPrivateKey = "sk_test_apikey_comes_here";
// if you already have the customer details and have his stripe customer id, then this is the time to retrieve and
// assign it to mStripeCustId
}
@Override
public boolean onCreateOptionsMenu(Menu menu) {
// Inflate the menu; this adds items to the action bar if it is present.
getMenuInflater().inflate(R.menu.menu_main, menu);
return true;
}
@Override
public boolean onOptionsItemSelected(MenuItem item) {
// Handle action bar item clicks here. The action bar will
// automatically handle clicks on the Home/Up button, so long
// as you specify a parent activity in AndroidManifest.xml.
int id = item.getItemId();
//noinspection SimplifiableIfStatement
if (id == R.id.action_settings) {
return true;
}
return super.onOptionsItemSelected(item);
}
public void doPayment(View view) {
boolean isValid = true;
Spinner s = (Spinner) findViewById(R.id.spinnerStripeExpMonth);
Spinner s2 = (Spinner) findViewById(R.id.spinnerStripeExpYear);
String cardNumber = "";
EditText textCard1 = (EditText) findViewById(R.id.editStripeCardNumber1);
EditText textCard2 = (EditText) findViewById(R.id.editStripeCardNumber2);
EditText textCard3 = (EditText) findViewById(R.id.editStripeCardNumber3);
EditText textCard4 = (EditText) findViewById(R.id.editStripeCardNumber4);
cardNumber = textCard1.getText().toString();
cardNumber += textCard2.getText().toString();
cardNumber += textCard3.getText().toString();
cardNumber += textCard4.getText().toString();
EditText textAmount = (EditText) findViewById(R.id.editStripeAmount);
EditText textName = (EditText) findViewById(R.id.editCustName);
EditText textEmail = (EditText) findViewById(R.id.editCustEmail);
EditText textAddress = (EditText) findViewById(R.id.editCustAddress);
try {
mAmount = new BigDecimal(Double.parseDouble(textAmount.getText().toString()));
} catch (NumberFormatException nex) {
Toast.makeText(getApplicationContext(), "Invalid amount entered", Toast.LENGTH_LONG).show();
isValid = false;
return;
}
if (cardNumber.length() < 16) {
Toast.makeText(getApplicationContext(), "Card number looks invalid", Toast.LENGTH_LONG).show();
isValid = false;
return;
}
EditText textCVV = (EditText) findViewById(R.id.editStripeCVV);
if (textCVV.getText().toString().length() < 3) {
Toast.makeText(getApplicationContext(), "CVC looks invalid", Toast.LENGTH_LONG).show();
isValid = false;
return;
}
int month = Integer.parseInt(s.getSelectedItem().toString());
int year = Integer.parseInt(s2.getSelectedItem().toString());
Card card = new Card(cardNumber, month, year, textCVV.getText().toString());
if ( !card.validateCard() ) {
Toast.makeText(getApplicationContext(), "Credit card validation failed!", Toast.LENGTH_LONG).show();
isValid = false;
return;
}
mCustomerAddress = textAddress.getText().toString();
mCustomerEmail = textEmail.getText().toString();
mCustomerName = textName.getText().toString();
mProgressBar.setCancelable(false);
mProgressBar.setMessage("Validating payment..");
mProgressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressBar.show();
if (mStripeCardToken == null || mStripeCardToken.equals("")) {
try {
mStripe = new Stripe(mPublicKey);
mStripe.createToken(
card,
new TokenCallback() {
public void onSuccess(Token token) {
mProgressBar.hide();
mToken = token;
mStripeCardToken = mToken.getId();
checkCustomerStatus();
}
public void onError(Exception error) {
mProgressBar.hide();
// Show localized error message
Toast.makeText(getApplicationContext(),
error.getMessage(),
Toast.LENGTH_LONG
).show();
return;
}
}
);
} catch (AuthenticationException aex) {
Toast.makeText(getApplicationContext(), aex.getMessage(), Toast.LENGTH_LONG).show();
}
} else {
checkCustomerStatus();
}
}
void checkCustomerStatus() {
if (mStripeCustId == null || mStripeCustId.equals("")) {
mProgressBar.setCancelable(false);
mProgressBar.setMessage("Adding customer to stripe account..");
mProgressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressBar.show();
new CheckCustomerTask().execute(0);
} else {
chargeTransaction();
}
}
private void chargeTransaction() {
mProgressBar.setCancelable(false);
mProgressBar.setMessage("Charging credit card..");
mProgressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressBar.show();
new MakeChargeTask().execute(0);
}
public void savePayment() {
// this is where you update the payment to your backend servers or database
// and then take the user to the next screen
Toast.makeText(getApplicationContext(), "Payment has been updated.", Toast.LENGTH_LONG).show();
}
public void updateCustomer() {
mProgressBar.setCancelable(false);
mProgressBar.setMessage("Updating customer details..");
mProgressBar.setProgressStyle(ProgressDialog.STYLE_SPINNER);
mProgressBar.show();
new UpdateCustomerTask().execute(0);
}
//////////////////////////////////////////////////////////////////////////////
//
// The params are dummy and not used
//
class UpdateCustomerTask extends AsyncTask<Integer, Integer, String> {
String mError = null;
@Override
protected String doInBackground(Integer... params) {
try {
// update the customer data in your backend or database
Thread.sleep(200);
} catch (InterruptedException iex) {}
return "Task Completed.";
}
@Override
protected void onPostExecute(String result) {
mProgressBar.hide();
if (mError != null && mError != "")
Toast.makeText(getApplicationContext(), mError, Toast.LENGTH_LONG).show();
else {
chargeTransaction();
}
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Integer... values) {
}
}
//////////////////////////////////////////////////////////////////////////////
//
// The params are dummy and not used
//
class CheckCustomerTask extends AsyncTask<Integer, Integer, String> {
String mError = null;
@Override
protected String doInBackground(Integer... params) {
String mError = "";
try {
if (mStripe == null)
mStripe = new Stripe(mPublicKey);
RequestOptions requestOptions = (new RequestOptions.RequestOptionsBuilder()).setApiKey(mPrivateKey).build();
Map<String, Object> customerParams = new HashMap<String, Object>();
customerParams.put("description", mCustomerName);
customerParams.put("email", mCustomerEmail);
customerParams.put("source", mStripeCardToken); // obtained with Stripe
Customer cust = Customer.create(customerParams, requestOptions);
mCustWasAdded = true;
mStripeCustId = cust.getId();
} catch (Exception cx) {
mError = cx.getMessage();
}
return "Task Completed.";
}
@Override
protected void onPostExecute(String result) {
mProgressBar.hide();
if (mError != null && mError != "")
Toast.makeText(getApplicationContext(), mError, Toast.LENGTH_LONG).show();
else {
if (mCustWasAdded)
updateCustomer();
else
chargeTransaction();
}
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Integer... values) {
}
}
//////////////////////////////////////////////////////////////////////////////
//
// The params are dummy and not used
//
class MakeChargeTask extends AsyncTask<Integer, Integer, String> {
String mError = null;
@Override
protected String doInBackground(Integer... params) {
DecimalFormat decimalFormat = new DecimalFormat("0.00");
String sAmount = decimalFormat.format(mAmount);
sAmount = sAmount.replace(".", "");
// Create the charge on Stripe's servers - this will charge the user's card
try {
if (mStripe == null)
mStripe = new Stripe(mPublicKey);
RequestOptions requestOptions = (new RequestOptions.RequestOptionsBuilder()).setApiKey(mPrivateKey).build();
Map<String, Object> chargeParams = new HashMap<String, Object>();
chargeParams.put("amount", Integer.parseInt(sAmount)); // amount in cents, again
chargeParams.put("currency", "usd");
chargeParams.put("customer", mStripeCustId);
chargeParams.put("description", "Payment description will come here");
Charge charge = Charge.create(chargeParams, requestOptions);
mTxnRef = charge.getId();
} catch (Exception e) {
// The card has been declined
mError = e.getMessage();
}
return "Task Completed.";
}
@Override
protected void onPostExecute(String result) {
mProgressBar.hide();
if (mError != null && mError != "")
Toast.makeText(getApplicationContext(), mError, Toast.LENGTH_LONG).show();
else {
savePayment();
}
}
@Override
protected void onPreExecute() {
}
@Override
protected void onProgressUpdate(Integer... values) {
}
}
}
SCREENSHOTS
App Screen

Stripe Transaction Details

Stripe Customer Details

how to integrate stripe on android?please provide me a latest article.