Skip to content
Developer Tools
Accelerate development using AI assistants and tools

Drop in - GooglePay

1. API Introduction

1.1 API List

Sequence of InteractionDirectionAPI TypeAPI PATH
2.1 Obtain Initialization Info for Frontend ComponentMerchant -> PayerMaxBackend API/applyDropinSession
2.3 Create Payment, Call Frontend Component Order APIMerchant -> PayerMaxBackend API/orderAndPay
2.4.1 Asynchronous Payment Result NotificationPayerMax -> MerchantBackend API/collectResultNotifyUrl
2.4.2 Query Payment TransactionMerchant -> PayerMaxBackend API/orderQuery

1.2 Environment Information

  • Sandbox Environment: https://pay-gate-uat.payermax.com/aggregate-pay/api/gateway/<API PATH>

  • Production Environment: https://pay-gate.payermax.com/aggregate-pay/api/gateway/<API PATH>

1.3 Request Headers

json
"headers": {
        "Accept": "application/json",
        "sign": "Please refer to the signing rules: https://docs-v2.payermax.comen/202506-version/developer/config-settings.html",//Required
        "Content-Type": "application/json"
}

2. Start Integration

2.1 Obtain Initialization Info for Frontend Component

The merchant server initiates an HTTP POST request through the /applyDropinSession API to obtain the client token clientKey and session token sessionKey required for frontend component initialization.

js
{
    "requestTime": "2024-11-20T01:56:36.753-02:00",
    "keyVersion": "1",
    "data": {
            "country":"US",
            "currency": "USD",
            "totalAmount": "19.99",
            "componentList": ["CARD","GOOGLEPAY"],
            "userId": "1447410849000200"
    },
    "appId": "381ded7c863c439a9e29b4519867965a",
    "version": "1.5",
    "merchantNo": ""
}
json
{
    "msg": "",
    "code": "APPLY_SUCCESS",
    "data": {
            "sessionKey": "964bffa7c9eb4951bd5ba11a2691e5ed",
            "notSupportedComponent": [],
            "clientKey": "8eef820ecbd443b7a608c2e0863750eb"
    }
}

2.2 Render Frontend Component

  1. Include the CDN package in the relevant HTML page.
html
<script src="https://cdn.payermax.com/dropin/js/pmdropin.min.js"></script>
  1. Embed a container area for the ApplePay button on the merchant page using a div tag.
html
<div class="frame-googlepay">  
    <!-- Form Content -->
</div>
  1. Initialize PayerMax Frames and mount GooglePay.
js
const googlePay = PMdropin.create('googlepay', {
    clientKey: "8eef820ecbd443b7a608c2e0863750eb",
    sessionKey: "0fdde7eda5fe4cc28ca8fdc759e28dc1",
    sandbox: true,
    payButtonConfig: {   
        buttonRadius: "12",
        buttonColor: "white",
        buttonType: "order",
        buttonLocale: "en",
        width: "240px",
        height: "40px"
    }
});
//Mount the button
googlePay.mount('.frame-googlepay');
  1. Listen to the button status. Once the user completes the Google Pay authentication flow, the frontend receives the paymentToken. The server then initiates the payment and returns the redirectUrl to the frontend to guide the user through 3DS authentication.
JavaScript
googlePay.on('ready', () => {
        console.log('Component initialization completed');
    })
