***

title: Save a customer's payment details
icon: money-check
intro: Use Hosted Fields to save a customer's payment details.
published: true
---------------------

For clean Markdown of any page, append .md to the page URL. For a complete documentation index, see https://docs.payroc.com/full-stack-guides/take-payments/hosted-fields/extend-your-integration/llms.txt. For full documentation content, see https://docs.payroc.com/full-stack-guides/take-payments/hosted-fields/extend-your-integration/llms-full.txt.

When you use Hosted Fields to capture a customer's payment details, we return a single-use token. You can use the single-use token only once, and it expires 30 minutes after we return it.

If you want to run a sale later or run multiple sales, you need to convert the single-use token into a secure token. You can use the secure token multiple times, and it doesn't expire.

## Before you begin

Make sure you have set up your integration to [run a sale](/guides/take-payments/hosted-fields/run-a-sale#run-a-sale-with-bank-account-details).

### Headers

To create the header of each POST request, you must include the following parameters:

* **Content-Type:** Include application/json as the value for this parameter.
* **Authorization:** Include your Bearer token in this parameter.
* **Idempotency-Key:** Include a UUID v4 to make the request idempotent.

```curl
-H "Content-Type: application/json"
-H "Authorization: <Bearer token>"
-H "Idempotency-Key: <UUID v4>"
```

### Errors

Make sure that your integration can handle errors. If a request is unsuccessful, we return an error that follows the [RFC 7807 format](https://www.rfc-editor.org/rfc/rfc7807). For more information about errors, go to [Errors](/api/errors).

## Integration steps

1. Update the JavaScript configuration
2. Convert the single-use token into a secure token.
3. (Optional) Run a sale with the secure token.

## Step 1. Update the JavaScript configuration

* In the JavaScript configuration, change the value for the mode parameter from payment to `tokenization`.

<CodeBlocks>
  ```js title="Card"
  <script
    src="https://cdn.uat.payroc.com/js/hosted-fields/hosted-fields-1.7.0.261457.js"
    integrity="sha384-m1A0nfFYa8sAfpDN0d60o4ztd/aCPC2xDVaOT31Urrmn4xypfHqgHQMayZeIK1PM"
    crossorigin="anonymous"
  ></script>

  <script>
    const cardForm = new Payroc.hostedFields({
      sessionToken: YOUR_SESSION_TOKEN,
      mode: "tokenization",
      fields: {
        card: {
          cardholderName: {
            target: ".card-holder-name",
            errorTarget: ".card-holder-name-error",
            placeholder: "Cardholder Name",
          },
          cardNumber: {
            target: ".card-number",
            errorTarget: ".card-number-error",
            placeholder: "1234 5678 1234 1211",
          },
          cvv: {
            wrapperTarget: ".card-cvv-wrapper",
            target: ".card-cvv",
            errorTarget: ".card-cvv-error",
            placeholder: "CVV",
          },
          expiryDate: {
            target: ".card-expiry",
            errorTarget: ".card-expiry-error",
            placeholder: "MM/YY",
          },
          submit: {
            target: ".submit-button",
            value: "Submit",
          },
        },
      },
    });
    padForm.initialize();
  </script>
  ```

  ```js title="ACH"
  <script
    src="https://cdn.uat.payroc.com/js/hosted-fields/hosted-fields-1.7.0.261457.js"
    integrity="sha384-m1A0nfFYa8sAfpDN0d60o4ztd/aCPC2xDVaOT31Urrmn4xypfHqgHQMayZeIK1PM"
    crossorigin="anonymous"
  ></script>

  <script>
    const achForm = new Payroc.hostedFields({
      sessionToken: YOUR_SESSION_TOKEN,
      mode: "tokenization",
      fields: {
        ach: {
          nameOnAccount: {
            target: ".ach-account-holder",
            errorTarget: ".ach-account-holder-error",
            placeholder: "Accountholder Name",
          },
          accountType: {
            target: ".ach-account-type",
            errorTarget: ".ach-account-type-error",
          },
          achAccountNumber: {
            target: ".ach-account-number",
            errorTarget: ".ach-account-number-error",
            placeholder: "Account Number",
          },
          routingNumber: {
            target: ".ach-routing-number",
            errorTarget: ".ach-routing-number-error",
            placeholder: "Routing Number",
          },
          submit: {
            target: ".submit-button",
            value: "Submit",
          },
        },
      },
    });
  </script>
  ```

  ```js title="PAD"
  <script
    src="https://cdn.uat.payroc.com/js/hosted-fields/hosted-fields-1.7.0.261457.js"
    integrity="sha384-m1A0nfFYa8sAfpDN0d60o4ztd/aCPC2xDVaOT31Urrmn4xypfHqgHQMayZeIK1PM"
    crossorigin="anonymous"
  ></script>

  <script>
    const padForm = new Payroc.hostedFields({
      sessionToken: YOUR_SESSION_TOKEN,
      mode: "tokenization",
      fields: {
        pad: {
          nameOnAccount: {
            target: ".pad-account-holder",
            errorTarget: ".pad-account-holder-error",
            placeholder: "Accountholder Name",
          },
          padAccountNumber: {
            target: ".pad-account-number",
            errorTarget: ".pad-account-number-error",
            placeholder: "Account Number",
          },
          institutionNumber: {
            target: ".pad-institution-number",
            errorTarget: ".pad-institution-number-error",
            placeholder: "Institution Number",
          },
          transitNumber: {
            target: ".pad-transit-number",
            errorTarget: ".pad-transit-number-error",
            placeholder: "Transit Number",
          },
          submit: {
            target: ".submit-button",
            value: "Submit",
          },
        },
      },
    });
  </script>
  ```
</CodeBlocks>

## Step 2. Convert the single-use token into a secure token

To convert the single-use token into a secure token, send a POST request to our Secure Tokens endpoint.

| Endpoint   | Prefix     | URL                                                                                                                                                                                  |
| :--------- | :--------- | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Test       | `api.uat.` | [https://api.uat.payroc.com/v1/processing-terminals/\{processingTerminalId}/secure-tokens](https://api.uat.payroc.com/v1/processing-terminals/\{processingTerminalId}/secure-tokens) |
| Production | `api.`     | [https://api.payroc.com/v1/processing-terminals/\{processingTerminalId}/secure-tokens](https://api.payroc.com/v1/processing-terminals/\{processingTerminalId}/secure-tokens)         |

### Request parameters

To create the body of your request, send the single-use token in the source object.

<Note>
  **Note:** If the single-use token represents card details, you also need to send a value for the mitAgreement parameter.
</Note>

<EndpointSchemaSnippet endpoint="POST /processing-terminals/{processingTerminalId}/secure-tokens" selector="request.body" />

### Example request

<EndpointRequestSnippet endpoint="POST /processing-terminals/{processingTerminalId}/secure-tokens" />

### Response fields

If your request is successful, our gateway converts the single-use token into a secure token. Our gateway returns the secure token in the token field. The response also contains the following fields:

<EndpointSchemaSnippet endpoint="POST /processing-terminals/{processingTerminalId}/secure-tokens" selector="response.body" />

### Response example

<EndpointResponseSnippet endpoint="POST /processing-terminals/{processingTerminalId}/secure-tokens" />

## Step 3. (Optional) Run a sale with the secure token

To run a sale with the secure token, the method that you need to follow depends on whether the secure token represents card details or bank account details.

Use the same methods that you used in [Run a Sale](/guides/take-payments/hosted-fields/run-a-sale#run-a-sale-with-bank-account-details), but update the following parameters in the paymentMethod object:

* **type** - Change the value to `secureToken`.
* **token** -  Include the secure token that you received in Step 2.