- Server to server callbacks are initiated from PhonePe server to the url provided by merchant when payment reaches to any terminal state (SUCESS or FAIL)
- There are two ways to enable server to server callbacks.
1.Either Register your static callback url with PhonePe. This is a one time process.
2.Or, Send the callback url along with each payment request.
The URL is specified in the request header as parameter: X-CALLBACK-URL
The URL should be HTTPS and running on the secured port 443.
HTTP mode for callback is specified in header X-CALL-MODE
If different callback url is present at each location, then preference will be given to second method.
NOTE: When a static QR transaction is being performed by the customer either SUCCESS or FAIL, the callback response is being sent from phonepe server on the mapped callback endpoint/URL within 5 seconds of the transaction. Our servers need an acknowledgement as 200 OK success from your end orelse we consider that 1st attempt as FAILED callback and retry for the 2nd attempt. 3 retries are performed from the server side on the merchant’s callback endpoint/URL
Payload
The payload that is going to be sent to the merchant on the specified callback url will have a base64 encoded json.
Upon base64 decoding the response, you should get a json with format similar to the response returned by transaction status API.
This is the best case callback that would be sent from PhonePe server to the merchants’ server. In the event of a callback failure, the onus is on the merchants to use the transaction status API and take the transaction to closure.
Callback headers
Following are the response headers sent with a callback.
Header Name | Header Value |
---|---|
Content-Type | application/json |
X-VERIFY | SHA256(response + salt key) + ### + salt index |
Response Parameters
Parameter Name | Type | Description |
---|---|---|
success | BOOLEAN | true/ false |
code | ENUM (see list of codes below) | This parameter is used to decide if payment is success or failed |
message | STRING | Descriptive message |
transactionId | STRING | transactionId (if this is static QR then this will be generated by PhonePe) |
merchantId | STRING | merchantId |
amount | LONG | Amount in paisa |
providerReferenceId | STRING | PhonePe transactionId |
paymentState | STRING | COMPLETED/ FAILED |
payResponseCode | STRING (Optional parameter to be sent in response) | More granular error codes for failure. |
paymentModes | List (Optional parameter to be sent in response) | Please see below for schema |
transactionContext | Object (Optional parameter to be sent in response) | Please see below for schema |
Server to Server Callback Response Codes
Code | Description |
---|---|
PAYMENT_SUCCESS | Payment is successful for QR scan |
PAYMENT_ERROR | Payment failed for QR scan |
PAYMENT_DECLINED | Payment declined by customer |
PAYMENT_CANCELLED | Payment cancelled by merchant |
Payment Modes (Optional parameter to be sent in response)
Parameter Name | Description |
---|---|
mode | ACCOUNT/ WALLET/ EXTERNAL_WALLET/ DEBIT_CARD/ CREDIT_CARD/ EXTERNAL_VPA/ EGV/ NET_BANKING |
amount | Amount in paisa |
utr | UTR for UPI payments. |
Transaction Context (Optional parameter to be sent in response)
Parameter Name | Description |
---|---|
qrCodeId | VPA of end-user |
storeId | Store Id where payment is initiated |
terminalId | Terminal Id where payment is initiated |
merchantOrderId _ | Merchant Order Id passed by the merchant |
curl -X POST \
https://api.merchant.com/response/phonepe \
-H 'content-type: application/json' \
-H 'x-verify: 2abaa82a4810c57dcd6aa52680dd772173b1e40770afe028131f31ddbe5487a8###1' \
-d '{
"response":"eyJzdWNjZXNzIjp0cnVlLCJjb2RlIjoiUEFZTUVOVF9TVUNDRVNTIiwibWVzc2FnZSI6IllvdXIgcGF5bWVudCBpcyBzdWNjZXNzZnVsLiIsImRhdGEiOnsidHJhbnNhY3Rpb25JZCI6IlRYMzIzMjE4NDk2NDQyMzQiLCJtZXJjaGFudElkIjoiTTIzMDYxNjA0ODMyMjA2NzU1NzkxNDAiLCJwcm92aWRlclJlZmVyZW5jZUlkIjoiUDE4MDYxNTEzMjMwOTM5MDA1NTQ5NTciLCJhbW91bnQiOjEwMDAsInBheW1lbnRTdGF0ZSI6IkNPTVBMRVRFRCIsInBheVJlc3BvbnNlQ29kZSI6IlNVQ0NFU1MiLCJwYXltZW50TW9kZXMiOlt7Im1vZGUiOiJBQ0NPVU5UIiwiYW1vdW50IjoxMDAwLCJ1dHIiOiI4MTY2MjY1MjE2MTYifV0sInRyYW5zYWN0aW9uQ29udGV4dCI6e319fQ=="
}'
{
"response": "eyJzdWNjZXNzIjp0cnVlLCJjb2RlIjoiUEFZTUVOVF9TVUNDRVNTIiwibWVzc2FnZSI6IllvdXIgcGF5bWVudCBpcyBzdWNjZXNzZnVsLiIsImRhdGEiOnsidHJhbnNhY3Rpb25JZCI6IlRYMzIzMjE4NDk2NDQyMzQiLCJtZXJjaGFudElkIjoiTTIzMDYxNjA0ODMyMjA2NzU1NzkxNDAiLCJwcm92aWRlclJlZmVyZW5jZUlkIjoiUDE4MDYxNTEzMjMwOTM5MDA1NTQ5NTciLCJhbW91bnQiOjEwMDAsInBheW1lbnRTdGF0ZSI6IkNPTVBMRVRFRCIsInBheVJlc3BvbnNlQ29kZSI6IlNVQ0NFU1MiLCJwYXltZW50TW9kZXMiOlt7Im1vZGUiOiJBQ0NPVU5UIiwiYW1vdW50IjoxMDAwLCJ1dHIiOiI4MTY2MjY1MjE2MTYifV0sInRyYW5zYWN0aW9uQ29udGV4dCI6e319fQ=="
}
{
"success":true,
"code":"PAYMENT_SUCCESS",
"message":"Your payment is successful.",
"data":{
"transactionId":"TX32321849644234",
"merchantId":"M2306160483220675579140",
"providerReferenceId":"P1806151323093900554957",
"amount":1000,
"paymentState":"COMPLETED",
"payResponseCode":"SUCCESS",
"paymentModes":[
{
"mode":"ACCOUNT",
"amount":1000,
"utr":"816626521616"
}
],
"transactionContext":{
"storeId":"store1",
"terminalId":"terminal1"
}
}
}
{
"success": false,
"code": "PAYMENT_ERROR",
"message": "Payment Failed",
"data": {
"merchantId": "TEST38642",
"transactionId": "ML333cXccc5",
"amount": 2000,
"merchantOrderId": "ML1502083864",
"paymentState": "FAILED",
"payResponseCode": "TIMED_OUT"
}
}
{
"success": true,
"code": "PAYMENT_CANCELLED",
"message": "Your request is in cancelled state.",
"data": {
"merchantId": "MERCHANTUAT",
"transactionId": "TX31484215159135",
"amount": 100,
"merchantOrderId": "TX31484215159135",
"paymentState": "CANCELLED",
"payResponseCode": "REQUEST_CANCEL_BY_REQUESTER"
}
}
- Success/Failure of transaction should be dependent on the code in response parameters
- Cross-check the amount which has been passed in forward payment path(Accept payment API) and in the response of Server to Server callback.