Introduction: Why Cashfree for Flutter?
Integrating a payment gateway into a mobile application is a critical step for any business looking to monetize its services. For Flutter developers, especially those targeting the Indian market, Cashfree presents a compelling option. It offers robust support for UPI, cards, net banking, and a particularly strong UPI Autopay feature for subscription services. The official Cashfree Flutter SDK, cashfree_pg, is actively maintained and null-safe, which are significant advantages.
However, the documentation can be fragmented, making the order of operations and, crucially, the server-side verification step—essential for preventing fraudulent transactions—easy to overlook. This article provides a clear, sequential guide to integrating Cashfree into your Flutter app, mirroring a production-ready workflow: order creation on your backend, initiating checkout in the app, verifying the payment server-side, and implementing webhooks for reconciliation.

Adding Dependencies
The first step is to include the necessary dependencies in your Flutter project. Open your pubspec.yaml file and add the official Cashfree Flutter SDK. Ensure you are using the latest stable version available.
dependencies:
flutter:
sdk: flutter
cashfree_pg: ^1.0.0 # Use the latest version
cupertino_icons: ^1.0.2
After adding the dependency, run flutter pub get in your terminal to download and link the package. For Android, you’ll need to add the Cashfree Payment Gateway SDK to your android/app/build.gradle file. Specifically, you’ll need to add the following to the dependencies block:
implementation 'com.cashfree.pg:cashfree-android-sdk:2.0.6' // Use the latest version
For iOS, no additional dependencies are typically required in the Podfile beyond what the Flutter build process handles, but ensure your project is configured to use a recent Swift version if prompted.
Backend Setup: Order Creation and Credentials
Before initiating a payment from your Flutter app, you must create an order on your backend server. This involves interacting with the Cashfree Payment Gateway APIs. You will need your App ID and Secret Key, which can be obtained from your Cashfree merchant dashboard.
Your backend endpoint for creating an order should:
- Generate a unique order ID.
- Specify the order amount and currency.
- Provide customer details (name, email, phone number).
- Include any relevant order metadata.
- Send a POST request to the Cashfree Orders API (e.g.,
https://api.cashfree.com/pg/ordersfor production).
The response from Cashfree will contain an order_id and other details necessary for initiating the payment in the app. It is crucial to securely store your Secret Key on the server and never expose it in the client-side application.
Flutter App Integration: Initiating Checkout
With the order created on the backend and the necessary credentials (App ID, order_id, and optionally a token obtained from Cashfree’s tokenization API if needed for specific flows) available in your Flutter app, you can now initiate the payment process using the cashfree_pg SDK.
The SDK requires a configuration object that includes your App ID, the order_id, and the payment mode (e.g., 'production' or 'sandbox'). You will also need to provide the order_token, which is generated by Cashfree's backend service when you call their API to create the order.
Here’s a simplified example of how to initialize the Cashfree SDK and open the payment UI:
import 'package:cashfree_pg/cashfree_pg.dart';
Future initiatePayment(String appId, String orderId, String orderToken) async {
CashfreePGSDK.setCallback(
onPaymentSuccess: (paymentDetails) {
print('Payment Successful: $paymentDetails');
// Navigate to success screen or show confirmation
},
onPaymentError: (paymentDetails) {
print('Payment Error: $paymentDetails');
// Navigate to failure screen or show error message
},
onPaymentPending: (paymentDetails) {
print('Payment Pending: $paymentDetails');
// Handle pending state, e.g., show a waiting message
},
);
final CashfreeConfig config = CashfreeConfig(
appId: appId,
orderId: orderId,
orderToken: orderToken,
paymentMode: 'production', // or 'sandbox'
);
await CashfreePGSDK.openCashfreePG(config);
}
The setCallback function is essential for handling the results of the payment attempt. These callbacks will inform your app whether the payment was successful, failed, or is still pending. The data passed to these callbacks includes transaction IDs and other relevant payment information.
Server-Side Verification: The Crucial Step
Relying solely on client-side callbacks for payment confirmation is a security risk. Malicious users could potentially manipulate the app to trigger success callbacks without actual payment. Therefore, robust server-side verification is mandatory.
After the onPaymentSuccess callback is received in your Flutter app, your app should communicate this event to your backend server. Your backend server must then verify the payment status directly with Cashfree using their server-to-server APIs. This typically involves:
- Receiving the
order_idand transaction details from the Flutter app. - Making an API call from your backend to Cashfree's API to fetch the actual status of the order.
- Comparing the status received from Cashfree with the details you expect.
- If the verification is successful, mark the order as paid in your system and fulfill the user's request (e.g., deliver digital goods, activate a service).
This two-step verification process—client-side confirmation for user experience and server-side validation for security—is fundamental to secure payment integrations. The Cashfree documentation details endpoints for fetching order status, which you should consult for precise API calls.
Webhooks for Reconciliation
For seamless reconciliation of payments, especially in high-volume applications or for subscription management, Cashfree provides webhooks. These are automated HTTP notifications sent from Cashfree's servers to a designated endpoint on your backend whenever a significant event occurs related to a payment (e.g., payment success, failure, refund).
To set this up:
- Configure a webhook URL in your Cashfree merchant dashboard.
- Ensure your backend server has an endpoint ready to receive and process POST requests from Cashfree.
- When a webhook is received, your server should validate the request (e.g., using a shared secret or signature provided by Cashfree) to ensure it's legitimate.
- Process the webhook payload to update your internal records, trigger fulfillment, or initiate other necessary actions.
Webhooks are vital for ensuring that your system accurately reflects payment statuses without requiring constant polling of Cashfree's APIs, thus improving efficiency and reliability.
Conclusion
Integrating Cashfree into your Flutter application involves careful coordination between your client-side Flutter code and your backend server. By following a structured approach—adding dependencies, securely handling credentials, initiating payments from the app, performing critical server-side verification, and utilizing webhooks for reconciliation—you can build a reliable and secure payment flow. While the documentation might require piecing together, this step-by-step guide provides the essential framework for a successful integration.
