Flutter SDK Integration

The steps to integrate the PhonePe Payment Gateway with flutter platform. We provide a plugin/bridge to integrate our SDK.

The minimum supported versions

  • Flutter Version: 2.17.0
  • Latest Flutter SDK Version: 3.0.0

We can implement with the below 2 steps:

  1. Add the native configuration (Android/iOS)
  2. Add the Plugin to the Flutter project
  1. Android – Add the native configuration in the Android Studio project
  2. iOS – Add the native configuration in the Xcode project
  3. Add the Plugin to your Flutter Project
    1. Init Method
    2. Start the Transaction
  4. Parameters
  5. Server Side Implementation

Android

Add the native configuration in the Android Studio project

  1. Add the below code to ‘repositories’ section of your project level build.gradle file
// Top-level build file where you can add configuration options common to all sub-projects/modules. 
allprojects { 
   repositories { 
      google() 
      maven { 
         url "https://phonepe.mycloudrepo.io/public/repositories/phonepe-intentsdk-android" 
      } 
   } 
}
  1. Build/Sync gradle:
    Go to the android folder inside your app & sync/build gradle (by typing ./gradlew build on the command line/ terminal)
  2. Merchants MainActivity should extend FlutterFragmentActivity
import io.flutter.embedding.android.FlutterFragmentActivity
class MainActivity : FlutterFragmentActivity()

iOS

Add the native configuration in the Xcode project

1. In your Info.plist under the iOS Xcode project, create or append a new Array type node LSApplicationQueriesSchemes to append the following values:

<key>LSApplicationQueriesSchemes</key> 
<array> 
   <string>ppemerchantsdkv1</string>  
   <string>ppemerchantsdkv2</string> 
   <string>ppemerchantsdkv3</string>
   <string>paytmmp</string>
   <string>gpay</string> 
</array>

2. Create a URLType for your app (Deeplink), if not already present.

For example, we have used: iOSIntentIntegration. (You can create your own identifier for your app)

URLScheme should match the below conditions

  • Only Alphabets (lower and upper case) and numbers are allowed.
  • We can allow special characters only like dot and Hyphen
  • The name should always start with alphabets.

The schema should be correct to redirect the app otherwise it will not redirect back to the merchant app.

3. For iOS dependency

cd ios 
pod install

4. For Monitoring Transaction State and getting callback from the PhonePe consumer app, add these lines in your AppDelegate.m, inside openURL:(NSURL *) url

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options 
{ 
  NSMutableDictionary *userInfo = [[NSMutableDictionary alloc] init]; 
  [userInfo setObject:options forKey:@"options"];    
  [userInfo setObject:url forKey:@"openUrl"]; 
  [[NSNotificationCenter defaultCenter] postNotificationName: @"ApplicationOpenURLNotification" object:nil userInfo:userInfo]; 
  return YES; 
}

Add the Plugin to your Flutter Project

  1. Add the dependency in the Flutter project from the command line
flutter pub add phonepe_payment_sdk
  1. Install the dependency from the command line
flutter pub get
  1. Import the package in your dart code
import 'package:phonepe_payment_sdk/phonepe_payment_sdk.dart';
  1. Call the PhonePe methods as below

Init Method

Initialize the init method before starting the transaction.

  /*
   * This method is used to initiate PhonePe Payment sdk.
   * Provide all the information as requested by the method signature.
   * Params:
   *    - environment: This signified the environment required for the payment sdk
   *      possible values: SANDBOX, PRODUCTION
   *      if any unknown value is provided, PRODUCTION will be considered as default.
   *    - merchantId: The merchant id provided by PhonePe at the time of onboarding.
   *    - flowId : An alphanumeric string without any special character. It acts as a common ID b/w
   *      your app user journey and PhonePe SDK. This helps to debug prod issue. 
   *      Recommended - Pass user-specific information or merchant user-id to track the journey.
   *    - enableLogging: If you want to enable / visualize sdk log @IOS
   *        - enable = YES
   *        - disable = NO
   */
  static Future<bool> init(String environment, String merchantId, String flowId,
      bool enableLogging) async {
    bool result = await _channel.invokeMethod('init', {
      'environment': environment,
      'merchantId': merchantId,
      'flowId': flowId,
      'enableLogs': enableLogging,
    });
    return result;
  }

Example:
PhonePePaymentSdk.init(environmentValue, merchantId, flowId, enableLogs)
    .then((isInitialized) => {
        setState(() {
            result = 'PhonePe SDK Initialized - $isInitialized';
        })
    })
    .catchError((error) {
        handleError(error);
        return <dynamic > {};
    });

