├── ios ├── Assets │ └── .gitkeep ├── Resources │ └── PrivacyInfo.xcprivacy ├── .gitignore ├── upi_pay.podspec └── Classes │ └── UpiPayPlugin.swift ├── doc └── api │ ├── categories.json │ ├── static-assets │ ├── favicon.png │ ├── play_button.svg │ ├── readme.md │ └── github.css │ ├── __404error.html │ └── upi_pay │ ├── UpiPay │ └── UpiPay.html │ ├── UpiTransactionStatus │ └── toString.html │ ├── ApplicationMeta │ ├── packageName.html │ ├── upiApplication.html │ ├── priority.html │ ├── ApplicationMeta.ios.html │ └── preferredOrder.html │ ├── UpiApplicationDiscoveryAppStatusType │ └── toString.html │ ├── UpiApplicationDiscoveryAppPaymentType │ └── toString.html │ ├── UpiTransactionResponse │ ├── status.html │ ├── txnId.html │ ├── txnRef.html │ ├── rawResponse.html │ ├── launchError.html │ ├── responseCode.html │ ├── approvalRefNo.html │ └── UpiTransactionResponse.iosError.html │ └── upi_pay-library.html ├── android ├── settings.gradle ├── gradle │ └── wrapper │ │ └── gradle-wrapper.properties ├── .gitignore ├── build.gradle └── src │ └── main │ └── AndroidManifest.xml ├── example ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ └── xcshareddata │ │ │ └── xcschemes │ │ │ └── Runner.xcscheme │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── .gitignore │ ├── Podfile.lock │ └── Podfile ├── android │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── drenther │ │ │ │ │ │ └── upi_pay_example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle.properties │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── build.gradle │ └── settings.gradle ├── .metadata ├── pubspec.yaml ├── README.md ├── test │ └── widget_test.dart ├── Podfile └── .gitignore ├── .gitignore ├── assets └── apps │ └── ios │ ├── com.mobikwik.png │ ├── money.bullet.png │ ├── com.UBI.BHIMUPI.png │ ├── com.one97.paytm.png │ ├── in.cointab.app.png │ ├── kvb.app.upiapp.png │ ├── com.freecharge.ios.png │ ├── com.google.paisa.png │ ├── com.vijayabank.UPI.png │ ├── com.phonepe.PhonePeApp.png │ ├── net.whatsapp.WhatsApp.png │ ├── com.jkbank.bhimjkbankupi.png │ ├── com.upi.federalbank.org.lotza.png │ ├── com.truesoftware.TrueCallerOther.png │ └── com.ausmallfinancebank.aupay.bhimupi.png ├── lib ├── upi_pay.dart ├── types │ ├── exceptions.dart │ ├── discovery.dart │ ├── transaction_details.dart │ ├── meta.dart │ └── response.dart └── src │ ├── platform_interface.dart │ ├── method_channel.dart │ └── transaction.dart ├── .github ├── PULL_REQUEST_TEMPLATE.md └── ISSUE_TEMPLATE │ ├── feature_request.md │ └── bug_report.md ├── pubspec.yaml ├── LICENSE ├── .metadata ├── upi_pay.iml ├── CHANGELOG.md ├── test └── upi_pay_test.dart └── APPS.md /ios/Assets/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /doc/api/categories.json: -------------------------------------------------------------------------------- 1 | [] 2 | -------------------------------------------------------------------------------- /android/settings.gradle: -------------------------------------------------------------------------------- 1 | rootProject.name = 'upi_pay' 2 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .dart_tool/ 3 | .idea/ 4 | .packages 5 | .pub/ 6 | build/ 7 | .vscode 8 | -------------------------------------------------------------------------------- /assets/apps/ios/com.mobikwik.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.mobikwik.png -------------------------------------------------------------------------------- /assets/apps/ios/money.bullet.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/money.bullet.png -------------------------------------------------------------------------------- /doc/api/static-assets/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/doc/api/static-assets/favicon.png -------------------------------------------------------------------------------- /assets/apps/ios/com.UBI.BHIMUPI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.UBI.BHIMUPI.png -------------------------------------------------------------------------------- /assets/apps/ios/com.one97.paytm.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.one97.paytm.png -------------------------------------------------------------------------------- /assets/apps/ios/in.cointab.app.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/in.cointab.app.png -------------------------------------------------------------------------------- /assets/apps/ios/kvb.app.upiapp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/kvb.app.upiapp.png -------------------------------------------------------------------------------- /assets/apps/ios/com.freecharge.ios.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.freecharge.ios.png -------------------------------------------------------------------------------- /assets/apps/ios/com.google.paisa.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.google.paisa.png -------------------------------------------------------------------------------- /assets/apps/ios/com.vijayabank.UPI.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.vijayabank.UPI.png -------------------------------------------------------------------------------- /assets/apps/ios/com.phonepe.PhonePeApp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.phonepe.PhonePeApp.png -------------------------------------------------------------------------------- /assets/apps/ios/net.whatsapp.WhatsApp.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/net.whatsapp.WhatsApp.png -------------------------------------------------------------------------------- /assets/apps/ios/com.jkbank.bhimjkbankupi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.jkbank.bhimjkbankupi.png -------------------------------------------------------------------------------- /assets/apps/ios/com.upi.federalbank.org.lotza.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.upi.federalbank.org.lotza.png -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /assets/apps/ios/com.truesoftware.TrueCallerOther.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.truesoftware.TrueCallerOther.png -------------------------------------------------------------------------------- /assets/apps/ios/com.ausmallfinancebank.aupay.bhimupi.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/assets/apps/ios/com.ausmallfinancebank.aupay.bhimupi.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx4G -XX:MaxMetaspaceSize=2G -XX:+HeapDumpOnOutOfMemoryError 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/drenther/upi_pay/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/drenther/upi_pay_example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.drenther.upi_pay_example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig" 3 | #include "Generated.xcconfig" 4 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip 7 | -------------------------------------------------------------------------------- /android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | distributionBase=GRADLE_USER_HOME 2 | distributionPath=wrapper/dists 3 | distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-all.zip 4 | networkTimeout=10000 5 | validateDistributionUrl=true 6 | zipStoreBase=GRADLE_USER_HOME 7 | zipStorePath=wrapper/dists 8 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /doc/api/static-assets/play_button.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: cc949a8e8b9cf394b9290a8e80f87af3e207dce5 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /doc/api/static-assets/readme.md: -------------------------------------------------------------------------------- 1 | # highlight.js 2 | 3 | Generated from https://highlightjs.org/download/ on 2021-03-07 4 | 5 | **Included languages:** 6 | 7 | * bash 8 | * c 9 | * css 10 | * dart 11 | * html, xml 12 | * java 13 | * javascript 14 | * json 15 | * kotlin 16 | * markdown 17 | * objective-c 18 | * plaintext 19 | * shell 20 | * swift 21 | * yaml 22 | -------------------------------------------------------------------------------- /android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | .kotlin/sessions 9 | 10 | # Remember to never publicly share your keystore. 11 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 12 | key.properties 13 | **/*.keystore 14 | **/*.jks 15 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | .kotlin/sessions 9 | 10 | # Remember to never publicly share your keystore. 11 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 12 | key.properties 13 | **/*.keystore 14 | **/*.jks 15 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | allprojects { 2 | repositories { 3 | google() 4 | mavenCentral() 5 | } 6 | } 7 | 8 | rootProject.buildDir = "../build" 9 | subprojects { 10 | project.buildDir = "${rootProject.buildDir}/${project.name}" 11 | } 12 | subprojects { 13 | project.evaluationDependsOn(":app") 14 | } 15 | 16 | tasks.register("clean", Delete) { 17 | delete rootProject.buildDir 18 | } 19 | -------------------------------------------------------------------------------- /ios/Resources/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyTrackingDomains 6 | 7 | NSPrivacyAccessedAPITypes 8 | 9 | NSPrivacyCollectedDataTypes 10 | 11 | NSPrivacyTracking 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @main 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /lib/upi_pay.dart: -------------------------------------------------------------------------------- 1 | export 'package:upi_pay/api.dart' show UpiPay; 2 | export 'package:upi_pay/types/applications.dart' show UpiApplication; 3 | export 'package:upi_pay/types/response.dart' 4 | show UpiTransactionResponse, UpiTransactionStatus; 5 | export 'package:upi_pay/types/meta.dart' show ApplicationMeta; 6 | export 'package:upi_pay/types/discovery.dart' 7 | show 8 | UpiApplicationDiscoveryAppStatusType, 9 | UpiApplicationDiscoveryAppPaymentType; 10 | -------------------------------------------------------------------------------- /lib/types/exceptions.dart: -------------------------------------------------------------------------------- 1 | class _UpiException implements Exception { 2 | String message; 3 | 4 | _UpiException(this.message); 5 | 6 | @override 7 | String toString() => this.message; 8 | } 9 | 10 | class InvalidUpiAddressException extends _UpiException { 11 | InvalidUpiAddressException([String? msg]) 12 | : super(msg ?? 'Invalid UPI Address'); 13 | } 14 | 15 | class InvalidAmountException extends _UpiException { 16 | InvalidAmountException(String msg) : super(msg); 17 | } 18 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Changes in this PR: 2 | 3 | - briefly describe the changes in the PR 4 | - list changes in list form to ease review process 5 | 6 | ### Motive / Approach 7 | 8 | Shortly explain the motive and approach behind your solution. Feel free to drop links to references 9 | 10 | ### Reference GitHub Issues: 11 | 12 | List related Github issues (if any) 13 | 14 | ### Related Screenshots: 15 | 16 | Provide updated Example screenshots if needed. (don't forget to update in README as well) 17 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: upi_pay_example 2 | description: Demonstrates how to use the upi_pay plugin. 3 | publish_to: "none" # Remove this line if you wish to publish to pub.dev 4 | version: 1.1.0 5 | 6 | environment: 7 | sdk: ">=3.5.4" 8 | flutter: ">=3.24.5" 9 | 10 | dependencies: 11 | cupertino_icons: ^1.0.8 12 | flutter: 13 | sdk: flutter 14 | upi_pay: 15 | path: ../ 16 | 17 | dev_dependencies: 18 | integration_test: 19 | sdk: flutter 20 | flutter_test: 21 | sdk: flutter 22 | flutter_lints: ^4.0.0 23 | 24 | flutter: 25 | uses-material-design: true 26 | -------------------------------------------------------------------------------- /ios/.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | .vagrant/ 3 | .sconsign.dblite 4 | .svn/ 5 | 6 | .DS_Store 7 | *.swp 8 | profile 9 | 10 | DerivedData/ 11 | build/ 12 | GeneratedPluginRegistrant.h 13 | GeneratedPluginRegistrant.m 14 | 15 | .generated/ 16 | 17 | *.pbxuser 18 | *.mode1v3 19 | *.mode2v3 20 | *.perspectivev3 21 | 22 | !default.pbxuser 23 | !default.mode1v3 24 | !default.mode2v3 25 | !default.perspectivev3 26 | 27 | xcuserdata 28 | 29 | *.moved-aside 30 | 31 | *.pyc 32 | *sync/ 33 | Icon? 34 | .tags* 35 | 36 | /Flutter/Generated.xcconfig 37 | /Flutter/ephemeral/ 38 | /Flutter/flutter_export_environment.sh -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # upi_pay_example 2 | 3 | Demonstrates how to use the upi_pay plugin. 4 | 5 | ## Getting Started 6 | 7 | This project is a starting point for a Flutter application. 8 | 9 | A few resources to get you started if this is your first Flutter project: 10 | 11 | - [Lab: Write your first Flutter app](https://flutter.dev/docs/get-started/codelab) 12 | - [Cookbook: Useful Flutter samples](https://flutter.dev/docs/cookbook) 13 | 14 | For help getting started with Flutter, view our 15 | [online documentation](https://flutter.dev/docs), which offers tutorials, 16 | samples, guidance on mobile development, and a full API reference. 17 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | **/dgph 2 | *.mode1v3 3 | *.mode2v3 4 | *.moved-aside 5 | *.pbxuser 6 | *.perspectivev3 7 | **/*sync/ 8 | .sconsign.dblite 9 | .tags* 10 | **/.vagrant/ 11 | **/DerivedData/ 12 | Icon? 13 | **/Pods/ 14 | **/.symlinks/ 15 | profile 16 | xcuserdata 17 | **/.generated/ 18 | Flutter/App.framework 19 | Flutter/Flutter.framework 20 | Flutter/Flutter.podspec 21 | Flutter/Generated.xcconfig 22 | Flutter/ephemeral/ 23 | Flutter/app.flx 24 | Flutter/app.zip 25 | Flutter/flutter_assets/ 26 | Flutter/flutter_export_environment.sh 27 | ServiceDefinitions.json 28 | Runner/GeneratedPluginRegistrant.* 29 | 30 | # Exceptions to above rules. 31 | !default.mode1v3 32 | !default.mode2v3 33 | !default.pbxuser 34 | !default.perspectivev3 35 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: upi_pay 2 | description: A flutter plugin to launch UPI payment applications on Android and 3 | iOS towards making UPI payments. 4 | version: 1.1.0 5 | 6 | homepage: https://github.com/drenther/upi_pay 7 | 8 | environment: 9 | sdk: ">=3.5.4 <4.0.0" 10 | flutter: ">=3.24.5" 11 | 12 | dependencies: 13 | decimal: ^3.0.2 14 | flutter: 15 | sdk: flutter 16 | plugin_platform_interface: ^2.1.8 17 | universal_io: ^2.2.2 18 | 19 | dev_dependencies: 20 | flutter_test: 21 | sdk: flutter 22 | 23 | flutter: 24 | plugin: 25 | platforms: 26 | android: 27 | package: com.drenther.upi_pay 28 | pluginClass: UpiPayPlugin 29 | ios: 30 | pluginClass: UpiPayPlugin 31 | assets: 32 | - assets/apps/ios/ 33 | -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - integration_test (0.0.1): 4 | - Flutter 5 | - upi_pay (1.0.0): 6 | - Flutter 7 | 8 | DEPENDENCIES: 9 | - Flutter (from `Flutter`) 10 | - integration_test (from `.symlinks/plugins/integration_test/ios`) 11 | - upi_pay (from `.symlinks/plugins/upi_pay/ios`) 12 | 13 | EXTERNAL SOURCES: 14 | Flutter: 15 | :path: Flutter 16 | integration_test: 17 | :path: ".symlinks/plugins/integration_test/ios" 18 | upi_pay: 19 | :path: ".symlinks/plugins/upi_pay/ios" 20 | 21 | SPEC CHECKSUMS: 22 | Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 23 | integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 24 | upi_pay: a7d6fab40381ea9b2f9f8d56da43829926ce1ff0 25 | 26 | PODFILE CHECKSUM: 0db4cc7016905767245764f5296317024ac37827 27 | 28 | COCOAPODS: 1.16.2 29 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | pluginManagement { 2 | def flutterSdkPath = { 3 | def properties = new Properties() 4 | file("local.properties").withInputStream { properties.load(it) } 5 | def flutterSdkPath = properties.getProperty("flutter.sdk") 6 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 7 | return flutterSdkPath 8 | }() 9 | 10 | includeBuild("$flutterSdkPath/packages/flutter_tools/gradle") 11 | 12 | repositories { 13 | google() 14 | mavenCentral() 15 | gradlePluginPortal() 16 | } 17 | } 18 | 19 | plugins { 20 | id "dev.flutter.flutter-plugin-loader" version "1.0.0" 21 | id "com.android.application" version "8.7.2" apply false 22 | id "org.jetbrains.kotlin.android" version "1.9.24" apply false 23 | } 24 | 25 | include ":app" 26 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: enhancement 6 | assignees: reeteshranjan, drenther 7 | 8 | --- 9 | 10 | ### Is your feature request related to a problem? Please describe. 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | ### Describe the solution you'd like 14 | A clear and concise description of what you want to happen. 15 | 16 | ### Describe alternatives you've considered 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | ### Any example solutions 20 | Mention any example solutions out there or what inspired the suggested solution 21 | 22 | ### Additional context 23 | Add any other context or screenshots about the feature request here. 24 | -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 12.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: bug 6 | assignees: reeteshranjan, drenther 7 | 8 | --- 9 | 10 | ### Describe the bug 11 | A clear and concise description of what the bug is. 12 | 13 | ### To Reproduce 14 | Steps to reproduce the behaviour: 15 | 1. Enter VPA 16 | 2. Trigger payment 17 | 3. Go to opened UPI app 18 | 4. ... 19 | 20 | ### Expected behaviour 21 | A clear and concise description of what you expected to happen. 22 | 23 | ### Screenshots 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | ### Environmental Details 27 | - OS: [e.g. Android 11] 28 | - Device: [e.g. OnePlus Nord] 29 | - Package Version: [e.g. v1.0.0] 30 | - UPI Applications in the device: [e.g. - GPay, Paytm] 31 | - Play Store: [e.g. Google, Mi, Vivo] 32 | - Other UPI / Payment packages used in the app: [e.g. - razorpay_flutter] 33 | 34 | ### Additional context 35 | Add any other context about the problem here. 36 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:upi_pay_example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Verify Platform version', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(Screen()); 17 | 18 | // Verify that platform version is retrieved. 19 | expect( 20 | find.byWidgetPredicate( 21 | (Widget widget) => 22 | widget is Text && widget.data!.startsWith('Running on:'), 23 | ), 24 | findsOneWidget, 25 | ); 26 | }); 27 | } 28 | -------------------------------------------------------------------------------- /ios/upi_pay.podspec: -------------------------------------------------------------------------------- 1 | # 2 | # To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. 3 | # Run `pod lib lint upi_pay.podspec` to validate before publishing. 4 | # 5 | Pod::Spec.new do |s| 6 | s.name = 'upi_pay' 7 | s.version = '1.0.0' 8 | s.summary = 'Flutter plugin for UPI payments.' 9 | s.description = <<-DESC 10 | A flutter plugin to launch UPI payment applications on Android and iOS towards making UPI payments. 11 | DESC 12 | s.homepage = 'https://github.com/drenther/upi_pay' 13 | s.license = { :file => '../LICENSE' } 14 | s.author = { 'Reetesh Ranjan' => 'reeteshranjan@piaxis.tech' } 15 | s.source = { :path => '.' } 16 | s.source_files = 'Classes/**/*' 17 | s.dependency 'Flutter' 18 | s.platform = :ios, '12.0' 19 | 20 | # Flutter.framework does not contain a i386 slice. 21 | s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'EXCLUDED_ARCHS[sdk=iphonesimulator*]' => 'i386' } 22 | s.swift_version = '5.0' 23 | end 24 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019 Soumyajit Pathak 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 7 | of the Software, and to permit persons to whom the Software is furnished to do 8 | so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. -------------------------------------------------------------------------------- /android/build.gradle: -------------------------------------------------------------------------------- 1 | group 'com.drenther.upi_pay' 2 | version '1.0-SNAPSHOT' 3 | 4 | buildscript { 5 | ext.kotlin_version = "1.9.24" 6 | repositories { 7 | google() 8 | mavenCentral() 9 | } 10 | 11 | dependencies { 12 | classpath("com.android.tools.build:gradle:8.7.2") 13 | classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version") 14 | } 15 | } 16 | 17 | allprojects { 18 | repositories { 19 | google() 20 | mavenCentral() 21 | } 22 | } 23 | 24 | apply plugin: 'com.android.library' 25 | apply plugin: 'kotlin-android' 26 | 27 | android { 28 | if (project.android.hasProperty("namespace")) { 29 | namespace = "com.drenther.upi_pay" 30 | } 31 | 32 | compileSdk = 34 33 | 34 | compileOptions { 35 | sourceCompatibility = JavaVersion.VERSION_1_8 36 | targetCompatibility = JavaVersion.VERSION_1_8 37 | } 38 | 39 | kotlinOptions { 40 | jvmTarget = JavaVersion.VERSION_1_8 41 | } 42 | 43 | sourceSets { 44 | main.java.srcDirs += "src/main/kotlin" 45 | test.java.srcDirs += "src/test/kotlin" 46 | } 47 | 48 | defaultConfig { 49 | minSdk = 21 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: "dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668" 8 | channel: "stable" 9 | 10 | project_type: plugin 11 | 12 | # Tracks metadata for the flutter migrate command 13 | migration: 14 | platforms: 15 | - platform: root 16 | create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 17 | base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 18 | - platform: android 19 | create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 20 | base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 21 | - platform: ios 22 | create_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 23 | base_revision: dec2ee5c1f98f8e84a7d5380c05eb8a3d0a81668 24 | 25 | # User provided section 26 | 27 | # List of Local paths (relative to this file) that should be 28 | # ignored by the migrate tool. 29 | # 30 | # Files that are not part of the templates will be ignored by default. 31 | unmanaged_files: 32 | - 'lib/main.dart' 33 | - 'ios/Runner.xcodeproj/project.pbxproj' 34 | -------------------------------------------------------------------------------- /upi_pay.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | plugins { 2 | id "com.android.application" 3 | id "kotlin-android" 4 | // The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins. 5 | id "dev.flutter.flutter-gradle-plugin" 6 | } 7 | 8 | android { 9 | namespace "com.drenther.upi_pay_example" 10 | compileSdkVersion 34 11 | ndkVersion "27.0.12077973" 12 | buildToolsVersion "34.0.0" 13 | 14 | compileOptions { 15 | sourceCompatibility = JavaVersion.VERSION_1_8 16 | targetCompatibility = JavaVersion.VERSION_1_8 17 | } 18 | 19 | kotlinOptions { 20 | jvmTarget = JavaVersion.VERSION_1_8 21 | } 22 | 23 | sourceSets { 24 | main.java.srcDirs += 'src/main/kotlin' 25 | } 26 | 27 | defaultConfig { 28 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 29 | applicationId = "com.drenther.upi_pay_example" 30 | minSdk = 21 31 | targetSdk = 34 32 | versionCode = flutter.versionCode 33 | versionName = flutter.versionName 34 | } 35 | 36 | buildTypes { 37 | release { 38 | // TODO: Add your own signing config for the release build. 39 | // Signing with the debug keys for now, so `flutter run --release` works. 40 | signingConfig = signingConfigs.debug 41 | } 42 | } 43 | } 44 | 45 | flutter { 46 | source = "../.." 47 | } -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | ## 1.1.0 2 | 3 | - Upgrade to latest build environment (Flutter 3.24.5, Gradle 8.10, Java 23) 4 | - Upgraded dependency packages 5 | - Required changes in build files due to upgrades in Flutter and Gradle 6 | - Created new Flutter project and merged it in, bringin in some other minor 7 | changes in various project files 8 | 9 | ## 1.0.1 10 | 11 | - Android API version 30 support 12 | 13 | ## 1.0.0 14 | 15 | - Null safety support 16 | - Recreated project to remove warnings around obsolete embedding version and not including AndroidX 17 | 18 | ## 0.3.0 19 | 20 | - Support for iOS 21 | - Working status of various UPI payment applications included 22 | - User can filter the apps discovery output against working status data by passing parameters. API remains backward compatible in syntax and semantics of providing properly working applications only in case no parameters are provided. 23 | 24 | ## 0.2.4 25 | 26 | - Updated MiPay package identifier and fix Axis Pay usage 27 | 28 | ## 0.2.3 29 | 30 | - Added Axis Pay 31 | 32 | ## 0.2.2 33 | 34 | - Mark the library as android only 35 | 36 | ## 0.2.1 37 | 38 | - Removed UPI Intent mode parameter because some applications do not strictly follow the UPI Specification and fails when intent parameter is passed 39 | 40 | ## 0.2.0 41 | 42 | - Upgraded kotlin_version to 1.3.61 43 | 44 | ## 0.1.2 45 | 46 | - Added MIT License 47 | 48 | ## 0.1.1 49 | 50 | - Added package description 51 | 52 | ## 0.1.0 53 | 54 | - Initial release 55 | -------------------------------------------------------------------------------- /example/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '12.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | # target 'RunnerTests' do 36 | # inherit! :search_paths 37 | # end 38 | end 39 | 40 | post_install do |installer| 41 | installer.pods_project.targets.each do |target| 42 | flutter_additional_ios_build_settings(target) 43 | end 44 | end 45 | -------------------------------------------------------------------------------- /ios/Classes/UpiPayPlugin.swift: -------------------------------------------------------------------------------- 1 | import Flutter 2 | import UIKit 3 | 4 | public class UpiPayPlugin: NSObject, FlutterPlugin { 5 | public static func register(with registrar: FlutterPluginRegistrar) { 6 | let channel = FlutterMethodChannel(name: "upi_pay", binaryMessenger: registrar.messenger()) 7 | let instance = UpiPayPlugin() 8 | registrar.addMethodCallDelegate(instance, channel: channel) 9 | } 10 | 11 | public func handle(_ call: FlutterMethodCall, result: @escaping FlutterResult) { 12 | let arguments = call.arguments as? NSDictionary 13 | switch call.method { 14 | case "getPlatformVersion": 15 | result("iOS " + UIDevice.current.systemVersion) 16 | case "canLaunch": 17 | let uri = (arguments!["uri"] as? String)! 18 | result(self.canLaunch(uri: uri)) 19 | return 20 | case "launch": 21 | let uri = (arguments!["uri"] as? String)! 22 | self.launchUri(uri: uri, result: result) 23 | return 24 | default: 25 | result(FlutterMethodNotImplemented) 26 | return 27 | } 28 | } 29 | 30 | private func canLaunch(uri: String) -> Bool { 31 | let url = URL(string: uri) 32 | return UIApplication.shared.canOpenURL(url!) 33 | } 34 | 35 | private func launchUri(uri: String, result: @escaping FlutterResult) -> Bool { 36 | if(canLaunch(uri: uri)) { 37 | let url = URL(string: uri) 38 | if #available(iOS 10, *) { 39 | UIApplication.shared.open(url!, completionHandler: { (ret) in 40 | result(ret) 41 | }) 42 | } else { 43 | result(UIApplication.shared.openURL(url!)) 44 | } 45 | } 46 | return false 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /doc/api/static-assets/github.css: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | github.com style (c) Vasily Polovnyov 4 | 5 | */ 6 | 7 | .hljs { 8 | display: block; 9 | overflow-x: auto; 10 | padding: 0.5em; 11 | color: #333; 12 | background: #f8f8f8; 13 | } 14 | 15 | .hljs-comment, 16 | .hljs-quote { 17 | color: #998; 18 | font-style: italic; 19 | } 20 | 21 | .hljs-keyword, 22 | .hljs-selector-tag, 23 | .hljs-subst { 24 | color: #333; 25 | font-weight: bold; 26 | } 27 | 28 | .hljs-number, 29 | .hljs-literal, 30 | .hljs-variable, 31 | .hljs-template-variable, 32 | .hljs-tag .hljs-attr { 33 | color: #008080; 34 | } 35 | 36 | .hljs-string, 37 | .hljs-doctag { 38 | color: #d14; 39 | } 40 | 41 | .hljs-title, 42 | .hljs-section, 43 | .hljs-selector-id { 44 | color: #900; 45 | font-weight: bold; 46 | } 47 | 48 | .hljs-subst { 49 | font-weight: normal; 50 | } 51 | 52 | .hljs-type, 53 | .hljs-class .hljs-title { 54 | color: #458; 55 | font-weight: bold; 56 | } 57 | 58 | .hljs-tag, 59 | .hljs-name, 60 | .hljs-attribute { 61 | color: #000080; 62 | font-weight: normal; 63 | } 64 | 65 | .hljs-regexp, 66 | .hljs-link { 67 | color: #009926; 68 | } 69 | 70 | .hljs-symbol, 71 | .hljs-bullet { 72 | color: #990073; 73 | } 74 | 75 | .hljs-built_in, 76 | .hljs-builtin-name { 77 | color: #0086b3; 78 | } 79 | 80 | .hljs-meta { 81 | color: #999; 82 | font-weight: bold; 83 | } 84 | 85 | .hljs-deletion { 86 | background: #fdd; 87 | } 88 | 89 | .hljs-addition { 90 | background: #dfd; 91 | } 92 | 93 | .hljs-emphasis { 94 | font-style: italic; 95 | } 96 | 97 | .hljs-strong { 98 | font-weight: bold; 99 | } 100 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /lib/types/discovery.dart: -------------------------------------------------------------------------------- 1 | /// Represents the type of payments in the apps that user wants to access. 2 | /// 3 | /// Passed as [paymentType] parameter of [UpiPay.getInstalledUpiApplications] 4 | /// API. 5 | enum UpiApplicationDiscoveryAppPaymentType { 6 | /// Individual-to-individual payment type. If this type is passed, then 7 | /// the package finds packages for which such payment works. Currently, it's 8 | /// the only type accepted. 9 | nonMerchant, 10 | 11 | /// Merchant payment type. Currently not accepted. Will represent merchant 12 | /// payment type once they are supported. 13 | merchant, 14 | 15 | /// Both individual-to-individual and merchant payment types. Not accepted 16 | /// currently. 17 | both, 18 | } 19 | 20 | /// Represents the UPI payment working status of apps that user wants to access. 21 | /// 22 | /// Passed as [statusType] parameter of [UpiPay.getInstalledUpiApplications] 23 | /// API. 24 | enum UpiApplicationDiscoveryAppStatusType { 25 | /// Indicates that user wants UPI apps with any working status (they must be 26 | /// discoverable, though) 27 | all, 28 | 29 | /// Indicates that user wants UPI apps that complete the UPI payment and may 30 | /// or may not involve the "unverified source" warning. Currently, only 31 | /// individual-to-individual payments are implemented, and this status type 32 | /// is relevant for them only as some apps give this warning in the payment 33 | /// process and take confirmation from user before proceeding for this type 34 | /// of payments. For merchant payments, this type may become irrelevant. 35 | workingWithWarnings, 36 | 37 | /// Indicates that user wants UPI apps that complete the UPI payment without 38 | /// the "unverified source" warning 39 | working, 40 | } 41 | -------------------------------------------------------------------------------- /test/upi_pay_test.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter_test/flutter_test.dart'; 2 | import 'package:upi_pay/types/transaction_details.dart'; 3 | import 'package:upi_pay/upi_pay.dart'; 4 | import 'package:upi_pay/src/platform_interface.dart'; 5 | import 'package:upi_pay/src/method_channel.dart'; 6 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; 7 | 8 | class MockUpiPayPlatform 9 | with MockPlatformInterfaceMixin 10 | implements UpiPayPlatform { 11 | @override 12 | Future getPlatformVersion() => Future.value('42'); 13 | 14 | @override 15 | Future canLaunch(String scheme) { 16 | // TODO: implement canLaunch 17 | throw UnimplementedError(); 18 | } 19 | 20 | @override 21 | Future?> getInstalledUpiApps() { 22 | // TODO: implement getInstalledUpiApps 23 | throw UnimplementedError(); 24 | } 25 | 26 | @override 27 | Future initiateTransaction(TransactionDetails transactionDetails) { 28 | // TODO: implement initiateTransaction 29 | throw UnimplementedError(); 30 | } 31 | 32 | @override 33 | Future launch(TransactionDetails transactionDetails) { 34 | // TODO: implement launch 35 | throw UnimplementedError(); 36 | } 37 | } 38 | 39 | void main() { 40 | final UpiPayPlatform initialPlatform = UpiPayPlatform.instance; 41 | 42 | test('$MethodChannelUpiPay is the default instance', () { 43 | expect(initialPlatform, isInstanceOf()); 44 | }); 45 | 46 | test('getPlatformVersion', () async { 47 | UpiPay upiPayPlugin = UpiPay(); 48 | MockUpiPayPlatform fakePlatform = MockUpiPayPlatform(); 49 | UpiPayPlatform.instance = fakePlatform; 50 | 51 | expect(await upiPayPlugin.getPlatformVersion(), '42'); 52 | }); 53 | } 54 | -------------------------------------------------------------------------------- /lib/src/platform_interface.dart: -------------------------------------------------------------------------------- 1 | import 'package:plugin_platform_interface/plugin_platform_interface.dart'; 2 | import 'package:upi_pay/types/transaction_details.dart'; 3 | 4 | import 'method_channel.dart'; 5 | 6 | abstract class UpiPayPlatform extends PlatformInterface { 7 | /// Constructs a UpiPayPlatform. 8 | UpiPayPlatform() : super(token: _token); 9 | 10 | static final Object _token = Object(); 11 | 12 | static UpiPayPlatform _instance = MethodChannelUpiPay(); 13 | 14 | /// The default instance of [UpiPayPlatform] to use. 15 | /// 16 | /// Defaults to [MethodChannelUpiPay]. 17 | static UpiPayPlatform get instance => _instance; 18 | 19 | /// Platform-specific implementations should set this with their own 20 | /// platform-specific class that extends [UpiPayPlatform] when 21 | /// they register themselves. 22 | static set instance(UpiPayPlatform instance) { 23 | PlatformInterface.verifyToken(instance, _token); 24 | _instance = instance; 25 | } 26 | 27 | Future getPlatformVersion() { 28 | throw UnimplementedError('platformVersion() has not been implemented.'); 29 | } 30 | 31 | Future initiateTransaction( 32 | TransactionDetails transactionDetails) async { 33 | throw UnimplementedError('initiateTransaction() has not been implemented.'); 34 | } 35 | 36 | Future launch(TransactionDetails transactionDetails) async { 37 | throw UnimplementedError('launch() has not been implemented.'); 38 | } 39 | 40 | Future>?> getInstalledUpiApps() async { 41 | throw UnimplementedError('getInstalledUpiApps() has not been implemented.'); 42 | } 43 | 44 | Future canLaunch(String scheme) async { 45 | throw UnimplementedError('canLaunch() has not been implemented.'); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .packages 28 | .pub-cache/ 29 | .pub/ 30 | /build/ 31 | 32 | # Android related 33 | **/android/**/gradle-wrapper.jar 34 | **/android/.gradle 35 | **/android/captures/ 36 | **/android/gradlew 37 | **/android/gradlew.bat 38 | **/android/local.properties 39 | **/android/**/GeneratedPluginRegistrant.java 40 | 41 | # iOS/XCode related 42 | **/ios/**/*.mode1v3 43 | **/ios/**/*.mode2v3 44 | **/ios/**/*.moved-aside 45 | **/ios/**/*.pbxuser 46 | **/ios/**/*.perspectivev3 47 | **/ios/**/*sync/ 48 | **/ios/**/.sconsign.dblite 49 | **/ios/**/.tags* 50 | **/ios/**/.vagrant/ 51 | **/ios/**/DerivedData/ 52 | **/ios/**/Icon? 53 | **/ios/**/Pods/ 54 | **/ios/**/.symlinks/ 55 | **/ios/**/profile 56 | **/ios/**/xcuserdata 57 | **/ios/.generated/ 58 | **/ios/Flutter/App.framework 59 | **/ios/Flutter/Flutter.framework 60 | **/ios/Flutter/Generated.xcconfig 61 | **/ios/Flutter/app.flx 62 | **/ios/Flutter/app.zip 63 | **/ios/Flutter/flutter_assets/ 64 | **/ios/Flutter/flutter_export_environment.sh 65 | **/ios/ServiceDefinitions.json 66 | **/ios/Runner/GeneratedPluginRegistrant.* 67 | 68 | # Exceptions to above rules. 69 | !**/ios/**/default.mode1v3 70 | !**/ios/**/default.mode2v3 71 | !**/ios/**/default.pbxuser 72 | !**/ios/**/default.perspectivev3 73 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 74 | 75 | .flutter-plugins-dependencies -------------------------------------------------------------------------------- /lib/src/method_channel.dart: -------------------------------------------------------------------------------- 1 | import 'package:universal_io/io.dart' as io; 2 | import 'package:flutter/services.dart'; 3 | import 'package:upi_pay/types/transaction_details.dart'; 4 | import 'package:flutter/foundation.dart'; 5 | 6 | import 'platform_interface.dart'; 7 | 8 | /// An implementation of [UpiPayPlatform] that uses method channels. 9 | class MethodChannelUpiPay extends UpiPayPlatform { 10 | /// The method channel used to interact with the native platform. 11 | @visibleForTesting 12 | final methodChannel = const MethodChannel('upi_pay'); 13 | 14 | @override 15 | Future getPlatformVersion() async { 16 | final version = 17 | await methodChannel.invokeMethod('getPlatformVersion'); 18 | return version; 19 | } 20 | 21 | Future initiateTransaction( 22 | TransactionDetails transactionDetails) async { 23 | if (!io.Platform.isAndroid) { 24 | throw UnsupportedError( 25 | 'The `initiateTransaction` call is supported only on Android'); 26 | } 27 | return methodChannel.invokeMethod( 28 | 'initiateTransaction', transactionDetails.toJson()); 29 | } 30 | 31 | Future launch(TransactionDetails transactionDetails) async { 32 | if (!io.Platform.isIOS) { 33 | throw UnsupportedError('The `launch` call is supported only on iOS'); 34 | } 35 | return methodChannel 36 | .invokeMethod('launch', {'uri': transactionDetails.toString()}); 37 | } 38 | 39 | Future>?> getInstalledUpiApps() async { 40 | if (!io.Platform.isAndroid) { 41 | throw UnsupportedError('The `getInstalledUpiApps` call is supported only ' 42 | 'on Android'); 43 | } 44 | return methodChannel 45 | .invokeListMethod>('getInstalledUpiApps'); 46 | } 47 | 48 | Future canLaunch(String scheme) async { 49 | if (!io.Platform.isIOS) { 50 | throw UnsupportedError('The `canLaunch` call is supported only on iOS'); 51 | } 52 | return methodChannel 53 | .invokeMethod('canLaunch', {'uri': scheme + "://"}); 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 14 | 18 | 22 | 27 | 31 | 32 | 33 | 34 | 35 | 36 | 38 | 41 | 42 | 43 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/src/transaction.dart: -------------------------------------------------------------------------------- 1 | import 'package:universal_io/io.dart' as io; 2 | import 'package:upi_pay/src/platform_interface.dart'; 3 | import 'package:upi_pay/types/response.dart'; 4 | import 'package:upi_pay/types/transaction_details.dart'; 5 | 6 | class UpiTransactionHelper implements _PlatformTransactionHelperBase { 7 | final helper = io.Platform.isAndroid 8 | ? AndroidTransactionHelper() 9 | : io.Platform.isIOS 10 | ? IosTransactionHelper() 11 | : null; 12 | static final _singleton = UpiTransactionHelper._inner(); 13 | factory UpiTransactionHelper() { 14 | return _singleton; 15 | } 16 | UpiTransactionHelper._inner(); 17 | 18 | @override 19 | Future transact( 20 | TransactionDetails transactionDetails) async { 21 | if (!(io.Platform.isAndroid || io.Platform.isIOS)) { 22 | throw UnsupportedError( 23 | 'UPI transaction is available only on Android and iOS'); 24 | } 25 | return helper!.transact(transactionDetails); 26 | } 27 | } 28 | 29 | class AndroidTransactionHelper implements _PlatformTransactionHelperBase { 30 | static final _singleton = AndroidTransactionHelper._inner(); 31 | factory AndroidTransactionHelper() { 32 | return _singleton; 33 | } 34 | AndroidTransactionHelper._inner(); 35 | 36 | @override 37 | Future transact( 38 | TransactionDetails transactionDetails) async { 39 | String? responseString = 40 | await UpiPayPlatform.instance.initiateTransaction(transactionDetails); 41 | return UpiTransactionResponse.android( 42 | responseString == null ? "" : responseString); 43 | } 44 | } 45 | 46 | class IosTransactionHelper implements _PlatformTransactionHelperBase { 47 | static final _singleton = IosTransactionHelper._inner(); 48 | factory IosTransactionHelper() { 49 | return _singleton; 50 | } 51 | IosTransactionHelper._inner(); 52 | 53 | @override 54 | Future transact( 55 | TransactionDetails transactionDetails) async { 56 | try { 57 | final bool? result = 58 | await UpiPayPlatform.instance.launch(transactionDetails); 59 | return UpiTransactionResponse.ios(result != null ? result : false); 60 | } catch (error, stack) { 61 | print('iOS UPI app launch failure: $error'); 62 | print('iOS UPI app launch failure stack: $stack'); 63 | return UpiTransactionResponse.iosError(error); 64 | } 65 | } 66 | } 67 | 68 | abstract class _PlatformTransactionHelperBase { 69 | Future transact( 70 | TransactionDetails transactionDetails); 71 | } 72 | -------------------------------------------------------------------------------- /lib/types/transaction_details.dart: -------------------------------------------------------------------------------- 1 | import 'package:decimal/decimal.dart'; 2 | import 'package:upi_pay/types/applications.dart'; 3 | import 'package:upi_pay/types/exceptions.dart'; 4 | 5 | class TransactionDetails { 6 | static const String _currency = 'INR'; 7 | static const int _maxAmount = 100000; 8 | 9 | final UpiApplication upiApplication; 10 | final String payeeAddress; 11 | final String payeeName; 12 | final String transactionRef; 13 | final String currency; 14 | final Decimal amount; 15 | final String? url; 16 | final String merchantCode; 17 | final String? transactionNote; 18 | 19 | TransactionDetails({ 20 | required this.upiApplication, 21 | required this.payeeAddress, 22 | required this.payeeName, 23 | required this.transactionRef, 24 | this.currency = TransactionDetails._currency, 25 | required String amount, 26 | this.url, 27 | this.merchantCode = '', 28 | this.transactionNote = 'UPI Transaction', 29 | }) : amount = Decimal.parse(amount) { 30 | if (!_checkIfUpiAddressIsValid(payeeAddress)) { 31 | throw InvalidUpiAddressException(); 32 | } 33 | final Decimal am = Decimal.parse(amount); 34 | if (am.scale > 2) { 35 | throw InvalidAmountException( 36 | 'Amount must not have more than 2 digits after decimal point'); 37 | } 38 | if (am <= Decimal.zero) { 39 | throw InvalidAmountException('Amount must be greater than 1'); 40 | } 41 | if (am > Decimal.fromInt(_maxAmount)) { 42 | throw InvalidAmountException( 43 | 'Amount must be less then 1,00,000 since that is the upper limit ' 44 | 'per UPI transaction'); 45 | } 46 | } 47 | 48 | Map toJson() { 49 | return { 50 | 'app': upiApplication.toString(), 51 | 'pa': payeeAddress, 52 | 'pn': payeeName, 53 | 'tr': transactionRef, 54 | 'cu': currency, 55 | 'am': amount.toString(), 56 | 'url': url, 57 | 'mc': merchantCode, 58 | 'tn': transactionNote, 59 | }; 60 | } 61 | 62 | String toString() { 63 | String uri = 'upi://pay?pa=$payeeAddress' 64 | '&pn=${Uri.encodeComponent(payeeName)}' 65 | '&tr=$transactionRef' 66 | '&tn=${Uri.encodeComponent(transactionNote!)}' 67 | '&am=${amount.toString()}' 68 | '&cu=$currency'; 69 | if (url != null && url!.isNotEmpty) { 70 | uri += '&url=${Uri.encodeComponent(url!)}'; 71 | } 72 | if (merchantCode.isNotEmpty) { 73 | uri += '&mc=${Uri.encodeComponent(merchantCode)}'; 74 | } 75 | return uri; 76 | } 77 | } 78 | 79 | bool _checkIfUpiAddressIsValid(String upiAddress) { 80 | return upiAddress.split('@').length == 2; 81 | } 82 | -------------------------------------------------------------------------------- /lib/types/meta.dart: -------------------------------------------------------------------------------- 1 | import 'dart:typed_data'; 2 | 3 | import 'package:universal_io/io.dart' as io; 4 | import 'package:upi_pay/types/applications.dart'; 5 | import 'package:flutter/material.dart'; 6 | 7 | /// Represents a UPI payment app and more relevant information. 8 | /// 9 | /// Contains [UpiApplication] representation of the UPI payment app. Also 10 | /// contains a logo image and other data. 11 | class ApplicationMeta { 12 | /// Android platform constructor. 13 | /// 14 | /// Stores the byte-array version of the logo apart from [_priority] and 15 | /// [_preferredOrder]. 16 | ApplicationMeta.android( 17 | this.upiApplication, 18 | this._icon, 19 | this._priority, 20 | this._preferredOrder, 21 | ); 22 | 23 | /// iOS platform constructor. 24 | ApplicationMeta.ios( 25 | this.upiApplication, 26 | ) : _icon = null, 27 | _priority = 0, 28 | _preferredOrder = 0; 29 | 30 | /// Returns an [Image] widget for the UPI app. 31 | /// 32 | /// [dimension] specifies width and height of the [Image] output. 33 | /// 34 | /// On Android, it creates an [Image] widget from the byte-array of the logo. 35 | /// On iOS, it creates an [Image] widget from logo stored as part of assets. 36 | Image iconImage(double dimension) { 37 | if (io.Platform.isAndroid) { 38 | return Image.memory(_icon!, width: dimension, height: dimension); 39 | } else if (io.Platform.isIOS) { 40 | return Image.asset( 41 | 'assets/apps/ios/${upiApplication.iosBundleId}.png', 42 | package: 'upi_pay', 43 | width: dimension, 44 | height: dimension, 45 | ); 46 | } 47 | throw UnsupportedError('`iconImage` is available on Android and iOS only'); 48 | } 49 | 50 | /// Gets the UPI app's package name. 51 | String get packageName => upiApplication.toString(); 52 | 53 | /// Getter for [_priority]. Leads to [UnsupportedError] on iOS. 54 | int get priority { 55 | if (io.Platform.isAndroid) { 56 | return _priority; 57 | } 58 | throw UnsupportedError('`priority` is not available on iOS'); 59 | } 60 | 61 | /// Getter for [_preferredOrder]. Leads to [UnsupportedError] on iOS. 62 | int get preferredOrder { 63 | if (io.Platform.isAndroid) { 64 | return _preferredOrder; 65 | } 66 | throw UnsupportedError('`preferredOrder` is not available on iOS'); 67 | } 68 | 69 | /// [UpiApplication] representation of the UPI app. 70 | final UpiApplication upiApplication; 71 | 72 | /// The byte-array version of the app's logo (Android-only). 73 | final Uint8List? _icon; 74 | 75 | /// Priority of execution. Provided for API response coverage (Android-only). 76 | /// Not used as of now. 77 | final int _priority; 78 | 79 | /// Preferred order of execution. Provided for API response coverage 80 | /// (Android-only). Not used as of now. 81 | final int _preferredOrder; 82 | } 83 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | upi_pay_example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSApplicationQueriesSchemes 24 | 25 | Bandhan 26 | BHIM 27 | CanaraMobility 28 | CentUPI 29 | com.amazon.mobile.shopping 30 | com.ausmallfinancebank.aupay.bhimupi 31 | com.jkbank.bhimjkbankupi 32 | com.rbl.rblimplicitjourney 33 | com.syndicate.syndupi 34 | com.vijayabank.UPI 35 | cred 36 | dbin 37 | freecharge 38 | gpay 39 | hdfcnewbb 40 | imobileapp 41 | in.cointab.app 42 | in.fampay.app 43 | kvb.app.upiapp 44 | lotza 45 | mobikwik 46 | money.bullet 47 | myairtel 48 | myJio 49 | paytm 50 | payzapp 51 | phonepe 52 | truecaller 53 | ucoupi 54 | upi 55 | upibillpay 56 | whatsapp 57 | www.citruspay.com 58 | 59 | LSRequiresIPhoneOS 60 | 61 | UILaunchStoryboardName 62 | LaunchScreen 63 | UIMainStoryboardFile 64 | Main 65 | UISupportedInterfaceOrientations 66 | 67 | UIInterfaceOrientationPortrait 68 | UIInterfaceOrientationLandscapeLeft 69 | UIInterfaceOrientationLandscapeRight 70 | 71 | UISupportedInterfaceOrientations~ipad 72 | 73 | UIInterfaceOrientationPortrait 74 | UIInterfaceOrientationPortraitUpsideDown 75 | UIInterfaceOrientationLandscapeLeft 76 | UIInterfaceOrientationLandscapeRight 77 | 78 | UIViewControllerBasedStatusBarAppearance 79 | 80 | CADisableMinimumFrameDurationOnPhone 81 | 82 | UIApplicationSupportsIndirectInputEvents 83 | 84 | 85 | 86 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /doc/api/__404error.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | upi_pay - Dart API docs 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 27 | 28 |
29 | 30 |
31 | 32 | 35 |
upi_pay
36 | 39 |
40 | 41 |
42 | 43 | 44 |
45 |

404: Something's gone wrong :-(

46 | 47 |
48 |

You've tried to visit a page that doesn't exist. Luckily this site 49 | has other pages.

50 |

If you were looking for something specific, try searching: 51 |

54 |

55 | 56 |
57 |
58 | 59 | 78 | 79 | 81 | 82 |
83 | 84 |
85 | 86 | upi_pay 87 | 1.0.0 88 | 89 | 90 | 91 |
92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 34 | 40 | 41 | 42 | 43 | 44 | 50 | 51 | 52 | 53 | 54 | 55 | 65 | 67 | 73 | 74 | 75 | 76 | 77 | 78 | 84 | 86 | 92 | 93 | 94 | 95 | 97 | 98 | 101 | 102 | 103 | -------------------------------------------------------------------------------- /android/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiPay/UpiPay.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | UpiPay constructor - UpiPay class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
UpiPay
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

UpiPay constructor 49 | Null safety 50 |

51 | 52 |
53 | UpiPay() 54 |
55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 |
63 | 64 | 108 | 109 | 111 | 112 |
113 | 114 |
115 | 116 | upi_pay 117 | 1.0.0 118 | 119 | 120 | 121 |
122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiTransactionStatus/toString.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | toString method - UpiTransactionStatus extension - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
toString
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

toString method 49 | Null safety 50 |

51 | 52 |
53 | 54 | 55 | String 56 | toString() 57 | 58 |
override
59 | 60 |
61 | 62 |
63 |

A string representation of this object.

64 |

Some classes have a default textual representation, 65 | often paired with a static parse function (like int.parse). 66 | These classes will provide the textual representation as 67 | their string represetion.

68 |

Other classes have no meaningful textual representation 69 | that a program will care about. 70 | Such classes will typically override toString to provide 71 | useful information when inspecting the object, 72 | mainly for debugging or logging.

73 |
74 | 75 | 76 | 77 | 78 | 79 |
80 | 81 | 126 | 127 | 129 | 130 |
131 | 132 |
133 | 134 | upi_pay 135 | 1.0.0 136 | 137 | 138 | 139 |
140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /doc/api/upi_pay/ApplicationMeta/packageName.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | packageName property - ApplicationMeta class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
packageName
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

packageName property 49 | Null safety 50 |

51 | 52 | 53 | 54 |
55 | 56 |
57 | String 58 | packageName 59 | 60 | 61 |
62 | 63 | 64 |
65 |

Gets the UPI app's package name.

66 |
67 | 68 | 69 |
70 |

Implementation

71 |
String get packageName => upiApplication.toString();
72 |
73 | 74 |
75 | 76 | 77 |
78 | 79 | 126 | 127 | 129 | 130 |
131 | 132 |
133 | 134 | upi_pay 135 | 1.0.0 136 | 137 | 138 | 139 |
140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiApplicationDiscoveryAppStatusType/toString.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | toString method - UpiApplicationDiscoveryAppStatusType extension - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
toString
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

toString method 49 | Null safety 50 |

51 | 52 |
53 | 54 | 55 | String 56 | toString() 57 | 58 |
override
59 | 60 |
61 | 62 |
63 |

A string representation of this object.

64 |

Some classes have a default textual representation, 65 | often paired with a static parse function (like int.parse). 66 | These classes will provide the textual representation as 67 | their string represetion.

68 |

Other classes have no meaningful textual representation 69 | that a program will care about. 70 | Such classes will typically override toString to provide 71 | useful information when inspecting the object, 72 | mainly for debugging or logging.

73 |
74 | 75 | 76 | 77 | 78 | 79 |
80 | 81 | 124 | 125 | 127 | 128 |
129 | 130 |
131 | 132 | upi_pay 133 | 1.0.0 134 | 135 | 136 | 137 |
138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiApplicationDiscoveryAppPaymentType/toString.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | toString method - UpiApplicationDiscoveryAppPaymentType extension - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
toString
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

toString method 49 | Null safety 50 |

51 | 52 |
53 | 54 | 55 | String 56 | toString() 57 | 58 |
override
59 | 60 |
61 | 62 |
63 |

A string representation of this object.

64 |

Some classes have a default textual representation, 65 | often paired with a static parse function (like int.parse). 66 | These classes will provide the textual representation as 67 | their string represetion.

68 |

Other classes have no meaningful textual representation 69 | that a program will care about. 70 | Such classes will typically override toString to provide 71 | useful information when inspecting the object, 72 | mainly for debugging or logging.

73 |
74 | 75 | 76 | 77 | 78 | 79 |
80 | 81 | 124 | 125 | 127 | 128 |
129 | 130 |
131 | 132 | upi_pay 133 | 1.0.0 134 | 135 | 136 | 137 |
138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | -------------------------------------------------------------------------------- /doc/api/upi_pay/ApplicationMeta/upiApplication.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | upiApplication property - ApplicationMeta class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
upiApplication
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

upiApplication property 49 | Null safety 50 |

51 | 52 |
53 | UpiApplication 54 | upiApplication 55 |
final
56 | 57 |
58 | 59 |
60 |

UpiApplication representation of the UPI app.

61 |
62 | 63 | 64 |
65 |

Implementation

66 |
final UpiApplication upiApplication;
 67 | 
 68 | 
69 |
70 | 71 | 72 |
73 | 74 | 121 | 122 | 124 | 125 |
126 | 127 |
128 | 129 | upi_pay 130 | 1.0.0 131 | 132 | 133 | 134 |
135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | -------------------------------------------------------------------------------- /doc/api/upi_pay/ApplicationMeta/priority.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | priority property - ApplicationMeta class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
priority
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

priority property 49 | Null safety 50 |

51 | 52 | 53 | 54 |
55 | 56 |
57 | int 58 | priority 59 | 60 | 61 |
62 | 63 | 64 |
65 |

Getter for _priority. Leads to UnsupportedError on iOS.

66 |
67 | 68 | 69 |
70 |

Implementation

71 |
int get priority {
 72 |   if (io.Platform.isAndroid) {
 73 |     return _priority;
 74 |   }
 75 |   throw UnsupportedError('`priority` is not available on iOS');
 76 | }
77 |
78 | 79 |
80 | 81 | 82 |
83 | 84 | 131 | 132 | 134 | 135 |
136 | 137 |
138 | 139 | upi_pay 140 | 1.0.0 141 | 142 | 143 | 144 |
145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /doc/api/upi_pay/ApplicationMeta/ApplicationMeta.ios.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | ApplicationMeta.ios constructor - ApplicationMeta class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
ApplicationMeta.ios
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

ApplicationMeta.ios constructor 49 | Null safety 50 |

51 | 52 |
53 | ApplicationMeta.ios(
  1. UpiApplication upiApplication
  2. 54 |
) 55 |
56 | 57 | 58 |
59 |

iOS platform constructor.

60 |
61 | 62 | 63 | 64 |
65 |

Implementation

66 |
ApplicationMeta.ios(
 67 |   this.upiApplication,
 68 | )   : _icon = null,
 69 |       _priority = 0,
 70 |       _preferredOrder = 0;
71 |
72 | 73 | 74 |
75 | 76 | 123 | 124 | 126 | 127 |
128 | 129 |
130 | 131 | upi_pay 132 | 1.0.0 133 | 134 | 135 | 136 |
137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /doc/api/upi_pay/ApplicationMeta/preferredOrder.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | preferredOrder property - ApplicationMeta class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
preferredOrder
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

preferredOrder property 49 | Null safety 50 |

51 | 52 | 53 | 54 |
55 | 56 |
57 | int 58 | preferredOrder 59 | 60 | 61 |
62 | 63 | 64 |
65 |

Getter for _preferredOrder. Leads to UnsupportedError on iOS.

66 |
67 | 68 | 69 |
70 |

Implementation

71 |
int get preferredOrder {
 72 |   if (io.Platform.isAndroid) {
 73 |     return _preferredOrder;
 74 |   }
 75 |   throw UnsupportedError('`preferredOrder` is not available on iOS');
 76 | }
77 |
78 | 79 |
80 | 81 | 82 |
83 | 84 | 131 | 132 | 134 | 135 |
136 | 137 |
138 | 139 | upi_pay 140 | 1.0.0 141 | 142 | 143 | 144 |
145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiTransactionResponse/status.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | status property - UpiTransactionResponse class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
status
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

status property 49 | Null safety 50 |

51 | 52 | 53 | 54 |
55 | 56 |
57 | UpiTransactionStatus? 58 | status 59 | 60 | 61 |
62 | 63 | 64 |
65 |

Getter for _status.

66 |
67 | 68 | 69 |
70 |

Implementation

71 |
UpiTransactionStatus? get status => _status;
72 |
73 | 74 |
75 | 76 | 77 |
78 | 79 | 129 | 130 | 132 | 133 |
134 | 135 |
136 | 137 | upi_pay 138 | 1.0.0 139 | 140 | 141 | 142 |
143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiTransactionResponse/txnId.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | txnId property - UpiTransactionResponse class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
txnId
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

txnId property 49 | Null safety 50 |

51 | 52 | 53 | 54 |
55 | 56 |
57 | String? 58 | txnId 59 | 60 | 61 |
62 | 63 | 64 |
65 |

Getter for _txnId. Leads to UnsupportedError on iOs.

66 |
67 | 68 | 69 |
70 |

Implementation

71 |
String? get txnId {
 72 |   if (io.Platform.isAndroid) {
 73 |     return _txnId;
 74 |   }
 75 |   throw UnsupportedError('The attribute txnId is not available on iOS');
 76 | }
77 |
78 | 79 |
80 | 81 | 82 |
83 | 84 | 134 | 135 | 137 | 138 |
139 | 140 |
141 | 142 | upi_pay 143 | 1.0.0 144 | 145 | 146 | 147 |
148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiTransactionResponse/txnRef.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | txnRef property - UpiTransactionResponse class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
txnRef
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

txnRef property 49 | Null safety 50 |

51 | 52 | 53 | 54 |
55 | 56 |
57 | String? 58 | txnRef 59 | 60 | 61 |
62 | 63 | 64 |
65 |

Getter for _txnRef. Leads to UnsupportedError on iOs.

66 |
67 | 68 | 69 |
70 |

Implementation

71 |
String? get txnRef {
 72 |   if (io.Platform.isAndroid) {
 73 |     return _txnRef;
 74 |   }
 75 |   throw UnsupportedError('The attribute txnRef is not available on iOS');
 76 | }
77 |
78 | 79 |
80 | 81 | 82 |
83 | 84 | 134 | 135 | 137 | 138 |
139 | 140 |
141 | 142 | upi_pay 143 | 1.0.0 144 | 145 | 146 | 147 |
148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiTransactionResponse/rawResponse.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | rawResponse property - UpiTransactionResponse class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
rawResponse
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

rawResponse property 49 | Null safety 50 |

51 | 52 | 53 | 54 |
55 | 56 |
57 | String? 58 | rawResponse 59 | 60 | 61 |
62 | 63 | 64 |
65 |

Getter for _rawResponse. Leads to UnsupportedError on iOs.

66 |
67 | 68 | 69 |
70 |

Implementation

71 |
String? get rawResponse {
 72 |   if (io.Platform.isAndroid) {
 73 |     return _rawResponse;
 74 |   }
 75 |   throw UnsupportedError('The attribute rawResponse is not available on iOS');
 76 | }
77 |
78 | 79 |
80 | 81 | 82 |
83 | 84 | 134 | 135 | 137 | 138 |
139 | 140 |
141 | 142 | upi_pay 143 | 1.0.0 144 | 145 | 146 | 147 |
148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiTransactionResponse/launchError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | launchError property - UpiTransactionResponse class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
launchError
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

launchError property 49 | Null safety 50 |

51 | 52 | 53 | 54 |
55 | 56 |
57 | String? 58 | launchError 59 | 60 | 61 |
62 | 63 | 64 |
65 |

Getter for _launchError. Leads to UnsupportedError on Android.

66 |
67 | 68 | 69 |
70 |

Implementation

71 |
String? get launchError {
 72 |   if (io.Platform.isIOS) {
 73 |     return _launchError;
 74 |   }
 75 |   throw UnsupportedError(
 76 |       'The attribute launchError is not available on Android');
 77 | }
78 |
79 | 80 |
81 | 82 | 83 |
84 | 85 | 135 | 136 | 138 | 139 |
140 | 141 |
142 | 143 | upi_pay 144 | 1.0.0 145 | 146 | 147 | 148 |
149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiTransactionResponse/responseCode.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | responseCode property - UpiTransactionResponse class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
responseCode
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

responseCode property 49 | Null safety 50 |

51 | 52 | 53 | 54 |
55 | 56 |
57 | String? 58 | responseCode 59 | 60 | 61 |
62 | 63 | 64 |
65 |

Getter for _responseCode. Leads to UnsupportedError on iOs.

66 |
67 | 68 | 69 |
70 |

Implementation

71 |
String? get responseCode {
 72 |   if (io.Platform.isAndroid) {
 73 |     return _responseCode;
 74 |   }
 75 |   throw UnsupportedError(
 76 |       'The attribute responseCode is not available on iOS');
 77 | }
78 |
79 | 80 |
81 | 82 | 83 |
84 | 85 | 135 | 136 | 138 | 139 |
140 | 141 |
142 | 143 | upi_pay 144 | 1.0.0 145 | 146 | 147 | 148 |
149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiTransactionResponse/approvalRefNo.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | approvalRefNo property - UpiTransactionResponse class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
approvalRefNo
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

approvalRefNo property 49 | Null safety 50 |

51 | 52 | 53 | 54 |
55 | 56 |
57 | String? 58 | approvalRefNo 59 | 60 | 61 |
62 | 63 | 64 |
65 |

Getter for _approvalRefNo. Leads to UnsupportedError on iOs.

66 |
67 | 68 | 69 |
70 |

Implementation

71 |
String? get approvalRefNo {
 72 |   if (io.Platform.isAndroid) {
 73 |     return _approvalRefNo;
 74 |   }
 75 |   throw UnsupportedError(
 76 |       'The attribute approvalRefNo is not available on iOS');
 77 | }
78 |
79 | 80 |
81 | 82 | 83 |
84 | 85 | 135 | 136 | 138 | 139 |
140 | 141 |
142 | 143 | upi_pay 144 | 1.0.0 145 | 146 | 147 | 148 |
149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /lib/types/response.dart: -------------------------------------------------------------------------------- 1 | import 'package:universal_io/io.dart' as io; 2 | 3 | /// Represents status of executing a UPI transaction by launching a UPI app. 4 | enum UpiTransactionStatus { 5 | /// UPI transaction submitted and is yet to complete (Android-only) 6 | /// See `Status` in [UPI Linking Specification](https://www.npci.org.in/sites/default/files/UPI%20Linking%20Specs_ver%201.6.pdf) 7 | submitted, 8 | 9 | /// UPI transaction is successful (Android-only) 10 | /// See `Status` in [UPI Linking Specification](https://www.npci.org.in/sites/default/files/UPI%20Linking%20Specs_ver%201.6.pdf) 11 | success, 12 | 13 | /// UPI transaction failed (Android-only) 14 | /// See `Status` in [UPI Linking Specification](https://www.npci.org.in/sites/default/files/UPI%20Linking%20Specs_ver%201.6.pdf) 15 | failure, 16 | 17 | /// UPI payment app launched with transaction parameters (iOS-only) 18 | launched, 19 | 20 | /// UPI payment app launch failed (iOS-only) 21 | failedToLaunch, 22 | } 23 | 24 | /// Structured data representing response of a UPI transaction request. 25 | class UpiTransactionResponse { 26 | /// See `txnId` in [UPI Linking Specification](https://www.npci.org.in/sites/default/files/UPI%20Linking%20Specs_ver%201.6.pdf) 27 | /// "Response Parameters" section (Android-only) 28 | String? _txnId; 29 | 30 | /// See `responseCode` in [UPI Linking Specification](https://www.npci.org.in/sites/default/files/UPI%20Linking%20Specs_ver%201.6.pdf) (Android-only) 31 | String? _responseCode; 32 | 33 | /// See `ApprovalRefNo` in [UPI Linking Specification](https://www.npci.org.in/sites/default/files/UPI%20Linking%20Specs_ver%201.6.pdf) (Android-only) 34 | String? _approvalRefNo; 35 | 36 | /// Status of transaction on Android / iOS 37 | UpiTransactionStatus? _status; 38 | 39 | /// See `txnRef` in [UPI Linking Specification](https://www.npci.org.in/sites/default/files/UPI%20Linking%20Specs_ver%201.6.pdf) (Android-only) 40 | String? _txnRef; 41 | 42 | /// Response string in the format specified in [UPI Linking Specification](https://www.npci.org.in/sites/default/files/UPI%20Linking%20Specs_ver%201.6.pdf) (Android-only) 43 | String? _rawResponse; 44 | 45 | /// UPI app launch exception (iOS-only) 46 | String? _launchError; 47 | 48 | /// Android platform constructor. 49 | /// 50 | /// Parses the response as per the [UPI Linking Specification](https://www.npci.org.in/sites/default/files/UPI%20Linking%20Specs_ver%201.6.pdf) 51 | /// to populate Android-specific attributes. 52 | UpiTransactionResponse.android(String responseString) { 53 | this._rawResponse = responseString; 54 | // Consider the response to be failure if success or submitted is not explicitly returned. 55 | this._status = UpiTransactionStatus.failure; 56 | List fragments = responseString.split('&'); 57 | fragments.forEach((fragment) { 58 | List keyValuePair = fragment.split('='); 59 | String normalizedKey = keyValuePair.first.toLowerCase(); 60 | String value = keyValuePair.last; 61 | switch (normalizedKey) { 62 | case 'txnid': 63 | this._txnId = value; 64 | break; 65 | case 'responsecode': 66 | this._responseCode = value; 67 | break; 68 | case 'approvalrefno': 69 | this._approvalRefNo = value; 70 | break; 71 | case 'status': 72 | if (value.toLowerCase().contains('success')) { 73 | this._status = UpiTransactionStatus.success; 74 | } else if (value.toLowerCase().contains('fail')) { 75 | this._status = UpiTransactionStatus.failure; 76 | } else if (value.toLowerCase().contains('submitted')) { 77 | this._status = UpiTransactionStatus.submitted; 78 | } else if (value.toLowerCase() == 's') { 79 | this._status = 80 | UpiTransactionStatus.success; // YuvaPay returns status=S 81 | } else { 82 | throw UnsupportedError('Unsupported UPI Transaction Status'); 83 | } 84 | break; 85 | case 'txnref': 86 | this._txnRef = value; 87 | } 88 | }); 89 | } 90 | 91 | /// iOS platform constructor. 92 | /// 93 | /// Populates [_status] as per the [result]. 94 | UpiTransactionResponse.ios(bool result) { 95 | _status = result 96 | ? UpiTransactionStatus.launched 97 | : UpiTransactionStatus.failedToLaunch; 98 | } 99 | 100 | /// iOS platform app launch exception case constructor. 101 | /// 102 | /// Populates [_status] and [_launchError]. 103 | UpiTransactionResponse.iosError(error) { 104 | _status = UpiTransactionStatus.failedToLaunch; 105 | _launchError = error.toString(); 106 | } 107 | 108 | String toString() { 109 | return 'UpiTransactionResponse { txnId: $_txnId, responseCode: ' 110 | '$_responseCode, approvalRefNo: $_approvalRefNo, status: $_status, ' 111 | 'txnRef: $_txnRef, rawResponse: $_rawResponse }'; 112 | } 113 | 114 | /// Getter for [_txnId]. Leads to [UnsupportedError] on iOs. 115 | String? get txnId { 116 | if (io.Platform.isAndroid) { 117 | return _txnId; 118 | } 119 | throw UnsupportedError('The attribute txnId is not available on iOS'); 120 | } 121 | 122 | /// Getter for [_responseCode]. Leads to [UnsupportedError] on iOs. 123 | String? get responseCode { 124 | if (io.Platform.isAndroid) { 125 | return _responseCode; 126 | } 127 | throw UnsupportedError( 128 | 'The attribute responseCode is not available on iOS'); 129 | } 130 | 131 | /// Getter for [_approvalRefNo]. Leads to [UnsupportedError] on iOs. 132 | String? get approvalRefNo { 133 | if (io.Platform.isAndroid) { 134 | return _approvalRefNo; 135 | } 136 | throw UnsupportedError( 137 | 'The attribute approvalRefNo is not available on iOS'); 138 | } 139 | 140 | /// Getter for [_status]. 141 | UpiTransactionStatus? get status => _status; 142 | 143 | /// Getter for [_txnRef]. Leads to [UnsupportedError] on iOs. 144 | String? get txnRef { 145 | if (io.Platform.isAndroid) { 146 | return _txnRef; 147 | } 148 | throw UnsupportedError('The attribute txnRef is not available on iOS'); 149 | } 150 | 151 | /// Getter for [_rawResponse]. Leads to [UnsupportedError] on iOs. 152 | String? get rawResponse { 153 | if (io.Platform.isAndroid) { 154 | return _rawResponse; 155 | } 156 | throw UnsupportedError('The attribute rawResponse is not available on iOS'); 157 | } 158 | 159 | /// Getter for [_launchError]. Leads to [UnsupportedError] on Android. 160 | String? get launchError { 161 | if (io.Platform.isIOS) { 162 | return _launchError; 163 | } 164 | throw UnsupportedError( 165 | 'The attribute launchError is not available on Android'); 166 | } 167 | } 168 | -------------------------------------------------------------------------------- /APPS.md: -------------------------------------------------------------------------------- 1 | # UPI Applications Status 2 | 3 | ## Summary 4 | 5 | Verification period: 01/Apr/21 - 19/Apr/21 6 | 7 | ### Working Android Applications 8 | 9 | Name | Version | "Unverified Source" warning 10 | -|-|- 11 | BHIM CUB eWallet | 1.6.1 | Yes 12 | BHIM DCB UPI | 2.1.16 | Yes 13 | BHIM YesPay | 4.17 14 | Cointab | 1.3.37 15 | Freecharge | 9.11.1 16 | iMobile | 12.6 17 | MahaUpi | 1.7.0 18 | Mobikwik | 22.5.2 19 | OmegaPay | 1.2.28 20 | Yuva Pay | 2.3.2 21 | 22 | ### Working iOS Applications 23 | 24 | Name | Version | "Unverified Source" warning 25 | -|-|- 26 | BHIM AUPay | 1.1 | Yes 27 | Cointab | 1.1.29 28 | Freecharge | 4.8.2 29 | Mobikwik | 23.0 30 | Paytm | 9.4.0 31 | WhatsApp | 2.21.71 32 | 33 | ## Codes 34 | 35 | ### UPI Setup Statuses 36 | 37 | 1. Works 38 | 2. Reserved 39 | 3. Bank account holders only 40 | 4. Error post UPI setup 41 | 5. UPI setup fails 42 | 6. UPI disabled 43 | 7. Under maintenance 44 | 8. Device verification fails 45 | 9. Device verification SMS fails 46 | 10. Unstable 47 | 48 | ### UPI Linking Implementation Status 49 | 50 | 1. Works 51 | 2. Implemented; but not getting discovered 52 | 3. Absent 53 | 54 | ### Transaction Functioning Status 55 | 56 | 1. Works 57 | 2. UPI ref not returned 58 | 3. Does not return to caller 59 | 4. Risk Threshold Exceeded Error 60 | 5. Daily Transaction Limit Exceeded Error 61 | 6. Security Error 62 | 7. Payment fails 63 | 8. Payment form is incomplete 64 | 9. Payment form not shown 65 | 10. Bails out stating invalid params 66 | 11. Bails out refusing the recipient 67 | 12. Unstable behaviour for intent call 68 | 69 | ## Android Status 70 | 71 | Name | Version | UPI Setup Status | UPI Linking Status | Transaction Functioning Status | "Unverified Source" warning | Notes 72 | -|-|-|-|-|-|- 73 | Airtel | 4.21.0.2 | 1 | 1 | 3 | | Manual navigation forced, results in 'user_canceled' response 74 | Amazon | 22.7.0.330 | 1 | 1 | 5 75 | BHIM | 2.6.5 | 1 | 1 | 4 76 | BHIM ALLBANK | 1.2.7 | 10 | 1 77 | BHIM Andhra Bank | 1.2.37 | 9 | 1 78 | BHIM AUPay | 1.0.11 | 1 | 1 | 7 | Yes 79 | BHIM Axis Pay | 2.6.10.10 | 1 | 1 | 3 80 | BHIM Bandhan UPI | 1.6.2 | 1 | 1 | 7 | Yes | "No value for TXN ID" error while paying 81 | BHIM BOB Pay | 3.4.10 | 1 | 1 | 4 82 | BHIM BOI UPI | 2.0.3 | 1 | 1 | 3 | Yes 83 | BHIM Cent UPI | 2.0.11 | 1 | 1 | 9 | Yes 84 | BHIM CORP UPI | 1.0.3 | 10 | 1 85 | BHIM CSB Pay | 1.2.1 | 1 | 1 | 7 | | Payment not complete and abruptly returns to caller 86 | BHIM CUB eWallet | 1.6.1 | 1 | 1 | Works | Yes 87 | BHIM DCB UPI | 2.1.16 | 1 | 1 | Works | Yes 88 | BHIM DLB UPI | 1.1.0 | 1 | 1 | 4 89 | BHIM Equitas UPI | 2.0.1 | 1 | 1 | 12 90 | BHIM IDFC First Bank UPI | 1.1.15 | 1 | 1 | 10 | | 'Not valid merchant' error 91 | BHIM Indian Bank UPI | 1.5.14 | 10 | 1 92 | BHIM IndusPay UPI | 3.2.3 | 1 | 1 | 7 | Yes | Fails without any explicit error message 93 | BHIM IOB UPI | 1.27 | 8 | 1 94 | BHIM JetPay | 2.0.0 | 1 | 1 | 12 | | Exits as soon as launched and returns to caller 95 | BHIM J&K Bank UPI | 1.1.5 | 8 | 2 96 | BHIM KBL UPI | 1.2.7 | 1 | 1 | 10 | Yes 97 | BHIM KVB Upay | 1.1.24 | 1 | 1 | 7 98 | BHIM LOTZA UPI | 3.5.1 | 1 | 1 | 12 99 | BHIM LVB Upaay | 1.3.5 | 9 | 2 100 | BHIM Oriental Pay | 2.0.16 | 10 | 1 101 | BHIM Paywiz V2 | 2.9 | 4 | 2 102 | BHIM PNB | 2.1.2 | 4 | 1 103 | BHIM PSB | 2.1.08 | 10 | 1 104 | BHIM RBL Pay | 2.0.3 | 1 | 1 | 12 105 | BHIM SBI Pay | 2.3.1 | 1 | 1 | 7 | Yes 106 | BHIM@Synd UPI | 2.9.4 | 10 | 2 107 | BHIM UCO UPI | 1.2.7 | 1 | 1 | 12 108 | BHIM United UPI Pay | 2.0.8 | 8 | 2 109 | BHIM Vijaya UPI | 1.2.0 | 8 | 1 110 | BHIM YesPay | 4.17 | 1 | 1 | Works 111 | BPay | 3.4.2 | 8 | 2 112 | Bullet | 1.1.0 | 1 | 1 | 7 113 | Canara Bank | 2.0.58 | 1 | 1 | 7 | Yes | "B07" error (parameter in UPI reqPay API response) 114 | Cointab | 1.3.37 | 1 | 1 | Works 115 | CRED | 2.1.17.15 | 1 | 1 | 4 116 | CUB mBank Plus | 1.6.6 | 1 | 3 117 | DakPay | 2.0.5 | 7 | 2 118 | Digitbank DBS | 4.12.1 | 3 | 1 119 | FamPay | 1.2.9 | 6 | 1 120 | Freecharge | 9.11.1 | 1 | 1 | Works 121 | Google Pay | 126.1.2 | 1 | 1 | 5 122 | HDFC Bank | 10.0.7 | 8 | 1 123 | HSBC Simply Pay | 1.22 | 1 | 1 | 2 | Yes 124 | iMobile | 12.6 | 1 | 1 | Works 125 | Khaalijeb | 2.4.26 | 6 | 2 126 | LazyPay | 7.6.2 | 2 | 1 127 | MahaUpi | 1.7.0 | 1 | 1 | Works 128 | Mi Pay | 2.14.0-g | 1 | 1 | 3 129 | Mobikwik | 22.5.2 | 1 | 1 | Works 130 | MudraPay | 1.8.7 | 5 | 2 131 | MyJio | 6.0.33 | 1 | 1 | 3 132 | OmegaPay | 1.2.28 | 1 | 1 | Works 133 | Paytm | 9.3.2 | 1 | 1 | 5 134 | PayZapp | 4.09.00.03 | 8 | 2 135 | PhonePe | 4.1.11 | 1 | 1 | 6 136 | RBL MoBank | 8.0.18 | 1 | 1 | 8 | | Form doesn't have the amount and cannot be edited 137 | Realme PaySa | 2.0.2 | 6 | 2 138 | SIB Mirror+ | 8.0.18 | 8 | 2 139 | Tranzapp | 1.8 | 1 | 1 | 7 | | "R03 payer name missing" error (parameter in UPI reqPay API response) 140 | U-Mobile | 7.12.0 | 3 | 1 141 | UltraCash | 1.10.49 | 1 | 1 | 7 | | "Transaction cancelled" error thrown 142 | WhatsApp | 2.21.7.14 | 1 | 1 | 11 | | A pre-launch popup appears with message about refusing to pay the recipient 143 | YesBank | 5.2.15 | 3 | 1 144 | Yuva Pay | 2.3.2 | 1 | 1 | Works 145 | 146 | ## iOS Status 147 | 148 | Name | Version | UPI Setup Status | UPI Linking Status | Transaction Functioning Status | "Unverified Source" warning | Notes 149 | -|-|-|-|-|-|- 150 | Airtel | 4.7.50 | 1 | 3 151 | Allahabad emPower | 3.0.1 | 10 | 3 152 | Amazon | 17.7.0 | 1 | 3 153 | BHIM | 2.6.5 | 1 | 3 154 | BHIM Andhra Bank | 2.4 | 9 | 3 155 | BHIM AUPay | 1.1 | 1 | 1 | Works | Yes 156 | BHIM Axis Pay | 3.3.3 | 1 | 3 157 | BHIM Bandhan UPI | 1.0.1 | 1 | 3 158 | BHIM BOB Pay | 1.9 | 1 | 3 159 | BHIM BOI UPI | 2.0.3 | 1 | 3 160 | BHIM Cent UPI | 2.0.11 | 1 | 3 161 | BHIM DCB UPI | 1.0 | 9 | 3 162 | BHIM DLB UPI | 1.3 | 1 | 3 163 | BHIM IDFC First Bank UPI | 1.9 | 1 | 3 164 | BHIM Indian Bank UPI | 1.6.1 | 10 | 3 165 | BHIM JK Bank UPI | 1.1.2 | 8 | 1 166 | BHIM KVB Upay | 1.1.16 | 1 | 1 | 9 167 | BHIM LOTZA Pay | 3.5 | 1 | 1 | 7 | | "Invalid intent" error 168 | BHIM LVB Upaay | 1.3.4 | 8 | 3 169 | BHIM RBL Pay | 2.0 | 4 | 3 170 | BHIM SBI Pay | 1.3.4 | 1 | 3 171 | BHIM@Synd UPI | 2.3 | 10 | 1 172 | BHIM UCO UPI | 1.6 | 1 | 3 173 | BHIM United UPI | 2.7 | 8 | 1 174 | BHIM Vijaya UPI | 1.4 | 8 | 1 175 | BHIM Yes Pay | 4.17 | 8 | 3 176 | BPay | 2.0.5 | 6 | 3 177 | Bullet | 1.1.0 | 1 | 1 | 8 | | Submit button is disabled in the payment form 178 | Canara Bank | 2.0.38 | 1 | 3 179 | Cointab | 1.1.29 | 1 | 1 | Works 180 | CRED | 2.5.8 | 1 | 3 181 | Digibank DBS | 4.12.2 | 3 | 3 182 | FamPay | 2.0.7 | 6 | 1 183 | Freecharge | 4.8.2 | 1 | 1 | Works 184 | Google Pay | 118.1.8 | 1 | 1 | 5 185 | HDFC Bank | 10.0.7 | 5 | 3 186 | HSBC Simply Pay | 2.3.2 | 1 | 3 187 | iMobile | 6.9 | 1 | 3 188 | LazyPay | 4.5.0 | 2 | 3 189 | Mobikwik | 23.0 | 1 | 1 | Works 190 | MyJio | 6.0.23 | 1 | 3 191 | Paytm | 9.4.0 | 1 | 1 | Works 192 | PhonePe | 5.6.00 | 1 | 1 | 6 193 | RBL MoBank | 8.0.21 | 6 | 3 194 | SIB Mirror+ | 8.0.14 | 4 | 3 195 | U-Mobile | 7.12.0 | 3 | 3 196 | WhatsApp | 2.21.71 | 1 | 1 | Works 197 | YesBank | 5.2.14 | 3 | 3 198 | -------------------------------------------------------------------------------- /doc/api/upi_pay/UpiTransactionResponse/UpiTransactionResponse.iosError.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | UpiTransactionResponse.iosError constructor - UpiTransactionResponse class - upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 37 |
UpiTransactionResponse.iosError
38 | 41 |
42 | 43 |
44 | 45 | 46 |
47 |
48 |

UpiTransactionResponse.iosError constructor 49 | Null safety 50 |

51 | 52 |
53 | UpiTransactionResponse.iosError(
  1. dynamic error
  2. 54 |
) 55 |
56 | 57 | 58 |
59 |

iOS platform app launch exception case constructor.

60 |

Populates _status and _launchError.

61 |
62 | 63 | 64 | 65 |
66 |

Implementation

67 |
UpiTransactionResponse.iosError(error) {
 68 |   _status = UpiTransactionStatus.failedToLaunch;
 69 |   _launchError = error.toString();
 70 | }
71 |
72 | 73 | 74 |
75 | 76 | 126 | 127 | 129 | 130 |
131 | 132 |
133 | 134 | upi_pay 135 | 1.0.0 136 | 137 | 138 | 139 |
140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | -------------------------------------------------------------------------------- /doc/api/upi_pay/upi_pay-library.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | upi_pay library - Dart API 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 26 | 27 |
28 | 29 |
30 | 31 | 35 |
upi_pay
36 | 39 |
40 | 41 |
42 | 43 | 44 |
45 |
46 |

upi_pay library 47 | Null safety 48 | 49 |

50 | 51 | 52 | 53 | 54 |
55 |

Classes

56 | 57 |
58 |
59 | ApplicationMeta 60 | 61 |
62 |
63 | Represents a UPI payment app and more relevant information. [...] 64 |
65 | 66 |
67 | UpiApplication 68 | 69 |
70 |
71 | Represents a UPI payment application. [...] 72 |
73 | 74 |
75 | UpiPay 76 | 77 |
78 |
79 | Helps with getting installed UPI apps and making payments using them. [...] 80 |
81 | 82 |
83 | UpiTransactionResponse 84 | 85 |
86 |
87 | Structured data representing response of a UPI transaction request. 88 |
89 | 90 |
91 |
92 | 93 | 94 | 95 | 96 | 97 | 98 |
99 |

Enums

100 | 101 |
102 |
103 | UpiApplicationDiscoveryAppPaymentType 104 | 105 |
106 |
107 | Represents the type of payments in the apps that user wants to access. [...] 108 |
109 | 110 |
111 | UpiApplicationDiscoveryAppStatusType 112 | 113 |
114 |
115 | Represents the UPI payment working status of apps that user wants to access. [...] 116 |
117 | 118 |
119 | UpiTransactionStatus 120 | 121 |
122 |
123 | Represents status of executing a UPI transaction by launching a UPI app. 124 |
125 | 126 |
127 |
128 | 129 | 130 | 131 |
132 | 133 | 153 | 154 | 177 | 178 |
179 | 180 |
181 | 182 | upi_pay 183 | 1.0.0 184 | 185 | 186 | 187 |
188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | --------------------------------------------------------------------------------