Open In App

Flutter – Cashfree Payment Gateway Integration

Last Updated : 14 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

The Cashfree Flutter SDK allows you to integrate Cashfree Payment Gateway into your application and start collecting payments from your customers. It is designed to minimise the complexity of handling and integrating payments in your Flutter project. So in this article, we are going to integrate Cashfree Payment Gateway with the Flutter application.

Step By Step Implementation

Step 1: Create a New Flutter Project in IDE

Create a simple flutter project either using Android Studio or by following the command

Dart




flutter create .


Step 2: Add the flutter_cashfree_pg_sdk package

Add the following package to your pubspec.yaml file

Dart




dependencies:
  flutter_cashfree_pg_sdk: ^2.0.25+28


The version may get change depending on your usage. We have preferred this package because it is developed by cashfree itself and it is maintained project

Important Tips: Always Prefer to use package that are developed by some big companies. Use that is maintained regularly by publisher.

Step 3: Create the cashfree account and get the API key and API secret

Cretae cashfree account by going on this website. And get the API key and API secret from here. Go to developers which you can found on top of the cashfree dashboard.

file

In payment gateway option there will be API keys option you have to click that.

WhatsApp-Image-2023-11-27-at-91641-PM

You can view API keys and update it .env file in your flutter project or save for serverside api calling.

Step 4: Now Create Cashfreepayment instance

We will create a simple cashfree payment instance like below to do all the activity during cashfree and bool variable for checking payment status.

Dart




// Cashfree Payment Instance
CFPaymentGatewayService cfPaymentGatewayService = CFPaymentGatewayService();


Step 5: Attach Event listeners

In the init function we will attach 2 events one will be call when payment is successfully done by user and another when some error happens. These are 2 function

1. Verifypayment

This will trigger when paymet is successfully done

Dart




void verifyPayment(String orderId) {
    // Here we will only print the statement 
      // to check payment is done or not
    isSuccess = true;
    setState(() {});
    print("Verify Payment $orderId");
  }


This will contain order id which you may need to update in your database or anywhere as per your requirement

2. OnError

This will trigger when some error happens

Dart




void onError(CFErrorResponse errorResponse, String orderId) {
   // printing the error message so that we can
      // show it to user or  checkourselves for testing
   isSuccess = false;
   setState(() {});
   print(errorResponse.getMessage());
   print("Error while making payment");
 }


This will contain parameters for error response and ordered. We will attach this callback in cashfreeinstance in init state like this

Dart




@override
void initState() {
  super.initState();
  // Attach events when payment is success and when error occured
  cfPaymentGatewayService.setCallback(verifyPayment, onError);
}


Step 6: We will create sessionid which will require in next step 6

In this we will create session id by passing some data into it which will require in next step. Generally this session id is create from server

curl --location 'https://sandbox.cashfree.com/pg/orders' \
--header 'Content-Type: application/json' \
--header 'x-client-id: CLIENT ID' \
--header 'x-client-secret: CLIENT SECRET' \
--header 'x-api-version: 2022-09-01' \
--header 'x-request-id: developer name' \
--data-raw '{
"order_amount": 1.00,
"order_id": "order_id",
"order_currency": "INR",
"customer_details": {
"customer_id": "customer_id",
"customer_name": "customer_name",
"customer_email": "customer_email",
"customer_phone": "+customer_mobile"
},
"order_meta": {
"notify_url": "https://test.cashfree.com"
},
"order_note": "some order note here"}'

You can use below curl for postman if you want it to create from there. To store API key and API secret We have use .env concept. You may refer to this article How to Add .env File in Flutter. If now we will create from flutter only by giving a simple API call using http.

Sample

You need to add http package and add following code in it. In this function there is orderID will also be required which must be unique and not in use by any previous transactions or orders.

Note: In customer details customer email,contact ,id is compulsory.

Dart




