Subscription Callback

Merchants can configure the Webhook/S2S Callback URLs along with username & password.

PROD – Merchants can configure URL, Username and Password on the PhonePe dashboard.

  • URL – Merchant’s Webhook URL
  • Username – Merchant configure their own username
  • Password – Merchant configure their own password
    Note: Merchants should ensure the configured username and password is being used in the code to validate the Authorization header.


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 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.

Authorization : SHA256(username:password)

anchor image
Copied !
FlowCallback Type
Setupsubscription.setup.order.completed
subscription.setup.order.failed
State Changesubscription.paused
subscription.unpaused
subscription.revoked
subscription.cancelled
Notification
(LINK)
subscription.notification.completed
subscription.notification.failed
Redemption
(LINK)
subscription.redemption.order.completed
subscription.redemption.order.failed
subscription.redemption.transaction.completed
subscription.redemption.transaction.failed
Refund
(LINK)
pg.refund.accepted
pg.refund.completed
pg.refund.failed

Key Notes

  • Merchants should rely only on the root level “payload.state” parameter for the status confirmation.
  • Avoid Strict Deserialization
  • Don’t rely on “type” parameter in the webhook response (This will be deprecated) instead rely on the “event” parameter only for the webhook event name.
  • expireAt and timestamp parameters will be a epoch timestamp ( in milliseconds)
anchor image
Copied !

Subscription Setup Completed

Note: Merchants should rely only on the highlighted “payload.state” parameter for the payment status confirmation.

{ "event": "subscription.setup.order.completed", "payload": { "merchantId": "SWIGGY8", "merchantOrderId": "MO1708797962855", "orderId": "OMO2402242336055135042802", "state": "COMPLETED", "amount": 200, "expireAt": 1708798385505, "paymentFlow": { "type": "SUBSCRIPTION_SETUP", "merchantSubscriptionId": "MS1708797962855", "authWorkflowType": "TRANSACTION", "amountType": "FIXED", "maxAmount": 200, "frequency": "ON_DEMAND", "expireAt": 1741345725943, "subscriptionId": "OMS2502051638460659623138" }, "paymentDetails": [ { "transactionId": "OM2402242336055865042862", "paymentMode": "UPI_INTENT", "timestamp": 1708797965588, "amount": 200, "payableAmount": 200, "feeAmount": 0, "state": "COMPLETED", "instrument": { "type": "ACCOUNT", "maskedAccountNumber": "XXXXXXXXXXX0945" }, "rail": { "type": "UPI", "utr": "405554491450", "vpa": "999@ybl", "umn": "d519347eb2374125bcad6e69a42cc13b@ybl" } } ] } }

Subscription Setup Failed

Note: Merchants should rely only on the highlighted “payload.state” parameter for the payment status confirmation.

{ "event": "subscription.setup.order.failed", "payload": { "merchantId": "SWIGGY8", "merchantOrderId": "MO1708797962855", "orderId": "OMO2402242336055135042802", "state": "FAILED", "amount": 200, "expireAt": 1708798385505, "errorCode": "INVALID_MPIN", "detailedErrorCode": "ZM", "paymentFlow": { "type": "SUBSCRIPTION_SETUP", "merchantSubscriptionId": "MS1708797962855", "authWorkflowType": "TRANSACTION", "amountType": "FIXED", "maxAmount": 200, "frequency": "ON_DEMAND", "expireAt": 1741345725943, "subscriptionId": "OMS2502051638460659623138" }, "paymentDetails": [ { "transactionId": "OM2402242336055865042862", "paymentMode": "UPI_INTENT", "timestamp": 1708797965588, "amount": 200, "payableAmount": 200, "feeAmount": 0, "state": "FAILED", "errorCode": "INVALID_MPIN", "detailedErrorCode": "ZM" } ] } }

Response Parameters

