Integration Steps

How the Agoda partner.js solution works

The partner.js solution enables partners to associate each booking attempt with a verified set of frontend session and device context signals. partner.js returns a verification token, which must be transmitted to Agoda through the Affiliate Book API (Agoda’s BE) as part of the booking request. Agoda uses this token to perform enhanced fraud analysis during booking processing.

The solution consists of three steps:

  1. Include partner.js on your website:You must load partner.js on your home and checkout page at a minimum. For optimal session continuity and more robust fraud detection, we highly recommend including the script on every page of the customer journey.

  2. Initialize a session in the browser: After the script is loaded, you must call the SDK initialization method to start or resume a session. During this step, partner.js collects eligible browser and device context signals in a non-blocking manner. The SDK supports common partner security configurations, including Content Security Policy constraints.

  3. Generate and submit the booking context token with your booking request: Immediately before submitting the booking to your backend, you must invoke the SDK checkout method to generate a verification token. Your frontend must forward the token to your backend, and your backend must include it unchanged in the Affiliate Book API request, as specified in this documentation.

📘

Important:

The booking context token must be treated as an opaque value. Partners must not decode, parse, or modify the token.

Integration flow

Follow the steps below to integrate partner.js into your website and enable token generation for fraud detection.


Step 1 - Installation & setup

Load partner.js on your home and checkout pages.

  • Required: Home (where the user starts their booking journey) and checkout page (where the booking is submitted)
  • Recommended: Search/details pages to establish the session earlier in the user journey.
  • (Global - Preferred): Add the script to your base layout/template. This ensures the SDK and its security beacons are pre-loaded and ready immediately upon navigation to the payment page.

Example:

Place the following script in the <head> or before the closing <body> tag.

<script src="https://cdn6.agoda.net/s-cdn-partner-sdk/v1/`partner.js`"></script>

The Partner SDK (partner.js) may dynamically load additional scripts and send browser beacons used for fraud detection and telemetry. To ensure full functionality (and avoid blocking required network calls), update your site’s Content Security Policy (CSP) to explicitly allow the SDK CDN, fraud vendor endpoints (Riskified), and the Bento analytics endpoints provided during onboarding.

Required CSP directives and example values

DirectivePurpose / DescriptionAllowed Sources / Notes
script-srcAllow loading of partner.js and any secondary script loaders/beacons- Agoda SDK CDN: https://cdn6.agoda.com - Riskified beacon/loader: https://beacon.riskified.com - Bento analytics scripts: https://bento.agoda.com - If you use nonces: Include 'nonce-YOUR_NONCE_VALUE' for each script tag that uses a nonce.
connect-srcAllow XHR/fetch/beacon network calls that the SDK will make- Partner SDK to call Agoda BE: https://*.agoda.com - Riskified endpoints: https://*.riskified.com - Bento analytics collection endpoint(s): (https://bento.agoda.com/) (covered with https://*.agoda.com)
worker-srcAllow telemetry- Agoda telemetry: https://www.agoda.com
img-srcAllow pixel image beacons (if used by fraud/analytics vendors)- Riskified image pixel: https://img.riskified.com

Example CSP header:

<meta http-equiv="Content-Security-Policy" content="
  script-src 
    'self' 
    https://www.agoda.com 
    https://*.agoda.com 
    https://*.riskified.com 
    https://cdn6.agoda.net; 

  connect-src 
    'self' 
    https://*.agoda.com 
    https://bento.agoda.com 
    https://*.agoda.local 
    https://*.riskified.com 

  worker-src 
    'self' 
    https://www.agoda.com 
    https://*.agoda.com 
    https://*.agoda.local;

   img-src 
    'self' 
    https://img.riskified.com;

">

Step 2 — Initialize a session in the browser

After the script loads, call the SDK initialization method to start (or resume) a session.

During initialization, the SDK collects eligible browser, session, and device context signals in a non-blocking manner. The SDK is designed to work with common partner security setups (including Content Security Policy (CSP) constraints).

  • You can handle the init result using either Promise or a Callback.

Option A: Using the Promise response

Assign the response to a variable to access the token directly.