createSessionID(String orderID) async {
  var headers = {
    'Content-Type': 'application/json',
    'x-client-id': dotenv.env["API_CLIENT"] ?? "",
    'x-client-secret': dotenv.env["API_SECRET"] ?? "",
    'x-api-version': '2022-09-01',// This is latest version for API
    'x-request-id': 'fluterwings'
  };
  print(headers);
  var request =
      http.Request('POST', Uri.parse('https://sandbox.cashfree.com/pg/orders'));
  request.body = json.encode({
    "order_amount": 1,// Order Amount in Rupees
    "order_id": orderID, // OrderiD created by you it must be unique
    "order_currency": "INR", // Currency of order like INR,USD
    "customer_details": {
      "customer_id": "customer_id", // Customer id
      "customer_name": "customer_name",// Name of customer 
      "customer_email": "flutterwings304@gmail.com",// Email id of customer
      "customer_phone": "+917737366393" // Phone Number of customer
    },
    "order_meta": {"notify_url": "https://test.cashfree.com"},
    "order_note": "some order note here" // If you want  to store something extra
  });
  request.headers.addAll(headers);
  
  http.StreamedResponse response = await request.send();
  
  if (response.statusCode == 200) {
    // If All the details is correct it will return the 
    // response and you can get sessionid for checkout
    return jsonDecode(await response.stream.bytesToString());
  } else {
    print(await response.stream.bytesToString());
    print(response.reasonPhrase);
  }
}


Step 7: We will launch the page for payment by adding this code

In previous step we have created session ID which we will be used now

1. Create session for particular session in flutter by setting basic things like environment,orderid,sessionid

Dart




Future<CFSession?> createSession() async {
    try {
      final mySessionIDData = await createSessionID(
          orderId); //This will create session id from flutter itself
            
      // Now we will se some parameter like orderID ,environment,payment sessionID 
      // after that we wil create the checkout session which 
      // will launch through which user can pay.
      var session = CFSessionBuilder()
          .setEnvironment(CFEnvironment.SANDBOX)
          .setOrderId(mySessionIDData["order_id"])
          .setPaymentSessionId(mySessionIDData["payment_session_id"])
          .build();
      return session;
    } on CFException catch (e) {
      print(e.message);
    }
    return null;
  }


2. Now we will finally launch the checkout page

Dart




pay() async {
    try {
      var session = await createSession();
      List<CFPaymentModes> components = <CFPaymentModes>[];
      // If you want to set paument mode to be shown to customer
      var paymentComponent =
          CFPaymentComponentBuilder().setComponents(components).build();
      // We will set theme of checkout session page like fonts, color
      var theme = CFThemeBuilder()
          .setNavigationBarBackgroundColorColor("#FF0000")
          .setPrimaryFont("Menlo")
          .setSecondaryFont("Futura")
          .build();
      // Create checkout with all the settings we have set earlier
      var cfDropCheckoutPayment = CFDropCheckoutPaymentBuilder()
          .setSession(session!)
          .setPaymentComponent(paymentComponent)
          .setTheme(theme)
          .build();
          // Launching the payment page
  
      cfPaymentGatewayService.doPayment(cfDropCheckoutPayment);
    } on CFException catch (e) {
      print(e.message);
    }
  }


Now payment page will open and we or user have to do payment.

Step 8: Now will verify the payment and update in cashfree

If payment is done successful then we will verify the payment and update its status if need in cashfree or in our database. We will simply print the statement for now. If payment is rejected or got some error we can handle different scenarios.But for now I have added the simple statement and update one variable where we can get to know whether payment is successful or not.

Complete Source Code:

Dart




class CashFreePayment extends StatefulWidget {
  const CashFreePayment({super.key});
  
  @override
  State<CashFreePayment> createState() => _CashFreePaymentState();
}
  
class _CashFreePaymentState extends State<CashFreePayment> {
  CFPaymentGatewayService cfPaymentGatewayService =
      CFPaymentGatewayService(); // Cashfree Payment Instance
  bool? isSuccess;
  
