SDK Integration (iOS)

1. PreRequisites

  1. XCode 12.5 or newer
  2. Cocoapod
  3. Onboarded on PhonePe as a Merchant (Given a MerchantID, & Saltkeys to generate the checksum on your servers)
  4. PhonePeAppId (Mandatory to pass in SDK initialization)

2. iOS PG SDK setup

The PhonePePayment framework is needed for the SDK to work for both Sandbox (Testing) and Production (Deployment) environments.

Latest Phonepe iOS SDK Version: 4.0.3

Step 2. Installation

To install it, simply add the following line to your Podfile:

pod 'PhonePePayment'

then run

pod install
Step 3.
import PhonePePayment

3. iOS App Side Implementation

  1. In your info.Plist, 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>ppemerchantsdkv4</string>
<string>ppemerchantsdkv5</string>
</array>

2. Initialize the SDK

let ppPayment = PPPayment(environment: .production,
                          flowId: "FLOW_ID",
                          merchantId: "MERCHANT_ID")
Parameter NameTypeDescription
environmentEnum.production for Production
.sandbox for PreProd
flowIdStringPass the merchant user Id or the unique string (UUID().uuidString) for every init for analytics purposes.
merchantIdStringThe merchant Id provided by PhonePe
enableLoggingBoolean[Optional Parameter]
– True
(To enable the SDK logs)
– False
(To disable the SDK logs)
Note: In Prod, make sure to set as False.

3. Collect Base64 encoded body, checksum, apiEndPoint and transactionID from your server using an API call

4. Initiate the payment process as follows:

var headers = [String: String]()
headers.updateValue("<Callback URL>", forKey: "X-CALLBACK-URL")
headers.updateValue("<Callback Mode>", forKey: "X-CALL-MODE")

let debitRequest = PPTransactionRequest(
    body: <#body received by your server#>,
    apiEndPoint: <#apiEndPoint received by your server#>,
    checksum: <#checksum received by your server#>,
    headers: <#headers#>)

PPPayment.startPhonePeTransactionRequest(
    debitRequest,
    on: self,
    animated: true) { (debitRequest, result) in
/*
Check result.successful to check if the payment flow was successful. 
This success only indicates payment flow completion and not actual transaction status. 
You need to query your server for actual transaction status.
*/

//Check result.error for checking why the payment flow failed
 
//If you get any error, refer to the iOS Merchant Integration Document section troubleshoot for the steps to debug.

}

5. Once App receives the response from the SDK, App must inform your server to validate the response by calling the Check Transaction Status

6. Get the validated result from the server and notify your app

7. Based on the result inform the user about Successful or Failed status of the transaction

Server Side

  1. Save the below assigned value at your server
String apiEndPoint = "/v4/debit";
  1. Construct the request body and encode it in Base 64 at your server as follows:
HashMap<String, Object> data = new HashMap<>();
data.put("merchantId", <Your merchant ID>); // String. Mandatory
data.put("transactionId", <Unique transaction id>); // String. Mandatory
data.put("amount", <amount in paise>); // Integer. Mandatory

//Note: Don't pass this if you are passing userAuthToken.
data.put("merchantUserId", userId); //String. Mandatory. Needed for linking 

//Note : Used only for OTP linking flow.
data.put("userAuthToken", userId); //String. Optional. Needed for linking 

data.put("merchantOrderId", <Order Id>); // String. Optional
data.put("message", <message summarizing the transaction>); // String. Optional
 
data.put("mobileNumber", <Mobile number of the user>); // String. Optional
data.put("email", <Email of the user>); // String. Optional
data.put("shortName", <Name of the user>); // String. Optional
 
data.put("subMerchant", <submerchant ID>); // String. ONLY if a submerchant id has been allocated to you.
 
// transactionId length should be less than 38 characters.
// merchantOrderId length should be less than 48 characters.
// merchantUserId length should be less than 64 characters.
// Put more info as intimated. Nesting is allowed
String base64Body = Base64(new GSON().toJson(data));
  1. Select one of the salts shared with you and note its index. Construct the X-verify at your server as follows:
String checksum = sha256(base64Body + apiEndPoint + salt) + ### + saltIndex;
  1. Once the payment is completed, please call the Check Transaction Status API to validate the response received via App. You can call the Check Transaction Status at regular intervals to fetch the response from PhonePe server in case response is not received in the application even after 10 minutes of initiating the application.
  2. The payment status can be Successful, Failed, Pending or any of the codes. For Pending, you should retry until the status changes to Successful or Failed.

SDK Methods

Check Availability

Request Payload:

{
    "merchantId": "MID",
    "mobileNumber": "993XXXXXXX",
    "merchantUserId": "User_1234"
}

Base64 Encoded Payload:

base64EncodedString = "ewogICAgIm1lcmNoYW50SWQiOiAiTUlEIiwKICAgICJtb2JpbGVOdW1iZXIiOiAiOTkzWFhYWFhYWCIsCiAgICAibWVyY2hhbnRVc2VySWQiOiAiVXNlcl8xMjM0Igp9"

Api End Point:

apiEndPoint = "/v3/availabilitycheck"

Checksum Calculation:

val payloadChecksum = SHA256(base64EncodedString + apiEndPoint + salt) + "###" + saltIndex

Check Availability Request:

let request = PPAvailabilityCheckRequest(data: base64EncodedString,
                                         checksum: payloadChecksum)

Pass the request into check availability method:

PPPayment.checkAvailability(request: request) { [weak self] isAvailable, responseCode in
   print("SDK Completion isAvailable: \(isAvailable), responseCode: \(responseCode)")
}

Sample Response:

//For Success
isAvailable: true, responseCode: "SUCCESS"

//For Failure
isAvailable: false, responseCode: "PHONEPE_APP_NOT_INSTALLED"