> For the complete documentation index, see [llms.txt](https://docs.2checkout.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.2checkout.com/2checkout-apis/2checkout-apis/2pay.js-payments-solution-integration-guide/use-cases/basic-implementation-for-2pay.js-payments-solution.md).

# Basic Implementation for 2Pay.js Payments Solution

Set up the 2Pay.js drop-in payments client to accept payments on your website.

Collecting payments consists of creating a payment form, tokenizing sensitive card information, and using that token to create a charge.

## Use case

{% stepper %}
{% step %}

### Create the payment form

Create a payment form with id="payment-form":

```html
<form type="post" id="payment-form">
  <div class="form-group">
    <label for="name" class="label control-label">Name</label>
    <input type="text" id="name" class="field form-control">
  </div>
  <button class="btn btn-primary" type="submit">Generate token</button>
</form>
```

{% endstep %}

{% step %}

### Add the card element

Inside the form add an element with id="card-element". The form should now look like this:

```html
<form type="post" id="payment-form">
  <div class="form-group">
    <label for="name" class="label control-label">Name</label>
    <input type="text" id="name" class="field form-control">
  </div>

  <div id="card-element">
    <!-- A TCO IFRAME will be inserted here. -->
  </div>

  <button class="btn btn-primary" type="submit">Generate token</button>
</form>
```

{% endstep %}

{% step %}

### Include the 2Pay.js library

Include the 2Pay.js drop-in payment client JavaScript:

```html
<script type="text/javascript" src="https://2pay-js.2checkout.com/v1/2pay.js"></script>
```

{% hint style="warning" %}
To maintain reduced PCI scope, it is mandatory to always include the 2pay.js library hosted on 2Checkout’s servers. Do not use bundle libraries that contain 2pay.js or host a copy of the 2pay.js library from your own servers as this increases your PCI requirements.
{% endhint %}
{% endstep %}

{% step %}

### Add configuration JavaScript to create the card component and generate a token

Insert the following configuration JavaScript to add the card component and generate a token request:

```javascript
window.addEventListener('load', function() {
  // Initialize the JS Payments SDK client.
  let jsPaymentClient = new  TwoPayClient('YOUR_MERCHANT_CODE');
  
  // Create the component that will hold the card fields.
  let component = jsPaymentClient.components.create('card');
  
  // Mount the card fields component in the desired HTML tag. This is where the iframe will be located.
  component.mount('#card-element');
  
  // Optionally track the time that it took for the user to enter their name
  let nameFieldStartTime = null;
  let holderNameTime = 0;

  const nameField = document.querySelector('#name');

  nameField.addEventListener('focus', function () {
    nameFieldStartTime = new Date().getTime();
  });

  nameField.addEventListener('blur', function () {
    if (nameFieldStartTime) {
      const endTime = new Date().getTime();
      holderNameTime = ((endTime - nameFieldStartTime) / 1000).toFixed(2);
    }
  });

  // Handle form submission.
  document.getElementById('payment-form').addEventListener('submit', (event) => {
    event.preventDefault();
    
    // Extract the Name field value
    const billingDetails = {
      billing: {
      	name: document.querySelector('#name').value,
      	holderNameTime: holderNameTime || 0
      },
      scope: 'subscription' // accepted values: subscription, ordering
    };

    // Call the generate method using the component as the first parameter
    // and the billing details as the second one
    jsPaymentClient.tokens.generate(component, billingDetails).then((response) => {
      console.log(response); // {token: '9578f608-e96e-4667-be68-0ab42d4fd7f4', cardBrand: 'visa'}
      const token = response.token; //use it to place your order
      const cardBrand = response.cardBrand;  // informative data, you may use is anyway you want
    }).catch((error) => {
      console.error(error);
    });
  });
});
```

{% endstep %}

{% step %}

### Place the order using the generated token

Follow [this](/2checkout-apis/2checkout-apis/2pay.js-payments-solution-integration-guide/use-cases/place-orders-via-api-using-a-2pay.js-token.md) article to place orders via API using a 2Pay.js token.
{% endstep %}
{% endstepper %}

## Demo

After performing the steps above, your implementation should look like this.

{% embed url="<https://codepen.io/2checkout-connectors/pen/PwGYdZa>" %}

### HTML

```html
<div class="container">
  <div class="row justify-content-md-center mt-5">
    <div class="col-12">
      <div class="card">
        <div class="card-body">
          <h5 class="card-title">Basic implementation for the 2Pay.js client</h5>
            
          <form type="post" id="payment-form">
            <div class="form-group">
              <label for="name" class="label control-label">Name</label>
              <input type="text" id="name" class="field form-control">
            </div>

            <div id="card-element">
              <!-- A TCO IFRAME will be inserted here. -->
            </div>

            <button class="btn btn-primary" type="submit">Generate token</button>
          </form>
        </div>
      </div>
    </div>
  </div>
</div>
```

### JavaScript

```javascript
window.addEventListener("load", function () {
  // Initialize the 2Pay.js client.
  let jsPaymentClient = new TwoPayClient("AVLRNG");

  // Create the component that will hold the card fields.
  let component = jsPaymentClient.components.create("card");

  // Mount the card fields component in the desired HTML tag. This is where the iframe will be located.
  component.mount("#card-element");

  // Handle form submission.
  document
    .getElementById("payment-form")
    .addEventListener("submit", (event) => {
      event.preventDefault();

      // Extract the Name field value
      const billingDetails = {
        name: document.querySelector("#name").value
      };

      // Call the generate method using the component as the first parameter
      // and the billing details as the second one
      jsPaymentClient.tokens
        .generate(component, billingDetails)
        .then((response) => {
          console.log(response); // {token: '9578f608-e96e-4667-be68-0ab42d4fd7f4', cardBrand: 'visa'}
          const token = response.token; //use it to place your order
          const cardBrand = response.cardBrand; // informative data, you may use is anyway you want
        })
        .catch((error) => {
          console.error(error);
        });
    });
});
```


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.2checkout.com/2checkout-apis/2checkout-apis/2pay.js-payments-solution-integration-guide/use-cases/basic-implementation-for-2pay.js-payments-solution.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
