Handle Webhooks with .NET SDK
Use callback verification to confirm that the callback you received from PhonePe is authentic.
Request
Request Parameters
| 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 |
Sample Request
public IActionResult CustomValidateCallback()
{
string responseBody = @"{
""event"": ""pg.order.completed"",
""payload"": {
""orderId"": ""OMOxx"",
""merchantId"": ""merchantId"",
""merchantOrderId"": ""merchantOrderId"",
""state"": ""EXPIRED"",
""amount"": 10000,
""expireAt"": 1291391291,
""metaInfo"": {
""udf1"": """",
""udf2"": """",
""udf3"": """",
""udf4"": """",
""udf5"": """"
},
""paymentDetails"": [
{
""paymentMode"": ""UPI_COLLECT"",
""timestamp"": 12121212,
""amount"": 10000,
""transactionId"": ""OM12333"",
""state"": ""FAILED"",
""errorCode"": ""AUTHORIZATION_ERROR"",
""detailedErrorCode"": ""ZM"",
""splitInstruments"": [
{
""rail"": {
""type"": ""PPI_EGV""
},
""instrument"": {
""type"": ""CREDIT_CARD"",
""bankTransactionId"": ""bankTransactionId"",
""bankId"": ""bankId"",
""brn"": ""brn"",
""arn"": ""arn""
},
""amount"": 10000
}
]
}
]
}
}";
try
{
var callbackResponse = _customCheckoutClient.ValidateCallback("username", "password", "bc842c31a9e54efe320d30d948be61291f3ceee4766e36ab25fa65243cd76e0e", responseBody);
return Ok(callbackResponse);
}
catch (Exception ex)
{
_logger.LogError(ex, "Custom ValidateCallback API Failed");
return StatusCode(500, new { message = ex.Message });
}
}Response
- 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 | Contains type of callback received at the merchant end. |
payload | CallbackData | Contains all the details related to that event. |
Callback Type
| Callback Type | Context |
| PG_ORDER_COMPLETED | Order Completed for PG |
| PG_ORDER_FAILED | Order Failed for PG |
| PG_REFUND_COMPLETED | Refund Completed for PG |
| PG_REFUND_ACCEPTED | Refund Accepted by PhonePe and will be initiated |
| PG_REFUND_FAILED | Refund Failed for PG |
- The
CallbackDataare explained below:
| Property | Type | Description |
merchantId | String | The merchant from which request was initiated |
state | String | State of the ORDER/REFUND |
refundId | String | Refund id generated by PhonePe (Only present in case of refund callback) |
merchantRefundId | String | Refund id generated by merchant (Only present in case of refund callback) |
orderId | String | Order id generated by PhonePe (Only present in case of order callbacks) |
originalMerchantOrderId | String | Order id generated by merchant (Only present in case of refund callback) |
merchantOrderId | String | Order id generated by merchant (Only present in case of order callbacks) |
expireAt | long | Expiry in epoch |
errorCode | String | Error code. (Only present when state is failed) |
detailedErrorCode | String | Detailed error code. (Only present when state is failed) |
paymentDetails | List<PaymentDetail> | Contain list of details of each transaction attempt made corresponding to this particular order |
amount | long | Amount in Paisa of the order/refund processed |
metaInfo | MetaInfo | Additional Information about the order |
- The
property 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.paymentDetails
| Property | Type | Description |
transactionId | String | Transaction Id generated by the PhonePe |
paymentMode | String | Mode of Payment. It can be anyone of the following modes: UPI_INTENTUPI_COLLECTUPI_QRCARDTOKENNET_BANKING |
timestamp | long | Timestamp of the attempted transaction in epoch |
state | String | Attempted transaction state. It can be any one of the following states:PENDINGCOMPLETEDFAILED |
amount | long | Amount in Paisa of the order/refund processed |
errorCode | String | Error code present only when the transaction state is Failed |
detailedErrorCode | String | Detailed Error Code present only when transaction state is Failed |
rail | PaymentRail | Contains processing rail details under which transaction attempt is made. |
instrument | PaymentInstrumentV2 | Contains instrument details of that particular transaction Id |
splitInstruments | List<InstrumentCombo> | Contains split instrument details of all the transactions made |
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. |
httpStatusCode | Integer | The status code of the http response. |
data | Map<String, String> | The details of the error that happened while calling PhonePe API. |
Sample Request
var merchantOrderID = Guid.NewGuid().ToString();
var payRequest = StandardCheckoutPayRequest.Builder()
.SetMerchantOrderId(merchantOrderID)
.SetAmount(100)
.SetRedirectUrl("https://www.merchant.com/redirect")
.SetExpireAfter(300)
.SetPaymentModeConfig(paymentModeConfig)
.SetMessage("message")
.Build();
try
{
StandardCheckoutPayResponse response = await checkoutClient.Pay(payRequest);
logger.LogInformation("Pay API Response:\n{Response}", JsonSerializer.Serialize(response, JsonOptions.IndentedWithRelaxedEscaping));
}
catch (Exception ex)
{
logger.LogError(ex);
}Response Models for Reference
- PaymentRail
- Represents different types of rail which will be received at the time of
getOrderStatus(). It falls under therailattribute in PaymentDetail Object
- Represents different types of rail which will be received at the time of
UPI RAIL
| Property | Type |
type | PaymentRailType |
utr | String |
upiTransactionId | String |
vpa | String |
PG RAIL
| Property | Type |
type | PaymentRailType |
transactionId | String |
authorizationCode | String |
serviceTransactionId | String |
PPI_WALLET RAIL
| Property | Type |
type | PaymentRailType |
PPI_EGV RAIL
| Property | Type |
type | PaymentRailType |
- PaymentRail
- Defines the type of rail used to initiate payment.
UPI RAIL
| Property | Type |
type | PaymentRailType |
utr | String |
upi_transaction_id | String |
vpa | String |
PG RAIL
| Property | Type |
| PaymentRailType |
| String |
| String |
| String |
- PaymentInstrumentV2
- Represents different types of instruments which will be received at the time of
getOrderStatus(). It falls under theinstrumentattribute in PaymentDetail Object
- Represents different types of instruments which will be received at the time of
ACCOUNT
| Property | Type |
| PaymentInstrumentType |
| String |
| String |
| String |
account_holder_name | String |
CREDIT_CARD
| Property | Type |
| PaymentInstrumentType |
| String |
| String |
| String |
brn | String |
DEBIT_CARD
| Property | Type |
| PaymentInstrumentType |
| String |
| String |
| String |
brn | String |
NET_BANKING
| Property | Type |
| PaymentInstrumentType |
| String |
| String |
| String |
brn | String |
EGV
| Property | Type |
| PaymentInstrumentType |
| String |
| String |
WALLET
| Property | Type |
| PaymentInstrumentType |
| String |