Initiate and Verify Refunds with .NET SDK


This section explains how to initiate a refund for a successful transaction using the Initiate Refund. You need to provide details like the original transaction ID, refund amount, and refund ID. After initiating the refund, you can use Refund Status to check whether the refund was successful, pending, or failed. These APIs help you manage the full refund lifecycle efficiently. Use them to ensure timely and transparent customer experiences.

Use the refund() function to initiate a refund. This ensures the amount is returned to the customer’s original payment method.

Parameters
ParameterTypeMandatoryDescription
refundRequestRefundRequestYesThe request built using RefundRequest builder.

You can use the RefundRequest Builder to create the refund request and the following are the attributes that merchant can pass.

Parameter NameData TypeMandatory
(Yes/No)
DescriptionConstraints
merchantRefundIdStringYesUnique refund ID assigned by youMax Length = 63 characters
originalMerchantOrderIdStringYesThe original order ID against which the refund is requested
amountLongYesRefund amount in paisa.Min value = 100 (in paise), Max value = order amount.
Sample Request
    public async Task<IActionResult> CustomRefund()
    {
        var merchantRefundId = Guid.NewGuid().ToString();

        var refundRequest = RefundRequest.Builder()
            .SetMerchantRefundId(merchantRefundId)
            .SetAmount(100)
            .SetMerchantOrderId("ORDER9999") // merchantOrderID whose refund is to be intitiated
            .Build();

        try
        {
            var response = await _customCheckoutClient.Refund(refundRequest);
            return Ok(response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Custom Refund API Failed");
            return StatusCode(500, new { message = ex.Message });
        }
    }

⚠️ Invalid Refund Amount!


The refund amount cannot exceed the initiated amount. It must always be less than or equal to the amount originally initiated.

The function returns a RefundResponse Object:

Parameter NameData TypeDescription
refundIdStringRefund ID generated by PhonePe PG.
stateStringThe state of the refund initiated. Initially it will be PENDING.
amountLongRefund amount in paisa.

Refund Status is used to retrieve the current status and details of a refund request made against a payment. By calling the getRefundStatus() function with the refund ID, you can track whether the refund is pending, successful, or failed, enabling you to manage and update refund workflows accordingly.

Pass the below parameter to get the refund status in getRefundStatus() :

Request Parameters
Parameter NameData TypeMandatoryDescription
refundIdStringYesRefund ID assigned by you at the time of refund initiation.
Sample Request
    public async Task<IActionResult> CustomRefundStatus(string refundId)
    {
        _logger.LogInformation($"Testing Custom GetRefundStatus API for Refund ID: {refundId}...");
        try
        {
            var response = await _customCheckoutClient.GetRefundStatus(refundId);
            _logger.LogInformation("Refund Status Response:\n{Response}", JsonSerializer.Serialize(response, new JsonSerializerOptions { WriteIndented = true }));
            return Ok(response);
        }
        catch (Exception ex)
        {
            _logger.LogError(ex, "Custom RefundStatus API Failed");
            return StatusCode(500, new { message = ex.Message });
        }
    }

It returns a RefundStatusResponse Object:

Object Properties
PropertiesData TypeDescription
merchantIdStringMerchant Id who initiated the refund.
merchantRefundIdStringRefund Id created by you at the time of refund initiation.
originalMerchantOrderIdStringThe order ID for which the refund was initiated.
amountLongRefund amount (in paisa).
stateStringThe status of the refund.
paymentDetailsList<PaymentRefundDetail>List of transaction attempts related to the refund.

The PaymentRefundDetail 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:

PropertyData TypeDescription
transactionIdStringThe transaction ID generated by PhonePe PG.
paymentModeStringThe payment method used
UPI_INTENT
UPI_COLLECT
UPI_QR
CARD
TOKEN
NET_BANKING
timestampLongTimestamp of the attempted transaction in epoch.
stateStringAttempted transaction state. It can be any one of the following states:
PENDING
COMPLETED
FAILED
errorCodeStringError code (only if the transaction failed).
detailedErrorCodeStringA more detailed error code (only if the transaction failed).
railPaymentRailContains processing rail details under which transaction attempt is made.
instrumentPaymentInstrumentV2Contains instrument details of that particular transaction ID.
splitInstrumentslist<InstrumentCombo>Payment instruments used:
ACCOUNT
CREDIT_CARD
DEBIT_CARD
NET_BANKING

In this section, you’ve learned how to initiate a refund and check its status. In the next section, you’ll understand how payment verification is handled using Webhooks, and how to manually verify the payment in case the webhook callback fails.

Is this article helpful?