> ## Documentation Index
> Fetch the complete documentation index at: https://www.cashfree.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Flutter Element Integration

> Integrate the Cashfree Payment Gateway Element SDK into your Flutter app to accept payments using card, net banking, and UPI Intent.

The Cashfree Payment Gateway Element SDK lets you build a fully custom payment experience within your Flutter application. Unlike the hosted checkout, you collect payment details directly in your own UI and pass them to the SDK, giving you complete control over the look and feel of your payment flow.

The SDK supports three payment methods: card, net banking, and UPI Intent. It runs on both Android and iOS from a single Dart codebase.

<Note>
  For card payments, the SDK provides a `CFCardWidget` that renders the card number field for you. Your application never receives the raw card number. You collect only the card holder name, expiry, and CVV in your own UI and pass them to the SDK alongside the widget.
</Note>

## Prerequisites

Complete the following tasks before you start the integration:

* Create a [Cashfree Merchant Account](https://merchant.cashfree.com/merchants/signup).
* Log in to the [Merchant Dashboard](https://merchant.cashfree.com/auth/login) and generate an **App ID** and **Secret Key**. Learn how to [generate API keys](/docs/api-reference/authentication#generate-api-keys).
* Use Cashfree Flutter SDK version **2.4.0+52** or above. Get it from [pub.dev](https://pub.dev/packages/flutter_cashfree_pg_sdk).
* Use Flutter **2.5.0** or above and Dart **3.0.0** or above.
* Set your Android application's `minSdkVersion` to API level 19 or higher.
* Set your iOS minimum deployment target to 12.0 or higher.

The integration consists of three steps:

<CardGroup cols={3}>
  <Card title="Step 1" icon="money-bill-wave" href="/docs/payments/online/element/mobile/flutter#step-1-create-an-order-server-side">
    Create an order
  </Card>

  <Card title="Step 2" icon="desktop" href="/docs/payments/online/element/mobile/flutter#step-2-open-the-payment-page-client-side">
    Open the payment page
  </Card>

  <Card title="Step 3" icon="circle-check" href="/docs/payments/online/element/mobile/flutter#step-3-confirm-the-payment-server-side">
    Confirm the payment
  </Card>
</CardGroup>

## Step 1: Create an order <Badge color="green">Server-side</Badge>

Create an order from your backend server before you process any payment.

<Note>This API requires your secret key. Create orders through your server only. Do not call this API directly from your mobile application.</Note>

##### API request for creating an order

Here's a sample request for creating an order using your desired backend language. Cashfree offers backend [SDKs](/docs/api-reference/payments/sdk#server-sdk) to simplify the integration process.

<CodeGroup>
  ```bash curl theme={"dark"}
  curl --location 'https://sandbox.cashfree.com/pg/orders' \
  --header 'X-Client-Secret: {{clientKey}}' \
  --header 'X-Client-Id: {{clientId}}' \
  --header 'x-api-version: 2025-01-01' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --data-raw '{
    "order_amount": 10.10,
    "order_currency": "INR",
    "customer_details": {
      "customer_id": "USER123",
      "customer_name": "joe",
      "customer_email": "joe.s@cashfree.com",
      "customer_phone": "+919876543210"
    },
    "order_meta": {
      "return_url": "https://b8af79f41056.eu.ngrok.io?order_id=order_123"
    }
  }'
  ```

  ```javascript nodejs theme={"dark"}
  import { Cashfree, CFEnvironment } from "cashfree-pg";

  const cashfree = new Cashfree(
  	CFEnvironment.PRODUCTION,
  	"{Client ID}",
  	"{Client Secret Key}"
  );

  function createOrder() {
  	var request = {
  		order_amount: "1",
  		order_currency: "INR",
  		customer_details: {
  			customer_id: "node_sdk_test",
  			customer_name: "",
  			customer_email: "example@gmail.com",
  			customer_phone: "9999999999",
  		},
  		order_meta: {
  			return_url:
  				"https://test.cashfree.com/pgappsdemos/return.php?order_id=order_123",
  		},
  		order_note: "",
  	};

  	cashfree
  		.PGCreateOrder(request)
  		.then((response) => {
  			console.log("Order created successfully:", response.data);
  		})
  		.catch((error) => {
  			console.error("Error setting up order request:", error.response.data);
  		});
  }
  ```

  ```python python theme={"dark"}
  from cashfree_pg.models.create_order_request import CreateOrderRequest
  from cashfree_pg.api_client import Cashfree
  from cashfree_pg.models.customer_details import CustomerDetails


  Cashfree.XClientId = {Client ID}
  Cashfree.XClientSecret = {Client Secret Key}
  Cashfree.XEnvironment = Cashfree.XSandbox
  x_api_version = "2023-08-01"

  def create_order():
          customerDetails = CustomerDetails(customer_id="123", customer_phone="9999999999")
          createOrderRequest = CreateOrderRequest(order_amount=1, order_currency="INR", customer_details=customerDetails)
          try:
              api_response = Cashfree().PGCreateOrder(x_api_version, createOrderRequest, None, None)
              print(api_response.data)
          except Exception as e:
              print(e)
  ```

  ```java java theme={"dark"}
  import com.cashfree.*;

  Cashfree.XClientId = {Client Key};
  Cashfree.XClientSecret = {Client Secret Key};
  Cashfree.XEnvironment = Cashfree.SANDBOX;

  static void createOrder() {
    CustomerDetails customerDetails = new CustomerDetails();
    customerDetails.setCustomerId("123");
    customerDetails.setCustomerPhone("9999999999");

    CreateOrderRequest request = new CreateOrderRequest();
    request.setOrderAmount(1.0);
    request.setOrderCurrency("INR");
    request.setCustomerDetails(customerDetails);
    try {
      Cashfree cashfree = new Cashfree();
      ApiResponse<OrderEntity> response = cashfree.PGCreateOrder("2023-08-01", request, null, null, null);
      System.out.println(response.getData().getOrderId());

    } catch (ApiException e) {
      throw new RuntimeException(e);
    }
  }
  ```

  ```go go theme={"dark"}
  import (
    cashfree "github.com/cashfree/cashfree-pg/v3"
  )

  func createOrder() {

  clientId := {Client ID}
  clientSecret := {Client Secret Key}
  cashfree.XClientId = &clientId
  cashfree.XClientSecret = &clientSecret
  cashfree.XEnvironment = cashfree.SANDBOX

  request := cashfree.CreateOrderRequest{
  		OrderAmount: 1,
  		CustomerDetails: cashfree.CustomerDetails{
  			CustomerId:    "1",
  			CustomerPhone: "9999999999",
  		},
  		OrderCurrency: "INR",
  		OrderSplits:   []cashfree.VendorSplit{},
  	}
  	version := "2023-08-01"
  	response, httpResponse, err := cashfree.PGCreateOrder(&version, &request, nil, nil, nil)
  	if err != nil {
  		fmt.Println(err.Error())
  	} else {
  		fmt.Println(httpResponse.StatusCode)
  		fmt.Println(response)
      }
  }
  ```

  ```csharp .net theme={"dark"}
  using cashfree_pg.Client;
  using cashfree_pg.Model;

  Cashfree.XClientId = {Client ID};
  Cashfree.XClientSecret = {Client Secret Key};
  Cashfree.XEnvironment = Cashfree.PRODUCTION;
  var cashfree = new Cashfree();
  var xApiVersion = "2023-08-01";

  void CreateOrder() {
      var customerDetails = new CustomerDetails("123", null, "9999999999");
      var createOrdersRequest = new CreateOrderRequest(null, 1.0, "INR", customerDetails);
      try {
          // Create Order
          var result = cashfree.PGCreateOrder(xApiVersion, createOrdersRequest, null, null, null);
          Console.WriteLine(result);
          Console.WriteLine(result.StatusCode);
          Console.WriteLine((result.Content as OrderEntity));
      } catch (ApiException e) {
          Console.WriteLine("Exception when calling PGCreateOrder: " + e.Message);
          Console.WriteLine("Status Code: " + e.ErrorCode);
          Console.WriteLine(e.StackTrace);
      }
  }
  ```

  ```php php theme={"dark"}
  \Cashfree\Cashfree::$XClientId = "<x-client-id>";
  \Cashfree\Cashfree::$XClientSecret = "<x-client-secret>";
  \Cashfree\Cashfree::$XEnvironment = Cashfree\Cashfree::$SANDBOX;

  $cashfree = new \Cashfree\Cashfree();

  $x_api_version = "2023-08-01";
  $create_orders_request = new \Cashfree\Model\CreateOrdersRequest();
  $create_orders_request->setOrderAmount(1.0);
  $create_orders_request->setOrderCurrency("INR");
  $customer_details = new \Cashfree\Model\CustomerDetails();
  $customer_details->setCustomerId("123");
  $customer_details->setCustomerPhone("9999999999");
  $create_orders_request->setCustomerDetails($customer_details);

  try {
      $result = $cashfree->PGCreateOrder($x_api_version, $create_orders_request);
      print_r($result);
  } catch (Exception $e) {
      echo 'Exception when calling PGCreateOrder: ', $e->getMessage(), PHP_EOL;
  }
  ```
</CodeGroup>

After successfully creating an order, you will receive a unique `order_id` and `payment_session_id` that you need for subsequent steps.

You can view the complete API request and response for `/orders` in the [Create Order API](/docs/api-reference/payments/latest/orders/create-order).

## Step 2: Open the payment page <Badge color="orange">Client-side</Badge>

After you create the order, open the payment page so the customer can provide payment details.

### 1. Set up the SDK

The Flutter SDK is hosted on [pub.dev](https://pub.dev/packages/flutter_cashfree_pg_sdk). Add it to your project:

```bash theme={"dark"}
flutter pub add flutter_cashfree_pg_sdk
```

Alternatively, add it directly to your `pubspec.yaml` file:

```yaml theme={"dark"}
dependencies:
  flutter_cashfree_pg_sdk: ^2.4.0+52
```

Then install the package:

```bash theme={"dark"}
flutter pub get
```

#### iOS configuration

To support UPI payments on iOS, add the following UPI app URI schemes to your application's `ios/Runner/Info.plist` file:

```xml theme={"dark"}
<key>LSApplicationQueriesSchemes</key>
<array>
  <string>amazonpay</string>
  <string>upi</string>
  <string>credpay</string>
  <string>bhim</string>
  <string>paytmmp</string>
  <string>phonepe</string>
  <string>tez</string>
  <string>navipay</string>
  <string>mobikwik</string>
  <string>myairtel</string>
  <string>popclubapp</string>
  <string>super</string>
  <string>kiwi</string>
  <string>simplypayupi</string>
  <string>whatsapp</string>
</array>
```

Then install the pods:

```bash theme={"dark"}
cd ios
pod install --repo-update
```

### 2. Select a payment method

The Element SDK supports the following payment methods:

<Tabs>
  <Tab title="Card">
    In this flow, the SDK renders the card number field using `CFCardWidget`, so your application never handles the raw card number. Your application collects the card holder name, expiry, and CVV in its own UI and passes them to the SDK along with a reference to the widget.
  </Tab>

  <Tab title="Net banking">
    In this flow, you identify the customer's bank using a bank code. The SDK opens Cashfree's hosted net banking screen so the customer can log in and authorise the payment.
  </Tab>

  <Tab title="UPI Intent">
    In this flow, the SDK discovers the UPI apps installed on the customer's device and launches the selected app so the customer can authorise the payment.
  </Tab>
</Tabs>

### 3. Complete the payment

To complete the payment, follow these steps:

1. Set up the payment callback.
2. Create a `CFSession` object.
3. Create the payment object for the selected payment method.
4. Initiate the payment using `doPayment()`.

#### Set up the payment callback

Register a success callback and an error callback using `setCallback()`. The SDK invokes the success callback with the order ID when the payment flow ends, and the error callback with a `CFErrorResponse` and order ID if the flow fails.

<Tip>Call `setCallback()` in `initState()`, before you call `doPayment()`.</Tip>

```dart theme={"dark"}
import 'package:flutter_cashfree_pg_sdk/api/cfpaymentgateway/cfpaymentgatewayservice.dart';
import 'package:flutter_cashfree_pg_sdk/api/cferrorresponse/cferrorresponse.dart';

var cfPaymentGatewayService = CFPaymentGatewayService();

@override
void initState() {
  super.initState();
  cfPaymentGatewayService.setCallback(verifyPayment, onError);
}

void verifyPayment(String orderID) {
  // Verify the order status from your backend. See Step 3.
}

void onError(CFErrorResponse errorResponse, String orderID) {
  print("${errorResponse.getMessage()}");
}
```

#### Create a session

The `CFSession` object holds the session context for the payment. It accepts the `order_id` and `payment_session_id` obtained from [Step 1](#step-1-create-an-order-server-side), and the Cashfree environment (`CFEnvironment.SANDBOX` or `CFEnvironment.PRODUCTION`).

```dart theme={"dark"}
import 'package:flutter_cashfree_pg_sdk/api/cfsession/cfsession.dart';
import 'package:flutter_cashfree_pg_sdk/utils/cfenums.dart';

var session = CFSessionBuilder()
    .setEnvironment(CFEnvironment.SANDBOX) // or CFEnvironment.PRODUCTION
    .setOrderId(orderId)
    .setPaymentSessionId(paymentSessionId)
    .build();
```

#### Create a payment object

The SDK provides a dedicated payment builder for each supported payment method. Build only the object that corresponds to the payment method your customer has selected.

<Tabs>
  <Tab title="Card">
    Render a `CFCardWidget` in your widget tree to collect the card number, then build the `CFCard` object using `setCardWidget` along with the remaining card details.

    ```dart theme={"dark"}
    import 'package:flutter_cashfree_pg_sdk/api/cfcard/cfcardwidget.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfcard.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfcardpayment.dart';

    final GlobalKey<CFCardWidgetState> cardWidgetKey = GlobalKey<CFCardWidgetState>();

    CFCardWidget cfCardWidget = CFCardWidget(
      key: cardWidgetKey,
      textStyle: null,
      inputDecoration: const InputDecoration(hintText: 'XXXX XXXX XXXX XXXX'),
      cardListener: cardListener,
      cfSession: session,
    );

    var card = CFCardBuilder()
        .setCardWidget(cfCardWidget)
        .setCardHolderName(cardHolderName)
        .setCardExpiryMonth(cardMM)
        .setCardExpiryYear(cardYY)
        .setCardCVV(cardCVV)
        .build();

    var cardPayment = CFCardPaymentBuilder()
        .setSession(session)
        .setCard(card)
        .savePaymentMethod(true) // optional, set true to save the card for future payments
        .build();
    ```

    <Note>
      To charge a previously saved card, call `setInstrumentId` on `CFCardBuilder` with the saved instrument ID instead of `setCardWidget`, and pass only the CVV.
    </Note>
  </Tab>

  <Tab title="Net banking">
    The `setBankCode` field accepts the numeric bank code of the customer's bank.

    ```dart theme={"dark"}
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfnetbanking.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfnetbankingpayment.dart';

    var netbanking = CFNetbankingBuilder()
        .setChannel("link")
        .setBankCode(3003) // required, numeric bank code
        .build();

    var netbankingPayment = CFNetbankingPaymentBuilder()
        .setSession(session)
        .setNetbanking(netbanking)
        .build();
    ```
  </Tab>

  <Tab title="UPI Intent">
    Use `CFUPIUtils().getUPIApps()` to discover the UPI apps installed on the customer's device, then build a `CFUPI` object using the selected app identifier. On Android, pass the app package name. On iOS, pass the UPI app URI scheme (for example, `phonepe://`).

    ```dart theme={"dark"}
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfupi.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfupipayment.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfupi/cfupiutils.dart';

    CFUPIUtils().getUPIApps().then((apps) {
      if (apps != null && apps.isNotEmpty) {
        String upiPackageName = apps[0]["id"] as String;

        var upi = CFUPIBuilder()
            .setChannel(CFUPIChannel.INTENT)
            .setUPIID(upiPackageName)
            .build();

        var upiPayment = CFUPIPaymentBuilder()
            .setSession(session)
            .setUPI(upi)
            .build();

        cfPaymentGatewayService.doPayment(upiPayment);
      }
    });
    ```
  </Tab>
</Tabs>

#### Initiate the payment

Call `doPayment()` to open the Cashfree payment flow for the selected method. The example below uses `cardPayment`. Replace it with `netbankingPayment` or `upiPayment` for your selected payment method.

```dart theme={"dark"}
cfPaymentGatewayService.doPayment(cardPayment);
```

#### Sample code

The following example shows a complete integration, including session creation, payment object setup for each method, and payment initiation.

<AccordionGroup>
  <Accordion title="Element checkout sample">
    ```dart theme={"dark"}
    import 'package:flutter/material.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfcard/cfcardlistener.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfcard/cfcardwidget.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cferrorresponse/cferrorresponse.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfcard.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfcardpayment.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfnetbanking.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfnetbankingpayment.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfupi.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpayment/cfupipayment.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfpaymentgateway/cfpaymentgatewayservice.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfsession/cfsession.dart';
    import 'package:flutter_cashfree_pg_sdk/api/cfupi/cfupiutils.dart';
    import 'package:flutter_cashfree_pg_sdk/utils/cfenums.dart';
    import 'package:flutter_cashfree_pg_sdk/utils/cfexceptions.dart';

    class ElementCheckoutPage extends StatefulWidget {
      const ElementCheckoutPage({Key? key}) : super(key: key);

      @override
      State<ElementCheckoutPage> createState() => _ElementCheckoutPageState();
    }

    class _ElementCheckoutPageState extends State<ElementCheckoutPage> {
      final cfPaymentGatewayService = CFPaymentGatewayService();

      // Replace with the order_id and payment_session_id from your backend.
      final String orderId = "ORDER_ID";
      final String paymentSessionId = "PAYMENT_SESSION_ID";
      final CFEnvironment environment = CFEnvironment.SANDBOX; // or CFEnvironment.PRODUCTION

      CFCardWidget? cfCardWidget;
      String upiPackageName = "";

      @override
      void initState() {
        super.initState();
        cfPaymentGatewayService.setCallback(verifyPayment, onError);

        final cardWidgetKey = GlobalKey<CFCardWidgetState>();
        try {
          var session = createSession();
          cfCardWidget = CFCardWidget(
            key: cardWidgetKey,
            textStyle: null,
            inputDecoration: const InputDecoration(hintText: 'XXXX XXXX XXXX XXXX'),
            cardListener: cardListener,
            cfSession: session,
          );
        } on CFException catch (e) {
          print(e.message);
        }

        // Discover the UPI apps installed on the device.
        CFUPIUtils().getUPIApps().then((apps) {
          if (apps != null && apps.isNotEmpty) {
            setState(() {
              upiPackageName = apps[0]["id"] as String;
            });
          }
        });
      }

      CFSession createSession() {
        return CFSessionBuilder()
            .setEnvironment(environment)
            .setOrderId(orderId)
            .setPaymentSessionId(paymentSessionId)
            .build();
      }

      void verifyPayment(String orderID) {
        // Verify the order status from your backend. See Step 3.
        print("Verify Payment: $orderID");
      }

      void onError(CFErrorResponse errorResponse, String orderID) {
        print("Payment failed for $orderID: ${errorResponse.getMessage()}");
      }

      void cardListener(CFCardListener cardListener) {
        print("Card digits entered: ${cardListener.getNumberOfCharacters()}");
      }

      void cardPay() {
        try {
          var session = createSession();
          var card = CFCardBuilder()
              .setCardWidget(cfCardWidget!)
              .setCardHolderName("John Doe")
              .setCardExpiryMonth("08")
              .setCardExpiryYear("28")
              .setCardCVV("123")
              .build();
          var cardPayment = CFCardPaymentBuilder()
              .setSession(session)
              .setCard(card)
              .savePaymentMethod(true)
              .build();
          cfPaymentGatewayService.doPayment(cardPayment);
        } on CFException catch (e) {
          print(e.message);
        }
      }

      void netbankingPay() {
        try {
          var session = createSession();
          var netbanking = CFNetbankingBuilder()
              .setChannel("link")
              .setBankCode(3003)
              .build();
          var netbankingPayment = CFNetbankingPaymentBuilder()
              .setSession(session)
              .setNetbanking(netbanking)
              .build();
          cfPaymentGatewayService.doPayment(netbankingPayment);
        } on CFException catch (e) {
          print(e.message);
        }
      }

      void upiIntentPay() {
        try {
          var session = createSession();
          var upi = CFUPIBuilder()
              .setChannel(CFUPIChannel.INTENT)
              .setUPIID(upiPackageName)
              .build();
          var upiPayment = CFUPIPaymentBuilder()
              .setSession(session)
              .setUPI(upi)
              .build();
          cfPaymentGatewayService.doPayment(upiPayment);
        } on CFException catch (e) {
          print(e.message);
        }
      }

      @override
      Widget build(BuildContext context) {
        return Scaffold(
          appBar: AppBar(title: const Text('Element checkout')),
          body: Padding(
            padding: const EdgeInsets.all(16.0),
            child: Column(
              children: [
                cfCardWidget!,
                const SizedBox(height: 12),
                ElevatedButton(onPressed: cardPay, child: const Text('Pay with card')),
                const SizedBox(height: 12),
                ElevatedButton(onPressed: netbankingPay, child: const Text('Pay with net banking')),
                const SizedBox(height: 12),
                ElevatedButton(onPressed: upiIntentPay, child: const Text('Pay with UPI Intent')),
              ],
            ),
          ),
        );
      }
    }
    ```
  </Accordion>
</AccordionGroup>

#### Sample GitHub code

You can explore a working integration example on GitHub:

<AccordionGroup>
  <Accordion title="Flutter Element integration">
    * [Card payment](https://github.com/cashfree/flutter-cashfree-pg-sdk/blob/553a9fe37ff53672552f9dd9d2ec7a7d7fb591d9/example/lib/main.dart#L520)
    * [UPI Intent payment](https://github.com/cashfree/flutter-cashfree-pg-sdk/blob/553a9fe37ff53672552f9dd9d2ec7a7d7fb591d9/example/lib/main.dart#L501)
    * [Net banking payment](https://github.com/cashfree/flutter-cashfree-pg-sdk/blob/553a9fe37ff53672552f9dd9d2ec7a7d7fb591d9/example/lib/main.dart#L482)
  </Accordion>
</AccordionGroup>

## Step 3: Confirm the payment <Badge color="green">Server-side</Badge>

After the SDK delivers a callback via `verifyPayment`, confirm the payment status from your backend before taking any action. The SDK callback signals only that the payment flow has ended. It does not guarantee a successful payment.

To verify an order you can call our `/pg/orders` endpoint from your backend. You can also use our SDK to achieve the same.

<CodeGroup>
  ```bash curl theme={"dark"}
  curl --request GET \
       --url https://sandbox.cashfree.com/pg/orders/{order_id} \
       --header 'accept: application/json' \
       --header 'x-api-version: 2025-01-01' \
       --header 'x-client-id: "YOUR APP ID GOES HERE"' \
       --header 'x-client-secret: "YOUR SECRET KEY GOES HERE"'
  ```

  ```javascript nodejs theme={"dark"}
  cashfree
  .PGFetchOrder("<order_id>")
  .then((response) => {
  	console.log("Order fetched successfully:", response.data);
  })
  .catch((error) => {
  	console.error("Error:", error.response.data.message);
  });
  ```

  ```python python theme={"dark"}
  from cashfree_pg.models.create_order_request import CreateOrderRequest
  from cashfree_pg.api_client import Cashfree
  from cashfree_pg.models.customer_details import CustomerDetails
  from cashfree_pg.models.order_meta import OrderMeta

  Cashfree.XClientId = "<x-client-id>"
  Cashfree.XClientSecret = "<x-client-secret>"
  Cashfree.XEnvironment = Cashfree.SANDBOX
  x_api_version = "2023-08-01"

  try:
      api_response = Cashfree().PGFetchOrder(x_api_version, "order_3242X4jQ5f0S9KYxZO9mtDL1Kx2Y7u", None)
      print(api_response.data)
  except Exception as e:
      print(e)

  ```

  ```java java theme={"dark"}
  import com.cashfree.*;
  //other code

  try {
      Cashfree.XClientId = "<x-client-id>";
      Cashfree.XClientSecret = "<x-client-secret>";
      Cashfree.XEnvironment = Cashfree.SANDBOX;

      Cashfree cashfree = new Cashfree();
      String xApiVersion = "2023-08-01";

      ApiResponse<OrderEntity> responseFetchOrder = cashfree.PGFetchOrder(xApiVersion, "<order_id>", null, null, null);
      System.out.println(response.getData().getOrderId());
  } catch (ApiException e) {
      throw new RuntimeException(e);
  }
  ```

  ```go go theme={"dark"}
  version := "2023-08-01"
  response, httpResponse, err := cashfree.PGFetchOrder(&version, "<order_id>", nil, nil, nil)
  if err != nil {
  	fmt.Println(err.Error())
  } else {
  	fmt.Println(httpResponse.StatusCode)
  	fmt.Println(response)
  }
  ```

  ```csharp .net theme={"dark"}
  using cashfree_pg.Client;
  using cashfree_pg.Model;

  Cashfree.XClientId = "<x-client-id>";
  Cashfree.XClientSecret = "<x-client-secret>";
  Cashfree.XEnvironment = Cashfree.SANDBOX;
  var cashfree = new Cashfree();
  var xApiVersion = "2023-08-01";

  try {
      var result = cashfree.PGFetchOrder(xApiVersion, "<order_id>>", null, null);
      Console.WriteLine(result);
      Console.WriteLine(result.StatusCode);
      Console.WriteLine((result.Content as OrderEntity));
  } catch (ApiException e) {
      Console.WriteLine("Exception when calling PGFetchOrder: " + e.Message);
      Console.WriteLine("Status Code: " + e.ErrorCode);
      Console.WriteLine(e.StackTrace);
  }
  ```

  ```php php theme={"dark"}
  $x_api_version = "2023-08-01";
  try {
      $response = $cashfree->PGFetchOrder($x_api_version, "<order_id>");
      print_r($response);
  } catch (Exception $e) {
      echo 'Exception when calling PGFetchOrder: ', $e->getMessage(), PHP_EOL;
  }
  ```
</CodeGroup>

<Note>
  Always verify the order status from your backend before you deliver goods or services to the customer. You can use the [Get Order API](/docs/api-reference/payments/latest/orders/get-order) for this. An order is successful when the `order_status` is `PAID`.
</Note>

## Testing

After you integrate a payment method, verify that it behaves as expected. Follow these steps to test:

1. Trigger a payment using each method you have integrated.
2. Confirm that the SDK opens the correct payment screen for the method (Cashfree's hosted net banking screen, the card widget's own flow, or the selected UPI app).
3. Confirm that `verifyPayment` or `onError` is called when the payment flow ends.

Use the [sandbox environment](/docs/payments/online/resources/sandbox-environment) to test payments before you go live.

## Error codes

Before it reaches the native SDK, the Flutter layer validates each builder call and throws a `CFException` if a required field is missing. Catch `CFException` around every builder and `doPayment()` call to handle these cases.

<Accordion title="Show validation exceptions">
  | Exception message | Cause |
  | - | - |
  | `order id cannot be empty` | `setOrderId` wasn't called, or was called with an empty string, on `CFSessionBuilder`. |
  | `payment session id cannot be empty` | `setPaymentSessionId` wasn't called, or was called with an empty string, on `CFSessionBuilder`. |
  | `environment value cannot be empty` | `setEnvironment` wasn't called on `CFSessionBuilder`. |
  | `session value cannot be empty` | `setSession` wasn't called on the payment builder (`CFCardPaymentBuilder`, `CFNetbankingPaymentBuilder`, or `CFUPIPaymentBuilder`). |
  | `callbacks have to be set before initiating the payment` | `doPayment()` was called before `setCallback()`. |
</Accordion>

If the payment itself fails after reaching the native SDK, your `onError` callback receives a `CFErrorResponse` with `getStatus()`, `getMessage()`, `getCode()`, and `getType()` accessors describing the failure.

<div
  className="callout info"
  style={{
backgroundColor: 'light-dark(#f9f7fd, #2d1b4e)',
borderColor: 'light-dark(#cdbaef, #6930ca)',
color: 'light-dark(#000000, #ffffff)'
}}
>
  <p style={{fontSize: '1.3em', fontWeight: '500', marginBottom: '16px'}}>Affiliate partner program</p>

  <p>As a developer building payment experiences for your clients, you can earn additional income while providing them with industry-leading payment solutions.</p>

  <p>Join the <a href="https://partner.cashfree.com/partner-ui/authentication/signup?source-action=Affiliate%20Program%20LP&action=Sign%20Up&button-id=StartNow_CashfreeAffiliatePartnerProgram">Cashfree affiliate partner program</a> and get rewarded every time your clients use Cashfree.</p>

  <p>**What you get:**</p>

  <ul>
    <li>Earn up to 0.25% commission on every transaction.</li>
    <li>Become a trusted fintech partner for your clients.</li>
    <li>Access to a dedicated partner manager for expert support.</li>
  </ul>

  <p>**What your clients get:**</p>

  <ul>
    <li>Instant activation and go live in minutes.</li>
    <li>Industry-best success rate across all payment modes.</li>
    <li>Effortless acceptance of international payments in 140+ currencies.</li>
  </ul>

  <p>Get started today. <a href="https://partner.cashfree.com/partner-ui/authentication/signup?source-action=Affiliate%20Program%20LP&action=Sign%20Up&button-id=StartNow_BecomeAPartner">Become a partner now</a>.</p>
</div>

<div class="hidden" data-table-of-contents="bottom">
  <p class="mt-4 font-medium flex items-center gap-2 related-docs-heading">
    <svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" class="w-4 h-4">
      <path d="M3 4h7a2 2 0 0 1 2 2v13a2 2 0 0 0-2-2H3z" />

      <path d="M21 4h-7a2 2 0 0 0-2 2v13a2 2 0 0 1 2-2h7z" />
    </svg>

    <span>Related topics</span>
  </p>

  <ul>
    <li><a href="/docs/api-reference/payments/latest/orders/create-order">Create Order API</a></li>
    <li><a href="/docs/api-reference/payments/latest/orders/get-order">Get Order API</a></li>
    <li><a href="/docs/payments/online/element/overview">Element Overview</a></li>
    <li><a href="https://github.com/cashfree/flutter-cashfree-pg-sdk" target="_blank">Flutter SDK on GitHub</a></li>
  </ul>
</div>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.