Welcome to the 2C2P Developer Zone

This is the resource where developers can find all the information needed to integrate the services offered by 2C2P with their e commerce system.

Google Pay

Introduction

Google Pay™ is a digital card wallet provided by Google. It enables your customer to checkout faster and simpler.

Prerequisites

To start accepting Google Pay in your checkout page you must signup with Google to get your Google Pay MerchantId
1) To get started, please visit Google Pay's Web Integration overview.
2) You need to complete Google Pay's Web Integration Checklist.
3) You need to request Production Access.

Accepting Google Pay

Import API JavaScript Library

<script async src="https://pay.google.com/gp/p/js/pay.js" onload="console.log('TODO: add onload function')"></script>

Implement a Google Pay button according to Google's Brand Guidelines

const button =
    paymentsClient.createButton({onClick: () => console.log('TODO: click handler')});
document.getElementById('container').appendChild(button);

Integrate With Google Pay

For Integrating with Google Pay, refer the Google API Guide

Following Payment Request Object parameters need to be submit to Google Pay. Refer Google Pay API Request Objects

Payment Object Parameter
Description

allowedAuthMethods

Support ["PAN_ONLY"]

allowedCardNetworks

Card brands that you agreed with 2C2P to process the payment, Currently support ["AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA"]

paymentDataRequest.merchantInfo.merchantId

Merchant Id Received from Google Pay

paymentDataRequest.merchantInfo.merchantName

Merchant Name

paymentDataRequest.transactionInfo.currencyCode

Payment Currency Support by 2C2P

paymentDataRequest.transactionInfo.totalPrice

Payment Amount

tokenizationSpecification.parameters.gateway

Gateway Identifier provided by 2C2P

tokenizationSpecification.parameters.gatewayMerchantId

Merchant Id provided by 2C2P

When payment has been processed from Google Pay End. Google Pay API will return Payment Object Response.

Google Pay Token, parameter paymentData.paymentMethodData.tokenizationData.token from Google Pay API Object Response is required to capture for submitting to 2C2P Secure Pay API

Sample code for integrate with Google Pay API

Below are the full sample code that show how to integrate to Google Pay API


