Merchants can configure the Webhook/S2S Callback URLs along with username & password.
PROD – Merchants can configure URL, Username and Password on the PhonePe dashboard.
UAT – Merchants can reach out to the Integration Team.
- Once the username and password is configured, PhonePe will pass the same SHA256 (username:password) as the “Authorization” header in s2s response.
- Merchants should calculate using the same logic and match with the one passed by PhonePe. If both are matching, then the response payload can be consumed by the merchant. Otherwise, merchants should ignore the response.
Callback Types
- pg.order.completed
- pg.order.failed
- pg.refund.accepted
- pg.refund.completed
- pg.refund.failed
PhonePe will pass the authorization header as :
Authorization : SHA256(username:password)
Callback Validation/Verification flow for merchants
For the incoming request, extract the basic authorization header “Authorization”, verify it with the one which you have shared with us and accept the response if Username and password matches.
Sample S2S Response of PG Custom Checkout Order Completed:
Note:
- Merchants should rely only on the highlighted “payload.state” parameter for the Payment status confirmation.
- Merchants should rely on the event parameter for the type of webhook received instead of “type” parameter which will be deprecated at later stage.
{
"type": "PG_ORDER_COMPLETED",
"event": "pg.order.completed",
"payload": {
"merchantId": "AIRTELUAT",
"merchantOrderId": "MO-974-9c0084d009a8",
"orderId": "OMO2411281510176245053157",
"state": "COMPLETED",
"amount": 100,
"expireAt": 1732959621335,
"metaInfo": {
"udf5": "<additional-information-5>",
"udf3": "<additional-information-3>",
"udf4": "<additional-information-4>",
"udf1": "<additional-information-1>",
"udf2": "<additional-information-2>"
},
"paymentDetails": [
{
"paymentMode": "UPI_INTENT",
"transactionId": "OM2411281510213355053368",
"timestamp": 1732786838930,
"amount": 100,
"state": "COMPLETED",
"splitInstruments": [
{
"amount": "100",
"rail": {
"type": "UPI",
"utr": "<utr>",
"upiTransactionId": "<upiTransactionId>",
"vpa": "<vpa>"
},
"instrument": {
"type": "ACCOUNT",
"maskedAccountNumber": "<maskedAccountNumber>",
"accountType": "SAVINGS",
"accountHolderName": "<accountHolderName>",
"ifsc": "<ifsc>"
}
}
]
}
]
}
}
Sample S2S Response of PG Custom Checkout Order Failed:
Note:
- Merchants should rely only on the highlighted “payload.state” parameter for the Payment status confirmation.
- Only for failed transactions with payload.state as FAILED, the optional parameters payload.errorCode and payload.detailedErrorCode will be present and merchants rely on these values for the failure reasons.
- Merchants should rely on the event parameter for the type of webhook received instead of “type” parameter which will be deprecated at later stage.
{
"type": "PG_ORDER_FAILED",
"event": "pg.order.failed",
"payload": {
"merchantId": "AIRTELUAT",
"merchantOrderId": "MO-c68-9f96cc57a7e8",
"orderId": "OMO2411281511242605053174",
"state": "FAILED",
"amount": 100,
"errorCode": "AUTHORIZATION_ERROR",
"detailedErrorCode": "ZM",
"expireAt": 1732959688009,
"metaInfo": {
"udf5": "<additional-information-5>",
"udf3": "<additional-information-3>",
"udf4": "<additional-information-4>",
"udf1": "<additional-information-1>",
"udf2": "<additional-information-2>"
},
"paymentDetails": [
{
"paymentMode": "UPI_INTENT",
"transactionId": "OM2411281511280095053516",
"timestamp": 1732786903141,
"amount": 100,
"state": "FAILED",
"errorCode": "AUTHORIZATION_ERROR",
"detailedErrorCode": "ZM",
"splitInstruments": [
{
"amount": "100",
"rail": {
"type": "UPI",
"upiTransactionId": "<upiTransactionId>"
},
"instrument": {
"type": "ACCOUNT",
"maskedAccountNumber": "<maskedAccountNumber>",
"accountType": "SAVINGS",
"accountHolderName": "<accountHolderName>",
"ifsc": "<ifsc>"
}
}
]
}
]
}
}
Sample S2S Response of PG Custom Checkout Refund Accepted:
Note: Merchants should rely only on the highlighted “payload.state” parameter for the Refund status confirmation.
{
"event": "pg.refund.accepted",
"payload": {
"merchantId": "merchantId",
"merchantRefundId": "merchantRefundId",
"originalMerchantOrderId": "Refund-12345",
"amount": 50000,
"state": "CONFIRMED",
"timestamp": 1706629419799,
"refundId": "OMR7896789"
}
}
Sample S2S Response of PG Custom Checkout Refund Completed:
Note: Merchants should rely only on the highlighted “payload.state” parameter for the Refund status confirmation.
Case 1: Original source of transaction = UPI
{
"event": "pg.refund.completed",
"payload": {
"merchantId": "merchantId",
"merchantRefundId": "merchantRefundId",
"originalMerchantOrderId": "Refund-12345",
"amount": 50000,
"state": "COMPLETED",
"timestamp": 1706629419799,
"refundId": "OMR7896789",
"splitInstruments": [
{
"rail": {
"type": "UPI",
"upiTransactionId": "upi12313",
"vpa": "abcd@ybl"
},
"instrument": {
"type": "ACCOUNT",
"accountType": "SAVINGS",
"maskedAccountNumber": "XXXXX1212"
},
"amount": 40000
},
{
"rail": {
"type": "WALLET"
},
"instrument": {
"type": "WALLET",
"walletId": "ABCD"
},
"amount": 10000
}
]
}
}
Case 2: Original source of transaction = CARD
{
"event": "pg.refund.completed",
"payload": {
"merchantId": "merchantId",
"merchantRefundId": "merchantRefundId",
"originalMerchantOrderId": "Refund-12345",
"amount": 50000,
"state": "COMPLETED",
"timestamp": 1706629419799,
"refundId": "OMR7896789",
"splitInstruments": [
{
"amount": 50000,
"rail": {
"type": "PG",
"transactionId": "transactionId",
"authorizationCode": "authorizationCode",
"serviceTransactionId": "serviceTransactionId"
},
"instrument": {
"type": "CREDIT_CARD",
"bankTransactionId": "bankTransactionId",
"bankId": "bankId",
"arn": "arn",
"brn": "brn"
}
}
]
}
}
Case 3: Original source of transaction = NET_BANKING
{
"event": "pg.refund.completed",
"payload": {
"merchantId": "merchantId",
"merchantRefundId": "merchantRefundId",
"originalMerchantOrderId": "Refund-12345",
"amount": 50000,
"state": "COMPLETED",
"timestamp": 1706629419799,
"refundId": "OMR7896789",
"splitInstruments": [
{
"amount": 50000,
"rail": {
"type": "PG",
"transactionId": "transactionId",
"authorizationCode": "authorizationCode",
"serviceTransactionId": "serviceTransactionId"
},
"instrument": {
"type": "NET_BANKING",
"bankTransactionId": "bankTransactionId",
"bankId": "bankId>",
"arn": "arn",
"brn": "brn"
}
}
]
}
}
Sample S2S Response of PG Custom Checkout Refund Failed:
Note:
- Merchants should rely only on the highlighted “payload.state” parameter for the Refund status confirmation.
- Also, splitInstruments parameter should be Optional as it may or many not be present if the state is “FAILED”.
- Only for failed transactions with payload.state as FAILED, the optional parameters payload.errorCode and payload.detailedErrorCode will be present and merchants rely on these values for the failure reasons.
Case 1: Original source of transaction = UPI
{
"event": "pg.refund.failed",
"payload": {
"merchantId": "merchantId",
"merchantRefundId": "merchantRefundId",
"originalMerchantOrderId": "Refund-12345",
"amount": 50000,
"state": "FAILED",
"timestamp": 1706629419799,
"refundId": "OMR7896789",
"errorCode": "UPI_BACKBONE_ERROR", // Only present in case of ERROR
"detailedErrorCode": "UPI_1231", // Only present in case of ERROR
"splitInstruments": [ // In case of failure this is optional. It may or may not be present.
{
"rail": {
"type": "UPI",
"upiTransactionId": "upi12313",
"vpa": "abcd@ybl"
},
"instrument": {
"type": "ACCOUNT",
"accountType": "SAVINGS",
"maskedAccountNumber": "XXXXX1212"
},
"amount": 40000
},
{
"rail": {
"type": "WALLET"
},
"instrument": {
"type": "WALLET",
"walletId": "ABCD"
},
"amount": 10000
}
]
}
}
Case 2: Original source of transaction = CARD
{
"event": "pg.refund.failed",
"payload": {
"merchantId": "merchantId",
"merchantRefundId": "merchantRefundId",
"originalMerchantOrderId": "Refund-12345",
"amount": 50000,
"state": "FAILED",
"timestamp": 1706629419799,
"refundId": "OMR7896789",
"errorCode": "PG_BACKBONE_ERROR", // Only present in case of ERROR
"detailedErrorCode": "UPI_1231", // Only present in case of ERROR
"splitInstruments": [ // In case of failure this is optional. It may or may not be present.
{
"amount": 50000,
"rail": {
"type": "PG",
"transactionId": "transactionId",
"authorizationCode": "authorizationCode",
"serviceTransactionId": "serviceTransactionId"
},
"instrument": {
"type": "CREDIT_CARD",
"bankTransactionId": "bankTransactionId",
"bankId": "bankId",
"arn": "arn",
"brn": "brn"
}
}
]
}
}
Case 3: Original source of transaction = NET_BANKING
{
"event": "pg.refund.failed",
"payload": {
"merchantId": "merchantId",
"merchantRefundId": "merchantRefundId",
"originalMerchantOrderId": "Refund-12345",
"amount": 50000,
"state": "FAILED",
"timestamp": 1706629419799,
"refundId": "OMR7896789",
"errorCode": "PG_BACKBONE_ERROR", // Only present in case of ERROR
"detailedErrorCode": "UPI_1231", // Only present in case of ERROR
"splitInstruments": [ // In case of failure this is optional. It may or may not be present.
{
"amount": 50000,
"rail": {
"type": "PG",
"transactionId": "transactionId",
"authorizationCode": "authorizationCode",
"serviceTransactionId": "serviceTransactionId"
},
"instrument": {
"type": "NET_BANKING",
"bankTransactionId": "bankTransactionId",
"bankId": "bankId",
"arn": "arn",
"brn": "brn"
}
}
]
}
}