# Web/WAP

> Learn how to integrate the embedded payment experience SDK into a web or WAP client.

In this topic, you'll learn how to integrate the embedded payment experience SDK into a web or WAP client, and it will allow you to render cashier pages in a computer browser or a mobile browser.

---

## Prerequisites

Before the integration, ensure that you have completed the following tasks:

- Install npm (Node Package Manager).
- Properly handle compatibility issues: Provide corresponding polyfills for Internet Explorer and other old browser versions. We recommend that you use [babel-preset-env](https://babeljs.io/docs/babel-preset-env) to address browser compatibility issues when you build a project.
- Use the following recommended browser versions:
  - For mobile browsers:
    - iOS 11 and later
    - Android 5.0 and later
  - For computer browsers, use the following recommended versions:

| Edge | Firefox | Chrome | Safari | Opera | Electron |
|------|---------|--------|--------|-------|----------|
| Latest 2 versions | Latest 2 versions | Latest 2 versions | Latest 2 versions | Latest 2 versions | Last 2 versions |

---

## Key integration steps

Integrate the SDK by following these steps:

### Step 1: Integrate the SDK package

**Merchant client**

To integrate the SDK package, please refer to [Integrate the SDK Package for Web/WAP](https://docs.antom.com/ac/sdks/web.md).

### Step 2: Create an SDK instance by using the AMSCashierPayment

**Merchant client**

- Create a config object: Required. The object must contain all of the following configuration parameters:
  - **locale**: Optional. String type. The merchant client recognizes the language type used by the user's browser and passes in the browser's multilingual information. The SDK provides corresponding language pages based on this information. Valid values are listed as follows. If other values are passed, English is used by default:
    - `en_US`: English
    - `es_ES`: Spanish
    - `fr_FR`: French
    - `nl_NL`: Dutch
    - `it_IT`: Italian
    - `de_DE`: German
    - `zh_CN`: Simplified Chinese
  - **environment**: Required string. It is used to pass in environmental information. Valid values are:
    - `sandbox`: Sandbox environment
    - `prod`: Production environment
  - **analytics**: Optional object. It is used to configure and analyze data. It contains the following value:
    - **enabled**: Optional Boolean. It defaults to `true`, which indicates that you allow the SDK to upload and analyze operational data to deliver a better service. If you do not allow the data to be uploaded and analyzed, specify it as `false`.
  - **onLog**: Optional. It is a callback method that is used to generate the error information about logs and API exceptions during the execution of the SDK.
  - **onEventCallback**: Optional. A callback function that returns various types of data or values, including event codes, `cardPaymentResultInfo` parameter for card payment, and `popRiskDecisionResultInfo` parameter for risk control. See the [References](https://docs.antom.com/ac/sdk/ref.md) for further information.
  - **onError**: Optional. Triggered when an error occurs during SDK usage (initialization exception, network timeout, etc.). Refer to the error codes in the References.

- Instantiate `AMSCashierPayment`.

> **Note**: The environment set by environment should be consistent with the environment in which you call the [createPaymentSession](https://docs.antom.com/ac/apo/payment_sessio.md) API in step 3.

**Example - Obtain the browser language:**

```javascript
let language = navigator.language || navigator.userLanguage;
language = language.replace("-", "_"); // Replace "-" with "_"
```

**Example - Create an SDK instance for npm package importing method:**

```javascript
import { AMSCashierPayment } from '@alipay/ams-checkout' // Package management

const checkoutApp = new AMSCashierPayment({
  environment: "sandbox",
  locale: "en_US",
  analytics: {
    enabled: true
  },
  onLog: ({code, message})=>{},
  onEventCallback: ({code, result})=>{},
  onError: ({code, message})=>{}
});
```

**Example - Create an SDK instance for CDN package importing method:**

```javascript
const checkoutApp = new window.AMSCashierPayment({
  environment: "sandbox",
  locale: "en_US",
  analytics: {
    enabled: true
  },
  product: "CASHIER_PAYMENT",
  onLog: ({code, message})=>{},
  onEventCallback: ({code, result})=>{},
  onError: ({code, message})=>{}
});
```

### Step 3: Initiate a createPaymentSession request

**Merchant server**

For the buyer's unbound card payment and the token payment mode after the card has been bound, please operate them separately as follows:

**Unbound card mode:**
If the buyer is not bound to a bank card, your client needs to monitor the buyer's card payment method selection event on its own. After monitoring the buyer's choice of card payment method, the merchant client initiates a [createPaymentSession](https://docs.antom.com/ac/apo/payment_session.md) request to the APO server. Once the response to the [createPaymentSession](https://docs.antom.com/ac/apo/payment_session.md) request is received, the `paymentSessionData` value in the response is used in Step 4.

**Card token mode:**
After the buyer selects the bound card payment method as the payment method, your client monitors the click event of the payment button. When the buyer selects the payment method and clicks the card binding button, the merchant client initiates the [createPaymentSession](https://docs.antom.com/ac/apo/payment_session.md) request to the APO server. In card token mode, you need to pass in the `paymentMethod.paymentMethodId` field to the card token returned to you by APO after the buyer binds the card. The method of obtaining the card token is as follows:

- Independent card binding: Obtain the card token through the `card.cardToken` field in the asset binding result notification sent to you by APO.
- Non-independent card binding: Obtain the card token through the `paymentResultInfo.cardToken` field in the payment result notification sent to you by APO or the response to actively query the payment result.

Once the response to the [createPaymentSession](https://docs.antom.com/ac/apo/payment_session.md) request is received, the `paymentSessionData` value in the response is used in Step 4.

**Example - createPaymentSession request (No card bound):**

```json
{
  "order": {
    "buyer": {
      "buyerName": {
        "firstName": "*****",
        "fullName": "D***u",
        "lastName": "Liu",
        "middleName": "Skr"
      },
      "buyerRegistrationTime": "2022-01-01T09:30:00+08:00",
      "referenceBuyerId": "tony.c"
    },
    "goods": [{
      "goodsBrand": "AMSDM",
      "goodsCategory": "card/ssr/adc",
      "goodsName": "Goods No.1",
      "goodsQuantity": "1",
      "goodsSkuName": "SKU1",
      "goodsUnitAmount": {
        "currency": "USD",
        "value": "10000"
      },
      "goodsUrl": "HangZhou LeiFenTa",
      "referenceGoodsId": "amsdm_good_tony_c_20230227_095825_922"
    }],
    "orderAmount": {
      "currency": "BRL",
      "value": "2129"
    },
    "orderDescription": "AMSDM_GIFT",
    "referenceOrderId": "amsdmorder_tony_c_20230227_095825_921"
  },
  "paymentAmount": {
    "currency": "BRL",
    "value": "2129"
  },
  "paymentFactor": {
    "isAuthorization": true
  },
  "paymentMethod": {
    "paymentMethodType": "CARD",
    "paymentMethodMetaData":{
        "paymentMethodRegion":"BR"
    }
  },
  "paymentNotifyUrl": "https://www.google.com.sg",
  "paymentRedirectUrl": "https://www.baidu.com",
  "paymentRequestId": "amsdmpayk_tony_c_20230227_095825_920_532",
  "productCode": "CASHIER_PAYMENT",
  "settlementStrategy": {
    "settlementCurrency": "USD"
  },
  "enableInstallmentCollection":"true"
}
```

**Example - createPaymentSession request (Token payment):**

```json
{
    "productCode": "CASHIER_PAYMENT",
    "paymentRequestId": "55bf93a6-71a1-4ca9-b014-53273bd674eb",
    "order": {
        "referenceOrderId": "926e1c32-4a6c-442e-b5ce-8ec5b902e18c",
        "orderDescription": "xxxxx",
        "orderAmount": {
            "currency": "EUR",
            "value": "100"
        },
        "buyer": {
            "referenceBuyerId": "yeiasdasda",
            "buyerPhoneNo": "134******71"
        }
    },
    "paymentAmount": {
        "currency": "EUR",
        "value": "100"
    },
    "paymentMethod": {
        "paymentMethodType": "CARD",
        "paymentMethodId": "alipayCardToken",
        "paymentMethodMetaData": {
          "isCardOnFile":true
        }
    },
    "paymentRedirectUrl": "https://www.yourMerchantWeb.com",
    "paymentNotifyUrl": "https://www.yourNotifyUrl",
    "paymentFactor": {
        "isAuthorization": true
    },
    "settlementStrategy": {
        "settlementCurrency": "EUR"
    }
}
```

**Example - Response for createPaymentSession request:**

```json
{
  "paymentSessionData": "UNvjVWnWPXJA4BgW+vfjsQj7PbOraafHY19X+6EqMz6Kvvmsdk+akdLvoShW5avHX8e8J15P8uNVEf/PcCMyXg==&&SG&&111",
  "paymentSessionExpiryTime": "2023-04-06T03:28:49Z",
  "paymentSessionId": "UNvjVWnWPXJA4BgW+vfjsQj7PbOraafHY19X+6EqMz6Ikyj9FPVUOpv+DjiIZqMe",
  "result": {
    "resultCode": "SUCCESS",
    "resultMessage": "success.",
    "resultStatus": "S"
  }
}
```

### Step 4: Create a payment element collection component using the mount method in the instance object

**Merchant client**

- Create the `div` element in the page DOM as the placeholder of the element collection component. For example `<div class="checkout-container" />`.

- Create a configuration object using the **sessionData** parameter: Pass in the complete data of the `paymentSessionData` field obtained in the response of the [createPaymentSession](https://docs.antom.com/ac/apo/payment_session.md) request into the `sessionData` parameter.

- Use **selector** to specify the element in the DOM that needs to contain the element collection component.

- Call the `mount()` method in the instance object to mount the card component to the DOM node:
  - **notRedirectAfterComplete**: Optional, Boolean type. The default value is `false`, which means it will jump back to your page after the payment is completed. The same applies when the value is empty. `true` value means there will be no jump after the payment is completed. You need to use the customer event code to control the card binding to complete the subsequent process. Please note that the payment result event code returned by the client is only used as a reference for the jump operation of the client page. For transaction status's updates, please refer to the results returned by the server's [notifyPayment](https://docs.antom.com/ac/apo/paymentrn_online.md) or [inquiryPayment](https://docs.antom.com/ac/apo/paymentri_online.md) API.

- Free resources of the SDK component by calling the `unmount()` method in the instance object. You need to unmount a component in the following cases:
  - When the user switches views to exit the checkout page, free the component resources created in the [createPaymentSession](https://docs.antom.com/ac/apo/payment_session.md).
  - When the user initiates multiple payments, free the component resources created in the previous [createPaymentSession](https://docs.antom.com/ac/apo/payment_session.md).
  - When the user completes the payment and sets `notRedirectAfterComplete` to `true`, free the component resources after obtaining specific payment result codes.

**Example - Call the mount() method:**

```javascript
async function mount(sessionData) {
  await checkoutApp.mount({
    sessionData: sessionData,
    selector: '.checkout-container',
    notRedirectAfterComplete: true,
  });
}
// Free SDK component resources
checkoutApp.unmount();
```

---

## References

The References offers callback data and code samples for integration steps. For further details, refer to the [References](https://docs.antom.com/ac/sdk/ref.md).