<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title>2C2P Google Pay Demo (3DS)</title>
</head>
<body>
    <div id="container"></div>
    <div id="result"></div>
    <!-- Mandatory Web Form Attributes:
         Form 'id': Used to identify the form that will be submitted to the backend.
         Form 'action': The address of the backend code that will submit payment request to 2c2p Payment Gateway.
         Form 'method': Should be set to 'POST' method
    -->
    <form id="2c2p-payment-form" action="payment_3ds.aspx" method="post">
        <!-- Optional Section Start -->
        <!--This extended section is optional, it can be fully customizable if neccessary -->
        <input type="hidden" id="mobilePaymentData" name="mobilePaymentData" /><br />
        <!-- Optional Section End -->
    </form>

    <!--Importing JSLibrary-->
    <script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js" defer></script>
    <script type="text/javascript">
        const baseRequest = {
            apiVersion: 2,
            apiVersionMinor: 0
        };

        const allowedCardNetworks = ["AMEX", "DISCOVER", "JCB", "MASTERCARD", "VISA"]; // Enable cards accepted

        const allowedCardAuthMethods = ["PAN_ONLY"]; // CRYPTOGRAM_3DS

        const billingAddressParameters = { phoneNumberRequired: true };

        const tokenizationSpecification = {
            type: 'PAYMENT_GATEWAY',
            parameters: {
                "gateway": "2c2p", 
                "gatewayMerchantId": "JT01",
            }
        };


        const baseCardPaymentMethod = {
            type: 'CARD',
            parameters: {
                allowedAuthMethods: allowedCardAuthMethods,
                allowedCardNetworks: allowedCardNetworks,
                billingAddressRequired: true,
                billingAddressParameters: billingAddressParameters,
                //cvcRequired: true,
            }
        };

        const isRTPCardPaymentMethod = {
            type: 'CARD',
            parameters: {
                allowedAuthMethods: allowedCardAuthMethods,
                allowedCardNetworks: allowedCardNetworks,
                billingAddressRequired: true,
                billingAddressParameters: billingAddressParameters,
            }
        };

        const cardPaymentMethod = Object.assign(
            {},
            baseCardPaymentMethod,
            {
                tokenizationSpecification: tokenizationSpecification
            }
        );


        let paymentsClient = null;

        /**
         * Configure your site's support for payment methods supported by the Google Pay
         * API.
         */
        function getGoogleIsReadyToPayRequest() {
            return Object.assign(
                {},
                baseRequest,
                {
                    allowedPaymentMethods: [isRTPCardPaymentMethod],
                    existingPaymentMethodRequired: true
                }
            );
        }

        /**
         * Configure support for the Google Pay API
         */
        function getGooglePaymentDataRequest() {
            const paymentDataRequest = Object.assign({}, baseRequest);
            paymentDataRequest.allowedPaymentMethods = [cardPaymentMethod];
            paymentDataRequest.transactionInfo = getGoogleTransactionInfo();
            paymentDataRequest.merchantInfo = {
                // @todo a merchant ID is available for a production environment after approval by Google
                // See {@link https://developers.google.com/pay/api/web/guides/test-and-deploy/integration-checklist|Integration checklist}
                merchantId: '03573441365420727591',
                merchantName: '2C2P Test Merchant'
            };
            return paymentDataRequest;
        }

        /**
         * Return an active PaymentsClient or initialize
         */
        function getGooglePaymentsClient() {
            if (paymentsClient === null) {
                paymentsClient = new google.payments.api.PaymentsClient({ environment: 'TEST' });
            }
            return paymentsClient;
        }

        /**
         * Initialize Google PaymentsClient after Google-hosted JavaScript has loaded
         */
        function onGooglePayLoaded() {
            const paymentsClient = getGooglePaymentsClient();
            paymentsClient.isReadyToPay(getGoogleIsReadyToPayRequest())
                .then(function (response) {
                    if (response.result) {
                        addGooglePayButton();
                        // @todo prefetch payment data to improve performance after confirming site functionality
                        prefetchGooglePaymentData();
                    } else {
                        alert("false");
                    }
                })
                .catch(function (err) {
                    // show error in developer console for debugging
                    console.error(err);
                });
        }

        /**
         * Add a Google Pay purchase button alongside an existing checkout button
         */
        function addGooglePayButton() {
            const paymentsClient = getGooglePaymentsClient();
            const button =
                paymentsClient.createButton({ onClick: onGooglePaymentButtonClicked });
            document.getElementById('container').appendChild(button);
        }

        /**
         * Provide Google Pay API with a payment amount, currency, and amount status
         */
        function getGoogleTransactionInfo() {
            return {
                currencyCode: 'SGD',
                totalPriceStatus: 'FINAL',
                // set to cart total
                totalPrice: '10.00'
            };
        }

        /**
         * Prefetch payment data to improve performance
         */
        function prefetchGooglePaymentData() {
            const paymentDataRequest = getGooglePaymentDataRequest();
            // transactionInfo must be set but does not affect cache
            paymentDataRequest.transactionInfo = {
                totalPriceStatus: 'NOT_CURRENTLY_KNOWN',
                currencyCode: 'USD'
            };
            const paymentsClient = getGooglePaymentsClient();
            paymentsClient.prefetchPaymentData(paymentDataRequest);
        }

        /**
         * Show Google Pay payment sheet when Google Pay payment button is clicked
         */
        function onGooglePaymentButtonClicked() {
            const paymentDataRequest = getGooglePaymentDataRequest();
            paymentDataRequest.transactionInfo = getGoogleTransactionInfo();

            const paymentsClient = getGooglePaymentsClient();
            paymentsClient.loadPaymentData(paymentDataRequest)
                .then(function (paymentData) {
                    // handle the response
                    processPayment(paymentData);
                })
                .catch(function (err) {
                    // show error in developer console for debugging
                    console.error(err);
                    alert(JSON.stringify(err));
                });
        }



        /**
         * Process payment data returned by the Google Pay API
         */
        function processPayment(paymentData) {
            $("#mobilePaymentData").val(JSON.stringify(JSON.parse(paymentData.paymentMethodData.tokenizationData.token)));
            // @todo pass payment data response to gateway to process payment
            document.forms[0].submit();
        }

    </script>

    <script async src="https://pay.google.com/gp/p/js/pay.js" onload="onGooglePayLoaded()"></script>
</body>
</html>

Integrate with 2C2P Secure API

Integrate with 2C2P's Securepay API to accept payment method Google Pay are required some specific parameter to be passed in. Following are Payment Request parameters

Parameter
Description

paymentChannel

Google Pay is GPAY

mobilePaymentData

  1. Get parameter paymentData.paymentMethodData.tokenizationData.token from front end.

  2. Convert parameter paymentData.paymentMethodData.tokenizationData.token in base64 encoded format.

  3. Pass in into parameter mobilePaymentData.

Sample code for integrate with 2C2P Secure API

Environment

Please refer Demo & Live Endpoint.