try {
 await window.partnerSDK.init({
   siteId: "12345",           // CID provided by Agoda
   environment: "production",    // or "sandbox"
   cspNonce: "rAnd0m12345",   // Optional nonce for CSP compliance
  });
 console.log("SDK is ready")  // Init success
} catch(e) {
   console.error("SDK init failed", error) // Init fail
}

Option B: Using a Callback

<script>
 window.partnerSDK.init({
   siteId: "12345",           // CID provided by Agoda
   environment: "production",    // or "sandbox"
   cspNonce: "rAnd0m12345",   // Optional nonce for CSP compliance
   onReady: () => console.log("SDK is ready"), // optional if used as promise
   onError: (error) => console.error("SDK init failed", error)
 });
</script>

Partner SDK init parameters

ParameterTypeRequiredDescription
siteIdstringRequiredUnique identifier provided by Agoda to the partner
environmentEnumRequiredEnvironment to use ("sandbox" or "production")
cspNoncestringOptionalAllows safe, authorized inline scripts/styles
onReadyfunctionOptionalHook to enable UI elements once the SDK is "live"
onErrorfunctionOptionalHook to catch network or configuration errors

Step 3 — Generate a context token (checkout)

Immediately before submitting the booking from your frontend, you must invoke the SDK checkout() method. This method collects required security signals and returns a booking context token, which must be forwarded to your backend.

  • First, prepare your cardDetails object:
// First, prepare your cardDetails object:  
const cardDetails = {  
  creditCardNumber: "4111...",   // Full card number  
  cardHolderName: "John Doe",  
  expiryDate: "122028",            // MMYYYYY format  
  cvc: "123"  
};
  • You can handle the checkout result using either Promise or a Callback.

Option A: Using the Promise response

Assign the response to a variable to access the token directly

const response = await window.partnerSDK.checkout(cardDetails);

if (response.success) {  
  // Access the token and send it to your backend  
  const token = response.sdk_context_token;  
  await submitBookingToBackend(token);  
}

Option B: Using a Callback

Pass a callback function as the second argument

const cb = (result) => {  
  if (result.success) {  
    console.log("Token received:", result.sdk_context_token);  
    // Proceed with your backend submission logic  
  } else {  
    // Log the error code and message  
    console.error(`Error [${response.error.code}]: ${response.error.message}`);  
  }  
};

window.partnerSDK.checkout(cardDetails, cb);
⚠️

Important:

The sdk_context_token is an opaque string. Your backend must include it unchanged in the Affiliate Book API request to ensure the transaction is correctly validated and attributed

Configuration parameters

SDK checkout parameters

ParameterTypeRequiredDescription
cardDetailsPaymentCardDetailsRequiredAn object containing the sensitive payment information (number, expiry, CVV)
callbackCheckoutCallbackOptionalA function triggered upon completion, providing the CheckoutResult to the caller.

PaymentCardDetails

ParameterTypeRequiredDescription
creditCardNumberstringRequiredThe credit card number will consist of 15 or 16 digits. Each digit can be 0-9
expiryDatestringRequiredExpiry Date in the format MMYYYY. Each digit can be 0-9
cvcstringRequiredCVC code consisting of 3-4 digits. Each digit can be 0-9
cardHolderNamestringRequiredCardholder name

CheckoutResult

ParameterTypeDescription
successbooleanIndicates if the verification was successful
sdk_context_tokenstringConditional. Only present if success is true. This is the opaque verification token that must be passed to your backend.
errorobjectConditional. Only present if success is false. Contains error details
error.codestringA machine-readable error identifier (e.g., FRAUD_FAIL, NETWORK_FAILURE).
error.messagestringA human-readable description of the error for logging purposes.

Step 4 — Pass the context token to backend

Send the token to your backend as part of your booking request payload.

  • Treat the token as opaque: do not decode, parse, or modify.
  • Do not persist to long-term storage (avoid localStorage/sessionStorage).
  • Avoid logging the token. If logging is unavoidable, mask it.

Full flow example for sample checkout page (only for reference) :

