搜索插件、代码仓与 APP 分类

flutter_upi_india 封面
插件详情v1.0.1

flutter_upi_india

一个 Flutter 插件,可在 Android 和 iOS 上启动 UPI 支付应用,以实现 UPI 支付。

AndroidiOS
近 30 天下载
1530
喜欢数
13
Pub 分数
140

安装插件

flutter pub add flutter_upi_india

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

一个 Flutter 插件,可实现 Android 和 iOS 移动应用程序中的 UPI(统一支付接口)支付集成。它允许用户通过启动其设备上安装的默认 UPI 应用(如 Google Pay 或 PhonePe)来发起 UPI 支付。该插件通过最少的设置即可处理对 UPI 应用的深度链接,简化了支付流程。它支持 Android 和 iOS 平台,非常适合需要无缝数字交易的印度市场应用。

适合场景

  • 在电子商务应用中启用UPI支付
  • 将数字支付集成到本地服务平台
  • 通过UPI支持账单支付
  • 促进点对点资金转账
  • 在移动应用中添加即时支付选项

主要特点

  • 启动设备上的默认UPI应用
  • Android 和 iOS 的跨平台支持
  • 用于发起 UPI 支付的简单 API
  • 无需处理敏感支付数据
  • 适用于所有主流 UPI 应用,如 Google Pay、PhonePe

适合对象

  • 印度金融科技初创企业
  • 面向印度用户的移动应用
  • 电子商务和实用程序应用
  • 需要UPI集成的支付网关
  • 开发低代码支付解决方案的开发者

使用建议

  • 需要在用户设备上安装支持UPI的应用程序
  • 发布后对支付流程的控制有限
  • 取决于用户的UPI应用配置
  • 不适用于服务器端事务处理
  • 如果未将UPI应用设为默认应用,可能无法使用

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

flutter_upi_india

version

Curruntly Working in android only with some specific banks. Open for Query and Discussion.

Find installed UPI payment apps on your phone and make payments using any one of them.

Package implements UPI Deep Linking And Proximity Integration Specification.

Android iOS
Android Screen Capture IOS Screen Capture

Getting Started

Add this package to your flutter project's pubspec.yaml as a dependency as follows:

dependencies:
  ...
  flutter_upi_india: ^1.0.1

Import the package as follows:

import 'package:flutter_upi_india/flutter_upi_india.dart';
iOS configuration

In Runner/Info.plist add or modify the LSApplicationQueriesSchemes key so it includes custom query schemes shown as follows:

  <key>LSApplicationQueriesSchemes</key>
  <array>
    ...
    <string>freecharge</string>
    <string>gpay</string>
    <string>in.fampay.app</string>
    <string>lotza</string>
    <string>mobikwik</string>
    <string>paytm</string>
    <string>phonepe</string>
    <string>upi</string>
    <string>upibillpay</string>
    <string>whatsapp</string>
    ...
  </array>
Usage
Get list of installed apps
final List<ApplicationMeta> appMetaList = await UpiPay.getInstalledUpiApplications();

Filter for mandate-capable apps:

final List<ApplicationMeta> mandateApps =
    await UpiPay.getInstalledUpiApplications(isForMandateApps: true);
Show an app's details
Widget appWidget(ApplicationMeta appMeta) {
  return Column(
    mainAxisAlignment: MainAxisAlignment.center,
    children: <Widget>[
      appMeta.iconImage(48), // Logo
      Container(
        margin: EdgeInsets.only(top: 4),
        alignment: Alignment.center,
        child: Text(
          appMeta.application.getAppName(),
          textAlign: TextAlign.center,
        ),
      ),
    ],
  );
}
Do a UPI transaction
Future doUpiTransation(ApplicationMeta appMeta) {
  final UpiTransactionResponse response = await UpiPay.initiateTransaction(
    amount: '100.00',
    app: appMeta.application,
    receiverName: 'John Doe',
    receiverUpiAddress: 'john@doe',
    transactionRef: 'UPITXREF0001',
    transactionNote: 'A UPI Transaction',
     // merchantCode: '7372',
  );
  print(response.status);
}

