razorpay in flutter
razorpay UI in flutter

The only provider of converged payments solutions in India that offers a product suite that enables your company to accept, process, and disburse payments is Razorpay. You can use all payment methods, including credit and debit cards, UPI and well-known mobile wallets with Razorpay.

Flutter Razorpay’s Custom-UI

Flutter plugin for the Razorpay Custom SDK. This flutter plugin is wrapper for our SDKs for Android and iOS both.

To learn more about this SDKs, how you can integrate them into flutter projects refer to this documentation :

Become familiar with the Razorpay Payment Flow.

Create a Razorpay Account and then use the Razorpay Dashboard to generate the API Keys. The Test keys can be used to mimic a sandbox environment. When using the Test keys, no genuine financial transaction takes place. Once the application has undergone extensive testing and is ready to go live, use Live keys.

Integrating Razorpay with custom UI in flutter app

Get started…

Installation

Step 1: Add this following dependencies into flutter project in pubspec.yaml file :

razorpay_flutter_customui: ^any

Step 2: Then to download the packahge use the terminal’s command line:

flutter pub get

Step 3: Import the dart file where required:

import 'package:razorpay_flutter_customui_example/payment_slection_page.dart';

Step 4: Make an instance of Razorpay.

_razorpay = Razorpay();

Event Listeners:

The event of a successful or unsuccessful payment is released by this plugin which employs event-based communication.

The event names are revealed using the Razorpay class constants EVENT PAYMENT SUCCESS, EVENT PAYMENT ERROR and EVENT EXTERNAL WALLET.

EVENT PAYMENT SUCCESS – for Successful payment

EVENT PAYMENT ERROR – for Error while payment is recorded

EVENT EXTERNAL WALLET – for The external wallet that was used for payment

Within the Razorpay class these occurrences are categorised as constants. The following code shows how to manage events by defining listener methods for each individual event:

 _razorpay?.on(Razorpay.EVENT_PAYMENT_SUCCESS, _handlePaymentSuccess);
 _razorpay?.on(Razorpay.EVENT_PAYMENT_ERROR, _handlePaymentError);
 _razorpay?.on(Razorpay.EVENT_EXTERNAL_WALLET, _handleExternalWallet);

Razorpay method

void _handlePaymentSuccess(PaymentSuccessResponse response) {
  // when payment succeeds
}
void _handlePaymentError(PaymentFailureResponse response) {
  // when payment fails
}
void _handleExternalWallet(ExternalWalletResponse response) {
  // when an external wallet was selected
}
//for clear the listener
 _razorpay.clear();

Create a function called openChecF() that accepts the API key, order id, amount, name and description in order to open the payment interface. The options variable which is supplied to the razorpay. open function contains these parameters.

void openChec() async {
    var options = {
      'key': 'Your_RazorPay_Key',
      'amount': 200,
      'name': 'jhon',
      'description': 'Payment',
      'prefill': {'contact': '9999999999', 'email': 'jhon@razorpay.com'},
      'external': {
        'wallets': ['paytm']
      }
    };

    try {
      _razorpay?.open(options);
    } catch (e) {
      debugPrint(e.toString());
    }
  }

Add this code you root directory file and follow this 

RazorPay UI Example

import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:razorpay_flutter_customui/razorpay_flutter_customui.dart';
import 'model/card_info_model.dart';

enum PaymentMethods { card, upi, nb, wallet, vas }

class PaymentSelectionPage extends StatefulWidget {
  @override
  _PaymentSelectionPageState createState() => _PaymentSelectionPageState();
}

class _PaymentSelectionPageState extends State<PaymentSelectionPage> {
  String selectedPaymentType = 'CARD';
  PaymentMethods selectedMethod = PaymentMethods.card;
  CardInfoModel? cardInfoModel;
  String key = "rzp_test_1DP5mmOlF5G5ag";
  String? availableUpiApps;
  bool showUpiApps = false;

  //rzp_test_1DP5mmOlF5G5ag  ---> Debug Key
  //rzp_live_6KzMg861N1GUS8  ---> Live Key
  //rzp_live_cepk1crIu9VkJU  ---> Pay with Cred

  Map<String, dynamic>? netBankingOptions;
  Map<String, dynamic>? walletOptions;
  String? upiNumber;