  @override
  void initState() {
    super.initState();
    // Attach events when payment is success and when error occured
    cfPaymentGatewayService.setCallback(verifyPayment, onError);
  }
  
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Cashfree Payment Flutter Template'),
      ),
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            ElevatedButton(onPressed: pay, child: const Text("Pay")),
            Text(
              "Payment Status $isSuccess",
              style: const TextStyle(fontSize: 20),
            )
          ],
        ),
      ),
    );
  } // When payment is done successfully
  
  void verifyPayment(String orderId) {
    // Here we will only print the statement 
    // to check payment is done or not
    isSuccess = true;
    setState(() {});
    print("Verify Payment $orderId");
  }
  
  // If some error occur during payment this will trigger
  void onError(CFErrorResponse errorResponse, String orderId) {
    // printing the error message so that we can show
    // it to user or  checkourselves for testing
    isSuccess = false;
    setState(() {});
    print(errorResponse.getMessage());
    print("Error while making payment");
  }
  
  String orderId = "my_order_id1";
  
  Future<CFSession?> createSession() async {
    try {
      final mySessionIDData = await createSessionID(
          orderId); // This will create session id from flutter itself
  
      // Now we will se some parameter like orderID ,environment,payment sessionID 
      // after that we wil create the checkout session 
      // which will launch through which user can pay.
      var session = CFSessionBuilder()
          .setEnvironment(CFEnvironment.SANDBOX)
          .setOrderId(mySessionIDData["order_id"])
          .setPaymentSessionId(mySessionIDData["payment_session_id"])
          .build();
      return session;
    } on CFException catch (e) {
      print(e.message);
    }
    return null;
  }
  
  pay() async {
    try {
      var session = await createSession();
      List<CFPaymentModes> components = <CFPaymentModes>[];
      // If you want to set paument mode to be shown to customer
      var paymentComponent =
          CFPaymentComponentBuilder().setComponents(components).build();
      // We will set theme of checkout session page like fonts, color
      var theme = CFThemeBuilder()
          .setNavigationBarBackgroundColorColor("#FF0000")
          .setPrimaryFont("Menlo")
          .setSecondaryFont("Futura")
          .build();
      // Create checkout with all the settings we have set earlier
      var cfDropCheckoutPayment = CFDropCheckoutPaymentBuilder()
          .setSession(session!)
          .setPaymentComponent(paymentComponent)
          .setTheme(theme)
          .build();
      // Launching the payment page
  
      cfPaymentGatewayService.doPayment(cfDropCheckoutPayment);
    } on CFException catch (e) {
      print(e.message);
    }
  }
  
  // webCheckout() async {
  //   try {
  //     var session = await createSession();
  //     var cfWebCheckout =
  //         CFWebCheckoutPaymentBuilder().setSession(session!).build();
  //     cfPaymentGatewayService.doPayment(cfWebCheckout);
  //   } on CFException catch (e) {
  //     print(e.message);
  //   }
  // }
}
  
createSessionID(String orderID) async {
  var headers = {
    'Content-Type': 'application/json',
    'x-client-id': dotenv.env["API_CLIENT"] ?? "",
    'x-client-secret': dotenv.env["API_SECRET"] ?? "",
    'x-api-version': '2022-09-01', // This is latest version for API
    'x-request-id': 'fluterwings'
  };
  print(headers);
  var request =
      http.Request('POST', Uri.parse('https://sandbox.cashfree.com/pg/orders'));
  request.body = json.encode({
    "order_amount": 1, // Order Amount in Rupees
    "order_id": orderID, // OrderiD created by you it must be unique
    "order_currency": "INR", // Currency of order like INR,USD
    "customer_details": {
      "customer_id": "customer_id", // Customer id
      "customer_name": "customer_name", // Name of customer
      "customer_email": "flutterwings304@gmail.com", // Email id of customer
      "customer_phone": "+917737366393" // Phone Number of customer
    },
    "order_meta": {"notify_url": "https://test.cashfree.com"},
    "order_note": "some order note here" // If you want  to store something extra
  });
  request.headers.addAll(headers);
  
  http.StreamedResponse response = await request.send();
  
  if (response.statusCode == 200) {
    // If All the details is correct it will return the
    // response and you can get sessionid for checkout
    return jsonDecode(await response.stream.bytesToString());
  } else {
    print(await response.stream.bytesToString());
    print(response.reasonPhrase);
  }
}


Output:

1. When payment is successful

2. When payment is failed



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads