### Build a checkout page on the client

- #### Load Upgate.js
Leverage Upgate.js to maintain PCI compliance by ensuring that payment information is transmitted directly to Upgate without accessing your server.
To stay compliant, consistently load Upgate.js from js.upgate.com.
Avoid incorporating the script into a bundle or hosting it independently.
Create `./public` folder and create `index.html` with code below:


```html
<html lang="en">
  <head>
    <script type="module" src="https://js.upgate.com/upgate.js"></script>
    <script type="module" src="/main.js"></script>
    <style>
      body {
        min-height: 100vh;
        justify-content: center;
        width: 350px;
        margin: 0 auto;
        display: flex;
        flex-direction: column;
        gap: 32px;
      }
    </style>
  </head>
  <body>
    <div id="payment"></div>
    <button id="buy" onclick="submit()">Buy</button>
  </body>
</html>
```

<br/>

- #### Mount Checkout element
Upon loading your checkout page, promptly initiate a request to the endpoint on your server to generate a new Checkout.
The URL provided by your endpoint is utilized for rendering the embedded checkout element.
Create a CheckoutElement and mount it to the element `<div id="payment">` in your payment form.
This incorporates an iframe containing a dynamic form that showcases configured payment method types available from the Checkout, enabling your customer to choose a payment method.
The form autonomously gathers the relevant payment details for the chosen payment method type.
Create `main.js` file with code below in `./public` folder:


```javascript
let upgate;
const elementId = "payment";
async function mount() {
  const { url } = await fetch("/checkout", { method: "POST" }).then((res) =>
    res.json()
  );
  upgate.mountPaymentElement(elementId, url);
  upgate.onResult(elementId, console.log); // use this method for handle result
}
function submit() {
  upgate.submit(elementId);
}
window.onload = async () => {
  upgate = new Upgate();
  mount();
};
```

Invoke `submit('%elementId%')`, providing the CheckoutElement and a `success_url` to specify the destination where Upgate should redirect the user upon completing the payment.
For payments necessitating authentication, Upgate presents a modal for 3D Secure authentication or directs the customer to an authentication page, contingent on the payment method utilized.
Following the completion of the authentication process, the customer is redirected to the specified `success_url`.

- #### Handle response after submit
Pass callback parameter in `upgate.onResult` function for handle `TResult` type object.


```typescript
export type TResult = {
  success: boolean;
  url?: string;
  error_message?: string;
  error_code?: number;
  retry?: boolean;
};
```

All types of Upgate.js you can find in [index.d.ts](https://js.upgate.com/index.d.ts).

- If `success: true` - payment processed successful.
- If `success: false; retry: false` - payment was not processed, and form must be unmounted with `unmountPaymentElement('payment')`.
- If `retry: true; success: false` you can submit same form again (form not valid for example).
- If payment was failed user will be redirected to `failure_url` with query parameters `?error_code=&error_message=`


<br/>