<script src="https://cdn6.agoda.net/s-cdn-partner-sdk/v1/`partner.js`" nonce="rAnd0m12345"></script>

<script>
        const payBtn = document.getElementById('pay-button');

        // 1. GENERATE CONFIG & INIT()
        window.partnerSDK.init({
            siteId: "12345", 
            environment: "sandbox", 
            cspNonce: "rAnd0m12345", // Optional
            onReady: () => console.log("SDK Ready."),
            onError: (error) =>  console.log("Init Failed: " + error.message)
        });

        // Enable Book button regardless of init() result
        payBtn.disabled = false;
        // 2. CHECKOUT LIFECYCLE
        payBtn.addEventListener('click', async () => {
            payBtn.disabled = true;

            // Generate cardDetails object from UI
            const cardDetails = {
                creditCardNumber: document.getElementById('cardNumber').value,
                cardHolderName: document.getElementById('holderName').value,
                expiryDate: document.getElementById('expiry').value, 
                cvc: document.getElementById('cvc').value
            };

            try {
                const response = await window.partnerSDK.checkout(cardDetails);

                if (response.success) {
                    const token = response.sdk_context_token;
                    console.log("Token generated! Sending to backend...");
                    
                    // Send to your backend
                    await submitBookingToBackend(token);
                    console.log("Booking Successful!");
                } else {
                    console.error("Checkout failed. Please check details.");
                    payBtn.disabled = false;
                }
            } catch (error) {
                console.error("Error: " + error.message);
                payBtn.disabled = false;
            }
        });



        async function submitBookingToBackend(token) {
            console.log("Payload for backend:", { sdk_context_token: token });
            // Example: await fetch('/api/book', { method: 'POST', body: JSON.stringify({token}) });
            return new Promise(resolve => setTimeout(resolve, 1000));
        }
</script>

Step 5 — Send context token and customer IP Address to Affiliate Book API

  • Pass sdk_context_token received from SDK to affiliate BookAPI.
  • To ensure high booking success rates, pass the customer ipAddress, customer email address, and customer phone number to affiliate Book API.
{
  "waitTime": 120,
  "bookingDetails": {
    "userCountry": "US",
    "searchId": 1629183207719830000,
    "tag": "00000000-0000-0000-0000-000000000000",
    "allowDuplication": false,
    "checkIn": "2022-12-23",
    "checkOut": "2022-12-24",
    "property": {
      "propertyId": 12157,
      "rooms": [
        {
          "blockId": "blockid_v3",
          "offerToken": "offer_token",
          "rate": {
            "inclusive": 798.58
          },
          "surcharges": [
            {
              "id": 278,
              "rate": {
                "inclusive": 12
              }
            },
            {
              "id": 279,
              "rate": {
                "inclusive": 12
              }
            }
          ],
          "guestDetails": [
            {
              "title": "Mr.",
              "firstName": "JSONTest",
              "lastName": "JSONTest",
              "countryOfResidence": "US",
              "gender": "Male",
              "age": 30,
              "primary": true
            }
          ],
          "currency": "USD",
          "paymentModel": "Merchant",
          "count": 1,
          "adults": 2,
          "children": 2,
          "childrenAges": [
            5,
            6
          ],
          "specialRequest": "high floor"
        }
      ]
    }
  },
  "customerDetail": {
    "language": "en-us",
    "title": "Mr.",
    "firstName": "Test",
    "lastName": "Test",
    "email": "[[email protected]](mailto:[email protected])",
    "phone": {
      "countryCode": "66",
      "areaCode": "2",
      "number": "22222222222"
    },
    "newsletter": false,
    "ipAddress": "customer IP Address",
  },
  "paymentDetails": {
    "contextToken": "token",
    "creditCardInfo": {
      "number": 123456789000,
      "expiryDate": "032029",
      "cvc": 543,
      "holderName": "JSONTEST"
    }
  }
}

Schema fields

ParameterTypeDescription
paymentDetails.contextTokenstringThe token generated from the SDK.
customerDetail.ipAddressstringThe customer IP Address.
customerDetail.emailstringCustomer email address.
customerDetail.phoneobjectCustomer phone number.