QR Init is used when the merchant wants to generate a new dynamic QR code.

👍

PROD

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

QR Init Endpoint: https://mercury-t2.phonepe.com/v3/qr/init

Request Headers

Header NameHeader Value
Content-Typeapplication/json
X-VERIFYSHA256(base64 encoded payload + "/v3/qr/init" +
salt key) + ### + salt index
X-CALLBACK-URLURL on which server to server response is required
once payment is done
X-CALL-MODEHTTP mode to be used for callback. Default Value: POST
X-PROVIDER-IDUsed for the cases where the merchant has multiple merchant IDs
{
  "merchantId": "MERCHANTUAT",
  "transactionId": "TX32321849644234",
  "merchantOrderId": "TX32321849644234",
  "amount": 1000,
  "storeId": "234555",
  "terminalId": "894237",
  "expiresIn": 1800,
  "gstBreakup": {
    "gst": 100,
    "cgst": 25,
    "cess": 25,
    "sgst": 25,
    "igst": 25,
    "gstIncentive": 100,
    "gstPercentage": 10
  },
  "invoiceDetails": {
    "invoiceNumber": "123456fffff##_##",
    "invoiceDate": "2021-06-29T10:13:54.022Z",
    "invoiceName": "bccbd_cjdcdjc******"
  }
}
{
  "request": "ewogICJtZXJjaGFudElkIjogIk1FUkNIQU5UVUFUIiwKICAidHJhbnNhY3Rpb25JZCI6ICJUWDMyMzIxODQ5NjQ0MjM0IiwKICAibWVyY2hhbnRPcmRlcklkIjogIlRYMzIzMjE4NDk2NDQyMzQiLAogICJhbW91bnQiOiAxMDAwLAogICJzdG9yZUlkIjogIjIzNDU1NSIsCiAgInRlcm1pbmFsSWQiOiAiODk0MjM3IiwKICAiZXhwaXJlc0luIjogMTgwMCwKICAiZ3N0QnJlYWt1cCI6IHsKICAgICJnc3QiOiAxMDAsCiAgICAiY2dzdCI6IDI1LAogICAgImNlc3MiOiAyNSwKICAgICJzZ3N0IjogMjUsCiAgICAiaWdzdCI6IDI1LAogICAgImdzdEluY2VudGl2ZSI6IDEwMCwKICAgICJnc3RQZXJjZW50YWdlIjogMTAKICB9LAogICJpbnZvaWNlRGV0YWlscyI6IHsKICAgICJpbnZvaWNlTnVtYmVyIjogIjEyMzQ1NmZmZmZmIyNfIyMiLAogICAgImludm9pY2VEYXRlIjogIjIwMjEtMDYtMjlUMTA6MTM6NTQuMDIyWiIsCiAgICAiaW52b2ljZU5hbWUiOiAiYmNjYmRfY2pkY2RqYyoqKioqKiIKICB9Cn0="
}

Request Parameters

Parameter NameTypeDescriptionMandatory
merchantIdSTRINGUnique MerchantID assigned to the merchant by PhonePeYes
subMerchantIdSTRINGUnique identity of end merchantNo
storeIdSTRINGStore Id of store. Should be unique across. Special characters like " ", ",", "@" etc. are not allowed. Length should be lesser than 38 charactersYes
terminalIdSTRINGUnique terminal Id for each POS device. Special characters like " ", ",", "@" etc. are not allowed. Length should be lesser than 38 charactersNo
gstBreakupOBJECTRefer below for gstBreakup detailsNo
invoiceDetailsOBJECTRefer below for invoice detailsNo
transactionIdSTRINGUnique transactionIdYes
amountLONGAmount in PaiseYes
expiresInLONGExpiry time in secondsYes
merchantOrderIdSTRINGOrderId. This can be same as transactionIdNo
messageSTRINGMessage for customerNo

Request Parameters - gstBreakup Details

Parameter NameTypeMandatoryComments
gstLONGNoIn Paise. Cannot be Negative.
cgstLONGNoIn Paise.Cannot be Negative.
cessLONGNoIn Paise.Cannot be Negative.
sgstLONGNoIn Paise.Cannot be Negative.
igstLONGNoIn Paise.Cannot be Negative.
gstIncentiveLONGNoIn Paise.Cannot be Negative.
gstPercentageDOUBLENoCannot be Negative.

Request Parameters - invoiceDetails

