EDC S2S Callback API

  • 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)
  • For enabling S2S callbacks at static level, Merchant/TSPs will provide a Static Callback URL at time of onboarding
  • For enabling Dynamic callbacks, the callback URL is specified in the request header of Init API as the parameter: X-CALLBACK-URL
  • The callback URL/endpoint should be HTTPS and running on the secured port 443.
  • HTTP mode for callback is specified in header X-CALL-MODE
  • Merchant/TSPs will have to create this endpoint at their server and expose the endpoint for callback to be sent
  • 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.

NOTE: When a EDC transaction is being performed by the customer either SUCCESS or FAIL, the callback response is being sent from phonepe server on the provided callback endpoint/URL within 5 seconds of the transaction. Our Phonepe servers need an acknowledgement of 200 OK success from merchant’s callback server orelse we’ll mark that 1st attempt as FAILED callback and retry for the 2nd attempt to receive the expected acknowledgement. 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 NameHeader Value
Content-Typeapplication/json
X-VERIFYSHA256(response + salt key) + ### + salt index

Response Parameters

Parameter NameTypeDescription
successBOOLEANtrue/ false
codeENUM(see list of codes below)This parameter is used to decide if payment is success or failed
messageSTRINGDescriptive message
transactionIdSTRINGtransactionId (if this is static QR then this will be generated by PhonePe)
merchantId
STRINGmerchantId
amountLONGAmount in paisa
providerReferenceIdSTRINGPhonePe transactionId
paymentStateSTRINGCOMPLETED/ FAILED
payResponseCodeSTRING (Optional parameter to be sent in response)More granular error codes for failure.
paymentModesList(Optional parameter to be sent in response)Please see below for schema
transactionContextObject(Optional parameter to be sent in response)Please see below for schema

Server to Server Callback Response Codes

CodeDescription
PAYMENT_SUCCESSPayment is successful for QR scan
PAYMENT_ERRORPayment failed for QR scan
PAYMENT_DECLINEDPayment declined by customer
PAYMENT_CANCELLEDPayment cancelled by merchant

Payment Modes (Optional parameter to be sent in response)

Parameter NameDescription
modeACCOUNT/ WALLET/
EXTERNAL_WALLET/ DEBIT_CARD/
CREDIT_CARD/ EXTERNAL_VPA/
EGV/ NET_BANKING
amountAmount in paisa
utrUTR for UPI payments.

Transaction Context (Optional parameter to be sent in response)

