Hey! Folks 👨🏻💻 today we’ll integrate the RazorPay Payment Gateway in Flutter.
Before we get started I urge you to go and check out our Flutter App Development Company.
Let’s start the party.
Create a fresh project to integrate the Razorpay Payment Gateway in Flutter.
Prerequisites
- Create a Razorpay Account.
- Generate API Keys from the Razorpay Dashboard. Once you are done with the integration, you can generate Live Mode API Keys and replace them in the integration.
- Know more about Razorpay Payment Flow.
Step 1.
Add Razorpay_flutter in pubspec.yaml file.
1 2 3 4 5 6 |
// SDK Version environment: sdk: ">=2.17.6 <3.0.0" dependencies: razorpay_flutter: ^1.3.4 |
Step 2.
If you are using Proguard for your builds, you need to add the following lines to the Proguard files:
1 2 3 4 5 6 7 |
-keepattributes *Annotation* -dontwarn com.razorpay.** -keep class com.razorpay.** {*;} -optimizations !method/inlining/ -keepclasseswithmembers class * { public void onPayment*(...); } |
Note: If there is no proguard file in Android app level then create a new file in
the directory – android/app/proguard-rules.pro
Step 3.
Now run the command in the terminal – flutter pub get
Minimum Version Requirement
- For Android, ensure that the minimum API level for your app is 19 or higher.
- For iOS, ensure that the minimum deployment target for your app is iOS 10.0 or higher. Also, don’t forget to enable bit code for your project.
Step 4.
Create a Razorpay instance.
1 |
_razorpay = Razorpay(); |
Attach event listener to listen to the changes at payment gateway sdk.
1 2 3 |
_razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, _handlePaymentSuccess); _razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, _handlePaymentError); _razorpay.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet); |
Creates handler for listeners.
1 2 3 4 5 6 7 8 9 10 11 |
void _handlePaymentSuccess(PaymentSuccessResponse response) { // Do something when payment succeeds } void _handlePaymentError(PaymentFailureResponse response) { // Do something when payment fails } void _handleExternalWallet(ExternalWalletResponse response) { // Do something when an external wallet is selected } |
Add this line after the payment gets successful and in dispose method.
1 |
_razorpay.clear(); // Removes all listeners |
razorpayOrderId you need to generate this orderId for payment.
you can generate test orderId in postman.
After the successful request, you’ll get this response.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
{ "id": "order_LjC8bnevx4rcVy", "entity": "order", "amount": 160700, "amount_paid": 0, "amount_due": 160700, "currency": "INR", "receipt": "497", "status": "created", "offer_id": "", "attempts": 0, "created_at": 1682681270, "notes": { "source": "", "merchant_order_id": 497 } } |
Check the full Code for the Razorpay Payment gateway.
main.dart file
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
void main() { runApp(const MyApp()); } class MyApp extends StatelessWidget { const MyApp({Key? key}) : super(key: key); // This widget is the root of your application. @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Razarpay Demo', theme: ThemeData( primarySwatch: Colors.blue, ), home: const PaymentRazorPayScreen() ); } } |
razorpay_payment_screen.dart
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 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 86 87 88 89 |
class RazorpayPaymentScreen extends StatefulWidget { const RazorpayPaymentScreen({Key? key}) : super(key: key); @override State<RazorpayPaymentScreen> createState() => _RazorpayPaymentScreenState(); } class _RazorpayPaymentScreenState extends State<RazorpayPaymentScreen> { Razorpay? _razorpay; @override void initState() { super.initState(); try { _razorpay = Razorpay(); _razorpay?.on(Razorpay.EVENT_PAYMENT_SUCCESS, _handlePaymentSuccess); _razorpay?.on(Razorpay.EVENT_PAYMENT_ERROR, _handlePaymentError); _razorpay?.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet); } catch (e) { debugPrint(e.toString()); } } @override void dispose() { super.dispose(); _razorpay?.clear(); } void openCheckout() async { var options = { 'key': "your_test_key", 'amount': (1 * 100), 'order_id': "orderData", 'name': "user_name", 'description': 'Payment', 'timeout': 300, 'prefill': {'contact': "add_phone_no_here", 'email': "add_email_here"}, // Add this line to add the orderId in razorpay dashboard "notes": {"order_id": 1234} }; try { _razorpay?.open(options); } catch (e) { debugPrint(e.toString()); } } void _handlePaymentSuccess(PaymentSuccessResponse response) { try { print( "RazorPayResponseData: OrderId: ${response.orderId}, PaymentId: ${response.paymentId}, Signature: ${response.signature}"); } catch (e) { print("RazorPayResponseError: $e"); } } void _handlePaymentError(PaymentFailureResponse response) { try { print("_handlePaymentError ${response.message}"); } catch (e) { print("_handlePaymentError: $e"); } } void _handleExternalWallet(ExternalWalletResponse response) { try { print("WalletResponse ${response.walletName}"); } catch (e) { print("WalletResponseError: $e"); } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text("Razorpay Demo App"), ), body: Center( child: TextButton( onPressed: openCheckout, child: const Text("Pay"), ), ), ); } } |
After the payment gets successful you can check the Razorpay dashboard.
NOTE: There is some issue in Razorpay SDK.
If you’re getting this issue “type ‘String’ is not a subtype of type ‘Map<dynamic, dynamic>?’ in type cast”
You need to add some code in their SDK.
in razorpay_flutter.dart file replace this code with existing code in PaymentFailureResponse function.
Before-
1 2 3 4 5 6 |
static PaymentFailureResponse fromMap(Map<dynamic, dynamic> map) { var code = map["code"] as int?; var message = map["message"] as String?; var responseBody = map["responseBody"] as Map<dynamic, dynamic>?; return new PaymentFailureResponse(code, message, responseBody); } |
After- Line no – 140
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
class PaymentFailureResponse { int? code; String? message; Map<dynamic, dynamic>? error; PaymentFailureResponse(this.code, this.message, this.error); static PaymentFailureResponse fromMap(Map<dynamic, dynamic> map) { var code = map["code"] as int?; var message = map["message"] as String?; Map<dynamic?, dynamic?> responseBodyMap; if (map["responseBody"] is Map) { responseBodyMap = map["responseBody"]; } else { responseBodyMap = json.decode(map["responseBody"]); } var responseBody = responseBodyMap as Map<dynamic, dynamic>?; return new PaymentFailureResponse(code, message, responseBody); } } |
That’s all for this Article 🎊 .
Conclusion
Razorpay Payment Gateway in Flutter in this blog we’ve learned how to integrate the razorpay into Flutter app.
Visit the link for Razorpay’s official documents.
Thanks for reading this blog. You can also check other blogs from here for more knowledge.