1

这就是我想要做的。我的应用有两种类型的用户——买家和卖家。卖家可以提供他们的 UPI ID,买家可以使用其设备上安装的任何 UPI 应用程序使用提供的卖家 UPI ID 向卖家付款。

我正在构建一个 UPI 支付 URL,如下所示:

String upiPaymentUrl = upi://pay?pa=<<Seller VPA ID>>&pn=<<Payee name>>&tn=<<Txn description>>&cu=INR

然后,我使用以下代码显示手机上所有启用 UPI 的应用程序:

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 应用程序时,知道是什么导致付款失败吗?

任何帮助/建议将不胜感激!

4

3 回答 3

2

根据 NPCI 的新规则,所有 upi 应用都绑定了最小交易。

如果receiver upi id 注册为非商业upiid,则无法成功支付。

所以解决方案是创建新的业务 UPI id。

于 2021-04-03T13:44:57.190 回答
1

所以这是我的用例。我有一个市场应用程序,买卖双方都在其中注册。卖家列出他们的产品。买家提议购买产品。卖家提供UPI信息(UPI ID或“一体式”二维码)。买方使用卖方通过应用程序提供的 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 码,您将获得一个“签名”的 UPI URL(大部分时间)。现在您所要做的就是使用 Intent 使用这个“签名”的 URL 启动 UPI 应用程序。使用这种方法,我可以使用除 GPay(!) 之外的所有应用程序进行支付。

更多信息 - 如果您无法获得签名的 UPI URL,您仍然可以使用上面提到的原始 UPI URL。只有使用发行人的 UPI 应用程序才能成功付款。即如果您使用的UPI ID 的发行者是HDFC 银行,那么使用“未签名”UPI URL 您可以调用HDFC 手机银行应用程序并进行支付。它总会成功的。

如果我能够以开发者身份在 UPI 注册并能够注册我的私钥,我将更新此线程以解释该过程。

于 2020-11-07T10:34:05.357 回答
0

当您通过 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);

此外,对于 Intent 创建的付款,参数modeorgid似乎是非可选的。


我不太确定您要完成什么。但是,由于我所看到的 API 并非旨在用于处理“用户对用户”付款,因此我将验证您所做的事情是否实际上是允许/可能的。您可能无法签署不针对您公司的交易,因此这不可能。

进一步执行这一点,为了签署您需要加密的意图,通常(在此类系统中)发生在您控制的服务器上以进行逆向工程并因此伪造付款。

免责声明:我对 UPI 没有经验,因此这个答案主要是基于猜测而不是经过测试。我建议在发布之前在 UPI 上查找更多资源。


我发现的其他一些资源:

于 2020-11-03T17:02:26.590 回答