Parameter NameDescription
qrCodeIdVPA of end-user
storeIdStore Id where payment is initiated
terminalIdTerminal 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":"ewogICAgInN1Y2Nlc3MiOiB0cnVlLAogICAgImNvZGUiOiAiU1VDQ0VTUyIsCiAgICAibWVzc2FnZSI6ICJZb3VyIHJlcXVlc3QgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZC4iLAogICAgImRhdGEiOiB7CiAgICAgICAgIm1lcmNoYW50SWQiOiAiTUVSQ0hBTlRVQVQiLAogICAgICAgICJzdG9yZUlkIjogInRlc3RzdG9yZTEiLAogICAgICAgICJ0ZXJtaW5hbElkIjogInRlc3RUZXJtaW5hbDEiLAogICAgICAgICJvcmRlcklkIjogIk1SQ0gxMjQiLAogICAgICAgICJ0cmFuc2FjdGlvbklkIjogIlRYTjAwMTExMTMyMTFfMThPQ1QwNCIsCiAgICAgICAgInJlZmVyZW5jZU51bWJlciI6ICI0NTcxNDMwNDIwMTYiLAogICAgICAgICJwYXltZW50TW9kZSI6ICJEUVIiLAogICAgICAgICJhbW91bnQiOiAwLAogICAgICAgICJzdGF0dXMiOiAiU1VDQ0VTUyIsCiAgICAgICAgInJlc3BvbnNlQ29kZSI6ICJudWxsIiwKICAgICAgICAicGF5bWVudEluc3RydW1lbnRzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJBQ0NPVU5UIiwKICAgICAgICAgICAgICAgICJhbW91bnQiOiAxMDAsCiAgICAgICAgICAgICAgICAidXBpVHJhbnNhY3Rpb25JZCI6ICJZQkw0Yjg0NTBiN2U4MWU0NmJjOTYyZmJlZTNlZTg1NTk0NSIKICAgICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInRpbWVzdGFtcCI6IDE3MjkyNTIwNTYxNjYKICAgIH0KfQ=="
}'
{
  "response": "ewogICAgInN1Y2Nlc3MiOiB0cnVlLAogICAgImNvZGUiOiAiU1VDQ0VTUyIsCiAgICAibWVzc2FnZSI6ICJZb3VyIHJlcXVlc3QgaGFzIGJlZW4gc3VjY2Vzc2Z1bGx5IGNvbXBsZXRlZC4iLAogICAgImRhdGEiOiB7CiAgICAgICAgIm1lcmNoYW50SWQiOiAiTUVSQ0hBTlRVQVQiLAogICAgICAgICJzdG9yZUlkIjogInRlc3RzdG9yZTEiLAogICAgICAgICJ0ZXJtaW5hbElkIjogInRlc3RUZXJtaW5hbDEiLAogICAgICAgICJvcmRlcklkIjogIk1SQ0gxMjQiLAogICAgICAgICJ0cmFuc2FjdGlvbklkIjogIlRYTjAwMTExMTMyMTFfMThPQ1QwNCIsCiAgICAgICAgInJlZmVyZW5jZU51bWJlciI6ICI0NTcxNDMwNDIwMTYiLAogICAgICAgICJwYXltZW50TW9kZSI6ICJEUVIiLAogICAgICAgICJhbW91bnQiOiAwLAogICAgICAgICJzdGF0dXMiOiAiU1VDQ0VTUyIsCiAgICAgICAgInJlc3BvbnNlQ29kZSI6ICJudWxsIiwKICAgICAgICAicGF5bWVudEluc3RydW1lbnRzIjogWwogICAgICAgICAgICB7CiAgICAgICAgICAgICAgICAidHlwZSI6ICJBQ0NPVU5UIiwKICAgICAgICAgICAgICAgICJhbW91bnQiOiAxMDAsCiAgICAgICAgICAgICAgICAidXBpVHJhbnNhY3Rpb25JZCI6ICJZQkw0Yjg0NTBiN2U4MWU0NmJjOTYyZmJlZTNlZTg1NTk0NSIKICAgICAgICAgICAgfQogICAgICAgIF0sCiAgICAgICAgInRpbWVzdGFtcCI6IDE3MjkyNTIwNTYxNjYKICAgIH0KfQ=="
}

{
    "success": true,
    "code": "SUCCESS",
    "message": "Your request has been successfully completed.",
    "data": {
        "merchantId": "MERCHANTUAT",
        "storeId": "teststore1",
        "terminalId": "testTerminal1",
        "orderId": "MRCH124",
        "transactionId": "TXN0011113211_18OCT04",
        "referenceNumber": "457143042016",
        "paymentMode": "DQR",
        "amount": 0,
        "status": "SUCCESS",
        "responseCode": "null",
        "paymentInstruments": [
            {
                "type": "ACCOUNT",
                "amount": 100,
                "upiTransactionId": "YBL4b8450b7e81e46bc962fbee3ee855945"
            }
        ],
        "timestamp": 1729252056166
    }
}

{
    "success": false,
    "code": "FAILED",
    "message": "Your request has been successfully completed.",
    "data": {
        "merchantId": "M101NLBM5TQL3U",
        "storeId": "MS2403212004046998204201",
        "terminalId": "MST2405301213090857163565",
        "orderId": "testorder1",
        "transactionId": "test_transaction1",
        "amount": 200,
        "paymentMode": "DQR",
        "status": "FAILED",
        "responseCode": "CONFIRMATION_DECLINED"
    }
}
  1. Success/Failure of transaction should be dependent on the code in response parameters
  2. Cross-check the amount which has been passed in forward payment path(Accept payment API) and in the response of Server to Server callback.