Handle Webhooks with Python SDK
Use callback verification to confirm that the callback you received from PhonePe is authentic.
The method is used to validate webhook or callback responses. You can use this method by passing all the necessary parameters.validateCallback()
Request
| Parameter Name | Data Type | Mandatory (Yes/NO) | Description |
username | String | Yes | Your unique username configured for the callback URL |
password | String | Yes | Your unique password configured for the callback URL |
authorization | String | Yes | Value of the Authorization header under the callback response. |
responseBody | String | Yes | The response body received in the callback as a string |
from phonepe.sdk.pg.payments.v2.standard_checkout_client import StandardCheckoutClient
from phonepe.sdk.pg.env import Env
client_id = "<YOUR_CLIENT_ID>"
client_secret = "<YOUR_CLIENT_SECRET>"
client_version = <CLIENT_VERSION> # Insert your client version here
env = Env.SANDBOX # Change to Env.PRODUCTION when you go live
should_publish_events = False
client = StandardCheckoutClient.get_instance(client_id=client_id,
client_secret=client_secret,
client_version=client_version,
env=env,
should_publish_events=should_publish_events)
authorization_header_data = "ef4c914c591698b268db3c64163eafda7209a630f236ebf0eebf045460df723a" # header value under `Authorization` key
phonepe_s2s_callback_response_body_string = """{"type": "PG_REFUND_COMPLETED","payload": {}}""" # callback body as string
username_configured = "MERCHANT_USERNAME"
password_configured = "MERCHANT_PASSWORD"
callback_response = client.validate_callback(username=username_configured,
password=password_configured,
callback_header_data=authorization_header_data,
callback_response_data=phonepe_s2s_callback_response_body_string)
callback_type = callback_response.callback_type
merchant_refund_id = callback_response.callback_data.merchant_refund_id
state = callback_response.callback_data.stateResponse
- The function returns a
CallbackResponseobject containing two main parameters:type, which indicates the event type, andpayload, which holds all the event-specific details.
| Parameter Name | Data Type | Description |
| type | CallbackType | Tells you what type of event happened (e.g., order completed, refund failed, etc.) |
| payload | CallbackData | Contains all the details related to that event |
- The event
typeare explained below:
| Event Type | Description |
CHECKOUT_ORDER_COMPLETED | The payment was successfully completed |
CHECKOUT_ORDER_FAILED | The payment failed |
PG_REFUND_COMPLETED | A refund was successfully processed |
PG_REFUND_FAILED | A refund request failed |
PG_REFUND_ACCEPTED | PhonePe Payment Gateway acknowledged the refund request, but it’s not completed yet |
- The
payloaddetails are explained below:
| Parameter Name | Data Type | Description |
merchantId | String | Merchant ID from which the request was initiated |
orderId | String | Order ID generated by PhonePe Payment Gateway (only for order callbacks) |
originalMerchantOrderId | String | Order ID generated by you (only for order callbacks) |
refundId | String | Refund ID generated by PhonePe PG (only for refund callbacks) |
| merchantRefundId | String | Refund ID generated by you (only for refund callbacks) |
state | String | The current state of the order or refund. |
amount | Long | The amount processed in paisa. |
expireAt | Long | The expiry timestamp in epoch format |
errorCode | String | The error code (only for failed transactions) |
detailedErrorCode | String | A more detailed error code (only for failures) |
metaInfo | MetaInfo | Metadata passed during order initialization |
paymentDetails | List<PaymentDetail> | The Payment details of the transaction |
ThePaymentRefundDetailproperty contains a list of payment details for each payment attempt made against an order. The details of each payment are explained in the table below.
| Attribute | Data Type | Description |
transactionId | String | Merchant ID from which the request was initiated |
paymentMode | String | Order ID generated by PhonePe Payment Gateway (only for order callbacks) |
timestamp | Long | Order ID generated by you (only for order callbacks) |
state | String | Attempted transaction state. It can be any one of the following states: • COMPLETED • FAILED • PENDING |
errorCode | String | Error code (only present when the state is failed) |
detailedErrorCode | String | A more specific error code (only present when the state is failed) |
Exception Handling
Exception handling in the PhonePe SDK is managed through the PhonePeException, which captures errors related to PhonePe APIs. It provides detailed information such as HTTP status code, error code, message, and additional error data to help identify and resolve issues effectively.
PhonePeException
Exception raised for errors related to PhonePe APIs.
| Attribute | Type | Description |
| code | String | The status code of the http response. |
message | String | The http error message. |
| Integer | The status code of the http response. |
data | Map<String, String> | The details of the error that happened while calling PhonePe API. |
from phonepe.sdk.pg.common.exceptions import PhonePeException
from phonepe.sdk.pg.payments.v2.standard_checkout_client import StandardCheckoutClient
from phonepe.sdk.pg.env import Env
client_id = "<YOUR_CLIENT_ID>"
client_secret = "<YOUR_CLIENT_SECRET>"
client_version = <CLIENT_VERSION> # Insert your client version here
env = Env.SANDBOX # Change to Env.PRODUCTION when you go live
should_publish_events = False
client = StandardCheckoutClient.get_instance(client_id=client_id,
client_secret=client_secret,
client_version=client_version,
env=env,
should_publish_events=should_publish_events)
try:
callback_valid = client.validate_callback(username="username_configured",
password="password_configured",
callback_header_data="ef4c914c591698b268db3c64163eafda7209a630f236ebf0eebf045460df723a",
callback_response_data="phonepe_s2s_callback_response_body_string")
except PhonePeException as exception:
print(exception.code)
print(exception.message)Response
- InstrumentCombo
- Represents a combination of the payment instrument and the payment rail used to complete a transaction.
| Property | Type | |
| PaymentInstrumentV2 | Instrument used for the payment. |
| PaymentRail | Rail used for the payment. |
| long | Amount transferred using the above instrument and rail. |
- PaymentRail
- Defines the type of rail used to initiate payment.
| Property | Type |
type | PaymentRailType |
utr | String |
upi_transaction_id | String |
vpa | String |
| Property | Type |
| PaymentRailType |
| String |
| String |
| String |
- PaymentInstrumentV2
- Represents the instrument used to initiate a payment. Various instrument types are listed below:
| Property | Type |
| PaymentInstrumentType |
| String |
| String |
| String |
account_holder_name | String |
| Property | Type |
| PaymentInstrumentType |
| String |
| String |
| String |
brn | String |
| Property | Type |
| PaymentInstrumentType |
| String |
| String |
| String |
brn | String |
| Property | Type |
| PaymentInstrumentType |
| String |
| String |
| String |
brn | String |
What’s Next?
Now that you have learned how to verify the payment and what happens when the webhook fails, this concludes your website integration. The next step is to complete UAT testing and understand the process to go live.