Sample Code – mSite Intent

The backend API Details of the mSite Intent on PhonePe PG.

UPI Open Intent –

Sample Request

{
  "merchantId": "MERCHANTUAT",
  "merchantTransactionId": "MT7850590068188104",
  "merchantUserId": "MU933037302229373",
  "amount": 10000,
  "callbackUrl": "https://webhook.site/callback-url",
  "mobileNumber": "9999999999",
	"deviceContext": {
    "deviceOS": "ANDROID"
  },
  "paymentInstrument": {
    "type": "UPI_INTENT",
    "targetApp": "PHONEPE"
  }
}
{
  "request": "ewogICJtZXJjaGFudElkIjogIk1FUkNIQU5UVUFUIiwKICAibWVyY2hhbnRUcmFuc2FjdGlvbklkIjogIk1UNzg1MDU5MDA2ODE4ODEwNCIsCiAgIm1lcmNoYW50VXNlcklkIjogIk1VOTMzMDM3MzAyMjI5MzczIiwKICAiYW1vdW50IjogMTAwMDAsCiAgImNhbGxiYWNrVXJsIjogImh0dHBzOi8vd2ViaG9vay5zaXRlL2NhbGxiYWNrLXVybCIsCiAgIm1vYmlsZU51bWJlciI6ICI5OTk5OTk5OTk5IiwKCSJkZXZpY2VDb250ZXh0IjogewogICAgImRldmljZU9TIjogIkFORFJPSUQiCiAgfSwKICAicGF5bWVudEluc3RydW1lbnQiOiB7CiAgICAidHlwZSI6ICJVUElfSU5URU5UIiwKICAgICJ0YXJnZXRBcHAiOiAiUEhPTkVQRSIKICB9Cn0="
}

Sample Response

{
  "success": true,
  "code": "PAYMENT_INITIATED",
  "message": "Payment Initiated",
  "data": {
    "merchantId": "MERCHANTUAT",
    "merchantTransactionId": "MT7850590068188104",
		"instrumentResponse": {
			"type": "UPI_INTENT",
			"intentUrl": "upi://pay?pa=MERCHANTUAT@ybl&pn=MerchantUAT&am=3.00&mam=3.00&tr=OD620471739210623&tn=Payment%20for%OD620471739210623&mc=5311&mode=04&purpose=00&utm_campaign=DEBIT&utm_medium=FKRT&utm_source=OD620471739210623"
    }   
  }
}

Sample Code

<!doctype html>
<html lang="en">
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <meta name="theme-color" content="#4CAF50">
  <title>Phonepe mIntent Flow</title>
  <link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
  <div id="contents">
    <h1>Phonepe mIntent</h1>
    <p>This merchant accepts Phonepe only.</p>
    <!-- Some Merchant code to select/enter product details -->
    <p><button style="font-weight: bolder;" onclick="onCheckoutClick()">PhonePe Pay</button></p>
  </div>
  <pre id="msg"></pre>
  <script src="pr.js"></script>
</body>
</html>
let request;

/**
 * Initializes the payment request object.
 * @return {PaymentRequest} The payment request object.
 */
function buildPaymentRequest() {
    if (!window.PaymentRequest) {
        return null;
    }

    const supportedInstruments = [{
        supportedMethods: "https://mercury-uat.phonepe.com/transact/pay",	//For UAT or PreProd
        data: {
            //url: redirectUrl //To pass redirect url from v4/debit response
            url: "upi://pay?pa=MERCHANTUAT@ybl&pn=merchant&am=1.00&mam=1.00&tr=7ad44192-69f3-4e38-bebe-8c4944c5bbc6&tn=Payment+for+7ad44192-69f3-4e38-bebe-8c4944c5bbc6&mc=5311&mode=04&purpose=00&utm_campaign=DEBIT&utm_medium=MERCHANTUAT&utm_source=7ad44192-69f3-4e38-bebe-8c4944c5bbc6"
        }
    }];

    const details = {
        id: "1111-71ca4e9f-748c-4de7-af7b-a84f3da75b4e-temp", //A unique id [optional], if not passed browser will generate one
        total: {
            label: 'Total',
            amount: {
                currency: 'INR',
                value: '100',
            }
        }
    };

    try {
        request = new PaymentRequest(supportedInstruments, details);
        if (typeof request.hasEnrolledInstrument === ‘ function’) {
            request.hasEnrolledInstrument().then(function(result) {
                if (result) {
                    //Show “pay by Phonepe” button in payment options
                }
            }).catch(function(err) {
                handleError(err); //handle error
            });
        } else {
            request.canMakePayment().then(function(result) {
                if (result) {
                    //Show “pay by Phonepe” button in payment options
                }
            }).catch(function(err) {
                handleError(err);
            });
        }

    } catch (e) {
        handleError(e);
    }
}

/**
 * Create payment request object for Phonepe payment.
 */
function onCheckoutClick() {
    buildPaymentRequest();
}


/**
 * Handles the response from PaymentRequest.show().
 */
function handlePaymentResponse(response) {
    //Check if the response.details.result is success
    //get the transaction ref id from the response
    //use transaction refId and merchant Id to fetch the status
    var fetchOptions = {
        method: 'POST',
        credentials: 'include',
        body: JSON.stringify(payloadForFetch)
    };
    var serverPaymentRequest = new Request('secure/payment/endpoint'); //endpoint to fetch the status from server
    fetch(serverPaymentRequest, fetchOptions).then(fetchResponse => {
        if (fetchResponse.status < 400) {
            response.complete("success"); //notifies the user agent that the user interaction is over, and causes any remaining user interface to be closed
        } else {
            response.complete("fail"); //notifies the user agent that the user interaction is over, and causes any remaining user interface to be closed
        };
    }).catch(reason => {
        response.complete("fail"); //notifies the user agent that the user interaction is over, and causes any remaining user interface to be closed
    });
}

