Accepting online payments is one of the most important features of any eCommerce, subscription, food delivery, booking, or service application. Razorpay is one of India's most popular payment gateways and provides a simple Flutter SDK for integrating secure payments.
In this tutorial, you'll learn how to integrate Razorpay into your Flutter application from scratch.
What is Razorpay?
Razorpay is a secure online payment gateway that allows businesses to accept payments through:
- UPI
- Credit Cards
- Debit Cards
- Net Banking
- Wallets
- EMI
- Pay Later
It offers an easy-to-use SDK for Flutter and excellent documentation.
Features
- Secure payments
- Fast integration
- UPI support
- Card payments
- Wallet payments
- Net Banking
- EMI options
- Payment callbacks
- Refund support
- Dashboard analytics
Prerequisites
Before starting, make sure you have:
- Flutter SDK installed
- Android Studio or VS Code
- Razorpay Account
- Android device or emulator
- Basic Flutter knowledge
Step 1: Create Razorpay Account
- Visit Razorpay Dashboard.
- Create a new account.
- Verify your mobile number and email.
- Complete your business verification.
- Generate API Keys.
You'll receive:
Key ID
and
Key Secret
Never expose your Key Secret inside your Flutter application.
Step 2: Create Flutter Project
flutter create razorpay_demo cd razorpay_demo
Step 3: Add Dependency
Open
pubspec.yaml
Add
dependencies:
flutter:
sdk: flutter
razorpay_flutter: ^1.4.0
Now install
flutter pub get
Step 4: Android Configuration
Open
android/app/src/main/AndroidManifest.xml
Add Internet Permission
<uses-permission android:name="android.permission.INTERNET"/>
Step 5: iOS Configuration
Open
ios/Runner/Info.plist
Add
<key>LSApplicationQueriesSchemes</key> <array> <string>upi</string> <string>phonepe</string> <string>paytmmp</string> <string>tez</string> </array>
Then run
pod install
Step 6: Import Razorpay
import 'package:razorpay_flutter/razorpay_flutter.dart';
Step 7: Create Razorpay Object
late Razorpay _razorpay;
Initialize
@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);
}
Step 8: Create Payment Function
void openCheckout() {
var options = {
'key': 'YOUR_KEY_ID',
'amount': 50000,
'name': 'Deep Crazy World',
'description': 'Flutter Course',
'prefill': {
'contact': '9876543210',
'email': 'user@email.com'
},
'external': {
'wallets': ['paytm']
}
};
try {
_razorpay.open(options);
} catch (e) {
print(e);
}
}
Amount Calculation
Razorpay accepts the amount in paise.
AmountValue₹1100₹101000₹10010000₹50050000
Example:
amount: 99900
Means
₹999
Step 9: Payment Success Callback
void _handlePaymentSuccess(
PaymentSuccessResponse response) {
print(response.paymentId);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Payment Successful"),
));
}
Step 10: Payment Failed
void _handlePaymentError(
PaymentFailureResponse response) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Payment Failed"),
));
}
Step 11: External Wallet
void _handleExternalWallet(
ExternalWalletResponse response) {
print(response.walletName);
}
Step 12: Dispose
@override
void dispose() {
_razorpay.clear();
super.dispose();
}
Step 13: Payment Button
ElevatedButton(
onPressed: openCheckout,
child: Text("Pay Now"),
)
Complete Example
class PaymentPage extends StatefulWidget {
const PaymentPage({super.key});
@override
State<PaymentPage> createState() => _PaymentPageState();
}
class _PaymentPageState extends State<PaymentPage> {
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);
}
void openCheckout() {
var options = {
'key': 'YOUR_KEY_ID',
'amount': 50000,
'name': 'Flutter Shop',
'description': 'Premium Product',
'prefill': {
'contact': '9876543210',
'email': 'abc@gmail.com'
}
};
_razorpay.open(options);
}
void _handlePaymentSuccess(
PaymentSuccessResponse response) {
print(response.paymentId);
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Payment Successful"),
),
);
}
void _handlePaymentError(
PaymentFailureResponse response) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Text("Payment Failed"),
),
);
}
void _handleExternalWallet(
ExternalWalletResponse response) {
print(response.walletName);
}
@override
void dispose() {
_razorpay.clear();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("Razorpay Demo"),
),
body: Center(
child: ElevatedButton(
onPressed: openCheckout,
child: Text("Pay Now"),
),
),
);
}
}
Test Cards
During testing, Razorpay provides test payment methods in Test Mode. Use the Razorpay Dashboard documentation for the latest test cards, UPI IDs, and wallet credentials. Never use real customer payment details while testing.
Best Practices
- Never store API Secret inside Flutter.
- Create Orders from your backend.
- Verify payment signature on the server.
- Always use HTTPS APIs.
- Validate payment before delivering products.
- Log payment responses securely.
- Handle payment failures gracefully.
- Implement retries for network issues.
Common Errors
Payment Failed
- Invalid API Key
- Internet connection issue
- Incorrect amount format
- Razorpay account not activated
Plugin Not Working
Run
flutter clean flutter pub get
Android Build Failed
Update Gradle
flutter doctor
Check Android SDK versions.
Payment Window Doesn't Open
Verify:
- Internet permission added
- Correct Key ID
- Razorpay initialized properly
- Event listeners registered
Production Checklist
- Enable Live Mode.
- Replace the Test Key with the Live Key ID.
- Keep the Key Secret only on your backend.
- Verify payment signatures server-side.
- Test UPI, cards, wallets, and refunds.
- Monitor transactions from the Razorpay Dashboard.
Advantages of Razorpay
- Easy Flutter integration
- Fast onboarding
- Multiple payment methods
- Secure transactions
- Excellent dashboard
- Refund support
- Subscription payments
- Payment links
- Smart analytics
Conclusion
Integrating Razorpay into a Flutter application is straightforward when you follow the proper setup process. For a production-ready integration, always create payment orders on your backend, verify the payment signature after a successful transaction, and never expose your API Secret in the mobile app. Following these practices helps ensure secure and reliable payment processing for your users.