Send a mandate request (uses upi://mandate):

Future doUpiMandate(ApplicationMeta appMeta) {
  return UpiPay.initiateTransaction(
    amount: '100.00',
    app: appMeta.application,
    receiverName: 'John Doe',
    receiverUpiAddress: 'john@doe',
    transactionRef: 'UPIMANDATE0001',
    transactionNote: 'UPI Mandate',
    isForMandate: true,
  );
}
Mandate parameters

Mandate requests can include additional parameters when isForMandate: true. Only non-null values are sent to the UPI app.

Future doUpiMandateWithParams(ApplicationMeta appMeta) {
  return UpiPay.initiateTransaction(
    amount: '250.00',
    app: appMeta.application,
    receiverName: 'Acme Subscriptions',
    receiverUpiAddress: 'acme@upi',
    transactionRef: 'UPIMANDATE0002',
    transactionNote: 'Monthly plan',
    isForMandate: true,
    // Mandate-specific parameters
    amountRule: 'MAX', // amrule
    blockFlag: 'Y', // block
    merchantName: 'ACME', // mn
    mode: 'UPI', // mode
    orgId: 'ACME001', // orgid
    purpose: '00', // purpose
    recurrence: 'MONTHLY', // recur
    recurrenceType: 'BEFORE', // recurtype
    recurrenceValue: '1', // recurvalue
    revocable: 'Y', // rev
    transactionId: 'TID12345', // tid
    txnType: 'CREATE', // txnType
    validityStart: '01012025', // validitystart
    validityEnd: '31122025', // validityend
  );
}

Mandate-capable apps can be filtered via UpiPay.getInstalledUpiApplications(isForMandateApps: true). Availability varies by app and platform, so verify with the target UPI app before production use.

Behaviour, Limitations & Measures

Android
Flow
  • On Android, the UPI Deep Linking And Proximity Integration Specification is implemented using Intents.
  • An Intent call with transaction request parameters includes the specific UPI app to be invoked.
  • Post the UPI transaction being processed by the chosen Android UPI app, it returns a response as per the format defined in the specification to the package's Android plugin layer.
  • The plugin layer parses this response to create a UpiTransactionResponse object that is returned to your calling code. This object clearly indicates the status of the UPI payment, i.e. was it successful, failed or being processed.
Measures

It is advised that you implement a server-side payment verification on top of this status reporting, to avoid being affected by any hacks in the UPI transaction workflow on client's phone.

iOS
Flow
  • On iOS, the UPI Deep Linking And Proximity Integration Specification is implemented using iOS custom schemes.
  • Each UPI payment app can listen to a payment request of the form upi://pay?... or upi://mandate?... sent by a caller app to iOS.
  • The specification does not let you specify the target app's identifier in this request. On iOS, there is no other disambiguation measure available such as any ordering of the UPI payment apps that can be retrieved using any iOS APIs. Hence, it's impossible to know which UPI payment app will be invoked.
  • One of the applicable apps gets invoked and it processes the payment. The custom schemes mechanism has no way to return a transaction status to your calling code. The calling code can only know if a UPI payment app was launched successfully or not.
How does the package then implement getInstalledUpiApps?

The apps that implement any other unique custom scheme other than upi are discovered using such custom schemes. In the list of returned apps, both the reliably discovered apps and the supported but undetectable apps are returned.

Your code can distinguish if an app in the list of discovered apps was detected or not by checking as follows:

bool isAppReallyDiscovered(ApplicationMeta applicationMeta) {
  return applicationMeta.application.discoveryCustomScheme != null
}
Measures
  • You will have to implement a payment verification on top of functionality available through this package.
  • You should distinguish discovered and supported-only apps using the mechanism in the above section. The example app can be used for reference.

UPI Apps' Functional Status Dynamics

UPI standards and systems are evolving, and accordingly behaviour and functionality of the UPI payment apps are changing. See Apps for details of current functional status of various applications that were verified by us.

Support for merchant and non-merchant payments

The UPI Deep Linking And Proximity Integration Specification is designed for merchant payments. It includes parameters in payment request that can be provided only if the payment was made to a merchant e.g. the merchant code (mc parameter), and a signature (crypto-hash) of the request created using merchant's private key.

However; various applications have been accepting requests without merchant details and signature and successfully processing payments. Possibly, the dilution could be due to the reason that such a package can only automate filling a payment form, and unless the user verifies the details in the form and enters the UPI pin, no damaging payments can be really made.

Over last few months, few applications have started changing their behaviour around non-merchant payments and one or more of the following are seen in few apps:

  • An implicit "unverified source" warning or a direct warning indicating that merchant data in the request is not correct
  • Z7 error, "Transaction Frequency Limit Exceeded": See UPI Error and Response Codes
  • U16 error, "Risk Threshold Exceeded", see UPI Error and Response Codes
  • An implicit "Security error"

This behaviour sometimes is not consistent even for the same app. For example, WhatsApp successfully completes transactions on iOS; but rejects non-merchant transactions on Android.

If you believe that your app's users' money is secure via their UPI pin, and you can let them use apps that successfully complete non-merchant transactions, then go ahead and pick the working apps in Apps and integrate this package.

Regressions

It's seen that post the Bank mergers of 2020-21 some of the bank apps have stopped working, even though they are still in Play Store and/or App Store.

iOS minimum versions

Several BHIM apps have stopped working on <iOS 13.5. This package's iOS support is verified on iPhone with iOS 14+.

Love to experiment yourself?

Default behaviour of the getInstalledUpiApps API is to give you only the completely successfully working UPI apps. You can make the package return other apps by passing relevant values for parameters of this API. Please see API documentation. To support this experimentation, we would add further tweaking to allow you to access UPI apps not seen and supported by this package shortly on Android.

Contributors ✨

This project follows the all-contributors specification. Contributions of any kind welcome and will be recognised!

Other related solutions

  • upi_india (repo) - Another solid flutter package for payment gateway free UPI integration. We often share issues faced / solution approaches and more. Go check them out as well!

所属分类

依赖

依赖清单 2 项

源码仓库

使用此插件的项目

暂无相关数据。