Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

UPI Payment Gateway using Android Deep Link

Is there any working sample to integrate UPI payment gateway using Android Deep Link. I went through NPCI specifications and implemented it with no success. Transaction is not getting completed.

protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);
        Console.WriteLine("Request Code:" + requestCode);
    }

    private void RunUPI(string MobileNo)
    {
        var UPIUri = Android.Net.Uri.Parse("upi://pay?pa=xxx@xxxx&pn=xxxxxx&mc=null&tid=null&tr=test101&tn=This%20is%20test%20payment&am=10&mam=null&cu=INR&url=null");
        Intent intent = new Intent();
        intent.SetAction(Intent.ActionView);
        intent.SetData(UPIUri);
        var activities = PackageManager.QueryIntentActivities(intent, PackageInfoFlags.MatchDefaultOnly);
        var isIntentSafe = activities.Count > 0;
        if (true == isIntentSafe)
        {
            var chooser = Intent.CreateChooser(intent, "Pay With");
            chooser.SetFlags(ActivityFlags.NewTask);
            // Verify the intent will resolve to at least one activity
            if (chooser.ResolveActivity(PackageManager) != null)
            {
                txnUPIRequestCode = 0;
                StartActivityForResult(chooser, txnUPIRequestCode);
            }
        }
    }
like image 983
Manikandan Avatar asked Mar 01 '18 02:03

Manikandan


1 Answers

The problem in your case is not related to UPI but how Android manages Activity results and Intents.

You cannot use the Intent.FLAG_ACTIVITY_NEW_TASK if the caller (in this case your Activity) is requesting a result from the activity being launched (the UPI PSP in this case). [source]

So a simple solution would be to simply create the Uri and launch the Intent without the flag. In java that would look like:

private void launchUPI(){
  // look below for a reference to these parameters
  Uri uri = Uri.parse("upi://pay").buildUpon()
    .appendQueryParameter("pa", "xxx@xxxxx")
    .appendQueryParameter("pn", "XYZXYZ")
    .appendQueryParameter("tn", "Pay for in-app purchase")
    .appendQueryParameter("am", "20")
    .appendQueryParameter("cu", "INR")
    .build();

  Intent upiPayIntent = new Intent(Intent.ACTION_VIEW);
  upiPayIntent.setData(uri);

  Intent chooser = Intent.createChooser(upiPayIntent, "Pay with");

  if(null != chooser.resolveActivity(getPackageManager())) {
    Log.d(TAG, "UPI Payment resolved to activity");
    startActivityForResult(chooser, REQ_UPIPAYMENT);
  } else {
    Log.d(TAG, "No activity found to handle UPI Payment");
  }
}

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);

  if(REQ_UPIPAYMENT == requestCode){
    if(RESULT_OK == resultCode){
      Log.d(TAG, "UPI Payment successfull");
    } else {
      Log.d(TAG, "UPI Payment failed");
    }
  }
}

As far the request parameters are concerned, following is a simple reference that I got from the UPI DeepLinking Specificication page.

  • pa: UPI Virtual address of the payee (the one who receives the payment)
  • pn: Name of the payee. Can be name of merchant or store.
  • tn: Transaction note. A simple description of the transaction, like, payment for in-app items, bill payments, etc.
  • am: Monetary amount of transaction in decimal format.
  • cu: Currency used in the transaction. Currently only INR is supported.

Using the above parameters, you can create a payment request static mode to the PSP app (apps like PayTM or bank applications).

To create a payment request in dynamic mode, you also need to add the following:

  • tr: Transaction reference. Your internal reference to the transaction in your system.

UPDATE 1

As the OP mentioned in the comments, to get back the response from the PSP app, like, transaction id, etc. we can use the Intent passed in the onActivityResult() when RESULT_OK == resultCode.

@Override protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  super.onActivityResult(requestCode, resultCode, data);

  if(REQ_UPIPAYMENT == requestCode){
    if(RESULT_OK == resultCode){
      Log.d(TAG, "UPI Payment successfull");
      String transId = data.getStringExtra("response");
    } else {
      Log.d(TAG, "UPI Payment failed");
    }
  }
}
like image 170
riyaz-ali Avatar answered Nov 09 '22 22:11

riyaz-ali