upi_pro_sdk

pub version pub points popularity License: MIT Platform

A production-grade Flutter SDK for seamless UPI (Unified Payments Interface) integration in India.
Supports UPI intent flow, deep links, VPA validation, payment status polling, and multi-app launchers โ€” all with a clean, type-safe API.


๐Ÿ“ฑ Demo

UPI Pro SDK Demo


โœจ Features

  • ๐Ÿš€ UPI Intent Flow โ€” Launch any installed UPI app (GPay, PhonePe, Paytm, BHIM, etc.)
  • ๐Ÿ”— Deep Link Support โ€” Generate and handle upi:// deep links
  • โœ… VPA Validation โ€” Validate Virtual Payment Addresses before initiating payment
  • ๐Ÿ“ก Payment Status Polling โ€” Poll transaction status with configurable retries
  • ๐Ÿ“ฒ Multi-App Launcher โ€” Show a bottom sheet with all available UPI apps
  • ๐Ÿ”’ Type-Safe Models โ€” Strongly typed UpiPaymentRequest, UpiPaymentResponse
  • ๐Ÿงช Fully Testable โ€” Injectable dependencies, mockable interfaces
  • ๐Ÿ“ฑ Android & iOS โ€” Works on both platforms

๐Ÿ“ฆ Installation

Add to your pubspec.yaml:

dependencies:
  upi_pro_sdk: ^0.1.0

Then run:

flutter pub get

โš™๏ธ Platform Setup

Android

Add the following to android/app/src/main/AndroidManifest.xml inside <manifest>:

<queries>
  <intent>
    <action android:name="android.intent.action.VIEW" />
    <data android:scheme="upi" />
  </intent>
</queries>

iOS

Add the following to ios/Runner/Info.plist:

<key>LSApplicationQueriesSchemes</key>
<array>
  <string>upi</string>
  <string>gpay</string>
  <string>phonepe</string>
  <string>paytmmp</string>
</array>

๐Ÿš€ Quick Start

1. Initialize the SDK

import 'package:upi_pro_sdk/upi_pro_sdk.dart';

final upiClient = UpiProClient(
  merchantId: 'your_merchant_id',
  merchantName: 'Your Business Name',
);

2. Initiate a Payment

final request = UpiPaymentRequest(
  payeeVpa: 'merchant@okaxis',
  payeeName: 'Acme Pvt Ltd',
  amount: 499.00,
  transactionId: 'TXN_${DateTime.now().millisecondsSinceEpoch}',
  transactionNote: 'Order #1042 payment',
  currency: 'INR',
);

try {
  final response = await upiClient.initiatePayment(request);

  switch (response.status) {
    case UpiPaymentStatus.success:
      print('Payment successful! UPI Ref: ${response.upiTransactionId}');
      break;
    case UpiPaymentStatus.pending:
      print('Payment pending. Poll for status.');
      break;
    case UpiPaymentStatus.failure:
      print('Payment failed: ${response.responseCode}');
      break;
  }
} on UpiException catch (e) {
  print('UPI Error: ${e.message} (code: ${e.code})');
}

3. Launch Multi-App UPI Selector

await upiClient.showAppChooser(
  context: context,
  request: request,
  onResponse: (UpiPaymentResponse response) {
    // handle response
  },
);

4. Validate a VPA

final result = await upiClient.validateVpa('user@oksbi');

if (result.isValid) {
  print('VPA is valid. Name: ${result.name}');
} else {
  print('Invalid VPA');
}

5. Poll Payment Status

final status = await upiClient.pollPaymentStatus(
  transactionId: 'TXN_1234567890',
  maxRetries: 5,
  retryInterval: Duration(seconds: 3),
);

print('Final status: ${status.status}');

๐Ÿ—‚๏ธ API Reference

UpiProClient

Method Description
initiatePayment(request) Initiates UPI payment via intent
showAppChooser(context, request, onResponse) Shows installed UPI apps in a bottom sheet
validateVpa(vpa) Validates a Virtual Payment Address
pollPaymentStatus(transactionId) Polls for transaction status
getInstalledUpiApps() Returns list of installed UPI apps

UpiPaymentRequest

Field Type Required Description
payeeVpa String โœ… Payee's VPA (e.g., merchant@okaxis)
payeeName String โœ… Payee display name
amount double โœ… Amount in INR
transactionId String โœ… Unique transaction ID

UpiPaymentResponse

Field Type Description
transactionId String Your transaction ID
upiTransactionId String? UPI network transaction ID
status UpiPaymentStatus success, pending, or failure
responseCode String? UPI response code
approvalRefNo String? Bank approval reference

๐Ÿงช Testing

// Use the mockable interface for unit tests
final mockClient = MockUpiProClient();

when(() => mockClient.validateVpa(any())).thenAnswer(
  (_) async => VpaValidationResult(isValid: true, name: 'Test User'),
);

Run tests:

flutter test

๐Ÿ“‹ Supported UPI Apps

App Android iOS
Google Pay โœ… โœ…
PhonePe โœ… โœ…
Paytm โœ… โœ…
BHIM โœ… โœ…
CRED โœ… โœ…
Other UPI Apps โœ… โš ๏ธ

๐Ÿค Contributing

Contributions are welcome! Please read CONTRIBUTING.md first.

  1. Fork the repo
  2. Create a feature branch: git checkout -b feat/your-feature
  3. Commit your changes: git commit -m 'feat: add your feature'
  4. Push and open a PR

๐Ÿ“„ License

MIT License โ€” see LICENSE for details.


๐Ÿ™ Acknowledgements

Built with โค๏ธ for the Indian Flutter developer community.
Follows NPCI UPI Linking Specifications.