Webhook Handling
PhonePe Payment Gateway uses Webhook (S2S Callbacks) to notify you about key events like payment completion or refund status. Here’s how it works:
- You need to provide a Webhook URL (a specific endpoint on your server) where these updates will be sent.
- To ensure secure communication, you should set up a username and password for authentication.
👍 Webhook Integration – Best Practices
- HTTPS Requirement: We strictly require that all listener URLs use HTTPS with valid SSL/TLS certificates.
- Acknowledge Promptly: Ensure your listener returns a 2xx status code (e.g., 200 OK) within 3-5 seconds to prevent timeouts.
- IP Whitelisting: Configure your network to allow traffic from our specific proxy IPs.
- Idempotency: Implement logic to handle duplicate events. It is possible for the same transaction webhook to trigger multiple times; your system should be able to handle this.
- Event Filtering: Select only to the specific events you need. This reduces unnecessary server load and processing “noise.”
- Authentication Standards: Ensure your configured username and password meet the following rules:
- Username: 5-20 characters, letters, digits, and underscores only.
- Password: 8-20 characters, must contain both letters and numbers.
Webhook Setup
- Configure Webhook: Follow these steps to set up a new webhook for receiving event notifications.
- Log in to your PhonePe Business Dashboard.Set the environment mode using the Test Mode toggle located on the dashboard.
- For
Sandbox(Testing): Ensure the toggle is switched ON.ForProduction(Live): Ensure the toggle is switched OFF.
- Webhook URL: Your server’s endpoint URL to receive notifications.Username: Your authentication username.Password: Your authentication password.Description: A brief description for your reference.
- Order Events:
subscription.setup.order.complete: Sent when an order is successfully completed
- For
- Click Create to save and complete the configuration.
- Your webhook is now active.
- Log in to your PhonePe Business Dashboard.Set the environment mode using the Test Mode toggle located on the dashboard.
- Authorization.
- Once configured, PhonePe Payment Gateway will send updates to your server using the provided username and password.
- These credentials will be used to create an Authorization header in the webhook response using SHA256 (username:password) method.
- Verification.
- For the incoming request, extract the header Authorization, verify it with the one which you have shared with us and accept the response if the Username and password match.
- If the hash matches the one sent by PhonePe Payment Gateway, the update is valid, and the response payload can be consumed.
- If it doesn’t match, the response should be ignored.
ℹ️ Authorization Header!
PhonePe Payment Gateway includes the Authorization header in the following format:
Authorization: SHA256(username:password)
Callback Validation/Verification
- 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.
- Use the “payload.state” Parameter: For payment status, rely only on the root-level “payload.state” field in the response
- Avoid Strict Deserialization: Don’t use overly strict rules for processing the response
- Use the “event” Parameter: Ignore the “type” parameter in the webhook response. Use the “event” parameter instead to identify the event type
- Time Format: The expireAt and timestamp fields will be in epoch time
Webhook Responses
Response for Order Completed
{
"merchantId": "SWIGGY8",
"orderId": "OMO123",
"state": "COMPLETED",
"amount": 0,
"currency": "INR",
"expireAt": 1756489597,
"metaInfo": {},
"paymentFlow": {
"type": "SUBSCRIPTION_SETUP",
"productType": "ENACH_MANDATE",
"authWorkflowType": "ZERO",
"authInstrumentType": "NET_BANKING",
"amountType": "VARIABLE",
"frequency": "MONTHLY",
"maxAmount": 20000000,
"expireAt": 1708779903873,
"subscriptionId": "OMO123"
},
"paymentDetails": null
}What if Webhook fails?
If you don’t receive the Webhook callback, you can use the Order Status to manually check the payment status