Integrating PayPal Payments In an Android Application
Posted By : Keshav Gupta | 09-Feb-2018
PayPal is an international acclaimed payment gateway that supports payment across the globe.The user can go for payment using PayPal account and can use its debit credit card.Now I am going to explain how we can go for PayPal enabled the android application.
Server Side Configuration:
Step1.Create an application at PayPal site and get your
https://developer.paypal.com/developer/accounts/
Application Side Configuration :
Step1: We will first need to integrate PayPal SDK in android application.For this, we need to add the following dependency in app/build.gradle
dependencies { compile 'com.paypal.sdk:paypal-android-sdk:2.14.3' }
Step2: We need to declare following payments upholding screens in AndroidManifest.xml.So that SDK can pick relevant screen when required from payment initialization to payment completion.We will be declaring some CardIoActivity to accept card payment.It will be like
<service android:name="com.paypal.android.sdk.payments.PayPalService" android:exported="false" /> <activity android:name="com.paypal.android.sdk.payments.PaymentActivity" /> <activity android:name="com.paypal.android.sdk.payments.LoginActivity" /> <activity android:name="com.paypal.android.sdk.payments.PaymentMethodActivity" /> <activity android:name="com.paypal.android.sdk.payments.PaymentConfirmActivity" /> <activity android:name="com.paypal.android.sdk.payments.PayPalFuturePaymentActivity" /> <activity android:name="com.paypal.android.sdk.payments.FuturePaymentConsentActivity" /> <activity android:name="com.paypal.android.sdk.payments.FuturePaymentInfoActivity" /> <activity android:name="com.paypal.android.sdk.payments.PayPalProfileSharingActivity" /> <activity android:name="com.paypal.android.sdk.payments.ProfileSharingConsentActivity" /> <activity android:name="io.card.payment.CardIOActivity" android:configChanges="keyboardHidden|orientation" /> <activity android:name="io.card.payment.DataEntryActivity" />
Step3: We will config PayPal environment.For that, we will put it in Sandbox.Then we will declare clientId created above.Note that It should be from sandbox account.
Step4: Then we will define requestCode for payment,
Step5: We will further wrap the whole configuration using PayPal wrapper class named as PayPalConfiguration by instantiating it.
private static final String TAG = "PayPalPaymentExample"; // sample price value private float totalPrice=100; //private static final String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_NO_NETWORK; private static final String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_SANDBOX; // private static final String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_PRODUCTION; // Development COnfig Paypal private static final String CONFIG_CLIENT_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //Live Config Paypal // private static final String CONFIG_CLIENT_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; private static final int REQUEST_PAY_PAYMENT = 1; private static final int REQUEST_PAY_FUTURE_PAYMENT = 2; private static final int REQUEST_PAY_PROFILE_SHARING = 3; private static PayPalConfiguration paypalConfig = new PayPalConfiguration() .environment(CONFIG_ENVIRONMENT) .clientId(CONFIG_CLIENT_ID) .merchantName("Sample Paypal") .merchantPrivacyPolicyUri(Uri.parse("https://www.example.com/privacy")) .merchantUserAgreementUri(Uri.parse("https://www.example.com/legal"));
Step6: Then we will initiate PayPal service to communicate with PayPal server by this code in onCreate() method of activity class
Step7: Then activity class will be having button view to initiate PayPal interface.
@Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.subscription_upgradeplans); Intent intent = new Intent(this,PayPalService.class); intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, paypalConfig); startService(intent); Button button=new Button(this); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); if (netInfo != null && netInfo.isConnectedOrConnecting()) { // code to initiate paypal user interface loading screen PayPalPayment thingToBuy = getThingToBuy(PayPalPayment.PAYMENT_INTENT_SALE); Intent intent = new Intent(PaypalConfigurationActivity.this,PaymentActivity.class); // send the same configuration for restart resiliency intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, paypalConfig); intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy); startActivityForResult(intent, REQUEST_PAY_PAYMENT); } else { Toast.makeText(PaypalConfigurationActivity.this,"Internet available",Toast.LENGTH_SHORT).show(); } } }); }
Step8: There will be one more method which will work like wrap what to buy context which will return PayPalPayment object
private PayPalPayment getThingToBuy(String paymentIntent) { return new PayPalPayment(new BigDecimal(totalPrice), "EUR", "sample item", paymentIntent); }
Step9: Finally we will be having payment callback code which will give success or failure token based on that we will verify our payment to our local server through a REST API call.As PayPal will return a
@Override protected void onActivityResult(int request, int result, Intent paydata) { if (request == REQUEST_PAY_PAYMENT) { if (result == Activity.RESULT_OK) { PaymentConfirmation confirmations = paydata.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION); if (confirmations != null) { try { String paymentId = confirmations.toJSONObject().getJSONObject("response").getString("id"); String state = confirmations.toJSONObject().getJSONObject("response").getString("state"); String payment_client = confirmations.getPayment().toJSONObject().toString(); if(paymentId!=null){ if(!paymentId.equalsIgnoreCase("")) { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); if (netInfo != null && netInfo.isConnectedOrConnecting()) { // api call to update local server for payment confirmation } else { Toast.makeText(PaypalConfigurationActivity.this,"Internet available",Toast.LENGTH_SHORT).show(); } } } } catch (JSONException e) { Log.e("tag", "failure occurred: ", e); Toast.makeText(getApplicationContext(), "PaymentConfirmation info received from PayPal", Toast.LENGTH_LONG).show(); } } } else if (result == Activity.RESULT_CANCELED) { Log.i(TAG, "payment is cancelled by user"); } else { Log.i(TAG, "invalid configurations submitted"); } } }
Step10: Final code for this class we
package com.sirius.activity; import android.app.Activity; import android.content.Context; import android.content.Intent; import android.net.ConnectivityManager; import android.net.NetworkInfo; import android.net.Uri; import android.os.Bundle; import android.support.annotation.Nullable; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.View; import android.widget.Button; import android.widget.Toast; import com.paypal.android.sdk.payments.PayPalConfiguration; import com.paypal.android.sdk.payments.PayPalPayment; import com.paypal.android.sdk.payments.PayPalService; import com.paypal.android.sdk.payments.PaymentActivity; import com.paypal.android.sdk.payments.PaymentConfirmation; import com.sirius.R; import org.json.JSONException; import java.math.BigDecimal; import java.text.SimpleDateFormat; import java.util.Calendar; /** * Created by keshav on 9/2/18. */ public class PaypalConfigurationActivity extends AppCompatActivity { private static final String TAG = "PayPalPaymentExample"; // sample price value private float totalPrice=100; //private static final String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_NO_NETWORK; private static final String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_SANDBOX; // private static final String CONFIG_ENVIRONMENT = PayPalConfiguration.ENVIRONMENT_PRODUCTION; // Development COnfig Paypal private static final String CONFIG_CLIENT_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; //Live Config Paypal // private static final String CONFIG_CLIENT_ID = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"; private static final int REQUEST_PAY_PAYMENT = 1; private static final int REQUEST_PAY_FUTURE_PAYMENT = 2; private static final int REQUEST_PAY_PROFILE_SHARING = 3; private static PayPalConfiguration paypalConfig = new PayPalConfiguration() .environment(CONFIG_ENVIRONMENT) .clientId(CONFIG_CLIENT_ID) .merchantName("Sample Paypal") .merchantPrivacyPolicyUri(Uri.parse("https://www.example.com/privacy")) .merchantUserAgreementUri(Uri.parse("https://www.example.com/legal")); @Override protected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.subscription_upgradeplans); Intent intent = new Intent(this,PayPalService.class); intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, paypalConfig); startService(intent); Button button=new Button(this); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); if (netInfo != null && netInfo.isConnectedOrConnecting()) { // code to initiate paypal user interface loading screen PayPalPayment thingToBuy = getThingToBuy(PayPalPayment.PAYMENT_INTENT_SALE); Intent intent = new Intent(PaypalConfigurationActivity.this,PaymentActivity.class); // send the same configuration for restart resiliency intent.putExtra(PayPalService.EXTRA_PAYPAL_CONFIGURATION, paypalConfig); intent.putExtra(PaymentActivity.EXTRA_PAYMENT, thingToBuy); startActivityForResult(intent, REQUEST_PAY_PAYMENT); } else { Toast.makeText(PaypalConfigurationActivity.this,"Internet available",Toast.LENGTH_SHORT).show(); } } }); } private PayPalPayment getThingToBuy(String paymentIntent) { return new PayPalPayment(new BigDecimal(totalPrice), "EUR", "sample item", paymentIntent); } @Override protected void onActivityResult(int request, int result, Intent paydata) { if (request == REQUEST_PAY_PAYMENT) { if (result == Activity.RESULT_OK) { PaymentConfirmation confirmations = paydata.getParcelableExtra(PaymentActivity.EXTRA_RESULT_CONFIRMATION); if (confirmations != null) { try { String paymentId = confirmations.toJSONObject().getJSONObject("response").getString("id"); String state = confirmations.toJSONObject().getJSONObject("response").getString("state"); String payment_client = confirmations.getPayment().toJSONObject().toString(); if(paymentId!=null){ if(!paymentId.equalsIgnoreCase("")) { ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); NetworkInfo netInfo = cm.getActiveNetworkInfo(); if (netInfo != null && netInfo.isConnectedOrConnecting()) { // api call to update local server for payment confirmation } else { Toast.makeText(PaypalConfigurationActivity.this,"Internet available",Toast.LENGTH_SHORT).show(); } } } } catch (JSONException e) { Toast.makeText(getApplicationContext(), "PaymentConfirmation info received from PayPal", Toast.LENGTH_LONG).show(); } } } else if (result == Activity.RESULT_CANCELED) { Log.i(TAG, "payment is cancelled by user"); } else { Log.i(TAG, "invalid configurations submitted"); } } } }
Note: When you are going to put your application into production.You need to change your config environment to Production and ConfigClientId to
That's all you have to do.
Cookies are important to the proper functioning of a site. To improve your experience, we use cookies to remember log-in details and provide secure log-in, collect statistics to optimize site functionality, and deliver content tailored to your interests. Click Agree and Proceed to accept cookies and go directly to the site or click on View Cookie Settings to see detailed descriptions of the types of cookies and choose whether to accept certain cookies while on the site.
About Author
Keshav Gupta
Keshav Gupta is Android Developer in Oodles, he always look forward for new tasks and new things to learn more.