  Map<dynamic, dynamic>? paymentMethods;
  List<NetBankingModel>? netBankingList;
  List<WalletModel>? walletsList;
  late Razorpay _razorpay;
  Map<String, dynamic>? commonPaymentOptions;

  @override
  void initState() {
    cardInfoModel = CardInfoModel();
    _razorpay = Razorpay();
    _razorpay.on(Razorpay.EVENT_PAYMENT_SUCCESS, _handlePaymentSuccess);
    _razorpay.on(Razorpay.EVENT_PAYMENT_ERROR, _handlePaymentError);
    _razorpay.initilizeSDK(key);
    fetchAllPaymentMethods();

    netBankingOptions = {
      'key': key,
      'amount': 100,
      'currency': 'INR',
      'email': 'ramprasad179@gmail.com',
      'contact': '9663976539',
      'method': 'netbanking',
    };

    walletOptions = {
      'key': key,
      'amount': 100,
      'currency': 'INR',
      'email': 'ramprasad179@gmail.com',
      'contact': '9663976539',
      'method': 'wallet',
    };

    commonPaymentOptions = {};

    super.initState();
  }

  fetchAllPaymentMethods() {
    _razorpay.getPaymentMethods().then((value) {
      paymentMethods = value;
      configureNetBanking();
      configurePaymentWallets();
    }).onError((error, stackTrace) {
      print('E :: $error');
    });
  }

  configureNetBanking() {
    netBankingList = [];
    final nbDict = paymentMethods?['netbanking'];
    nbDict.entries.forEach(
      (element) {
        netBankingList?.add(
          NetBankingModel(bankKey: element.key, bankName: element.value),
        );
      },
    );
  }

  configurePaymentWallets() {
    walletsList = [];
    final walletsDict = paymentMethods?['wallet'];
    walletsDict.entries.forEach(
      (element) {
        if (element.value == true) {
          walletsList?.add(
            WalletModel(walletName: element.key),
          );
        }
      },
    );
  }

  void _handlePaymentSuccess(Map<dynamic, dynamic> response) {
    final snackBar = SnackBar(
      content: Text(
        'Payment Success : ${response.toString()}',
      ),
      action: SnackBarAction(
        label: 'Okay',
        onPressed: () {},
      ),
    );
    ScaffoldMessenger.of(context).showSnackBar(snackBar);
    print('Payment Success Response : $response');
  }

  void _handlePaymentError(Map<dynamic, dynamic> response) {
    final snackBar = SnackBar(
      content: Text(
        'Payment Error : ${response.toString()}',
      ),
      action: SnackBarAction(
        label: 'Okay',
        onPressed: () {},
      ),
    );
    ScaffoldMessenger.of(context).showSnackBar(snackBar);
    print('Payment Error Response : $response');
  }

  String validateCardFields() {
    if ((cardInfoModel?.cardNumber == '') ||
        (cardInfoModel?.cardNumber == null)) {
      return 'Card Number Cannot be Empty';
    }
    if ((cardInfoModel?.expiryMonth == '') ||
        (cardInfoModel?.expiryMonth == null)) {
      return 'Expiry Month / Year Cannot be Empty';
    }
    if ((cardInfoModel?.cvv == '') || (cardInfoModel?.cvv == null)) {
      return 'CVV Cannot be Empty';
    }
    if ((cardInfoModel?.mobileNumber == '') ||
        (cardInfoModel?.mobileNumber == null)) {
      return 'Mobile number cannot be Empty';
    }
    if ((cardInfoModel?.email == '') || (cardInfoModel?.email == null)) {
      return 'Email cannot be Empty';
    }
    return '';
  }