Parameter NameData TypeDescription
merchantIdSTRINGUnique Id assigned to the merchant in
the PhonePe system. Assigned during
merchant onboarding.
merchantOrderIdSTRINGUnique OrderId passed by the merchant
while creating the order.
orderIdSTRINGPhonePe generated orderID
stateSTRINGStatus of the Mandate Setup.
Possible values:
● COMPLETED
● FAILED
● PENDING
amountLONGPassed by the merchant in Paise
expireAtDateTimeEpoch Time (in milliseconds)
errorCodeSTRINGFailure reason
[PRESENT ONLY IF STATE = FAILED]
detailedErrorCodeSTRINGDetailed Failure reason
[PRESENT ONLY IF STATE = FAILED]
MetaInfoARRAYMetadata passed by the merchant only.
paymentFlowOBJECTDetail of Subscription.
paymentFlow.typeSTRINGType should be
“SUBSCRIPTION_REDEMPTION” for
redemption.
paymentFlow.merchantSubscriptionIdSTRINGSubscription ID passed by merchant
paymentFlow.amountTypeSTRINGNature of redemption amount
Possible Values:
● FIXED
● VARIABLE
paymentFlow.maxAmountLONGMax amount upto which redemptions will be allowed
paymentFlow.frequencySTRINGSubscription frequency
paymentFlow.subscriptionIdSTRINGPhonePe generated Subscription Id
paymentDetailsARRAYDetails of the payment
anchor image
Copied !

Subscription Cancelled

Note: Merchants should rely only on the highlighted “payload.state” parameter for the subscription status confirmation.

{ "type": "SUBSCRIPTION_CANCELLED", "payload": { "merchantSubscriptionId": "MS1708797962855", "subscriptionId": "OMS2402242336054995042603", "state": "CANCELLED", "authWorkflowType": "TRANSACTION", "amountType": "FIXED", "maxAmount": 200, "frequency": "ON_DEMAND", "expireAt": 1737278524000, "pauseStartDate": 1708798426196, "pauseEndDate": 1708885799000 } }

Subscription Revoked

Note: Merchants should rely only on the highlighted “payload.state” parameter for the subscription status confirmation.

{ "type": "SUBSCRIPTION_REVOKED", "payload": { "merchantSubscriptionId": "MS1708797962855", "subscriptionId": "OMS2402242336054995042603", "state": "REVOKED", "authWorkflowType": "TRANSACTION", "amountType": "FIXED", "maxAmount": 200, "frequency": "ON_DEMAND", "expireAt": 1737278524000, "pauseStartDate": 1708798426196, "pauseEndDate": 1708885799000 } }

Subscription Paused

Note: Merchants should rely only on the highlighted “payload.state” parameter for the subscription status confirmation.

{ "type": "SUBSCRIPTION_PAUSED", "payload": { "merchantSubscriptionId": "MS1708797962855", "subscriptionId": "OMS2402242336054995042603", "state": "PAUSED", "authWorkflowType": "TRANSACTION", "amountType": "FIXED", "maxAmount": 200, "frequency": "ON_DEMAND", "expireAt": 1737278524000, "pauseStartDate": 1708798426196, "pauseEndDate": 1708885799000 } }

Subscription Unpaused

Note: Merchants should rely only on the highlighted “payload.state” parameter for the subscription status confirmation.

{ "type": "SUBSCRIPTION_UNPAUSED", "payload": { "merchantSubscriptionId": "MS1708797962855", "subscriptionId": "OMS2402242336054995042603", "state": "ACTIVE", "authWorkflowType": "TRANSACTION", "amountType": "FIXED", "maxAmount": 200, "frequency": "ON_DEMAND", "expireAt": 1737278524000, "pauseStartDate": null, "pauseEndDate": null } }

Response Parameters

Parameter NameData TypeDescription
merchantSubscriptionIdStringUnique merchant subscription Id passed by the merchant while creating the subscription.
subscriptionIdStringPhone generated subscription Id.
stateStringStatus of the subscription. Possible values:
● ACTIVE
● CANCELLED
● REVOKED
● PAUSED
authWorkflowTypeStringType of Authorisation
amountTypeStringType of amount Fixed and Variable
maxAmountStringMax Amount that can be charged
frequencyStringFrequency type of subscription
expireAtDateTimeSubscription Expiry Time (in milliseconds)
pauseStartDateDateTimeSubscription pause start date only for Pause State or else null. (in milliseconds)
pauseEndDateDateTimeSubscription pause end date only for Pause state or else null. (in milliseconds)