SDKLess Intent integration for iOS.
PhonePe will give the ppe:// intent to the merchant on SDKLess integration to launch the PhonePe App.
Steps to Integrate SDKLess Solution
To support SDKLess integration, deviceContext has to be added to the request body of the v4/debit API call.
Request for PhonePe Intent
{
"merchantId": "MERCHANTUAT",
"transactionId": "e474af20-a2a6-46c1-9a5d-73910ae86d0b",
"merchantOrderId": "",
"merchantUserId": "user9999",
"amount": 100,
"mobileNumber": "9999999999",
"paymentScope": "PHONEPE",
"deviceContext": {
"deviceOS": "IOS",
"isPPAppPresent": true,
"merchantCallBackScheme": "iOSIntentIntegration",
"appSupportedSchemas": [
"ppemerchantsdkv1"
]
}
}
{
"request": "ewogICAgIm1lcmNoYW50SWQiOiAiTUVSQ0hBTlRVQVQiLAogICAgInRyYW5zYWN0aW9uSWQiOiAiZTQ3NGFmMjAtYTJhNi00NmMxLTlhNWQtNzM5MTBhZTg2ZDBiIiwKICAgICJtZXJjaGFudE9yZGVySWQiOiAiIiwKICAgICJtZXJjaGFudFVzZXJJZCI6ICJ1c2VyOTk5OSIsCiAgICAiYW1vdW50IjogMTAwLAogICAgIm1vYmlsZU51bWJlciI6ICI5OTk5OTk5OTk5IiwKICAgICJwYXltZW50U2NvcGUiOiAiUEhPTkVQRSIsCiAgICAiZGV2aWNlQ29udGV4dCI6IHsKICAgICAgImRldmljZU9TIjogIklPUyIsCiAgICAgICJpc1BQQXBwUHJlc2VudCI6IHRydWUsCiAgICAgICJtZXJjaGFudENhbGxCYWNrU2NoZW1lIjogImlPU0ludGVudEludGVncmF0aW9uIiwKICAgICAgImFwcFN1cHBvcnRlZFNjaGVtYXMiOiBbCiAgICAgICAgInBwZW1lcmNoYW50c2RrdjEiCiAgICAgIF0KICAgIH0KICB9"
}
Request for Open Intent
{
"merchantId": "MERCHANTUAT",
"transactionId": "e474af20-a2a6-46c1-9a5d-73910ae86d0b",
"merchantUserId": "user9999",
"amount": 100,
"mobileNumber": "9999999999",
"paymentScope": "ALL_UPI_APPS",
"openIntentWithApp":"PHONEPE",
"deviceContext": {
"deviceOS": "iOS",
"merchantCallBackScheme": "iOSIntentIntegration"
}
}
{
"merchantId": "MERCHANTUAT",
"transactionId": "e474af20-a2a6-46c1-9a5d-73910ae86d0b",
"merchantUserId": "user9999",
"amount": 100,
"mobileNumber": "9999999999",
"paymentScope": "ALL_UPI_APPS",
"openIntentWithApp": "GPAY",
"deviceContext": {
"deviceOS": "iOS"
}
}
merchantCallBackScheme
The merchantCallBackScheme can be passed only for the PhonePe App (“openIntentWithApp”: “PHONEPE”) that helps to open the merchant app after the completion of the Payment.
{
"request": "ewogICJtZXJjaGFudElkIjogIk1FUkNIQU5UVUFUIiwKICAidHJhbnNhY3Rpb25JZCI6ICJlNDc0YWYyMC1hMmE2LTQ2YzEtOWE1ZC03MzkxMGFlODZkMGIiLAogICJtZXJjaGFudFVzZXJJZCI6ICJ1c2VyOTk5OSIsCiAgImFtb3VudCI6IDEwMCwKICAibW9iaWxlTnVtYmVyIjogIjk5OTk5OTk5OTkiLAogICJwYXltZW50U2NvcGUiOiAiQUxMX1VQSV9BUFBTIiwKICAib3BlbkludGVudFdpdGhBcHAiOiJQSE9ORVBFIiwKICAiZGV2aWNlQ29udGV4dCI6IHsKICAgICJkZXZpY2VPUyI6ICJpT1MiLAogICAgIm1lcmNoYW50Q2FsbEJhY2tTY2hlbWUiOiAiaU9TSW50ZW50SW50ZWdyYXRpb24iCiAgfQp9"
}
Request Parameters
Parameter Name | Type | Mandatory | Description |
---|---|---|---|
merchantId | STRING | Yes | Unique MerchantID assigned to the merchant by PhonePe |
transactionId | STRING | Yes | Unique TransactionID generated by the merchant to track request to PhonePe. transactionId length should be less than 38 characters. |
merchantOrderId | STRING | No | OrderID generated by the merchant merchantOrderId length should be less than 48 characters. |
merchantUserId | STRING | Yes | [Mandatory for Web Flow] Unique UserID generated by merchant. This is used to pre-login users authenticated on PhonePe Web flow. Un-authenticated users are redirected to PhonePe login page. Conversions are higher when this is provided. Avoid passing email/mobile number. Skip this for guest users. merchantUserId length should be less than 64 characters. |
amount | LONG | Yes | Transaction amount in Paise. |
paymentScope | STRING | Conditional | The Payment Scope should be passed. For PhonePe Intent, the value should be PHONEPE For Open Intent, the value should be ALL_UPI_APPS |
openIntentWithApp | STRING | Conditional | For PhonePe Intent with paymentScope= “PHONEPE”, openIntentWithApp is not required. For Open Intent with paymentScope= “ALL_UPI_APPS”, the values should be passed be as per the app selected by the user ● PHONEPE ● GPAY ● PAYTM |
mobileNumber | STRING | No | Mobile number of the user |
appSupportedSchema | ARRAY | Yes | This key will contain schema supported by the PhonePe App from these 3 allowed schema lists. |
deviceOS | STRING | Yes | This is used to find the request device OS Possible Value: iOS |
isPPAppPresent | BOOL | Yes | This is used to find if PhonePe App is present or not. Possible Values: true – If PhonePe App Present false – If PhonePe App is not Present |
merchantCallBackScheme | STRING | Optional | This value will be used to open the merchant app after the completion of the transaction on the PhonePe app. Note: Works only with PhonePe App. |
Response for PhonePe Intent
{
"success": true,
"code": "SUCCESS",
"message": "Your request has been successfully completed.",
"data": {
"redirectType": "INTENT",
"redirectURL": "ppe://pay?pa=MERCHANTUAT@ybl&pn=MERCHANT&am=1.00&mam=1.00&tr=e474af20-a2a6-46c1-9a5d-73910ae86d0b&tn=Payment+for+e474af20-a2a6-46c1-9a5d-73910ae86d0b&mc=5311&mode=04&purpose=00&utm_campaign=DEBIT&utm_medium=MERCHANTUAT&utm_source=e474af20-a2a6-46c1-9a5d-73910ae86d0b&mcbs=demoAppScheme"
}
}
Response for Open Intent
{
"success": true,
"code": "SUCCESS",
"message": "Your request has been successfully completed.",
"data": {
"redirectType": "OPEN_INTENT",
"redirectURL": "ppe://pay?pa=SWIGGY8@ybl&pn=MERCHANT&am=1.00&mam=1.00&tr=92eef18b-110b-4d50-b609-9a5d44ff2c88&tn=Payment+for+92eef18b-110b-4d50-b609-9a5d44ff2c88&mc=5311&mode=04&purpose=00&utm_campaign=DEBIT&utm_medium=SWIGGY8&utm_source=92eef18b-110b-4d50-b609-9a5d44ff2c88&mcbs=demoAppScheme",
"unavailableUpiApps": null
}
}
{
"success": true,
"code": "SUCCESS",
"message": "Your request has been successfully completed.",
"data": {
"redirectType": "OPEN_INTENT",
"redirectURL": "gpay://upi/pay?pa=SWIGGY8@ybl&pn=MERCHANT&am=1.00&mam=1.00&tr=1cac394d-7582-4b69-9414-8b655f677a8b&tn=Payment+for+1cac394d-7582-4b69-9414-8b655f677a8b&mc=5311&mode=04&purpose=00&utm_campaign=DEBIT&utm_medium=SWIGGY8&utm_source=1cac394d-7582-4b69-9414-8b655f677a8b",
"unavailableUpiApps": null
}
}
{
"success": true,
"code": "SUCCESS",
"message": "Your request has been successfully completed.",
"data": {
"redirectType": "OPEN_INTENT",
"redirectURL": "paytmmp://upi/pay?pa=SWIGGY8@ybl&pn=MERCHANT&am=1.00&mam=1.00&tr=e224f57d-c514-47f0-b8cc-5b3cab4038af&tn=Payment+for+e224f57d-c514-47f0-b8cc-5b3cab4038af&mc=5311&mode=04&purpose=00&utm_campaign=DEBIT&utm_medium=SWIGGY8&utm_source=e224f57d-c514-47f0-b8cc-5b3cab4038af",
"unavailableUpiApps": null
}
}
Redirection after Payment Completion
For GPay and Paytm, the redirection will be manual after the completion of the payment.
Integration Steps
App Side
- In your Info.plist, create or append a new Array type node LSApplicationQueriesSchemes to append the following values:
Text<key>LSApplicationQueriesSchemes</key> <array> <string>ppemerchantsdkv1</string> <string>ppemerchantsdkv2</string> <string>ppemerchantsdkv3</string> <string>paytmmp</string> <string>gpay</string> </array>

