问题描述
这就是我想要做的。我的应用有两种类型的用户-买方和卖方。卖方可以提供自己的UPI ID,而买方可以使用设备上安装的任何UPI应用程序,使用提供的卖方UPI ID向卖方付款。
我正在构建如下的UPI付款URL:
String upiPaymentUrl = upi://pay?pa=<<Seller VPA ID>>&pn=<<Payee name>>&tn=<<Txn description>>&cu=INR
Intent intent = new Intent(Intent.ACTION_VIEW);
intent.setData(Uri.parse(upiPaymentUrl));
Intent chooser = Intent.createChooser(intent,getString(R.string.payment_title));
startActivityForResult(chooser,Constant.REQUEST_CODE_UPIPAYMENT,null);
启动选定的UPI应用程序,并正确填充我在URI中给出的所有数据。然后,我开始付款,但付款始终失败。当我按原样使用UPI应用程序(不从我的应用程序调用)并使用与构造UPI URL相同的值时,付款会顺利进行。知道从我的应用程序调用UPI应用程序时可能导致付款失败的原因吗?
任何帮助/建议将不胜感激!
解决方法
通过Intent启动付款时,您需要签署Intent。
请参阅本文档中带有黄色标记的部分:https://web.archive.org/web/20200921110005/https://www.npci.org.in/sites/default/files/UPI%20Linking%20Specs_ver%201.6.pdf
原始URL似乎已失效,但被包括Google在内的多个来源引用。
这将导致如下所示:
Uri uri =
new Uri.Builder()
.scheme("upi")
.authority("pay")
.appendQueryParameter("pa","your-merchant-vpa@xxx")
.appendQueryParameter("pn","your-merchant-name")
.appendQueryParameter("mc","your-merchant-code")
.appendQueryParameter("tr","your-transaction-ref-id")
.appendQueryParameter("tn","your-transaction-note")
.appendQueryParameter("am","your-order-amount")
.appendQueryParameter("cu","INR")
.build();
// Sign the uri as specified
String signature = someSignatureFunction(uri);
uri.buildUpon()
.appendQueryParameter("sign",signature);
此外,参数mode
和orgid
对于Intent创建的付款似乎不是可选的。
我不太确定您要完成什么。但是由于我所看到的API并非旨在用于处理“用户到用户”付款,因此我将验证您正在做的事情是否实际上被允许/可能进行。您可能无法签署未定向到您公司的交易,从而使这不可能。
进一步加强这一点,为了对Intent进行签名,您需要加密,该加密通常在这种系统中(在此类系统中)在您控制的服务器上进行,以进行反向工程并因此伪造付款。
免责声明:我对UPI没有任何经验,因此此答案主要基于猜测,未经测试。我建议发布之前在UPI上查找更多资源。
我发现了一些其他资源:
-
在npci主页上单击“开发人员”时,会链接
- infinit.co.in。
- https://infinit.co.in/Solutions/UPI/product_doc.pdf-5.11解释了已签署的意图概念及其通常的工作原理
- https://www.npci.org.in/what-we-do/upi/product-overview-UPI产品官方页面,找不到太多有用的信息
这是我的用例。我有一个市场应用程序,买卖双方都在此进行注册。卖家列出他们的产品。买家提供购买产品的报价。卖方提供UPI信息(UPI ID或“多合一” QR码)。买方使用卖方通过应用提供的UPI信息来开始付款。
一种方法是将自己注册为NCPI(infinit.co.in)的独立开发人员,然后申请使用UPI。我还不知道完整的过程,因为我一直无法访问UPI(!)。我的假设是,一旦允许访问,您就可以在UPI基础结构中注册私钥。要启动付款,请创建UPI深度链接URL,如下所示。
upi:// pay?pa = &pn = &tn = &cu = INR
使用您的应用附带的公共密钥对此进行签名。如@JensV所述,UPI开发人员文档中提供了要签署的规范。
现在,如果您不想执行上述任何操作,可以使用哪些选项?我看到两种选择:一种是要求卖方提供其UPI ID,然后在您的应用程序中允许买方将卖方UPI ID复制到剪贴板上,这样他们便可以打开任何UPI付款应用程序(GPay,Paytm等)并粘贴发起付款时的UPI ID。另一种简洁的方法是要求卖方获得“多合一”商人QR码。使用任何一个库(有很多)扫描QR码,您将获得一个“签名的” UPI URL(大部分时间)。现在,您要做的就是使用Intent通过此“签名” URL启动UPI应用程序。通过这种方法,我可以使用GPay(!)以外的所有应用执行付款。
更多信息-如果您无法获取已签名的UPI URL,则仍然可以使用上述原始UPI URL。只有使用发行人的UPI应用程序才能成功付款。即,如果您使用的UPI ID的发行者是HDFC银行,则使用“未签名”的UPI URL,您可以调用HDFC移动银行应用程序并进行付款。它将永远成功。
如果我能够向UPI注册为开发人员并能够注册我的私钥,则我将更新此线程以解释该过程。
,根据 NPCI 的新规则,所有 upi 应用程序绑定最小交易。
如果收款人upi id注册为非商业upiid,则无法成功支付。
所以解决方案是创建新的业务 UPI id。