googlePay.on('load', (res = {}) => {
    const { code, msg } = res || {};
    if (code === "SUCCESS") {
        console.log('[merchant][load]success:', res)
    } else {
        console.log('[merchant][load]fail:', res)
    }
})
googlePay.on('payButtonClick', (res) => {
    googlePay.emit('setDisabled', true);
    googlePay.emit('canMakePayment')
        .then(paymentRes => {
            console.log('canMakePayment')
            if (paymentRes.code === 'APPLY_SUCCESS') {
                const paymentToken = paymentRes?.data?.paymentToken;
                console.log('paymentToken:', paymentToken)
                // ⚠️ Initiate payment API
                // The merchant requests their own backend API to place the order, 
                // The merchant constructs request parameters using params, which must include paymentToken
                const params = {  // Add params definition
                    token: paymentToken,
                };
                _postapi('orderAndPay', params)
                    .then(apiRes => {
                        const code = (apiRes || {}).code;
                        if (code === 'APPLY_SUCCESS') { 
                            if(apiRes.threeDSUrl){
                            handle3DS(threeDSUrl)
                            // Complete 3DS using the PayerMax in-component popup; alternatively, open threeDSUrl in a new browser tab to complete 3DS
                            }    
                            googlePay.emit('paySuccess');// Payment successful, googlePay widget disappears
                        } else {
                            googlePay.emit('payFail');// Payment failed, googlePay widget disappears
                        }
                        googlePay.emit('setDisabled', false);// ⚠️ Unfreeze the form after the payment API call completes
                    })
                    .catch(err => {
                        console.error('API request failed:', err);
                        googlePay.emit('setDisabled', false);// Unfreeze the form if an exception occurs
                    });
            }
        })
        .catch(err => {
            console.error('Payment capability check failed:', err);
            googlePay.emit('setDisabled', false);
        });
}); 

// If a URL (i.e., threeDSUrl) is returned after orderAndPay, use the handle3DS method to trigger the popup
function handle3DS(threeDSUrl) {
  googlePay.create3DSPopup({
    // width/height are not passed, they will be automatically calculated based on the device and viewport; they can also be explicitly passed, e.g., '80%', '400px', etc.
    url: threeDSUrl,
    // If the 3DS link does not support iframe (i.e., returns NOT_SUPPORTED, causing our popup to fail), we automatically handle it by default via window.location.href = url;
    // However, if the merchant uses a WebView and restricts the behavior of window.location.href = url, the merchant needs to control the redirection manually using the custom jumpToUrlFn function.
    //jumpToUrlFn: (url) => {
    //  window.location.href = url; // Merchant handles opening the URL manually
    //}

  })
  .then(res => {
    if (res.code === '3DS_PROCESSED') {
      // 3DS process completed, proceed with the payment flow.
      console.log('3DS process completed', res.data);
      // The merchant needs to maintain the existing logic here. The merchant side should actively query the payment result and continue subsequent interactions.
      proceedPayment(res.data);
    }
  })
  .catch(err => {
    if (err.code === 'USER_CANCEL') {
      // The merchant can choose not to handle this, but should allow the user to click the payment button again
      showMessage('You have closed the verification window');
    } else {
      showMessage('Verification exception occurred, please try again');
    }
  });
}
  1. Get the paymentToken. Once the user confirms the payment on the frontend, the frontend canMakePayment API will return the following information, which is used for the backend to initiate the payment.
Json
{
    "msg": "",
    "code": "APPLY_SUCCESS",
    "data": {
        "paymentToken": "CPT771e98494eff41f1a03a715ebab69cc9",
        "cardOrg": "VISA",
        "maskCardNumber": "444433****1111",
        "cardExpirationMonth": "12",
        "cardType": "CREDIT",
        "cardExpirationYear": "26",
        "cardHolderFullName": "Jemy Cheung",
        "agreementAccepted": true,
        "cardBinNo": "444433",
        "cardIssuingCountry": "US"
    }
}

2.3 Create Payment

  1. Merchant Server: Call the /orderAndPay API to initiate an HTTP POST request and create a payment.
