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:
- Add the native configuration (Android/iOS)
- Add the Plugin to the Flutter project
Sequence
- Android – Add the native configuration in the Android Studio project
- iOS – Add the native configuration in the Xcode project
- Add the Plugin to your Flutter Project
- Parameters
- Server Side Implementation
Android
Add the native configuration in the Android Studio project
- 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"
}
}
}
- Build/Sync gradle:
Go to the android folder inside your app & sync/build gradle (by typing ./gradlew build on the command line/ terminal) - 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
- Add the dependency in the Flutter project from the command line
flutter pub add phonepe_payment_sdk
- Install the dependency from the command line
flutter pub get
- Import the package in your dart code
import 'package:phonepe_payment_sdk/phonepe_payment_sdk.dart';
- 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 Name | Data Type | Description |
environment | Enum | Possible Values: 1. SANDBOX 2. PRODUCTION |
merchantId | String | Merchant ID provided by the PhonePe Team |
flowId | String | Pass the merchant user Id or a unique alphanumeric random string |
enableLogging | Boolean | – True (To enable the SDK logs) – False (To disable the SDK logs) Note: In Prod, make sure to set as False. |
request | String | The request for the payment initiation Note: Refer to Step 3 under Server Side Implementation |
appSchema | String | [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 Name | Data Type | Description |
orderId | String | The PhonePe generated orderId received in the Create Order API response. |
merchantId | String | Merchant ID provided by the PhonePe Team |
token | String | The Order Token received in the Create Order API response. |
paymentMode.type | String | For 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
- Flutter Sample App – https://github.com/PhonePe/phonepe-pg-sdk-flutter