PayUMoney is one of the most trusted payment gateways which offers secure mobile payments. Executing PayUMoney Integration in Android is fast and easy albeit it may present you to some challenges.
Steps to Implement Seamless PayUMoney Android Integration Method:
- You first need to setup a test page with PayUMoney to initiate the integration. A test merchant account along with test credit card credentials will be given to experience the overall transaction flow. You first need to make a transaction request on PayUMoney’s test server. Once this is done, you can move to PayUMoney’s production server.
- Next step is to generate a ‘Post Request’ to initiate the transaction. This must have mandatory and optional parameters. The ‘Post Request’ needs to hit the PayUMoney URLs mentioned below:
- For PayU Test Server:
POST URL: https://test.payu.in/_payment - For PayU Production (LIVE) Server:
POST URL: https://secure.payu.in/_payment - One of the mandatory parameters in the merchant-initiated ‘Post Request’ is termed as hash. You need to calculate the hash correctly, which in most cases is critical.
- Once the transaction ‘Post Request’ hits the PayUMoney server, it creates a new transaction entry in the database. And to identify each new transaction in the database, a unique identifier is generated every time at PayUMoney’s end. The identifier that is created is called as the PayUMoney ID or MihPayID.
- The customer will now be redirected to PayUMoney’s payment page with the ‘Post Request’. The customer can select a particular payment option and click on ‘Pay Now’ button. PayUMoney then redirects the customer to the desired bank. Now they need to go through the authentication process on bank’s login page after which the bank gives the success or failure response to PayUMoney.
- On the basis of the response from the bank, PayUMoney marks the transaction status and provides the final transaction response string to the merchant via ‘Post Response’.
- Along with ‘Post Response,’ you will also receive the hash parameters. As mentioned in step 3, calculating the hash is critical. So you need to verify the hash value correctly at your end and then accept or reject the invoice order. This will help you avoid any tampering by the user and ensure a secure transaction experience.
PayUMoneyActivity.java
import android.app.ProgressDialog; import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.drawable.Drawable; import android.os.Bundle; import android.os.Handler; import android.support.v7.app.AlertDialog; import android.support.v7.app.AppCompatActivity; import android.util.Log; import android.view.LayoutInflater; import android.view.MenuItem; import android.view.View; import android.webkit.WebResourceError; import android.webkit.WebResourceRequest; import android.webkit.WebView; import android.webkit.WebViewClient; import android.widget.ImageView; import android.widget.Toast; import java.math.BigDecimal; import java.math.RoundingMode; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Collection; import java.util.HashMap; import java.util.Map; import java.util.Random; import java.util.Timer; import java.util.TimerTask; public class PayUMoneyActivity extends AppCompatActivity { WebView webView; Context activity; int mId; private String mMerchantKey = "marchent key";//For merchant and salt key you need to contact payu money tech support otherwise you get error private String mSalt = "salt key";//copy and paste works fine private String mBaseURL = "https://secure.payu.in/"; private String mAction = ""; // For Final URL private String mTXNId; // This will create below randomly private String mHash; // This will create below randomly private String mProductInfo = "Books"; // From Previous Activity private String mFirstName; // From Previous Activity private String mEmailId; // From Previous Activity private double mAmount; // From Previous Activity private String mPhone; // From Previous Activity private String mServiceProvider = "payu_paisa"; private String mSuccessUrl = "success url"; private String mFailedUrl = "failure url"; boolean isFromOrder; Handler mHandler = new Handler(); private String TAG = "User info"; private ProgressDialog progressDialog; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_payumoney); progressBarVisibilityPayuChrome(View.VISIBLE); webView = (WebView) findViewById(R.id.payumoney_webview); activity = getApplicationContext(); Bundle bundle = getIntent().getExtras(); if (bundle != null) { mFirstName = bundle.getString("name"); mEmailId = bundle.getString("email"); // mProductInfo = bundle.getString("productInfo"); mAmount = bundle.getDouble("amount");//in my case amount getting as String so i parse it double mPhone = bundle.getString("phone"); mId = bundle.getInt("id"); isFromOrder = bundle.getBoolean("isFromOrder"); Random rand = new Random(); String randomString = Integer.toString(rand.nextInt()) + (System.currentTimeMillis() / 1000L); mTXNId = hashCal("SHA-256", randomString).substring(0, 20); mAmount = new BigDecimal(mAmount).setScale(0, RoundingMode.UP).intValue(); mHash = hashCal("SHA-512", mMerchantKey + "|" + mTXNId + "|" + mAmount + "|" + mProductInfo + "|" + mFirstName + "|" + mEmailId + "|||||||||||" + mSalt); mAction = mBaseURL.concat("/_payment"); webView.setWebViewClient(new WebViewClient() { @Override public void onReceivedError(WebView view, WebResourceRequest request, WebResourceError error) { super.onReceivedError(view, request, error); Toast.makeText(activity, "Oh no! " + error, Toast.LENGTH_SHORT).show(); } @Override public boolean shouldOverrideUrlLoading(WebView view, String url) { return super.shouldOverrideUrlLoading(view, url); } @Override public void onPageStarted(WebView view, String url, Bitmap favicon) { super.onPageStarted(view, url, favicon); } @Override public void onPageFinished(WebView view, String url) { if (url.equals(mSuccessUrl)) { Intent intent = new Intent(PayUMoneyActivity.this, PaymentStatusActivity.class); intent.putExtra("firstname", mFirstName + "(" + mEmailId + ")"); intent.putExtra("transaction_id", mTXNId); intent.putExtra("productinfo", mProductInfo); intent.putExtra("status", "Payment Successfully... "); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } else if (url.equals(mFailedUrl)) { Intent intent = new Intent(PayUMoneyActivity.this, PaymentStatusActivity.class); intent.putExtra("firstname", mFirstName + "(" + mEmailId + ")"); intent.putExtra("transaction_id", mTXNId); intent.putExtra("status", "Payment Failed..."); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); startActivity(intent); finish(); } new Handler().postDelayed(new Runnable() { @Override public void run() { progressBarVisibilityPayuChrome(View.GONE); } }, 10000); super.onPageFinished(view, url); } }); webView.setVisibility(View.VISIBLE); webView.getSettings().setBuiltInZoomControls(true); webView.getSettings().setDomStorageEnabled(true); webView.clearHistory(); webView.clearCache(true); webView.getSettings().setJavaScriptEnabled(true); webView.getSettings().setSupportZoom(true); webView.getSettings().setUseWideViewPort(false); webView.getSettings().setLoadWithOverviewMode(false); webView.addJavascriptInterface(new PayUJavaScriptInterface(PayUMoneyActivity.this), "PayUMoney"); Map<String, String> mapParams = new HashMap<>(); mapParams.put("key", mMerchantKey); mapParams.put("txnid", mTXNId); mapParams.put("amount", String.valueOf(mAmount)); mapParams.put("productinfo", mProductInfo); mapParams.put("firstname", mFirstName); mapParams.put("email", mEmailId); mapParams.put("phone", mPhone); mapParams.put("surl", mSuccessUrl); mapParams.put("furl", mFailedUrl); mapParams.put("hash", mHash); mapParams.put("service_provider", mServiceProvider); webViewClientPost(webView, mAction, mapParams.entrySet()); } else { Toast.makeText(activity, "Something went wrong, Try again.", Toast.LENGTH_LONG).show(); } } public void webViewClientPost(WebView webView, String url, Collection<Map.Entry<String, String>> postData) { StringBuilder sb = new StringBuilder(); sb.append("<html><head></head>"); sb.append("<body onload='form1.submit()'>"); sb.append(String.format("<form id='form1' action='%s' method='%s'>", url, "post")); for (Map.Entry<String, String> item : postData) { sb.append(String.format("<input name='%s' type='hidden' value='%s' />", item.getKey(), item.getValue())); } sb.append("</form></body></html>"); Log.d("TAG", "webViewClientPost called: " + sb.toString()); webView.loadData(sb.toString(), "text/html", "utf-8"); } public String hashCal(String type, String str) { byte[] hashSequence = str.getBytes(); StringBuffer hexString = new StringBuffer(); try { MessageDigest algorithm = MessageDigest.getInstance(type); algorithm.reset(); algorithm.update(hashSequence); byte messageDigest[] = algorithm.digest(); for (int i = 0; i < messageDigest.length; i++) { String hex = Integer.toHexString(0xFF & messageDigest[i]); if (hex.length() == 1) hexString.append("0"); hexString.append(hex); } } catch (NoSuchAlgorithmException NSAE) { } return hexString.toString(); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (item.getItemId() == android.R.id.home) { onPressingBack(); } return super.onOptionsItemSelected(item); } @Override public void onBackPressed() { onPressingBack(); } private void onPressingBack() { final Intent intent; if (isFromOrder) intent = new Intent(PayUMoneyActivity.this, MyJavahome.class); else intent = new Intent(PayUMoneyActivity.this, MyJavahome.class); intent.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); AlertDialog.Builder alertDialog = new AlertDialog.Builder(PayUMoneyActivity.this); alertDialog.setTitle("Warning"); alertDialog.setMessage("Do you cancel this transaction?"); alertDialog.setPositiveButton("Yes", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { finish(); startActivity(intent); } }); alertDialog.setNegativeButton("No", new DialogInterface.OnClickListener() { public void onClick(DialogInterface dialog, int which) { dialog.dismiss(); } }); alertDialog.show(); } public class PayUJavaScriptInterface { Context mContext; PayUJavaScriptInterface(Context c) { mContext = c; } public void success(long id, final String paymentId) { mHandler.post(new Runnable() { public void run() { mHandler = null; Toast.makeText(PayUMoneyActivity.this, "Payment Successfully.", Toast.LENGTH_SHORT).show(); Intent intent = new Intent(PayUMoneyActivity.this, PaymentStatusActivity.class); intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP | Intent.FLAG_ACTIVITY_SINGLE_TOP); intent.putExtra("result", "success"); intent.putExtra("paymentId", paymentId); startActivity(intent); finish(); } }); } } public void progressBarVisibilityPayuChrome(int visibility) { if (getApplicationContext() != null && !isFinishing()) { if (visibility == View.GONE || visibility == View.INVISIBLE) { if (progressDialog != null && progressDialog.isShowing()) progressDialog.dismiss(); } else if (progressDialog == null || !progressDialog.isShowing()) { progressDialog = showProgress(this); } } } public ProgressDialog showProgress(Context context) { if (getApplicationContext() != null && !isFinishing()) { LayoutInflater mInflater = LayoutInflater.from(context); final Drawable[] drawables = {getResources().getDrawable(R.drawable.image1), getResources().getDrawable(R.drawable.image2), getResources().getDrawable(R.drawable.image3), getResources().getDrawable(R.drawable.image4) }; View layout = mInflater.inflate(R.layout.prog_dialog, null); final ImageView imageView; imageView = (ImageView) layout.findViewById(R.id.imageView); ProgressDialog progDialog = new ProgressDialog(context); final Timer timer = new Timer(); timer.scheduleAtFixedRate(new TimerTask() { int i = -1; @Override synchronized public void run() { runOnUiThread(new Runnable() { @Override public void run() { i++; if (i >= drawables.length) { i = 0; } imageView.setImageBitmap(null); imageView.destroyDrawingCache(); imageView.refreshDrawableState(); imageView.setImageDrawable(drawables[i]); } }); } }, 0, 500); progDialog.setOnDismissListener(new DialogInterface.OnDismissListener() { @Override public void onDismiss(DialogInterface dialog) { timer.cancel(); } }); progDialog.show(); progDialog.setContentView(layout); progDialog.setCancelable(true); progDialog.setCanceledOnTouchOutside(false); return progDialog; } return null; } }
activity_payumoney.xml
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/r_layout"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal"> <FrameLayout
android:id="@+id/parent"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:visibility="gone" /> <WebView android:id="@+id/payumoney_webview"
android:layout_width="match_parent"
android:layout_height="match_parent" /> </RelativeLayout>
Comments
Post a Comment