Cancel Payment Request

PROD

Base Url: https://mercury-t2.phonepe.com

Cancel API: https://mercury-t2.phonepe.com/v3/charge/{merchantId}/{transactionId}/cancel

<html-block html=”

Request Headers

“>

Header NameHeader Value
Content-Typeapplication/json
X-VERIFYSHA256(“/v3/charge/{merchantId}/{transactionId}/cancel” +
salt key) + ### + salt index

<html-block html=”

Path Parameters

“>

Parameter NameTypeDescriptionMandatory
merchantIdSTRINGUnique Merchant ID assigned to the merchant by PhonePeYes
transactionIdSTRINGUnique Transaction ID generated by the merchant to track this request to PhonePeYes

<html-block html=”

Response Parameters

“>

Parameter NameTypeDescription
successBOOLEANSuccess status of the request
codeENUMSee below section for list of codes
messageSTRINGShort message about status
dataOBJECTEmpty object

<html-block html=”

Response Codes

“>

The code in the above API response could be.

  • SUCCESS
  • INTERNAL_SERVER_ERROR : There can be internal server error. Merchant should retry the cancel API request.
  • INVALID_TRANSACTION_ID
  • PAYMENT_ALREADY_COMPLETED : Payment has been succesful hence can’t cancel the request. For this case merchant should trigger successful transaction, generating the bill.
{
  "success":true,
 "code":"SUCCESS",
 "message":"Your request has been successfully completed."
}
{
  "success":false,
  "code":"PAYMENT_ALREADY_COMPLETED",
  "message":"Payment is already complete."
}
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;
using System.Net;
using System.Text;
using System.Security.Cryptography;
using Newtonsoft.Json;

namespace Rextester
{
    public class Program
    {
        private const string PHONEPE_STAGE_BASE_URL = "https://mercury-uat.phonepe.com/enterprise-sandbox";
        private string merchantKey = "8289e078-be0b-484d-ae60-052f117f8deb";
        private const string merchantId = "M2306160483220675579140";
        
        public bool SendCancelRequest()
        {
            string headerString = String.Format("/v3/charge/{0}/{1}/cancel{2}”, merchantId, transactionId, merchantKey);
            Console.WriteLine("headerString: " + headerString);
            string checksum = GenerateSha256ChecksumFromBase64Json("", headerString);
            checksum = checksum + "###1";
            Console.WriteLine(checksum);

            bool result = CallCancelApi(checksum);

            return result;
        }
        
        private bool CallCancelApi(String xVerify)
        {
            Console.WriteLine("CallPhonePeStatusApi()");
            string txnURL = PHONEPE_STAGE_BASE_URL;
            String urlSuffix = String.Format("/v3/charge/{0}/{1}/cancel”, merchantId, transactionId);
            txnURL = txnURL + urlSuffix;

            Console.WriteLine("Url: " + txnURL);
            
            try
            {
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(txnURL);

                      webRequest.Method = "POST";
                webRequest.ContentType = "application/json";
                webRequest.Headers.Add("x-verify", xVerify);

                string responseData = string.Empty;
                
                using (StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream()))
                {
                    responseData = responseReader.ReadToEnd();
                    if (responseData.Length > 0)
                    {
                        PhonePeCollectResponseBody responseBody = JsonConvert.DeserializeObject<PhonePeCollectResponseBody>(responseData);
                        Console.WriteLine(responseData);
                        Console.WriteLine(responseBody.message);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return false;
            }
            return false;
        }
		
        // calculate SHA256
        private string GenerateSha256ChecksumFromBase64Json(string base64JsonString, string jsonSuffixString)
        {
            string checksum = null;
            SHA256 sha256 = SHA256.Create();
            string checksumString = base64JsonString + jsonSuffixString;
            byte[] checksumBytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(checksumString));
            //checksum = BitConverter.ToString(checksumBytes).Replace("-", string.Empty);
            foreach (byte b in checksumBytes)
            {
                checksum += $"{b:x2}";
            }
            return checksum;
        }

        public static void Main(string[] args){
            Program obj = new Program();
            bool QRResponse = obj.SendCancelRequest();
            Console.WriteLine(" Success");
        }
    }

    public class PhonePeCollectResponseBody
    {
        public bool success;
        public string code;
        public string message;
        public Data data;
    }
    public class Data
    {
        public string transactionId;
        public int amount;
        public string merchantId;
        public string providerReferenceId;
    }
}

from django.shortcuts import render
from django.http import HttpResponse
import requests
import base64
import hashlib
from rest_framework.decorators import api_view
import json
from django.http import JsonResponse
import qrcode
import os

txnid = "TEST20231004021525T"
baseUrl = 'https://mercury-uat.phonepe.com/enterprise-sandbox'
MID = 'MERCHANTUAT'
saltkey = 'f1fed176-917c-4c1b-b5ae-1e1d39e1f8d5'
keyindex = '1'

def canceltransaction(request):
    merchantId = MID
    transactionId = txnid
    url = baseUrl + '/v3/charge/' + merchantId + '/' + transactionId + '/cancel'
    # for Sha256 calculation
    api_saltkey = saltkey
    str_forSha256 = '/v3/charge/' + merchantId + '/' + transactionId + '/cancel' + api_saltkey
    sha_value = hashlib.sha256(str_forSha256.encode('UTF-8')).hexdigest()
    x_verify = sha_value + '###' + keyindex

    headers = {
        "Content-Type": "application/json",
        "X-VERIFY": x_verify,
        "x-callback-url":"https://webhook.site/83892277-ac4f-4bc8"
    }
    print(headers)
    print(url)
    res = requests.post(url=url, headers=headers)
    return HttpResponse(res)
{“method”:”post”,”url”:”/v3/charge/{merchantId}/{transactionId}/cancel”,”auth”:”required”,”results”:{“codes”:[{“name”:””,”code”:”{ \”success\”: true,\n \”code\”: \”SUCCESS\”,\n \”message\”:\”Your request has been successfully completed.\”,\n \”data\”:{}\n}”,”language”:”json”,”status”:200},{“name”:””,”code”:”{}”,”language”:”json”,”status”:400}]},”params”:[{“name”:”merchantId”,”type”:”string”,”enumValues”:””,”default”:””,”desc”:”Unique Merchant ID assigned to the merchant by PhonePe”,”required”:false,”in”:”path”,”ref”:””,”_id”:”5f310bd19c236501368dbec5″},{“name”:”transactionId”,”type”:”string”,”enumValues”:””,”default”:””,”desc”:”Unique Transaction ID generated by the merchant to track this request to PhonePe”,”required”:false,”in”:”path”,”ref”:””,”_id”:”5f310bd19c236501368dbec4″},{“name”:”Content-Type”,”type”:”string”,”enumValues”:””,”default”:”application/json”,”desc”:””,”required”:false,”in”:”header”,”ref”:””,”_id”:”5f310bd19c236501368dbec3″},{“name”:”X-VERIFY”,”type”:”string”,”enumValues”:””,”default”:””,”desc”:”SHA256(\”/v3/charge/{merchantId}/{transactionId}/cancel\” + salt key) + ### + salt index”,”required”:false,”in”:”header”,”ref”:””,”_id”:”5f310bd19c236501368dbec2″}],”examples”:{“codes”:[]},”apiSetting”:”64c244096688b200429110a5″}
https://mercury-uat.phonepe.com/enterprise-sandbox