/**
 * Click event listener for “pay by Phonepe” button
 * Launch payment request for Phonepe payment.
 */
function onPayByPhonePeClick() {
    if (!window.PaymentRequest || !request) {
        return;
    }
    let paymentTimeout = window.setTimeout(function() {
        window.clearTimeout(paymentTimeout);
        request.abort()
            .then(function() {
                console.log('Payment timed out');
            })
            .catch(function() {
                console.log('Unable to abort the transaction');
            });
    }, 10 * 60 * 1000); /* 10 minutes */
    try {
        request.show()
            .then(function(response) {
                window.clearTimeout(paymentTimeout);
                handlePaymentResponse(response); // Handle response from browser.
            })
            .catch(function(err) {
                handleError(err); //handle error
            });
    } catch (e) {
        handleError(e);
    }
}
let request;

/**
 * Initializes the payment request object.
 * @return {PaymentRequest} The payment request object.
 */
function buildPaymentRequest() {
    if (!window.PaymentRequest) {
        return null;
    }

    const supportedInstruments = [{
        supportedMethods: "https://mercury-t2.phonepe.com/transact/pay",	//For Production
				// For PhonePe Prod: "https://mercury-t2.phonepe.com/transact/pay",

        data: {
            //url: redirectUrl //To pass redirect url from v4/debit response
            url: "upi://pay?pa=MERCHANT@ybl&pn=merchant&am=1.00&mam=1.00&tr=7ad44192-69f3-4e38-bebe-8c4944c5bbc6&tn=Payment+for+7ad44192-69f3-4e38-bebe-8c4944c5bbc6&mc=5311&mode=04&purpose=00&utm_campaign=DEBIT&utm_medium=MERCHANTUAT&utm_source=7ad44192-69f3-4e38-bebe-8c4944c5bbc6"
        }
    }];

    const details = {
        id: "1111-71ca4e9f-748c-4de7-af7b-a84f3da75b4e-temp", //A unique id [optional], if not passed browser will generate one
        total: {
            label: 'Total',
            amount: {
                currency: 'INR',
                value: '100',
            }
        }
    };

    try {
        request = new PaymentRequest(supportedInstruments, details);
        if (typeof request.hasEnrolledInstrument === ‘ function’) {
            request.hasEnrolledInstrument().then(function(result) {
                if (result) {
                    //Show “pay by Phonepe” button in payment options
                }
            }).catch(function(err) {
                handleError(err); //handle error
            });
        } else {
            request.canMakePayment().then(function(result) {
                if (result) {
                    //Show “pay by Phonepe” button in payment options
                }
            }).catch(function(err) {
                handleError(err);
            });
        }

    } catch (e) {
        handleError(e);
    }
}

/**
 * Create payment request object for Phonepe payment.
 */
function onCheckoutClick() {
    buildPaymentRequest();
}


/**
 * Handles the response from PaymentRequest.show().
 */
function handlePaymentResponse(response) {
    //Check if the response.details.result is success
    //get the transaction ref id from the response
    //use transaction refId and merchant Id to fetch the status
    var fetchOptions = {
        method: 'POST',
        credentials: 'include',
        body: JSON.stringify(payloadForFetch)
    };
    var serverPaymentRequest = new Request('secure/payment/endpoint'); //endpoint to fetch the status from server
    fetch(serverPaymentRequest, fetchOptions).then(fetchResponse => {
        if (fetchResponse.status < 400) {
            response.complete("success"); //notifies the user agent that the user interaction is over, and causes any remaining user interface to be closed
        } else {
            response.complete("fail"); //notifies the user agent that the user interaction is over, and causes any remaining user interface to be closed
        };
    }).catch(reason => {
        response.complete("fail"); //notifies the user agent that the user interaction is over, and causes any remaining user interface to be closed
    });
}

/**
 * Click event listener for “pay by Phonepe” button
 * Launch payment request for Phonepe payment.
 */
function onPayByPhonePeClick() {
    if (!window.PaymentRequest || !request) {
        return;
    }
    let paymentTimeout = window.setTimeout(function() {
        window.clearTimeout(paymentTimeout);
        request.abort()
            .then(function() {
                console.log('Payment timed out');
            })
            .catch(function() {
                console.log('Unable to abort the transaction');
            });
    }, 10 * 60 * 1000); /* 10 minutes */
    try {
        request.show()
            .then(function(response) {
                window.clearTimeout(paymentTimeout);
                handlePaymentResponse(response); // Handle response from browser.
            })
            .catch(function(err) {
                handleError(err); //handle error
            });
    } catch (e) {
        handleError(e);
    }
}

Sample Response in the Callback function (for show method)

// paymentDetails sample 
{
   requestId: "{{PAYMENT_REQUEST_ID}}",            		// Unique id passed in details/generated by browser
   methodName: "{{}}",                             		// String MerchantID
   details: {
          txnId: "YBLca62648cd325400a8cc7aef84a7a5b96”,	// transaction id generated by the app
          txnRef: "TX1581683875995",          			// transaction ref id, this needs to be used to fetch status
          Status: "Success”,                  			// payment status
          responseCode: "00"
     },             
   shippingAddress: null,  // Number - In Paisa
   payerName: null, // String
   payerEmail: null,
   payerPhone: null
}