Parameter NameTypeMandatoryComments
invoiceNumberStringNo
invoiceDateStringNoShould be of the format 1970-01-01T05:30:00+05:30
invoiceNameStringNo
{
  "success": true,
  "code": "SUCCESS",
  "message": "Your request has been successfully completed.",
  "data": {
    "merchantId": "MERCHANTUAT",
    "transactionId": "TX32321849644234",
    "amount": 1000,
    "qrString": "upi://pay?pa=MERCHANTUAT@ybl&pn=Test%20MerchantTT&am=10.00&mam=10.00&tr=TX32321849644234&tn=Payment%20for%20TX32321849644234&mc=5311&mode=04&purpose=00&gstBrkUp=GST:1.0|CGST:0.25|SGST:0.25|IGST:0.25|CESS:0.25|GSTIncentive:1.0|GSTPCT:10.0&invoiceNo=123456fffff##_##&invoiceDate=2021-06-29T15:43:54+05:30&invoiceName=bccbd_cjdcdjc******"
  }
}

Response Codes

CodeDescription
INVALID_TRANSACTION_IDDuplicate TransactionID
BAD_REQUESTInvalid request payload
AUTHORIZATION_FAILEDIncorrect X-VERIFY header
INTERNAL_SERVER_ERRORSomething went wrong
SUCCESSAPI successful

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";
        private string transactionId = "mer_order_8";
        private int amount = 100;
        private string storeId = "store1";
        private string terminalId = "terminal1";
        private int expiresIn = 180;

        public bool SendPaymentRequest(){
            PhonePeCollectRequest phonePeCollectRequest = new PhonePeCollectRequest();

            phonePeCollectRequest.merchantId = merchantId;
            phonePeCollectRequest.transactionId = transactionId;
            phonePeCollectRequest.merchantOrderId = transactionId;
            phonePeCollectRequest.amount = amount;
            phonePeCollectRequest.expiresIn = expiresIn;
            phonePeCollectRequest.storeId = storeId;
            phonePeCollectRequest.terminalId = terminalId;

			//convert string to json
            String jsonStr = JsonConvert.SerializeObject(phonePeCollectRequest);
            Console.WriteLine(jsonStr);
            
            string base64Json = ConvertStringToBase64(jsonStr);
            Console.WriteLine(base64Json);
            string jsonSuffixString = "/v3/qr/init" + merchantKey;
            string checksum = GenerateSha256ChecksumFromBase64Json(base64Json, jsonSuffixString);
            checksum = checksum + "###1";
            Console.WriteLine(checksum);
            
            string txnURL = PHONEPE_STAGE_BASE_URL + "/v3/qr/init";
            Console.WriteLine("txnURL : " + txnURL);
            try
            {
                HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(txnURL);

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

                PhonePeCollectApiRequestBody phonePeCollectApiRequestBody = new PhonePeCollectApiRequestBody();
                phonePeCollectApiRequestBody.request = base64Json;
                String jsonBody = JsonConvert.SerializeObject(phonePeCollectApiRequestBody);

                using (StreamWriter requestWriter = new StreamWriter(webRequest.GetRequestStream()))
                {
                    requestWriter.Write(jsonBody);
                }

                string responseData = string.Empty;

                using (StreamReader responseReader = new StreamReader(webRequest.GetResponse().GetResponseStream()))
                {
                    responseData = responseReader.ReadToEnd();
                    if (responseData.Length > 0)
                    {
                        //Dictionary<string, string> responseParam = JSONConvert.decode(responseData);
                        PhonePeCollectResponseBody responseBody = JsonConvert.DeserializeObject<PhonePeCollectResponseBody>(responseData);
                        Console.WriteLine(responseData);
                        Console.WriteLine(responseBody.message);
                    }
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e);
                return false;
            }
            
            return false;
        }
        
        public bool SendCheckPaymentStatusRequest()
        {
            string headerString = String.Format("/v3/transaction/{0}/{1}/status{2}", merchantId, transactionId, merchantKey);
            Console.WriteLine("headerString: " + headerString);
            string checksum = GenerateSha256ChecksumFromBase64Json("", headerString);
            checksum = checksum + "###1";
            Console.WriteLine(checksum);

            bool result = CallPhonePeStatusApi(checksum);

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

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

                webRequest.Method = "GET";
                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;
        }
        
		//convert jsonBody to base64
        public string ConvertStringToBase64(string inputString)
        {
            string base64Json = null;
            byte[] requestBytes = Encoding.UTF8.GetBytes(inputString);
            base64Json = Convert.ToBase64String(requestBytes);
            return base64Json;
        }
		
		// calculte 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.SendPaymentRequest();
            Console.WriteLine("QR Success");
            bool statusResponse = obj.SendCheckPaymentStatusRequest();
            Console.WriteLine("Payment status check");
        }
    }

    public class PhonePeCollectRequest
    {
        public string merchantId;
        public string transactionId;
        public string merchantOrderId;
        public int amount;
        public int expiresIn;
        public string storeId;
        public string terminalId;
    }

    public class PhonePeCollectApiRequestBody
    {
        public string request;
    }
    
    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;
    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.Base64;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.nio.charset.StandardCharsets;