- 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) and pass it in the deviceContext.merchantCallBackScheme of Debit request.

Server Side
- Save the below-assigned value to your server.
String apiEndPoint = "/v4/debit";
- Construct the request body with the required parameters in deviceContext and encode it in Base 64 format.
- Select one of the salts shared with you and note its index. Construct the X-verify (Checksum) at your server as follows:
String checksum = sha256(base64Body + apiEndPoint + salt) + ### + saltIndex;
- Call the Debit API with the constructed request and checksum to get the Intent URL in the response to launching the PhonePe App.
- Pass the received Intent or Web URL to the frontend.
- If Intent URL is received, launch the Intent URL to initiate the payment using the PhonePe App
- If Web URL is received, redirect the user to the web URL using web view.
- Once the payment is completed, please check the status of the transaction with your server. If the S2S response is not received, call the Check Transaction Status API to validate the response. You can call the Check Transaction Status at regular intervals to fetch the response from the PhonePe server.
- The payment status can be Successful, Failed, Pending or any of the codes. For Pending, you should retry until the status changes to Success or Failure.
Code Snippet to Generate “deviceContext”
To find appSupportedSchema + isPPAppPresent value, the below code snippet has to be used to check it or to generate deviceContext.
Usage: PhonePeContextGenerator(callbackSchema: “demoAppSchema”).getDeviceContext()
class PhonePeContextGenerator {
private let callbackSchema: String?
init(callbackSchema: String?) {
self.callbackSchema = callbackSchema
}
private struct UriSchemeConstants {
static let uriScheme1 = "ppemerchantsdkv1"
static let uriScheme2 = "ppemerchantsdkv2"
static let uriScheme3 = "ppemerchantsdkv3"
static let hyphenation = "://"
}
private func isPhonePeInstalled() -> Bool {
DispatchQueue.main.sync {
guard let openUrl1 = URL(string: UriSchemeConstants.uriScheme1 + UriSchemeConstants.hyphenation),
let openUrl2 = URL(string: UriSchemeConstants.uriScheme2 + UriSchemeConstants.hyphenation),
let openUrl3 = URL(string: UriSchemeConstants.uriScheme3 + UriSchemeConstants.hyphenation) else {
return false
}
let appInstalled = UIApplication.shared.canOpenURL(openUrl1) ||
UIApplication.shared.canOpenURL(openUrl2) ||
UIApplication.shared.canOpenURL(openUrl3)
return appInstalled
}
}
private func getAppSupportedSchema() -> [String] {
var supportedAppSchemas: [String] = []
DispatchQueue.main.sync {
[UriSchemeConstants.uriScheme1, UriSchemeConstants.uriScheme2, UriSchemeConstants.uriScheme3].forEach { (scheme) in
if let openUrl = URL(string: scheme + UriSchemeConstants.hyphenation),
UIApplication.shared.canOpenURL(openUrl) {
supportedAppSchemas.append(scheme)
}
}
}
return supportedAppSchemas
}
func getDeviceContext() -> [String: Any] {
var context: [String: Any] = [:]
context["appSupportedSchemas"] = getAppSupportedSchema()
context["isPPAppPresent"] = isPhonePeInstalled()
context["deviceOS"] = "iOS"
if let schema = callbackSchema {
context["merchantCallBackScheme"] = schema
}
return context
}
}