protected void Page_Load(object sender, EventArgs e)
        {
            if (!Page.IsPostBack)
            {
                if (base.Request.HttpMethod == "POST")
                {
                    #region ALL Fields

                    string cardholderEmail = "", payCategoryID = "", userDefined1 = "", userDefined2 = "", userDefined3 = "", userDefined4 = "", userDefined5 = "", storeCard = "",
                        ippTransaction = "", installmentPeriod = "", interestType = "", recurring = "", invoicePrefix = "", recurringAmount = "", allowAccumulate = "", maxAccumulateAmt = "",
                        recurringInterval = "", recurringCount = "", chargeNextDate = "", promotion = "", request3DS = "", statementDescriptor = "", agentCode = "", channelCode = "", paymentExpiry = "", mobileNo = "", tokenizeWithoutAuthorization = "",
                        paymentChannel = "", storeCardUniqueID = "", panBank = "";

                    #endregion

                    //Merchant Account Information
                    string merchantID = "JT01";             //Get MerchantID from 2c2p PGW Dashboard
                    string secretKey = "7jYcp4FxFdf0";      //Get SecretKey from 2c2p PGW Dashboard

                    //Product Information
                    string uniqueTransactionCode = "Invoice" + DateTime.Now.ToString("yyMMddHHmmss");
                    string desc = "Test Payment";
                    string amt = "000000001000";            //12 digit format
                    string currencyCode = "702";            //Ref: http://en.wikipedia.org/wiki/ISO_4217

                    //Customer Information
                    string cardholderName = "John Doe";
                    string country = "SG";

                    //Request Information
                    string timeStamp = DateTime.Now.ToString("ddMMyyHHmmss");
                    string apiVersion = "9.9";

                    string mobilePaymentData = Request.Form["mobilePaymentData"]; //Retrieve encrypted credit card data

                    mobilePaymentData = base64Encode(mobilePaymentData);

                    //Construct payment request message
                    string payloadXml = "<PaymentRequest>" +
                            "<timeStamp>" + timeStamp + "</timeStamp>" +
                            "<merchantID>" + merchantID + "</merchantID>" +
                            "<paymentChannel>GPAY</paymentChannel>" +
                            "<uniqueTransactionCode>" + uniqueTransactionCode + "</uniqueTransactionCode>" +
                            "<desc>" + HttpUtility.HtmlEncode(desc) + "</desc>" +
                            "<amt>" + amt + "</amt>" +
                            "<currencyCode>" + currencyCode + "</currencyCode>" +
                            "<panCountry>" + country + "</panCountry>" +
                            "<cardholderName>" + cardholderName + "</cardholderName>" +
                            "<mobilePaymentData>" + mobilePaymentData + "</mobilePaymentData>" + 
                            "</PaymentRequest>";

                    // Full payload elements:
                    /*
                     string xml = "<PaymentRequest>" +
                     "<version>" + apiVersion + "</version>" +                                          //request version number (9.1)
                     "<timeStamp>" + timeStamp + "</timeStamp>" +                                       //request timestamp
                     "<merchantID>" + merchantID + "</merchantID>" +                                    //Merchant MID
                     "<uniqueTransactionCode>" + uniqueTransactionCode + "</uniqueTransactionCode>" +   //Merchant's transaction ID
                     "<desc>" + desc + "</desc>" +                                                      //Transaction descrption
                     "<amt>" + amt + "</amt>" +                                                         //Transaction amount in 12 digit format
                     "<currencyCode>" + currencyCode + "</currencyCode>" +                              //Transaction Currency code
                     "<paymentChannel></paymentChannel>" +                      						//Payment Channel - 123, MPU, ALIPAY, UPOP
                     "<storeCardUniqueID></storeCardUniqueID>" +                                        //For authorization with Stored Card Token
                     "<panBank></panBank>" +                                                            //Card holder bank name
                     "<panCountry></panCountry>" +                                                      //Card holder bank country
                     "<cardholderName>" + cardholderName + "</cardholderName>" +                        //Card holder name
                     "<cardholderEmail></cardholderEmail>" +                                            //Card holder email
                     "<payCategoryID></payCategoryID>" +                                                //Transaction category ID
                     "<userDefined1></userDefined1>" +                                                  //Merchant defined field
                     "<userDefined2></userDefined2>" +                                                  //Merchant defined field
                     "<userDefined3></userDefined3>" +                                                  //Merchant defined field
                     "<userDefined4></userDefined4>" +                                                  //Merchant defined field
                     "<userDefined5></userDefined5>" +                                                  //Merchant defined field
                     "<storeCard></storeCard>" +                                                        //Store card details after transaction completed Y/N
                     "<recurring></recurring>" +                                                        //Recurring - transaction Y/N
                     "<invoicePrefix></invoicePrefix>" +                                                //Recurring - invoice prefix (max 15 chars)
                     "<recurringAmount></recurringAmount>" +                                            //Recurring - transaction amount
                     "<allowAccumulate></allowAccumulate>" +                                            //Recurring - allow transaction amount to accumulate over draft
                     "<maxAccumulateAmt></maxAccumulateAmt>" +                                          //Recurring - maximum over draft amount allowed
                     "<recurringInterval></recurringInterval>" +                                        //Recurring - interval in days
                     "<recurringCount></recurringCount>" +                                              //Recurring - number of occurance
                     "<chargeNextDate></chargeNextDate>" +                                              //Recurring - next charge date
                     "<ippTransaction></ippTransaction>" +				    		                    //IPP - transaction Y/N
                     "<installmentPeriod></installmentPeriod>" +			    	                    //IPP - installment period in months
                     "<interestType></interestType>" +					    		                    //IPP - interest paid by C/M (C=Customer, M=Merchant)
                     "<promotion></promotion>" +                                                        //Promotion code
                     "<request3DS></request3DS>" +						    		                    //3DS - Y (Yes)/N (No)/F (forced - only ECI 05 and 02 are accepted)
                     "<statementDescriptor></statementDescriptor>" +		    	                    //Display text on cardholder's account statement 
                     "<agentCode></agentCode>" +							    	                    //123 - Agent Code
                     "<channelCode></channelCode>" +						    	                    //123 - Channel Code
                     "<paymentExpiry></paymentExpiry>" +					    	                    //123 - Payment Expiry
                     "<mobileNo></mobileNo>" +							    		                    //123 - Payer Mobile No
                     "<tokenizeWithoutAuthorization></tokenizeWithoutAuthorization>" +                  //Tokenize without authorization
                     "<encCardData>" + encryptedCardInfo + "</encCardData>" +                           //Encrypted card data
                     "</PaymentRequest>"; 
                    */

                    string payload = base64Encode(payloadXml);                                //Convert payload to base64  
                    string hash = getHMAC2(payload, secretKey);                         //Calculate Hash Value

                    // Full payment elements:
                    /*
                     string xml = "<PaymentRequest>" +
                         "<version>" + apiVersion + "</version>" +                                          //request version number (9.1)
                         "<payload>" + payload + "</payload>" +                                             //request payload
                         "<signature>" + signature + "</signature>" +                                       //signature
                     "</PaymentRequest>"; 
                    */

                    string xml = "<PaymentRequest>" +
                        "<version>" + apiVersion + "</version>" +                                          //request version number (9.9)
                        "<payload>" + payload + "</payload>" +                                             //request payload
                        "<signature>" + hash + "</signature>" +                                       //signature
                    "</PaymentRequest>";

                    string data = base64Encode(xml);                                //Convert payload to base64                    
                    string url = "https://demo2.2c2p.com/2C2PFrontEnd/SecurePayment/PaymentAuth.aspx";
                    Response.Write(FrontendPost(url, data));
                }
            }
        }


        private string FrontendPost(string url, string request)
        {
            try
            {
                string strPost = "";
                strPost += "<form name=\"ResultForm\" id=\"ResultForm\" action=\"" + url + "\" method=\"post\" >";
                strPost += "<input type=\"hidden\" name=\"paymentRequest\" id=\"paymentRequest\" value=\"" + request + "\">";
                strPost += "<h3>Please wait while submitting payment request . . .</h3>";
                strPost += "<script language=\"JavaScript\">document.ResultForm.submit();</script>";
                strPost += "</form>";
                return strPost;
            }
            catch (Exception exception)
            {
                return "";
            };
        }

        private string base64Encode(string plainText)
        {
            var plainTextBytes = System.Text.Encoding.UTF8.GetBytes(plainText);
            return Convert.ToBase64String(plainTextBytes);
        }

        private string getHMAC2(string signatureString, string secretKey)
        {
            System.Text.UTF8Encoding encoding = new System.Text.UTF8Encoding();
            byte[] keyByte = encoding.GetBytes(secretKey);
            HMACSHA256 hmac = new HMACSHA256(keyByte);
            byte[] messageBytes = encoding.GetBytes(signatureString);
            byte[] hashmessage = hmac.ComputeHash(messageBytes);
            return ByteArrayToHexString(hashmessage);
        }

        private string ByteArrayToHexString(byte[] Bytes)
        {
            StringBuilder Result = new StringBuilder();
            string HexAlphabet = "0123456789ABCDEF";
            foreach (byte B in Bytes)
            {
                Result.Append(HexAlphabet[(int)(B >> 4)]);
                Result.Append(HexAlphabet[(int)(B & 0xF)]);
            }
            return Result.ToString().ToUpper();
        }

Updated 5 months ago

Google Pay


Suggested Edits are limited on API Reference Pages

You can only suggest edits to Markdown body content, but not to the API spec.