import javax.xml.bind.DatatypeConverter;

public class DynamicQRApi 
{
    static String apiSaltKey = "369eaf8a-662f-4919-83f2-1dd8e01f2cad";
    static String urlEndpoint = apiSaltKey+ "/v3/qr/init";
	
	public static String GenerateSha256FromBase64Json(String base64Encoded, String urlEndpoint)
	{
		@SuppressWarnings("unused")
		String checksumString= base64Encoded+urlEndpoint;
		MessageDigest md = null;
		try 
		{
			md = MessageDigest.getInstance("SHA-256");
		} 
		catch (NoSuchAlgorithmException e) { e.printStackTrace(); }
	    //byte[] hash = md.digest(urlEndpoint.getBytes());
		md.update(checksumString.getBytes());
		byte[] byteData = md.digest();
		// Convert the byte array to a hexadecimal string
        StringBuilder checksum = new StringBuilder();
        for (byte b : byteData) 
        {
            checksum.append(String.format("%02x", b));
        }
	    return checksum.toString();
	}	
    @SuppressWarnings("null")
	public static void main(String[] args) throws Exception, IOException
    {
    	String apiUrl = "https://mercury-uat.phonepe.com/enterprise-sandbox/v3/qr/init";
    	
        // Request parameters
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("merchantId", "PATNAUAT");
        params.put("transactionId", "TX1234567890104");
        params.put("merchantOrderId", "M1234567013");
        params.put("amount", (long) 100);
        params.put("expiresIn", (long) 1800);
        params.put("storeId", "store1");
        params.put("terminalId", "terminal1");
        
        String jsonString = params.toString();
        byte[] encodedBytes = Base64.getEncoder().encode(jsonString.getBytes());
        String base64EncodedString = new String(encodedBytes);

        //creating X-verify
        String checksum = GenerateSha256FromBase64Json(base64EncodedString,urlEndpoint);
        checksum = checksum + "###1";
        try
        {
        URL url = new URL(apiUrl);
        HttpURLConnection conn = (HttpURLConnection) url.openConnection();
        conn.setRequestMethod("POST");
        conn.setRequestProperty("Content-Type", "application/json");
        conn.setRequestProperty("X-verify", checksum);
        conn.setDoOutput(true);
        
        try (OutputStream os = conn.getOutputStream())
        {
        	byte[] input = base64EncodedString.getBytes("utf-8");
            os.write(input, 0, input.length);
        }
        
        int responseCode = conn.getResponseCode();
        System.out.println("Response Code: " + responseCode);
        // Read the response from the server
        if (responseCode == HttpURLConnection.HTTP_OK) {
            try (InputStream is = conn.getInputStream()) {
                byte[] buffer = new byte[1024];
                int bytesRead;
                while ((bytesRead = is.read(buffer)) != -1) {
                    System.out.write(buffer, 0, bytesRead);
                }
            }
        } else {
            // Handle error response here if needed
            System.err.println("Error Response: " + responseCode);
        }
     // Close the connection
        conn.disconnect();
    }
        catch (IOException e) {
            e.printStackTrace();
        }
    }
}


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 qrInit(request):
    url = baseUrl + '/v3/qr/init'

    payload = {
        'merchantId': MID,
        'transactionId': txnid,
        "merchantOrderId": "MO145001",  
        'amount': 100,
        'expiresIn': 180,
        "message": "Test",
        "subMerchant": "",
        "storeId": "store1"
        #"terminalId": "2190961",
        # "gstBreakup": {},
        # "invoiceDetails": {}
     }

    # for base64 encoded payload
    strjson = json.dumps(payload)
    encoded_dict = strjson.encode('UTF-8')
    encodeddata = base64.b64encode(encoded_dict)
    encodeddata = encodeddata.decode('UTF-8')
    data = {
        "request": encodeddata
    }
    print(url)
    print(json.dumps(data))
    # for Sha256 calculation
    # api_saltkey = '/v3/qr/init' + saltkey
    str_forSha256 = encodeddata + '/v3/qr/init' + saltkey
    sha_value = hashlib.sha256(str_forSha256.encode('UTF-8')).hexdigest()
    x_verify = sha_value + '###' + keyindex
    print(x_verify);

    headers = {
        "Content-Type": "application/json",
        #"x-callback-url": "https://webhook.site/83892277-ac4f-4bc8",
        # "X-REDIRECT-MODE": "POST",
        "x-call-mode":"POST",
        #"x-provider-id": "M24015632468732",
        "X-VERIFY": x_verify
    }
    print(headers)
    res = requests.post(url=url, data=json.dumps(data), headers=headers)
    return HttpResponse(res)
Language
Click Try It! to start a request and see the response here!