diff
{
        "requestTime": "2024-11-20T01:56:45.802-02:00",
        "keyVersion": "1.5", 
        "data": {
        "currency": "USD",
        "country":"US",
        "totalAmount": 19.99,      
        "expireTime": "3600",
        "paymentDetail": {
+               "paymentToken": "dbe78b7dd4fa4b668bacfdcc7153821d",//Callback to frontend paymentDetail after the user enters card info and clicks pay
                "buyerInfo": {
                        "clientIp": "146.75.136.237",
                        "userAgent": "Chrome"
                },
+               "sessionKey": "abf62fdcf9c4408cb73117db6e740713"
        },
        "frontCallbackUrl": "https://",
        "subject": "xxx Game HK Limited",
        "outTradeNo": "ov1_5b89ced71d764ed9994e6882d88082f7",
        "notifyUrl": "https://",
        "userId": "1447410849000200",
        "integrate": "Direct_Payment",
        "terminalType": "WEB"
        },
        "appId": "381ded7c863c439a9e29b4519867965a",
        "version": "1.5",
        "merchantNo": "P04010116880289"
}
json
{
    "msg": "Success.",
    "code": "APPLY_SUCCESS",
    "data": {
        "outTradeNo": "test_da78b1f3c2f9443b966347fc89305fc9",
        "tradeToken": "T2024052805951921811176",
        "status": "SUCCESS"
    }
}

2.4 Get Payment Result

The data.status in the response of the Create Payment/orderAndPay API is not the final payment status. Therefore, merchants should not use it directly to update the payment result.

2.4.1 Payment Result Notification

See Get Payment Result Integration - Payment Result Notification.

2.4.2 Payment Result Inquiry

See Get Payment Result Integration - Payment Result Inquiry.

3. API

Usage method: PMdropin.API.

APIDescriptionDetails
createInstantiate a built-in componentRefer3.1 create
mountMount instantiated component to div tagRefer3.2 mount
onListen eventsRefer3.3 on
emitTrigger eventsRefer3.5 emit

3.1 create

Used to initialize components, please use PMdropin.create(ComponentName, Options).

ComponentName Explanation

ComponentNameField TypeDescription
applepaystringApplePay Compoment

Options Explanation

OptionsRequired Or NotField TypeDefault Value
clientKeyYString-
sessionKeyYString-
sandboxNBooleanfalse
themeNStringlight
payButtonStyleNString-

3.2 mount

sed to mount initialization component instances, please use PMdropin.mount(Tag).

Tag Explanation

TagDescription
idThe value of the id element that needs to be mounted, such as PMdropin.mount('#applepay-frame')
classThe value of the class element that needs to be mounted, such as PMdropin.mount('.applepay-frame')

3.3 on

Used to listen to component built-in response events, please use PMdropin.on(Event, CallbackFunction).

Event Explanation

TagDescriptionReturned Value
readyTriggered when the component completes loadingnull
payButtonClickTriggered when the ApplePay button is clickednull

3.4 create3DSPopup

Used to open the 3DS authentication page within an in-component popup.

Language Settings Note: The SDK automatically retrieves the language from the instance configuration; there is no need to pass it separately in create3DSPopup. Important Note: 3DS_PROCESSED only indicates that the 3DS verification process has been completed; it does not mean the verification was successful. The merchant must query the final verification result (success/failure) via subsequent APIs.

Input Parameters:

ParameterTypeRequiredDefault ValueDescription
urlstringY-The 3DS authentication page URL (obtained from the orderAndPay API).
showMaskbooleanNtrueWhether to display the background mask overlay.
widthstringNResponsivePopup width. If omitted, it will be automatically calculated based on the device/viewport.
heightstringNResponsivePopup height. If omitted, it will be automatically calculated based on the device/viewport.
jumpToUrlFnfunctionNo(url)=>{window.location.href = url;}Merchant custom redirection method

Returns:

CODEDescriptionHandling Suggestions
3DS_PROCESSED3DS process has been handled.Proceed with the subsequent payment flow, and actively query the final authentication result via the API.
USER_CANCELUser closed the popup.Prompt the user that the window has been closed, and allow them to retry.
INVALID_PARAMSInvalid input parameters for the call.Check the input parameters based on err.msg (e.g., ensure the URL is required, non-empty, and of the correct type), then retry after correction.
NOT_SUPPORTEDThe current issuer bank page does not support opening via an iframe popupWe will automatically downgrade to window.location.href to open the URL. If you restrict window.location.href, please use jumpToUrlFn for custom redirection.

