Merchant Checklist
UAT Sign-Off Process
- Once the integration is completed, Merchants must share the UAT instance for the end-to-end flow verification.
- Any issues identified in the UAT stage must be fixed and verified by the integration POC in the UAT itself.
- Only if all the use cases are handled properly, the integration POC will provide the UAT Sign-off and it should be acknowledged by the Merchant to proceed further and release the Production Credentials.
API Wise Checklist
The below API wise checklist will help the Merchants to handle all the necessary use cases during the integration phase itself to ensure smoother UAT closure.
Note: None of the use cases are Optional. It is mandatory to be implemented.
Authorization API
- Merchants must rely on the expires_at parameter received in the response.
- Option 1: Merchant should check whether the token is active or expired before every API request.
- If token is active, then the same token can be used in the API request.
- If token is expired, then the Authorization API should be called to regenerate the new token and use the new token in the API request
- Option 2: Merchant can setup a scheduler that will regenerate the new token by calling Authorization API, 3 or 5 minutes before the actual expiry of the existing token.
- Note: Merchant should not call the Authorization API to fetch the new token before every API request without relying on the expiry.
Payment API
Request
Common Parameters
- merchantOrderId – Merchants should always pass unique merchantOrderId for each and every request.
- expireAfter – Order expiry in seconds. If not passed, default value will be used. [For Custom Checkout: Min Value = 300, Max Value = 5184000 (in Seconds)]
- amount – Merchants should pass the amount parameter value in Paise (Multiply the Rs value by 100)
- udf – Merchants should pass the user defined fields in metaInfo only if it is being used, otherwise skip the metaInfo. Currently 5 fields are provided and use only the number of fields required and remove the fields which are not being used instead of passing empty value.
- paymentFlow.type – should be passed PG
UPI Intent – Parameters
Note: Merchants should identify and list only the UPI apps which are present in the user’s device.
- paymentFlow.paymentMode.type – should be passed “UPI_INTENT”
- paymentFlow.paymentMode.targetApp –
[Android] should be passed with the package name of the UPI app selected by the user.
[iOS] should be passed with the static app name of the UPI app selected by the user. - deviceContext.deviceOS – should be passed with “ANDROID” or “IOS” depending on the platform.
- deviceContext.merchantCallBackScheme – [Only for iOS] should be passed with the URL schema of the merchant app
UPI Collect – Parameters
Note: Before calling this API, merchants should validate the VPA entered by the user using UPI Address Validate API. If Invalid, then the error message should be shown to the user.
- paymentFlow.paymentMode.type – should be passed “UPI_COLLECT”
- paymentFlow.paymentMode.details.type – should be passed “VPA”
- paymentFlow.paymentMode.details.vpa – should be passed with the VPA entered by the user.
UPI QR – Parameters
- paymentFlow.paymentMode.type – should be passed “UPI_QR”
Note: Merchants can convert either intentUrl or qrData received in the response into a QR image and display on the checkout page.
Card – Parameters
Note: Merchants should be PCI DSS Complaint to process the Custom Card flow.
- paymentFlow.paymentMode.type – should be passed “CARD”
- cardDetails.encryptedCardNumber– The 16 digit card number entered by the user should be RSA 4096 encrypted with the given Public Key.
- cardDetails.encryptionKeyId– The encryption Key Id will be numeric value provided along with the Public Key.
- cardDetails.expiry.month – Expiry month
- cardDetails.expiry.year – Expiry year (4 digits)
- cardDetails.encryptedCvv– The 3 digit cvv number entered by the user should be RSA 4096 encrypted with the given Public Key.
- paymentFlow.merchantUrls.redirectUrl– should be passed with the Merchant’s redirection URL where the UI control will be given back once the payment is completed by the user.
Token – Parameters
Note: Merchants should be PCI DSS Complaint to process the Custom Card flow.
- paymentFlow.paymentMode.type – should be passed “TOKEN”
- tokenDetails.encryptedToken– The token number entered by the user should be RSA 4096 encrypted with the given Public Key.
- tokenDetails.encryptionKeyId– The encryption Key Id will be numeric value provided along with the Public Key.
- tokenDetails.expiry.month – Expiry month
- tokenDetails.expiry.year – Expiry year (4 digits)
- tokenDetails.encryptedCvv– The 3 digit cvv number entered by the user should be RSA 4096 encrypted with the given Public Key.
- tokenDetails.cryptogram– The cryptogram fetched from the gateway where the card was tokenised.
- tokenDetails.panSuffix– The last four digits of cardNumber.
- paymentFlow.merchantUrls.redirectUrl– should be passed with the Merchant’s redirection URL where the UI control will be given back once the payment is completed by the user.
NetBanking – Parameters
Note: Merchants should get the list of supported Banks and it’s respective Bank Ids. Only the supported Banks should be listed on the Checkout page and routed to PhonePe.
- paymentFlow.paymentMode.type – should be passed “NET_BANKING”
- paymentFlow.paymentMode.bankId– The respective bankId of the bank selected by the user should be passed.
- paymentFlow.merchantUrls.redirectUrl– should be passed with the Merchant’s redirection URL where the UI control will be given back once the payment is completed by the user.
Response
- orderId – In the Payment API response, PhonePe will provide the orderId parameter which is PhonePe generated OrderId for that transaction. Merchants can map the OrderId received in response with the merchantOrderId passed in the request.
- redirectUrl – In the Payment API response for Card, Token and NetBanking, the redirectUrl parameter will contain the bank’s redirection URL which the Merchant has to redirect the user on the browser. Merchant must ensure the URL shared by PhonePe is used as it is without modifying or truncating any value in the URL.
- intentUrl – In the Payment API response for UPI Intent or UPI QR, the intentUrl parameter will contain the intent URL which the Merchant has to launch on the UI. Merchant must ensure the URL shared by PhonePe is used as it is without modifying or truncating any value in the URL.
Order Status API
- Avoid Strict Deserialization of the response payload.
- Merchants must rely on the root level “state” parameter for the payment status confirmation.
- COMPLETED – The transaction is successful.
- FAILED – The transaction has failed.
- PENDING – The transaction is still in the processing state.
- Avoid Strict Deserialization of the response payload.
- Partners must rely on the root level “state” parameter for the payment status confirmation.
- COMPLETED – The transaction is successful.
- FAILED – The transaction has failed.
- PENDING – The transaction is still in the processing state.
Handling Pending Scenario:
- If the state is PENDING, then there can be two possibilities.
Option 1:- The transaction can be marked as Failed by the merchant and the Payment Failure page can be shown to the users on the UI.
- At the same time, the transaction has to be reconciled on the server side till the terminal status Success/Failure is reached. If successful, then the Refund has to be initiated.
Note: For this use case, it is highly recommended to integrate the Refund API.
- Option 2:
- The transaction can be marked as Pending by the merchant and the Payment Pending page can be shown to the users on the UI.
- At the same time, the transaction has to be reconciled on the server side till the terminal status COMPLETED/FAILED is reached. If it is successful, then the Order can be fulfilled.
For PENDING, the reconciliation process must be setup, and the recommended frequency interval of PG Order Status API as follows:
Order Status API – Reconciliation [MANDATORY]
If the payment status is Pending, then Order Status API should be called in the following interval:
- The first status check at 20-25 seconds post transaction start, then
Every 3 seconds once for the next 30 seconds,
Every 6 seconds once for the next 60 seconds,
Every 10 seconds for the next 60 seconds,
Every 30 seconds for the next 60 seconds, and then
Every 1 min until the terminal state (Else, till the expireAfter value passed in the request).
Webhook Handling
- Avoid Strict Deserialization of the response payload.
- Merchants must rely only on the root level “payload.state” parameter for the payment status confirmation.
- Don’t rely on “type” parameter in the webhook response (This will be deprecated) instead Merchants must rely on the “event” parameter only for the webhook event name.
- expireAt and timestamp parameters will be a epoch timestamp ( in milliseconds)
- [MANDATORY] Once the response is received, Merchants should calculate the Authorization header value (SHA256(username:password)) and match with the value received in the webhook headers.
- Only if both the values are matching, Merchants should update the payment status.
- If the values doesn’t match, the webhook can be a fraudulent response and it should be ignored. Further, Merchants can update the realtime status based on Order Status API response.
- Webhook Config:
- UAT: Share the UAT webhook URL with the Integration team on the integration thread to get it configured for the UAT MID.
Note: For Production, Merchants should configure directly on the PhonePe Business Dashboard.
- UAT: Share the UAT webhook URL with the Integration team on the integration thread to get it configured for the UAT MID.
Refund API
Note: Refunds can be initiated via Dashboard or API. The below details are applicable only if the Refund is implemented via API.
- merchantRefundId – Merchants should always pass unique merchantRefundId for each and every refund request.
- originalMerchantOrderId – Merchants should pass the actual merchantOrderId passed in the Payment API for which the refund has to be done.
- amount – Merchants should pass the amount parameter value in Paise (Multiply the Rs value by 100)
- Once the Refund is initiated, the initial state will be “PENDING” and Merchants can get the updated status either via Webhook or Refund Status API. It is mandatory to implement both.
Refund Status API
- Avoid Strict Deserialization of the response payload.
- Merchants must rely on the root level “state” parameter for the refund status confirmation.
- If you receive the “state” parameter as PENDING or CONFIRMED in the Refund API response, then the Order Status API with the merchantRefundId should be called for this refund transaction until the final state COMPLETED/FAILED is reached. The Scheduler/Cron Job must be set as per the merchant’s convenience to get the terminal state. Also, Merchants should make sure not to initiate another refund for the same transaction while previous refund transaction is still in the PENDING or CONFIRMED state.
- If you receive the “state” parameter as COMPLETED in the Refund Order Status API response, then the refund has been processed successfully.
- If you receive the “state” parameter as FAILED in the Refund Order Status API response, then the refund transaction has failed and the refund has to be reinitiated again with a unique merchantRefundId.