  @override
  void dispose() {
    super.dispose();
    _razorpay.clear();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Select Payment Method'),
      ),
      backgroundColor: Colors.blue.shade50,
      body: SafeArea(
        child: Container(
          color: Colors.white,
          child: Padding(
            padding: const EdgeInsets.all(8.0),
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.center,
              children: [
                Align(
                  alignment: Alignment.center,
                  child: Wrap(
                    spacing: 8.0,
                    runSpacing: 8.0,
                    children: [
                      PaymentTypeSelectionButton(
                        paymentTitle: 'CARD',
                        onPaymentTypeTap: () {
                          setState(() {
                            selectedPaymentType = 'CARD';
                            selectedMethod = PaymentMethods.card;
                          });
                        },
                      ),
                      PaymentTypeSelectionButton(
                        paymentTitle: 'UPI',
                        onPaymentTypeTap: () {
                          setState(() {
                            selectedPaymentType = 'UPI';
                            selectedMethod = PaymentMethods.upi;
                          });
                        },
                      ),
                      PaymentTypeSelectionButton(
                        paymentTitle: 'NET BANKING',
                        onPaymentTypeTap: () {
                          setState(() {
                            selectedPaymentType = 'NET BANKING';
                            selectedMethod = PaymentMethods.nb;
                          });
                        },
                      ),
                      PaymentTypeSelectionButton(
                        paymentTitle: 'WALLET',
                        onPaymentTypeTap: () {
                          setState(() {
                            selectedPaymentType = 'WALLET';
                            selectedMethod = PaymentMethods.wallet;
                          });
                        },
                      ),
                      PaymentTypeSelectionButton(
                        paymentTitle: 'VAS',
                        onPaymentTypeTap: () {
                          setState(() {
                            selectedPaymentType = 'VAS';
                            selectedMethod = PaymentMethods.vas;
                          });
                        },
                      ),
                    ],
                  ),
                ),
                const SizedBox(height: 32.0),
                Expanded(
                  child: getReleventUI(),
                ),
                Padding(
                  padding: const EdgeInsets.all(12.0),
                  child: Text(
                    'Selected Payment Type : $selectedPaymentType',
                    style: const TextStyle(
                      fontWeight: FontWeight.w600,
                    ),
                  ),
                ),
              ],
            ),
          ),
        ),
      ),
    );
  }

  Widget getReleventUI() {
    switch (selectedMethod) {
      case PaymentMethods.card:
        return buildCardDetailsForm();
      case PaymentMethods.upi:
        return buildUPIForm();
      case PaymentMethods.nb:
        return buildBanksList();
      case PaymentMethods.wallet:
        return buildWalletsList();
      case PaymentMethods.vas:
        return buildForVas();
      default:
        return buildUPIForm();
    }
  }

  Widget buildForVas() {
    return Column(
      children: [
        ElevatedButton(
          onPressed: () {},
          child: const Text('Make Payment'),
          style: ElevatedButton.styleFrom(
            primary: Colors.blue.shade900,
          ),
        ),
        ElevatedButton(
          onPressed: () {},
          child: const Text('Make Payment With Data'),
          style: ElevatedButton.styleFrom(
            primary: Colors.blue.shade900,
          ),
        )
      ],
    );
  }

  Widget buildWalletsList() {
    return ListView.builder(
      itemCount: walletsList?.length,
      itemBuilder: (context, item) {
        return ListTile(
          title: Text(walletsList?[item].walletName ?? ''),
          trailing: const Icon(Icons.arrow_forward_ios),
          onTap: () {
            walletOptions?['wallet'] = walletsList?[item].walletName;
            if (walletOptions != null) {
              _razorpay.submit(walletOptions!);
            }
          },
        );
      },
    );
  }

  Widget buildBanksList() {
    return ListView.builder(
      itemCount: netBankingList?.length,
      itemBuilder: (context, item) {
        return ListTile(
          title: Text(netBankingList?[item].bankName ?? ''),
          trailing: const Icon(Icons.arrow_forward_ios),
          onTap: () {
            netBankingOptions?['bank'] = netBankingList?[item].bankKey;
            if (netBankingOptions != null) {
              _razorpay.submit(netBankingOptions!);
            }
          },
        );
      },
    );
  }

  Widget buildUPIForm() {
    upiNumber = '';
    return Container(
      height: 200.0,
      child: Column(
        crossAxisAlignment: CrossAxisAlignment.stretch,
        children: [
          Column(
            children: [
              Row(
                children: [
                  const Text('VAP :'),
                  const SizedBox(width: 8.0),
                  Flexible(
                    child: TextField(
                      textAlign: TextAlign.center,
                      decoration: const InputDecoration(
                        hintText: 'VPA',
                      ),
                      onChanged: (value) {
                        upiNumber = value;
                      },
                    ),
                  ),
                ],
              ),
            ],
          ),
          const SizedBox(height: 16.0),
          Row(
            mainAxisAlignment: MainAxisAlignment.spaceBetween,
            children: [
              ElevatedButton(
                  onPressed: () {
                    FocusScope.of(context).unfocus();
                    var options = {
                           'key': 'Your_RazorPay_Key',
                            'amount': 200,
                             'name': 'jhon',
                              'description': 'Payment',
                             'prefill': {'contact': '9999999999', 'email': 'jhon@razorpay.com'},
                              'external': {
                                      'wallets': ['paytm']
                                 }
                    };
                    _razorpay.submit(options);
                  },
                  style: ElevatedButton.styleFrom(
                    primary: Colors.blue.shade900,
                  ),
                  child: const Text('Intent Flow')),
              ElevatedButton(
                  onPressed: () {
                    if ((upiNumber == null) || (upiNumber == '')) {
                      ScaffoldMessenger.of(context).showSnackBar(
                        const SnackBar(
                          content: Text('Plese Enter VPA'),
                        ),
                      );
                      return;
                    }

                    FocusScope.of(context).unfocus();
                    var options = {
                      'key': key,
                      'amount': 100,
                      'currency': 'INR',
                      'email': 'ramprasad179@gmail.com',
                      'contact': '9663976539',
                      'method': 'upi',
                      'vpa': upiNumber,
                      '_[flow]': 'collect',
                    };
                    _razorpay.submit(options);
                  },
                  style: ElevatedButton.styleFrom(
                    primary: Colors.blue.shade900,
                  ),
                  child: const Text('Collect Flow'))
            ],
          ),
          ElevatedButton(
            onPressed: () async {
              final upiApps = await _razorpay.getAppsWhichSupportUpi();
              availableUpiApps = upiApps.toString();
              setState(() {
                showUpiApps = true;
              });
              print(upiApps);
            },
            style: ElevatedButton.styleFrom(
              primary: Colors.blue.shade900,
            ),
            child: const Text('Get All UPI Supported Apps'),
          ),
          Visibility(
            visible: showUpiApps,
            child: Flexible(
              child: Text(availableUpiApps ?? ''),
            ),
          )
        ],
      ),
    );
  }

  Widget buildCardDetailsForm() {
    return Container(
      height: 200.0,
      child: SingleChildScrollView(
        child: Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: [
            Column(
              children: [
                Row(
                  children: [
                    const Text('Card Number :'),
                    const SizedBox(width: 8.0),
                    Flexible(
                      child: TextField(
                        textAlign: TextAlign.center,
                        decoration: const InputDecoration(
                          hintText: 'Card Number',
                        ),
                        onChanged: (newValue) =>
                            cardInfoModel?.cardNumber = newValue,
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 16.0),
                Row(
                  children: [
                    const Text('Expiry :'),
                    const SizedBox(width: 8.0),
                    Flexible(
                      child: TextField(
                          textAlign: TextAlign.center,
                          decoration: const InputDecoration(
                            hintText: '12/23',
                          ),
                          onChanged: (newValue) {
                            final month = newValue.split('/').first;
                            final year = newValue.split('/').last;
                            cardInfoModel?.expiryYear = year;
                            cardInfoModel?.expiryMonth = month;
                          }),
                    ),
                    const SizedBox(width: 8.0),
                    const Text('CVV'),
                    const SizedBox(width: 8.0),
                    Flexible(
                      child: TextField(
                        textAlign: TextAlign.center,
                        decoration: const InputDecoration(
                          hintText: '***',
                        ),
                        onChanged: (newValue) => cardInfoModel?.cvv = newValue,
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 16.0),
                Row(
                  children: [
                    const Text('Name :'),
                    const SizedBox(width: 8.0),
                    Flexible(
                      child: TextField(
                        textAlign: TextAlign.center,
                        decoration: const InputDecoration(
                          hintText: 'Card Holder Name',
                        ),
                        onChanged: (newValue) =>
                            cardInfoModel?.cardHolderName = newValue,
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 16.0),
                Row(
                  children: [
                    const Text('Phone :'),
                    const SizedBox(width: 8.0),
                    Flexible(
                      child: TextField(
                        textAlign: TextAlign.center,
                        decoration: const InputDecoration(
                          hintText: 'Mobile Number',
                        ),
                        onChanged: (newValue) =>
                            cardInfoModel?.mobileNumber = newValue,
                      ),
                    ),
                  ],
                ),
                const SizedBox(height: 16.0),
                Row(
                  children: [
                    const Text('Email :'),
                    const SizedBox(width: 8.0),
                    Flexible(
                      child: TextField(
                        textAlign: TextAlign.center,
                        decoration: const InputDecoration(
                          hintText: 'Email-ID',
                        ),
                        onChanged: (newValue) =>
                            cardInfoModel?.email = newValue,
                      ),
                    ),
                  ],
                ),
              ],
            ),
            const SizedBox(height: 16.0),
            Row(
              mainAxisAlignment: MainAxisAlignment.spaceBetween,
              children: [
                ElevatedButton(
                  onPressed: () {
                    var error = validateCardFields();
                    if (error != '') {
                      print(error);
                      ScaffoldMessenger.of(context)
                          .showSnackBar(SnackBar(content: Text(error)));
                      return;
                    }
                    var options = {
                      'key': key,
                      'amount': 100,
                      "card[cvv]": cardInfoModel?.cvv,
                      "card[expiry_month]": cardInfoModel?.expiryMonth,
                      "card[expiry_year]": cardInfoModel?.expiryYear,
                      "card[name]": cardInfoModel?.cardHolderName,
                      "card[number]": cardInfoModel?.cardNumber,
                      "contact": cardInfoModel?.mobileNumber,
                      "currency": "INR",
                      'email': cardInfoModel?.email,
                      'description': 'Fine T-Shirt',
                      "method": "card"
                    };
                    _razorpay.submit(options);
                  },
                  style: ElevatedButton.styleFrom(
                    primary: Colors.blue.shade900,
                  ),
                  child: const Text('Submit'),
                ),
                ElevatedButton(
                    onPressed: () async {
                      /* print('Pay With Cred Tapped');
                      final paymentMethods = await _razorpay.getPaymentMethods();
                      print('Payment Methods Retrievend: $paymentMethods'); */

                      var options = {
                        'key': key,
                        'amount': 100,
                        'currency': 'INR',
                        'email': 'ramprasad179@gmail.com',
                        'app_present': 0,
                        'contact': '9663976539',
                        'method': 'app',
                        'provider': 'cred',
                        // 'callback_url': 'flutterCustomUI://'
                      };
                      // _razorpay.submit(options);
                      // String logo = await _razorpay.getBankLogoUrl("UTIB");
                      // print(logo);
                      /* final isvalidVpa = await _razorpay.isValidVpa('9663976539@upi');
                      print(isvalidVpa); */

                      /* final supportedUpiApps =
                          await _razorpay.getAppsWhichSupportUpi();
                      print(supportedUpiApps); */

                      /* final cardNetwork =
                          await _razorpay.getCardsNetwork("4111111111111111");
                      print(cardNetwork); */

                      /* final walletLogo
                          await _razorpay.getWalletLogoUrl('paytm');
                      print('Wallet URL : $walletLogo'); */

                      /* final length =
                          await _razorpay.getCardNetworkLength('VISA');
                      print(length); */
                    },
                    style: ElevatedButton.styleFrom(
                      primary: Colors.blue.shade900,
                    ),
                    child: const Text('Pay With Cred (Collect FLow)'))
              ],
            )
          ],
        ),
      ),
    );
  }
}

class PaymentTypeSelectionButton extends StatelessWidget {
  final String? paymentTitle;
  final VoidCallback? onPaymentTypeTap;

  PaymentTypeSelectionButton({
    this.paymentTitle,
    this.onPaymentTypeTap,
  });

  @override
  Widget build(BuildContext context) {
    return InkWell(
      onTap: onPaymentTypeTap,
      child: Container(
        decoration:
            BoxDecoration(border: Border.all(color: Colors.black, width: 0.5)),
        child: Padding(
          padding: const EdgeInsets.all(8.0),
          child: Text(paymentTitle ?? ''),
        ),
      ),
    );
  }
}



For this example app source code click here GitHub

Video Tutorial on Integrating RazorPay in Flutter App

Conclusion

This is a small  flutter example that will integrate Razorpay custom ui ,  you can modify this code with your needs ,so just click on gitHub and get the code.

Thanks for reading this post 💙…..

Have a good day