3.5 emit

Used to invoke the component's built-in methods, using the formatPMdropin.emit(Event, Params).

EventParamsDescription
canMakePaymentObjectObtain the token for the current payment
switchThemestringSwitch theme
setDisabledBooleanSet the availability status of the component
setpayButtonConfigObjectSet button styles

3.5.1 emit.canMakePayment

  1. Checks whether the current component status meets the conditions to initiate a payment, and returns the paymentToken after verification passes.
js
PMdropin.emit('canMakePayment', params?)

params is an optional parameter. If the merchant server has already provided complete payment information when calling the /applyDropinSession API, you can call PMdropin.emit('canMakePayment') directly without passing parameters.

  1. Options Configuration:
OptionsRequiredField TypeDescription
totalAmountNStringPayment amount, formatted as a pure numeric string (e.g., '1.00'). This is only recommended for scenarios where the merchant server did not pass the amount when calling the /applyDropinSession API to obtain pre-component initialization information. This amount is solely used for display within the Apple Pay payment sheet.

Example:

js
PMdropin.emit('canMakePayment', {
  totalAmount: '1.00'
})

Notes:

  • totalAmount only accepts valid numeric strings (e.g., '0.01', '99.99'). If an invalid value is passed, the API will return the error code AMOUNT_INVALID.
  • If the merchant server has already provided the amount when calling /applyDropinSession, the amount used during final order submission must be consistent with it; otherwise, it may lead to payment failure or risk control interception.
  • Please ensure that the totalAmount passed in canMakePayment is strictly consistent with the amount during final order submission; otherwise, it may lead to payment failure or risk control interception.

canMakePayment Response:

CodeDescription
APPLY_SUCCESSSuccessfully obtained the paymentToken.
UNKNOWN_ISSUEException occurred / Internal error.
AMOUNT_INVALIDInvalid input amount format.

3.5.2 emit.setDisabled

  • Set the component available state
  • Type: Boolean
  • Default: false
js
// Button disabled state
PMdropin.emit('setDisabled', true)

// Button enabled state
PMdropin.emit('setDisabled', false)

3.5.3 emit.setpayButtonConfig

  • Sets the button styles
  • Type: Object
  • Default:
Go
{
  buttonRadius: "12", // Sets the Google Pay button border radius. String
  buttonColor: 'default', // Sets the button color. "default"/"white"/"black"
  buttonType: 'plain',
  buttonLocale: 'en',
  width: "240px",
  height: "40px",
}

4. Internal Field Description

FieldDefault ValueTypeEnumerationDescription
width"240px"String/Set Google Pay button width
height"40px"String/Set Google Pay button height
buttonRadius"12"String/Set the border radius of the googlepay button String
buttonColor'default'String'default'/'white'/ 'black' Set button color
buttonType'plain'String"plain","buy","book","checkout","donate","order","pay","subscribe"Set button type Same as GooglePay official. See Preview demo for customized button
buttonLocale'en'String'en'/'ja'/'zh'/... International language encodingSet the multi-language text on the button, the same as GooglePay official, only supports the specified type, such as "checkout", "donate", etc.

5. Color Display

InputEffect Preview
default
white
black
入参效果预览
default
white
black

6. buttonType Display

InputEffect Preview
"plain"
"buy"
"book"
"checkout"
"donate"
"order"
"pay"
"subscribe"

7. buttonLocale Display

InputEffect PreviewDescription
"ja"Japanese
"bg"Bulgarian

Was this page helpful?

Thank you for your help in improving PayerMax Product Docs!

Released under the MIT License.