๐ณ Razorpay Flutter
Accept payments seamlessly across all platforms
Android โข iOS โข Web โข Windows โข Linux โข macOS
Getting Started โข Installation โข Usage โข API Reference โข Examples
โจ Features
- ๐ True Cross-Platform - Single API for Android, iOS, Web, Windows, Linux, and macOS
- ๐ฏ Event-Driven Architecture - Clean, reactive payment flow handling
- ๐ Production Ready - Built on official Razorpay SDKs for mobile platforms
- ๐ช Native Windows Support - Seamless WebView integration with InAppWebView
- ๐งช Test Mode - Full sandbox environment support for development
- ๐ฑ External Wallets - Support for Paytm, PhonePe, Google Pay, and more
- โก Zero Configuration - Works out of the box with minimal setup
โ Support the Development
๐ Help Keep This Project Alive & Thriving
As a full-time developer working on this plugin in my limited spare time, your support means the world! Every contribution helps me dedicate more hours to:
โจ Adding new features โข ๐ Fixing bugs faster โข ๐ Improving documentation โข ๐ Supporting new platforms
๐ If this plugin saved you hours of work, consider buying me a chai!
Your support directly impacts how much time I can invest in making this plugin better for everyone.
๐ธ Screenshots
๐ Getting Started
Prerequisites
Before integrating this plugin, you'll need:
- Razorpay Account - Sign up here
- API Keys - Generate from your Razorpay Dashboard
- Use Test Keys for development (no real transactions)
- Switch to Live Keys for production
๐ก New to Razorpay? Learn about the payment flow before integrating.
๐ฆ Installation
Add razorpay_web to your pubspec.yaml:
dependencies:
razorpay_web: ^3.1.0
Then run:
flutter pub get
Platform-Specific Setup
๐ค Android Setup
Minimum Requirements
- Min SDK Version: 19 (Android 4.4+)
Update android/app/build.gradle:
android {
defaultConfig {
minSdkVersion 19 // Ensure this is at least 19
}
}
ProGuard Rules (if using)
Add to your ProGuard configuration:
-keepattributes *Annotation*
-dontwarn com.razorpay.**
-keep class com.razorpay.** {*;}
-optimizations !method/inlining/
-keepclasseswithmembers class * {
public void onPayment*(...);
}
๐ iOS Setup
Minimum Requirements
- Min Deployment Target: iOS 10.0
- Bitcode: Enabled
Update ios/Podfile:
platform :ios, '10.0'
post_install do |installer|
installer.pods_project.targets.each do |target|
target.build_configurations.each do |config|
config.build_settings['ENABLE_BITCODE'] = 'YES'
config.build_settings['SWIFT_VERSION'] = '5.0'
end
end
end
Add use_frameworks! if you encounter Swift header issues:
use_frameworks!
Then run:
cd ios && pod install
๐ Web Setup
Add the Razorpay checkout script to web/index.html inside the <body> tag:
<body>
<!-- Other content -->
<script src="https://checkout.razorpay.com/v1/checkout.js"></script>
<script src="main.dart.js" type="application/javascript"></script>
</body>
๐ช Windows Setup
Requirements
- Microsoft Edge WebView2 Runtime (pre-installed on Windows 10/11)
No additional configuration needed! The plugin uses flutter_inappwebview to provide a native-like payment experience.
โ ๏ธ Important: You must pass
contextparameter when callingopen()on Windows.
๐ง Linux Setup
Uses the same WebView implementation as Windows. No additional setup required.
๐ macOS Setup
Requirements
Uses the same WebView implementation as Windows.
Entitlements Configuration
Add network client permission to your entitlements files:
macos/Runner/DebugProfile.entitlements:
<key>com.apple.security.network.client</key>
<true/>
macos/Runner/Release.entitlements:
<key>com.apple.security.network.client</key>
<true/>
This is required for the WebView to load Razorpay's checkout page.
โ ๏ธ Important: You must pass
contextparameter when callingopen()on macOS.
๐ป Usage
Quick Start
import 'package:flutter/material.dart';
import 'package:razorpay_web/razorpay_web.dart';
class PaymentScreen extends StatefulWidget {
@override
_PaymentScreenState createState() => _PaymentScreenState();
}
class _PaymentScreenState extends State<PaymentScreen> {
late Razorpay _razorpay;
@override
void initState() {
super.initState();
_razorpay = Razorpay();
_razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, _handlePaymentSuccess);
_razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, _handlePaymentError);
_razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet);
}
@override
void dispose() {
super.dispose();
_razorpay.clear();
}
void openCheckout() async {
var options = {
'key': 'rzp_test_1DP5mmOlF5G5ag',
'amount': 100, // amount in the smallest currency unit (paise)
'name': 'Acme Corp.',
'description': 'Fine T-Shirt',
'prefill': {
'contact': '8888888888',
'email': 'test@razorpay.com'
},
'external': {
'wallets': ['paytm']
}
};
try {
_razorpay.open(options, context: context);
} catch (e) {
debugPrint('Error: $e');
}
}
void _handlePaymentSuccess(PaymentSuccessResponse response) {
print('Success: ${response.paymentId}');
// Do something when payment succeeds
}
void _handlePaymentError(PaymentFailureResponse response) {
print('Error: ${response.code} - ${response.message}');
// Do something when payment fails
}
void _handleExternalWallet(ExternalWalletResponse response) {
print('External Wallet: ${response.walletName}');
// Do something when an external wallet is selected
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: Text('Razorpay Payment')),
body: Center(
child: ElevatedButton(
onPressed: openCheckout,
child: Text('Pay Now'),
),
),
);
}
}
Step-by-Step Guide
1๏ธโฃ Import the Package
import 'package:razorpay_web/razorpay_web.dart';
2๏ธโฃ Create Razorpay Instance
late Razorpay _razorpay;
@override
void initState() {
super.initState();
_razorpay = Razorpay();
}
3๏ธโฃ Attach Event Listeners
The plugin uses an event-driven architecture. Attach listeners for payment events:
_razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, _handlePaymentSuccess);
_razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, _handlePaymentError);
_razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet);
4๏ธโฃ Define Event Handlers
void _handlePaymentSuccess(PaymentSuccessResponse response) {
// Payment ID: response.paymentId
// Order ID: response.orderId (if order was created)
// Signature: response.signature (for verification)
}
void _handlePaymentError(PaymentFailureResponse response) {
// Error code: response.code
// Error message: response.message
}
void _handleExternalWallet(ExternalWalletResponse response) {
// Wallet name: response.walletName
}
5๏ธโฃ Configure Payment Options
var options = {
'key': 'YOUR_RAZORPAY_KEY', // Required
'amount': 50000, // Required (in paise: 50000 = โน500)
'name': 'Your Business Name',
'description': 'Product Description',
'order_id': 'order_xyz123', // Optional: for order-based payments
'prefill': {
'contact': '9876543210',
'email': 'customer@example.com'
},
'theme': {
'color': '#F37254'
}
};
๐ See all available options
6๏ธโฃ Open Checkout
// For Android, iOS, and Web
_razorpay.open(options);
// For Windows, Linux, and macOS (context required)
_razorpay.open(options, context: context);
7๏ธโฃ Clean Up
@override
void dispose() {
super.dispose();
_razorpay.clear(); // Remove all event listeners
}
๐งช Testing
Razorpay provides test UPI IDs for sandbox testing:
| UPI ID | Result |
|---|---|
success@razorpay |
โ Payment Success |
failure@razorpay |
โ Payment Failure |
Use these with any test Razorpay key to simulate payment flows without real transactions.
๐ API Reference
Razorpay Class
Methods
open(Map<String, dynamic> options, {BuildContext? context})
Opens the Razorpay checkout interface.
Parameters:
options(required): Payment configuration mapkey(required): Your Razorpay API keyamount(required): Amount in smallest currency unit (paise for INR)name: Business/product namedescription: Payment descriptionorder_id: Order ID for order-based paymentsprefill: Pre-filled customer detailstheme: Checkout UI customization- See all options
context(optional): BuildContext - Required for Windows, Linux, and macOS
Example:
_razorpay.open({
'key': 'rzp_test_1DP5mmOlF5G5ag',
'amount': 100,
'name': 'Acme Corp.',
}, context: context);
on(String event, Function handler)
Registers an event listener for payment events.
Parameters:
event: Event name (use constants fromRazorpayclass)handler: Callback function with appropriate response type
Example:
_razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, (PaymentSuccessResponse response) {
print('Payment ID: ${response.paymentId}');
});
clear()
Removes all event listeners. Call this in dispose() to prevent memory leaks.
Example:
@override
void dispose() {
_razorpay.clear();
super.dispose();
}
Event Names
Use these constants from the Razorpay class:
| Constant | Value | Description |
|---|---|---|
EVENT_PAYMENT_SUCCESS |
"payment.success" |
Payment completed successfully |
EVENT_PAYMENT_ERROR |
"payment.error" |
Payment failed or encountered an error |
EVENT_EXTERNAL_WALLET |
"payment.external_wallet" |
External wallet was selected |
Response Models
PaymentSuccessResponse
Emitted when payment succeeds.
| Property | Type | Description |
|---|---|---|
paymentId |
String? |
Unique payment identifier |
orderId |
String? |
Order ID (if order-based payment) |
signature |
String? |
Payment signature for verification (orders only) |
Example:
void _handlePaymentSuccess(PaymentSuccessResponse response) {
print('Payment ID: ${response.paymentId}');
print('Order ID: ${response.orderId}');
print('Signature: ${response.signature}');
}
PaymentFailureResponse
Emitted when payment fails.
| Property | Type | Description |
|---|---|---|
code |
int? |
Error code (see error codes below) |
message |
String? |
Human-readable error message |
Example:
void _handlePaymentError(PaymentFailureResponse response) {
print('Error Code: ${response.code}');
print('Error Message: ${response.message}');
}
ExternalWalletResponse
Emitted when user selects an external wallet.
| Property | Type | Description |
|---|---|---|
walletName |
String? |
Name of the selected wallet (e.g., "paytm") |
Example:
void _handleExternalWallet(ExternalWalletResponse response) {
print('Wallet: ${response.walletName}');
}
Error Codes
Access these constants from the Razorpay class:
| Constant | Value | Description |
|---|---|---|
NETWORK_ERROR |
0 |
Network connectivity issue |
INVALID_OPTIONS |
1 |
Invalid options passed to open() |
PAYMENT_CANCELLED |
2 |
User cancelled the payment |
TLS_ERROR |
3 |
Device doesn't support TLS v1.1 or v1.2 |
UNKNOWN_ERROR |
4 |
An unknown error occurred |
Example:
void _handlePaymentError(PaymentFailureResponse response) {
if (response.code == Razorpay.NETWORK_ERROR) {
print('Network error occurred');
} else if (response.code == Razorpay.PAYMENT_CANCELLED) {
print('User cancelled the payment');
}
}
๐ฏ Examples
Basic Payment
void makePayment() {
var options = {
'key': 'rzp_test_1DP5mmOlF5G5ag',
'amount': 50000, // โน500
'name': 'Product Name',
'description': 'Product Description',
};
_razorpay.open(options, context: context);
}
Order-Based Payment
void makeOrderPayment() {
// First, create an order on your backend
// Then use the order_id in options
var options = {
'key': 'rzp_test_1DP5mmOlF5G5ag',
'amount': 50000,
'name': 'Product Name',
'order_id': 'order_xyz123', // Order ID from backend
'prefill': {
'contact': '9876543210',
'email': 'customer@example.com'
}
};
_razorpay.open(options, context: context);
}
Custom Theme
void makeStyledPayment() {
var options = {
'key': 'rzp_test_1DP5mmOlF5G5ag',
'amount': 50000,
'name': 'Your Business',
'theme': {
'color': '#F37254',
'backdrop_color': '#000000'
},
'image': 'https://your-logo-url.com/logo.png',
};
_razorpay.open(options, context: context);
}
With External Wallets
void makeWalletPayment() {
var options = {
'key': 'rzp_test_1DP5mmOlF5G5ag',
'amount': 50000,
'name': 'Product Name',
'external': {
'wallets': ['paytm', 'phonepe', 'googlepay']
}
};
_razorpay.open(options, context: context);
}
Complete Example
Check out the example app for a full working implementation with:
- Event listener setup
- Test UPI IDs for success/failure
- Error handling
- Platform-specific context handling
๐ง Troubleshooting
iOS: CocoaPods compatibility error
Error:
Specs satisfying the `razorpay_flutter` dependency were found, but they required a higher minimum deployment target.
Solution:
Update ios/Podfile:
platform :ios, '10.0'
Then run:
cd ios && pod install
iOS: Swift header file not found
Error:
'razorpay_flutter/razorpay_flutter-Swift.h' file not found
Solution:
Add use_frameworks! to ios/Podfile:
use_frameworks!
Then run:
cd ios && pod install
Android: minSdkVersion error
Error:
uses-sdk:minSdkVersion 16 cannot be smaller than version 19
Solution:
Update android/app/build.gradle:
defaultConfig {
minSdkVersion 19
}
Windows: Context parameter required
Error:
BuildContext is required for Windows platform
Solution:
Always pass context when calling open() on Windows:
_razorpay.open(options, context: context);
macOS: WebView blank or crashing
Error:
onWebContentProcessDidTerminate
Solution: Add network client entitlement to both entitlements files:
macos/Runner/DebugProfile.entitlements:
<key>com.apple.security.network.client</key>
<true/>
macos/Runner/Release.entitlements:
<key>com.apple.security.network.client</key>
<true/>
Then rebuild your app:
flutter clean
flutter build macos
Type mismatch in event handlers
Error:
type 'PaymentFailureResponse' is not a subtype of type 'PaymentSuccessResponse'
Solution: Ensure your event handlers have correct signatures:
void _handlePaymentSuccess(PaymentSuccessResponse response) { }
void _handlePaymentError(PaymentFailureResponse response) { }
void _handleExternalWallet(ExternalWalletResponse response) { }
Class name conflict
Error:
xxxx is not defined for the class 'Razorpay'
Solution:
Check if you're accidentally redeclaring the Razorpay class. The plugin exports it from package:razorpay_web/razorpay_web.dart.
๐ Documentation
- Razorpay Payment Gateway Docs
- Checkout Options Reference
- Android SDK Documentation
- iOS SDK Documentation
- Payment Flow Guide
๐ค Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
๐ Acknowledgments
- Built on top of official Razorpay Android and iOS SDKs
- Uses flutter_inappwebview for Windows/Linux/macOS support
- Inspired by the Flutter community's need for a truly cross-platform payment solution
โ ๏ธ Disclaimer
This is NOT an official Razorpay plugin.
This plugin is an independent, community-driven project and is not affiliated with, endorsed by, or officially supported by Razorpay.
Use at your own risk. The author and contributors:
- Are not responsible for any issues, damages, or losses arising from the use of this plugin
- Make no warranties or guarantees regarding functionality, security, or reliability
- Are not liable for any financial transactions or payment processing issues
- Recommend thorough testing in sandbox/test mode before production use
For official Razorpay integrations and support, please refer to Razorpay's official documentation.
Made with โค๏ธ for the Flutter community