Start the Transaction

  /*
    * This method is used to initiate PhonePe Transaction Flow.
    * Provide all the information as requested by the method signature.
    * Params:
    *    - request : The request body for the transaction as per the developer docs.
    *    - appSchema: @Optional(Not need for Android) For iOS, Your custom URL Schemes, as per the developer docs.
    *
    * Return: Will be returning a dictionary / hashMap
    *  {
    *     status: String, // string value to provide the status of the transaction
    *                     // possible values: SUCCESS, FAILURE, INTERRUPTED
    *     error: String   // if any error occurs
    *  }
    */
  static Future<Map<dynamic, dynamic>?> startTransaction(
      String request, String appSchema) async {
    var dict = <String, dynamic>{'request': request, 'appSchema': appSchema};
    Map<dynamic, dynamic>? result =
        await _channel.invokeMethod('startTransaction', dict);
    return result;
  }

Example:
PhonePePaymentSdk.startTransaction(request, appSchema)
    .then((response) => {
        setState(() {
            if (response != null) {
                String status = response['status'].toString();
                String error = response['error'].toString();
                if (status == 'SUCCESS') {
                    result = "Flow Completed - Status: Success!";
                } else {
                    result =
                        "Flow Completed - Status: $status and Error: $error";
                }
            } else {
                result = "Flow Incomplete";
            }
        })
    })
    .catchError((error) {
        handleError(error);
        return <dynamic > {};
    });

Parameters

Parameter NameData TypeDescription
environmentEnumPossible Values:
1. SANDBOX
2. PRODUCTION
merchantIdStringMerchant ID provided by the PhonePe Team
flowIdStringPass the merchant user Id or a unique alphanumeric random string
enableLoggingBoolean– True (To enable the SDK logs)
– False (To disable the SDK logs)
Note: In Prod, make sure to set as False.
requestStringThe request for the payment initiation
Note: Refer to Step 3 under Server Side Implementation
appSchemaString[Only for iOS]Your App URL Scheme – To return the UI control back to the merchant app.

Server Side Implementation

Step 1. Fetch Auth Token

Merchants to check whether the valid Auth Token is present already. If not, the Fetch Auth Token API should be called to get the valid Auth Token.

Step 2. Call the Create Order API

Merchants should call Create Order API for Order creation with the valid Auth Token from the merchant Backend side by passing the required details. PhonePe backend will pass the Order Token in response to the merchant Backend.

Step 3. Construct the JSON request body
Merchants should construct the JSON request body as per the payment flow and pass the JSON payload as STRING in the startTransaction method.

For Standard Checkout

{
    "orderId": "UNIQUE11_122",
    "merchantId": "PRODTEST",
    "token": "hq4wOGdzX31IuPyyh7/7AYOLiipO42P8QtgmusudZHta7zUAMbV5uMV5f6kF1hmvheryrKRViCFFSkJeROPrcCNJ4SyRFeXk3DYalFsnngRPJb+0KaVOQDN129hOh4d8VMZig/xHnLD08kBbDlCfqU0tgrmLOJ0DrhRK0siw5UpJJpQXkHpiZN+57O51IFhul0WhcQPZQKR6nkk4N3DXUUdJ6h0k7xJSgeCPf7mR+MrbelCCr+t97HoqJ1ufLpDIKk8faOoz9mMus67VwQqPAlbYLGQ+74/Ow+BbNjiHG1Vae/PJN54kHu+IrOdle0i801evPR2XSZ2lvF/DokpFGlG/d2oWi6R1fomf7I9DozvCFYUm2eU9iizjiiPbTomUYYl5d/WiDelXZZ5GgM/aFUoUSpUs8BlW+5lZpmX5KvyUaLHH3A5U7kD2xPnExcZAWigAcdfL0tStRuW0q8W77MNzQ875aMjVlpLlrZUMkumLJELTuev+BXeZUg==",
    "paymentMode": {
        "type": "PAY_PAGE"
    }
}

Parameters

Parameter NameData TypeDescription
orderIdStringThe PhonePe generated orderId received in the Create Order API response.
merchantIdStringMerchant ID provided by the PhonePe Team
tokenStringThe Order Token received in the Create Order API response.
paymentMode.typeStringFor Standard Checkout,
value should be PAY_PAGE
Step 4. Check the payment status

Once the payment is completed, merchants should check with the backend server if the Webhook has been received or not.

  • If not, merchants should call the Order Status API to fetch the current payment status.
  • If the status is terminal status like: COMPLETED or FAILED, the the order status can be updated accordingly.
  • If incase, the status is PENDING, then merchants should call the Order Status API at regular intervals like every 15 secs or 30 secs or 1min once till the terminal status is reached.

Sample App