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.
  • 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.For Production (Live): Ensure the toggle is switched OFF.
      Navigate to Developer Settings from the side menu.Select the Webhook tab and click the Create Webhook button.In the configuration form, fill in the following details:
      • 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.
      From the list of active events, choose:
      • Order Events:
        • subscription.setup.order.complete: Sent when an order is successfully completed
    • Click Create to save and complete the configuration.
    • Your webhook is now active.
  • 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)

  • 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
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
}

If you don’t receive the Webhook callback, you can use the Order Status to manually check the payment status

Is this article helpful?