# Overview

Vaultera now offers a Vaultera PCI API - a solution to work with sensitive Credit Card information so you can outsource PCI DSS scope from your application to ours.

Vaultera PCI allow partners to exchange information about Credit Cards between any system both incoming and outgoing. Also, we support operations to show cards via iframe and collect by iframe.

This is a simple diagram of how Vaultera is in the middle of an API call (Proxy) and returns bookings in a PCI Compliant way.

<figure><img src="/files/Gzjfg38Kpnr3764gkPYO" alt=""><figcaption><p>Tokenization on Response</p></figcaption></figure>

<figure><img src="/files/kSq3RYdWNFGAVf5sao5N" alt=""><figcaption><p>Detokenization on Request</p></figcaption></figure>


# Registration & Authentication

### Registration

Access to Vaultera PCI is only available by demand. Please, contact us via <sales@vaultera.co> to get your account. We provide a free trial for any system.

If you are a developer and wish to test please get in touch, the process is simple. We cannot provide self signup since it is a sensitive service.

### Authentication

#### API Key Authentication

After registration, you will receive `Master API Key`, which you can use as sign for your requests to our API.

To sign request by API Key, you should pass it as a GET argument into your query:

```
GET https://pci.vaultera.co/api/v1/api_keys?api_key={YOUR_API_KEY}
```

{% hint style="warning" %}
**MASTER API KEY NOTE**

We strongly recommend that you don’t use the **Master API Key** for testing, development or production environments. Instead, you should generate a **Second API Key** (count is not limited) via our API Key methods and use that.

If your **Second API Key** will be compromised, you can revoke it and generate a new one.
{% endhint %}

#### Session Token Authentication

Embedded operations such as Show card iframe or Card capture iframe use a `Session Token` to handle authorization. `Session Token` is a one-off key to perform an operation at your account.

We use a `Session Token` with embedded operations to prevent any potentials leaks, because the Embedded operations key is visible to the end client.

Read more about Session Tokens here.


# API Key and Session Tokens

At this section we describe how to work with API Keys and Session Tokens API

## API Key

As we mentioned before, an API Key is an authentication sign method which should be used to make requests to the Vaulera PCI API endpoints.

{% hint style="warning" %}
You should protect your API Keys to prevent leaks. Don’t store API Keys in your Source Code and limit the count of people who have access to the API Keys.
{% endhint %}

### API Key Structure

API Key is represented with the next fields:

`id` unique identifier based at UUID v.4\
`api_key` API Key value (Masked)\
`description` String field with custom human readable notes about API Key if provided (Can be used to show where this key is used)\
`status` Enumerable field with 2 possible values (active, revoked). If key is active you can use it to perform operations.\
`created_at` Timestamp, when API Key was created.\
`revoked_at` Timestamp, when API Key was revoked.

### Get list of API Keys

Method to get list of existing API Keys associated with the account.

{% tabs %}
{% tab title="Request" %}

```
GET https://pci.vaultera.co/api/v1/api_keys?api_key={YOUR_API_KEY}
```

{% endtab %}

{% tab title="Success Response" %}

```javascript
{
  "data": [
    {
      "id": "4cdced9e-31ef-4f36-ad9a-3c9512f5646e",
      "type": "api_key",
      "attributes": {
        "id": "4cdced9e-31ef-4f36-ad9a-3c9512f5646e",
        "api_key": "...4a39b3",
        "description": "Application key",
        "status": "active",
        "created_at": "2020-06-08T05:49:10.979Z",
        "revoked_at": null
      }
    }
  ]
}
```

{% endtab %}
{% endtabs %}

Method will return success result with code `200 OK` and list of `api_key` under data node.

### Create API Key

Method to create a new API Key.

{% tabs %}
{% tab title="Request" %}

```
POST https://pci.vaultera.co/api/v1/api_keys?api_key={YOUR_API_KEY}

{
  "api_key": {
    "description": "API KEY description"
  }
}
```

{% endtab %}

{% tab title="Success Response" %}

```javascript
{
  "data": {
    "id": "4cdced9e-31ef-4f36-ad9a-3c9512f5646e",
    "type": "api_key",
    "attributes": {
      "id": "4cdced9e-31ef-4f36-ad9a-3c9512f5646e",
      "api_key": "4cdced9e31ef4f36ad9a4a39b3",
      "description": "Application key",
      "status": "active",
      "created_at": "2020-06-08T05:49:10.979Z",
      "revoked_at": null
    }
  }
}
```

{% endtab %}
{% endtabs %}

Method will return success result with code `200 OK`. Response will contain `api_key` structure.

{% hint style="warning" %}
API Key will be visible only at this response, all other methods will not show the API Key again. The API Key will be automatically generated and show once only.
{% endhint %}

### Get API Key by ID

Method to get information about the API Key by ID.

{% tabs %}
{% tab title="Request" %}

```
GET https://pci.vaultera.co/api/v1/api_keys/{id}?api_key={YOUR_API_KEY}
```

{% endtab %}

{% tab title="Success Response" %}

```javascript
{
  "data": {
    "id": "4cdced9e-31ef-4f36-ad9a-3c9512f5646e",
    "type": "api_key",
    "attributes": {
      "id": "4cdced9e-31ef-4f36-ad9a-3c9512f5646e",
      "api_key": "...4a39b3",
      "description": "Application key",
      "status": "active",
      "created_at": "2020-06-08T05:49:10.979Z",
      "revoked_at": null
    }
  }
}
```

{% endtab %}
{% endtabs %}

Method will return success result with code `200 OK`. Response will contain `api_key` structure.

### Revoke API Key

Method to revoke API Key. After this action, each request signed by a revoked key will fail and return an Authorization error.

{% tabs %}
{% tab title="Request" %}

```
DELETE https://pci.vaultera.co/api/v1/api_keys/{id}?api_key={YOUR_API_KEY}
```

{% endtab %}

{% tab title="Success Response" %}

```javascript
Status: 204 No Content
```

{% endtab %}
{% endtabs %}

Method will return success result with code `204 No Content`. Response will contain `api_key` structure.

## Session Token operations

Embedded operations at Vaultera PCI will expect to receive a `Session Token` as an authorization sign. To generate a `Session Token`, you can use the next method:

{% tabs %}
{% tab title="Request" %}

```
POST https://pci.vaultera.co/api/v1/session_tokens?api_key={YOUR_API_KEY}

{
  "session_token": {
    "scope": "show_card"
  }
}
```

{% endtab %}

{% tab title="Response" %}

```javascript
{
  "data": {
    "id": "string",
    "type": "session_token",
    "attributes": {
      "session_token": "string",
      "scope": "show_card"
    }
  }
}
```

{% endtab %}
{% endtabs %}

Please, take a look at the scope argument, it represents how you can use the created `Session Token`. The scope allows 3 values: `card`, `show_card` and `show_service_code`.

If `Session Token` is created with scope `card` you can use it to capture card information.

If `Session Token` is created with scope `show_card` you can use it to get the card information, but does not include the `Service Code` for this card.

If `Session Token` is created with scope `show_service_code` you will only see the `Service Code` and not the card details.


# Card API

Methods to control cards

## Capture Cards operations

### Capture Card from 3rd party API

This method can be used to send a request to a 3rd party service (eg. OTA or CM) and extract the credit card information from the response (e.g. Booking with card details inside).

{% tabs %}
{% tab title="Request" %}

```
POST https://pci.vaultera.co/api/v1/capture?api_key={YOUR_API_KEY}&method={HTTP_METHOD}&url={TARGET_URL}&profile={TOKENIZATION_PROFILE}
```

{% endtab %}
{% endtabs %}

**Arguments**

| Argument  | Description                                                                                                       |
| --------- | ----------------------------------------------------------------------------------------------------------------- |
| `method`  | HTTP Method to send request to target endpoint. One of: `get`, `post`, `put`, `delete`, `patch` `head`, `options` |
| `url`     | Encoded URL of Target Endpoint, should use `https` protocol                                                       |
| `profile` | Tokenization profile what should be applied to extract Credit Card data from Response                             |

Any provided Headers or Content Body will be provided to Target endpoint without any changes.

Method will return answer from Target Endpoint. Credit Card data will be masked based at Tokenization Profile settings.

Credit card token can be returned at Header X-PCI-VAULTERA-TOKENS or inside specific node at response body.

Please, read more about Tokenization Profiles.

### Capture Card Form

To get Credit Card information from your Guests, you can use Capture Card Embedded Form.

This method return HTML Page what you can embed into your application to collect Card information from clients.

{% tabs %}
{% tab title="Request" %}

```
GET https://pci.vaultera.co/api/v1/capture_form?session_token={SESSION_TOKEN}
```

{% endtab %}
{% endtabs %}

To generate the Card Capture Form you should generate a Session Token with scope `card`.

You can find out more information about Capture Card Form here.

### Save Card at Storage

Sometimes you would like to save a Card directly with Vaultera PCI. To do that, you can use this method.

{% tabs %}
{% tab title="Request" %}

```
POST https://pci.vaultera.co/api/v1/cards?api_key={YOUR_API_KEY}

{
  "card": {
    "card_number": "4111111111111111",
    "card_type": "visa",
    "cardholder_name": "JOHN DOE",
    "service_code": "123",
    "expiration_month": "12",
    "expiration_year": "2021"
  }
}
```

{% endtab %}

{% tab title="Success Response" %}

```javascript
{
  "data": {
    "id": "2f97cef45086488fa823ba3c014a3bc1",
    "type": "card",
    "attributes": {
      "card_number": "411111******1111",
      "card_type": "visa",
      "cardholder_name": "JHON DOE",
      "service_code": "***",
      "expiration_month": "12",
      "expiration_year": "2021",
      "card_token": "2f97cef45086488fa823ba3c014a3bc1"
    }
  }
}
```

{% endtab %}
{% endtabs %}

Method will return success response with code `200 OK`. Response will contain `credit card` info with masked fields and `card_token` which can be used for another operations with cards.

{% hint style="info" %}
This is useful if you wish to move cards from another PCI Service to Vaultera.
{% endhint %}

## Card operations

### Send Card

To send card to a 3rd party service (e.g. Payment Gateway), you can use the the Send Card method:

{% tabs %}
{% tab title="Request" %}

```
POST https://pci.vaultera.co/api/v1/cards/{card_token}/send?api_key={YOUR_API_KEY}&method={HTTP_METHOD}&url={TARGET_ENDPOINT}

{
  "card": {
    "card_number": "%CARD_NUMBER%",
    "cardholder_name": "%CARDHOLDER_NAME%",
    "service_code": "%SERVICE_CODE%",
    "expiration_month": "%EXPIRATION_MM%",
    "expiration_year": "%EXPIRATION_YYYY%"
  }
}
```

{% endtab %}

{% tab title="Send card to Stripe" %}

```
POST https://pci.vaultera.io/api/v1/cards/<card_token>/send?api_key=<api_key>&method=post&url=https%3A%2F%2Fapi.stripe.com%2Fv1%2Fpayment_methods

HEADERS
Authorization: Basic encode_base64("sk_stripe_key:<stripe_key>")
Content-Type: application/x-www-form-urlencoded

BODY
type=card&card[number]=%CARD_NUMBER%&card[exp_month]=%EXPIRATION_MM%&card[exp_year]=%EXPIRATION_YYYY%&card[cvc]=%SERVICE_CODE%
```

{% endtab %}
{% endtabs %}

**Arguments**

| **Argument** | **Descriotion**                                                                                                    |
| ------------ | ------------------------------------------------------------------------------------------------------------------ |
| `card_token` | Credit Card token at Vaultera                                                                                      |
| `method`     | HTTP Method to send request to target endpoint. One of: `get`, `post`, `put`, `delete`, `patch`, `head`, `options` |
| `url`        | Encoded URL of Target Endpoint, should use `https` protocol                                                        |

Query Body is optional and depends to Target Endpoint API. Basically, it should contain structure expected by Target Endpoint. To insert real card data into request you can use Drop Ins.

Method with return response from Target Endpoint.

### Authorize Card

By PCI DSS rules, we should remove Service Code immediately after the card is Authorized. Some operations at our API call this action automatically. But, because you can catch some problems with Send Card method (3rd party service provide error response), we do not remove Service Code automatically after using the Send Card Method. If your application successfully sent the card info to the 3rd party service, please call Authorize Card method.

{% hint style="info" %}
Please use this method to remove the service code once you have **successfully** sent the card to the payment gateway. This is an important part of PCI-DSS.
{% endhint %}

{% tabs %}
{% tab title="Request" %}

```
POST https://pci.vaultera.co/api/v1/cards/{card_token}/auth?api_key={YOUR_API_KEY}
```

{% endtab %}

{% tab title="Success Response" %}

```javascript
Status: 204 No Content
```

{% endtab %}
{% endtabs %}

### Remove Card from Storage

If card is not longer required for your business processes, you should remove it from storage by calling this method:

{% tabs %}
{% tab title="Request" %}

```
DELETE https://pci.vaultera.co/api/v1/cards/{card_token}?api_key={YOUR_API_KEY}
```

{% endtab %}

{% tab title="Success Response" %}

```javascript
Status: 204 No Content
```

{% endtab %}
{% endtabs %}

### Show Card Form

To implement the ability to Show Card at your application you can use method Show Card. This method will return HTML Page with credit card information that you can insert into your application.

```
GET https://pci.vaultera.co/api/v1/show_card?card_token={CARD_TOKEN}&session_token={SESSION_TOKEN}&service_code_token={SERVICE_CODE_TOKEN}
```

**Arguments**

| Argument             | Description                                                                    |
| -------------------- | ------------------------------------------------------------------------------ |
| `card_token`         | Card token at Vaultera.PCI                                                     |
| `session_token`      | One-off Session token with scope `show_card`                                   |
| `service_code_token` | One-off Session token with scope `show_service_code` to show Card Service Code |

By default, Vaultera PCI will return a HTML page where user can see Card Number, Expiration Date, Card Type and Cardholder Name, but Service Code (CVV, CVC) will be hidden. To be able to see Service code, you should provide the service\_code\_token which will be used to request Service Code.

Service Code will be hidden by a button, by clicking this button the user will load Service Code and it will be immediately removed from Storage.

{% hint style="info" %}
Our iframe to show card information makes the user click to see the service code (CVV/CVC). This is helpful because once it is viewed it must be deleted.
{% endhint %}


# Card Capture IFrame API

JavaScript API to work with Card Capture IFrame

To initiate the Card Capture IFrame, please insert the IFrame tag into your target page.

```markup
<iframe
  id="cardCaptureIframe"
  height="300"
  scrolling="no"
  style="border: 0;"
  src="{{cardCaptureIframeUrl}}">
</iframe>
```

Where `cardCaptureIframeUrl` is valid Card Capture URL.

## IFrame communication

To communicate with the IFrame to submit form or get results you should use [postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) browser API.

### Submit Form

To submit Card Capture form you should trigger `submit` event.

```javascript
const cardCaptureIframe = document.getElementById("cardCaptureIframe");
cardCaptureIframe.contentWindow.postMessage("submit", "https://pci.vaultera.co");
```

### Validate Form

To Validate Card Capture form you should trigger `validate` event.

{% hint style="info" %}
This validation method can be used to get validity from state from your js code. With this you can build workflows on your side based on this information. For example, you can prevent form submission if the card in the iframe is not valid.

This validation also triggers on submit event and does the same validations as you can see in real time. So, if you don't have any external logic which is based on card form validity state you can just use the "submit" method.
{% endhint %}

```javascript
const cardCaptureIframe = document.getElementById("cardCaptureIframe");
cardCaptureIframe.contentWindow.postMessage("validate", "https://pci.vaultera.co");
```

### Handle response

To handle responses from Card Capture Form you should create `listener` function.

```javascript
const PCI_PROXY_DOMAIN = "https://pci.vaultera.co";
const listener = (event) => {
  if (event.origin !== PCI_PROXY_DOMAIN) {
    return;
  }
  if (event.data.valid) {
    console.log("card valid: ", event.data.valid);
  }
  if (event.data.success) {
    console.log(event.data);
  }
}

window.addEventListener("message", listener);
```

#### Validate response

```javascript
{
  "event_type": "validate",
  "valid": true|false
}
```

#### Submit response

```javascript
{
  "event_type": "submit",
  "success": true,
  "card": {
    "card_number": "411111******1111",
    "card_token": "<token>",
    "cardholder_name": "JHON DOE",
    "expiration_month": "11",
    "expiration_year": "2023",
    "service_code": "***",
    "card_type": "visa"
  }
}
```

## IFrame configuration

### Accepted card types

Param: `only|except`

Value: *list of card types*

Default: *none*

You can pass additional query param for card capture iframe and configure which cards you accept. This can be done in two ways.

1. You can set a list of cards you accept and only these cards would be allowed to be created from an iframe.&#x20;
2. You can provide a list of cards you want to exclude, for example American Express.&#x20;

To configure the list of card types you want to accept you should provide a `only` query param with a list of card types.

Example to accept only visa and mastercard:

```
https://pci.vaultera.co/api/v1/capture_form?session_token=<SESSION_TOKEN>&only=visa,mastercard
```

To accept all cards except some specific type you should provide `except` query params with list of card types.

Example to exclude American Express:

```
https://pci.vaultera.co/api/v1/capture_form?session_token=<SESSION_TOKEN>&except=american-express
```

List of card types:

* visa
* mastercard
* american-express
* money-club
* discover
* jcb
* unionpay
* maestro
* link
* me
* hyper
* hypercard

So if you want just to accept all cards except American Express you need to modify your card capture iframe url to something like this

```
https://pci.vaultera.co/api/v1/capture_form?session_token=<SESSION_TOKEN>&except=american-express
```

### Custom styles

Param: `style`

Value: style name

Default: *none*

Card capture iframe can be customized with your own css to match your needed look and feel. To load additional css styles you need to provide `style` query param with styles name. These styles can be added to your account by contacting support.

### Language

Param: `lang`

Value: en|ru

Default: en

To change language of your capture form `lang` query param needed to be specified.

Supported languages:

* de
* en
* el
* es
* is
* it
* pt
* ru

Any additional language can be added by contacting support.

### Service Code

#### Optional

Param: `service_code_optional`

Value: true|false

Default: false

Make service code optional and not require.

#### Hidden

Param: `service_code_visible`

Value: true|false

Default: true

Make service code not visible.


# Show Card IFrame API

JavaScript API to work with the Card Show Iframe

To show cards in a PCI safe way you can use the Show Card method. This method will return a HTML Page with credit card information that you can show to your end users.

No sensitive data will touch your servers and you will remain out of scope.

{% hint style="danger" %}
Requirements to use Iframe

* Generated iframe link should be passed to the user so iframe would be loaded on the client side; it's not allowed to view them on server-side for any purposes (like printing or scraping)
* 2fa for login into the system or 2fa for viewing the card should be implemented; User password retyping does not qualify as 2fa.
* All view requests should be logged on your side so you will know which user is trying to view the card. Ideally you need Username, timestamp, card viewed, IP address, location of IP.
* We will disable view\_card functionality on your account if our monitoring system detects suspicious activities on your account until further investigation.
  {% endhint %}

```
GET https://pci.vaultera.co/api/v1/show_card?card_token={CARD_TOKEN}&session_token={SESSION_TOKEN}&service_code_token={SERVICE_CODE_TOKEN}
```

**Arguments**

| Argument             | Description                                                                    |
| -------------------- | ------------------------------------------------------------------------------ |
| `card_token`         | Card token at Vaultera.PCI                                                     |
| `session_token`      | One-off Session token with scope `show_card`                                   |
| `service_code_token` | One-off Session token with scope `show_service_code` to show Card Service Code |
| `lang` (optional)    | Override default language                                                      |
| `style` (optional)   | Additional custom CSS styles                                                   |

Vaultera PCI will return a HTML page where the user can see the

* Card Number
* Expiration Date
* Card Type
* Cardholder Name
* Service Code (CVV, CVC) Button

To be able to see Service code (CVV), you should provide the service\_code\_token which will be used to request Service Code.

Service Code will be hidden by a button, by clicking this button the user will load Service Code and it will be immediately removed from Storage.

{% hint style="info" %}
Our iframe to show card information makes the user click to see the service code (CVV/CVC). This is helpful because once it is viewed it must be deleted.
{% endhint %}

## Customization

### Language

Supported languages: de, en, el, es, is, it, pt, ru.

If you need custom language please contact support.

### Styles

Card show iframe can be customized with your own CSS to match your needed look and feel. Custom styles can be added to your account by contacting support.


# Profile List

List of already created profiles you can use to get started quickly

{% hint style="warning" %}
If the profile you are looking for is not listed please get in touch so we can create for you.
{% endhint %}

## Understanding Profiles

**Profiles are blueprints for credit card handling:** Each Vaultera profile defines how to tokenize or detokenize credit card details for a specific booking engine or data source. It outlines where the card information is located in the booking data and how to replace it with a secure token (during tokenization) or reinsert the real card data (during detokenization).

**Using a profile token when fetching bookings:** When you retrieve bookings via Vaultera, you must specify which profile to use for credit card handling. In your API request, include the profile’s token name (for example, `profile=site_minder` or `profile=booking_com_body`). This tells Vaultera which blueprint to apply, ensuring credit card numbers are properly tokenized (or detokenized) in the returned data.

**Profile List page is informational only:** The list below shows all pre-created profiles and their token names for reference. This page is for informational purposes – it is **not** an interface for direct interaction (editing or selecting profiles). If you need a new profile that isn’t listed, please get in touch with us to have it created.

## Header or Body

Vaultera PCI can provide the token in the header or in the body of the booking. You will need to select the correct profile depending which is your preference.

## Request New Profiles

Please email us if you need a new profile created. We need the full response (XML or Json) examples with one and/or with multiple bookings.

## Created Profiles

We have profiles for these services already created, please use in your request

<table data-header-hidden><thead><tr><th width="176.33333333333331">Company</th><th>Token Name (Header)</th><th>Token Name (Body)</th></tr></thead><tbody><tr><td>Company</td><td>Token Name (Header)</td><td>Token Name (Body)</td></tr><tr><td>My Allocator</td><td></td><td>myallocator</td></tr><tr><td>Siteminder</td><td>site_minder</td><td>site_minder_body</td></tr><tr><td>Vertical Booking</td><td>vertical_booking</td><td></td></tr><tr><td>Wubook</td><td>wubook</td><td>wubook_body</td></tr><tr><td>Booking.com</td><td>booking_com</td><td>booking_com_body</td></tr><tr><td>Expedia</td><td>expedia</td><td>expedia_body</td></tr><tr><td>Hostel World</td><td>hostelworld_xml, hostelworld_json</td><td>hostelworld_xml_body</td></tr><tr><td>Agoda</td><td>agoda</td><td>agoda_body</td></tr><tr><td>Yieldplanet</td><td>yieldplanet</td><td></td></tr><tr><td>Staah</td><td>staah</td><td></td></tr><tr><td>Channex</td><td></td><td>channex, channex_entity</td></tr><tr><td>Ctrip</td><td></td><td>ctrip</td></tr><tr><td>Despegar</td><td></td><td>despegar</td></tr><tr><td>Dorms</td><td></td><td>dorms</td></tr><tr><td>Hotelbeds</td><td>hotelbeds</td><td></td></tr><tr><td>Hotetec</td><td>hotetec</td><td></td></tr><tr><td>Inntopia</td><td>inntopia</td><td></td></tr><tr><td>Nextpax</td><td>nextpax</td><td></td></tr><tr><td>Cubilis</td><td>cubilis</td><td></td></tr></tbody></table>


# Tokenisation Profile

How to manage profiles to work with incoming cards

A Tokenisation Profile is a setting to represent how to exclude information from a 3rd party service message.&#x20;

{% hint style="danger" %}
Please ask us to create profiles for you (No Charge), we have working profiles and can make new profiles easily.
{% endhint %}

### Tokenisation Profile structure

```javascript
{
  "id": "441928a5-6cf6-4735-ae95-8b1a27178d1c",
  "type": "tokenization_profile",
  "attributes": {
    "id": "441928a5-6cf6-4735-ae95-8b1a27178d1c",
    "name": "sample",
    "profile": {
      "type": "json",
      "schema": {
        "message_node": {
          "selector": "$.data"
        },
        "card_node": {
          "selector": "attributes.guarantee"
        }
      },
      "card_token_placement": {
        "type": "card_node",
        "card_token_node": "token",
        "error_node": "error",
      },
      "card_node": {
        "card_number": {
          "selector": "card_number"
        },
        "cardholder_name": {
          "selector": "cardholder_name"
        },
        "expiration_month": {
          "selector": "expiration_date",
          "transformation": "substring:0,2"
        },
        "expiration_year": {
          "selector": "expiration_date",
          "transformation": "substring:3,6"
        },
        "service_code": {
          "selector": "cvv"
        }
      }
    },
    "created_at": "2020-06-08T05:49:10.979Z",
    "updated_at": "2020-06-08T05:49:10.979Z"
  }
}
```

| Field        | Description                                |
| ------------ | ------------------------------------------ |
| `id`         | Unique identifier based at UUID v4         |
| `name`       | Tokenisation profile name, URL-safe string |
| `profile`    | Tokenisation profile structure             |
| `created_at` | timestamp when profile was created         |
| `updated_at` | timestamp when profile was updated         |

#### **Profile**

| **Field**              | Description                                              |
| ---------------------- | -------------------------------------------------------- |
| `type`                 | type of incoming content (JSON or XML)                   |
| `schema`               | information about message\_node and card\_node placement |
| `card_token_placement` | information about card\_token destination                |
| `card_node`            | information about card information nodes                 |

#### **Schema**

| Field          | Description                                                                                                 |
| -------------- | ----------------------------------------------------------------------------------------------------------- |
| `message_node` | JSON object with selector field with JSONPath or XPath to booking message node at 3rd party service message |
| `card_node`    | JSON object with selector field with relative JSONPath or XPath to credit card node                         |

#### **Card Token Placement**

| Field  | Description                                                                                           |
| ------ | ----------------------------------------------------------------------------------------------------- |
| `type` | One of possible values: card\_node, headers                                                           |
| `node` | required field if type is card\_node, XPath or JSONPath to node, where card\_token should be inserted |

If you choose `card_node`, `card_token` will be inserted into message structure. If `headers` chosen, card\_token will be return at `X-PCI-VAULTERA-TOKENS` Header. If message contain several bookings, we will return several card\_tokens. If one of messages does not have credit card info, it will be represent as an empty string at Headers.

#### Card Node

| Field              | Description                                                      |
| ------------------ | ---------------------------------------------------------------- |
| `card_number`      | JSON object with selector for Card Number                        |
| `cardholder_name`  | JSON object with selector for Cardholder name                    |
| `expiration_month` | JSON object with selector for Expiration Month                   |
| `expiration_year`  | JSON object with selector for Expiration Year                    |
| `service_code`     | <p>JSON object with selector for Service Code (CVV, CVC)<br></p> |

Each selector can contain field selector with JSONPath or XPath, and field transformation to modify the excluded value.

Please, keep in mind, our Tokenisation Profiles are based at XPath or JSONPath functionality.


# Detokenisation Profile

How to send card details to 3rd party services safely

## Detokenisation Profiles

Same as a Tokenisation Profiles a Detokenisation Profile is used to extract Credit Card info from messages coming from 3rd party service into your application, Detokenisation Profiles describe how to insert real Credit Card data back into your messages that are going to 3rd party services.

{% hint style="info" %}
You will typically use detokenisation to send the card details to a payment gateway.
{% endhint %}

Detokenisation Profiles are used with the secure domain feature. Usually you will have one Detokenization profile per application.

**Detokenization Profile Structure**

```
{
  "id": "441928a5-6cf6-4735-ae95-8b1a27178d1c",
  "type": "detokenization_profile",
  "attributes": {
    "id": "441928a5-6cf6-4735-ae95-8b1a27178d1c",
    "name": "sample",
    "profile": {
      "type": "json",
      "schema": {
        "message_node": "$.data",
        "card_node": "attributes.guarantee",
        "card_token_node": "token"
      },
      "target_card_node": "card_node",
      "card_node": {
        "card_number": "%CARD_NUMBER%",
        "cardholder_name": "%CARDHOLDER_NAME%",
        "expiration_month": "%EXPIRATION_MM%",
        "expiration_year": "%EXPIRATION_YYYY%",
        "cvv": "%SERVICE_CODE%"
      },
    },
    "created_at": "2020-06-08T05:49:10.979Z",
    "updated_at": "2020-06-08T05:49:10.979Z"
  }
}
```

`id` - unique identifier based at UUID v4\
`name` - URL-safe profile name\
`type` - type of message content (JSON or XML)\
`schema` - information where to find card token\
`target_card_node` - relative selector to insert card information\
`card_node` - card node structure description with Drop Ins


# Drop In's

These are used to insert sensitive information in your outgoing messages.

## Drop Ins

Vaultera PCI support the following drop ins:

{% hint style="info" %}
These are used when you want to send your tokenised card details to another service like a payment gateway. Since you don't have the card number and associated details in your application.
{% endhint %}

**Drop in**

| **Description**    | ​Title                                |
| ------------------ | ------------------------------------- |
| %CARD\_NUMBER%     | Card number                           |
| %CARDHOLDER\_NAME% | Cardholder name                       |
| %SERVICE\_CODE%    | Sevice Code (CVV / CVC)               |
| %EXPIRATION\_MM%   | Expiration month with leading zero    |
| %EXPIRATION\_YYYY% | Expiration year in full format (YYYY) |
| %EXPIRATION\_YY%   | Expiration year in short format (YY)  |
| %CARD\_TYPE%       | Card Type                             |


# Custom Secure URL Endpoint

If you have 3rd parties send card details into your system directly

Some OTA and Channel Managers may push bookings directly into your system including the card numbers.

To support this you will need to setup a custom CNAME like secure.yourpms.com and point it to the Vaultera PCI service servers.

If you require the secure endpoint please get in touch

There is no API required for this just a setup process and tokenization profiles.


# Account usage

Account information

## Usage

### Get account usage for a specific date

This method can be used to retrieve your account usage for a specific date. Must be a date in the past.

{% tabs %}
{% tab title="Request" %}

```
GET https://pci.vaultera.co/api/v1/account/usage/{date}?api_key={YOUR_API_KEY}
```

{% endtab %}

{% tab title="Response" %}

```
{
  "data": [
    {
      "type": "usage",
      "attributes": {
        "type": "tokenizations",
        "value": 123
      }
    },
    {
      "type": "usage",
      "attributes": {
        "type": "detokenizations",
        "value": 321
      }
    },
    {
      "type": "usage",
      "attributes": {
        "type": "storage",
        "value": 10
      }
    }
  ]
}
```

{% endtab %}
{% endtabs %}

**Arguments**

| Argument | Description                                                     |
| -------- | --------------------------------------------------------------- |
| `date`   | Date in yyyy-MM-dd format, should be in the past, ex 2021-08-31 |

### Returns

**Success**\
Method can return a Success result with `200 OK` HTTP Code if operation is successful. Will contain a list of usage in the answer.

* ```
  tokenizations (How many cards tokenised on that day)
  ```
* ```
  detokenizations (How many detokenisations on that day)
  ```
* ```
  storage (How many cards stored older than 24 Months)
  ```

\
\
**Unauthorised Error**\
Method can return a Unauthorised Error result with `401 Unauthorized` HTTP Code if wrong Bearer Token provided.&#x20;


# FAQ

Commonly asked questions about Vaultera PCI

## Outgoing IP Address

If you need to add our IP address to a whitelist:

* 63.32.246.136
* 52.212.96.216

## Can this work with any solution?

Yes, any application can work with Vaultera PCI but there will be some developer time required to change your processes.

## What payment gateways do you support?

Vaultera PCI supports sending cards to any PCI Compliant endpoint, most often this is a payment gateway but it could be another system such as a channel manager or PMS.

## The tokenization fee includes cards with CVV/CVC?

Yes our card tokenization fee for a card includes the card and the CVV/CVC. We don't charge extra fees for this.

## Can users view the card and CVV?

Yes, we provide an iframe so your users can view the card and the CVV/CVC. Viewing CVV/CVC is only allowed 1 time as per PCI-DSS rules.

## Are there extra fees to view cards?

No, all transaction with the tokenised card is included in the fee

## Can we have an API key to test?

Yes, please contact us and we can provide an API key for a free trial

## Can we customize the card view iframe for our brand?

Yes, custom css can be provided to style the view of the iframe. We have to check it meets PCI standards. Usually its only simple changes such as colours and no external resources.


# Examples

Here you can find some examples of how to use Vaultera PCI services.

## Sending a Card to Stripe via Vaultera Detokenization (Drop-Ins)

To securely charge a credit card with Stripe using Vaultera, you will use Vaultera's **detokenization** process with **Drop-In** placeholders. The high-level steps are:

1. **Tokenize (store) the credit card with Vaultera** – obtain a `card_token` for the card.
2. **Detokenize (send) the card to Stripe** – use Vaultera's `Send Card` API with Drop-In placeholders to forward the card data to Stripe's API.
3. *(Optional)* **Authorize (wipe CVV)** – after a successful charge or PaymentMethod creation, instruct Vaultera to remove the CVV from storage (per PCI DSS requirements).

Below we detail each step, with examples in cURL and Node.js.

### 1. Store/Tokenize the Credit Card in Vaultera

First, store the customer's credit card in Vaultera’s PCI vault to get a secure token. You can do this either via Vaultera’s hosted **Card Capture IFrame** or by making a direct API call. For example, a direct API request to store a card might look like:

```bash
POST https://pci.vaultera.co/api/v1/cards?api_key=<VAULTERA_API_KEY>
Content-Type: application/json

{
  "card": {
    "card_number": "4111111111111111",
    "card_type": "visa",
    "cardholder_name": "JOHN DOE",
    "service_code": "123",
    "expiration_month": "12",
    "expiration_year": "2021"
  }
}
```

This returns a JSON response containing a unique `card_token` for the stored card. For example, the response includes a token like `"card_token": "2f97cef45086488fa823ba3c014a3bc1"` (along with masked card details) This `card_token` will represent the card in all future operations.

{% hint style="info" %}
*Note:* Instead of direct API calls, you can also use Vaultera’s front-end IFrame to capture card details securely. In either case, you end up with a `card_token` that references the stored card.
{% endhint %}

### 2. Detokenize and Send Card Data to Stripe (Drop-Ins)

Once you have a `card_token`, you can instruct Vaultera to **detokenize** the card and forward the data to Stripe. Vaultera uses **Drop-In placeholders** to insert sensitive card information into outgoing requests. These placeholders act as markers in your request body that Vaultera will replace with the actual card data during the detokenization process. The supported Drop-Ins include: `%CARD_NUMBER%` (card PAN), `%CARDHOLDER_NAME%`, `%SERVICE_CODE%` (CVV), `%EXPIRATION_MM%` (2-digit month), `%EXPIRATION_YYYY%` (4-digit year), `%EXPIRATION_YY%` (2-digit year), and `%CARD_TYPE%`.

**How it works:** You call Vaultera’s **Send Card** endpoint, specifying the target Stripe API URL and HTTP method, and include a request body with card fields set to the Drop-In placeholders. Vaultera will retrieve the actual card details from its vault and substitute those `%PLACEHOLDERS%` with the real data, then forward the request to Stripe on your behalf. This way, your system never handles raw card numbers, yet Stripe receives the necessary card info.

#### Example using cURL

Below is a cURL example that uses Vaultera to create a Stripe PaymentMethod (type: card) using a stored card token:

```shell
curl -X POST "https://pci.vaultera.co/api/v1/cards/<CARD_TOKEN>/send?api_key=<VAULTERA_API_KEY>&method=post&url=https%3A%2F%2Fapi.stripe.com%2Fv1%2Fpayment_methods" \
     -H "Content-Type: application/json" \
     -H "Authorization: Basic <BASE64_ENCODED_STRIPE_SECRET:>" \
     -d '{
           "card": {
             "card_number": "%CARD_NUMBER%",
             "cardholder_name": "%CARDHOLDER_NAME%",
             "service_code": "%SERVICE_CODE%",
             "expiration_month": "%EXPIRATION_MM%",
             "expiration_year": "%EXPIRATION_YYYY%"
           }
         }'
```

Let's break down this request:

* **Endpoint:** We call Vaultera’s `POST /api/v1/cards/{card_token}/send` endpoint, including our Vaultera `api_key` in the query params. We also specify `method=post` and the `url` of the Stripe API (URL-encoded). In this case, the target is Stripe’s `https://api.stripe.com/v1/payment_methods` endpoint (encoded as `url=https%3A%2F%2Fapi.stripe.com%2Fv1%2Fpayment_methods`).
* **Headers:** We set `Content-Type: application/json` for Vaultera to accept our JSON body. **Importantly,** we include an `Authorization` header with Stripe credentials: `Basic <encoded_secret_key>`. This is the Stripe **Secret Key** (e.g. `sk_live_...` or `sk_test_...`) base64-encoded with an empty password (the usual Stripe Basic Auth format). Vaultera will forward this Authorization header to Stripe unchanged, allowing the request to authenticate with Stripe.
* **Body:** The JSON body contains a `"card"` object with all the required Stripe card fields, but instead of actual numbers we use the Drop-In placeholders. For example, `"card_number": "%CARD_NUMBER%"` and `"service_code": "%SERVICE_CODE%"`. When Vaultera receives this, it knows to replace those tokens with the real card number, CVV, etc., from the vault before sending to Stripe. The resulting forwarded request that Stripe sees will have the actual card data (e.g. `card[number]=4242424242424242`, `card[cvc]=123`, etc.).

Vaultera will execute this request to Stripe and return Stripe’s response back to you. In this example, Stripe would return the newly created PaymentMethod object if the call is successful.

### 3. Post-Transaction: Authorize (Remove CVV) and Cleanup

After you successfully send the card to Stripe (e.g. Stripe created a PaymentMethod or processed a charge), it is recommended to call Vaultera’s **Authorize Card** endpoint to remove the sensitive CVV from storage. By PCI DSS rules, the CVV (service code) should not be stored after authorization. You can do this with:

```sh
POST https://pci.vaultera.co/api/v1/cards/<CARD_TOKEN>/auth?api_key=<VAULTERA_API_KEY>
```

This will return `204 No Content` and wipe the `service_code` for that card token. (The card itself can still be stored for future use, minus the CVV.) If the card is no longer needed at all, you can also delete it from Vaultera using the `DELETE /cards/{card_token}` endpoint

## How to use Vaultera PCI with Channex

To tokenise cards from Channex you need to perform capture requests from **secure.channex.io** endpoint (if you want to test with Channex staging account it will be **secure-staging.channex.io**).&#x20;

There are two Vaultera tokenisation profiles that should be used depending on which Channex endpoint you use.\
\
**Request template**\
`POST https://pci.vaultera.co/api/v1/capture?api_key=<API_KEY>&profile=<PROFILE>&method=get&url<SECURE_CHANNEX_ENDPOINT>`\ <br>

* API\_KEY - your Vaultera PCI api\_key
* PROFILE - tokenisation profile name
* SECURE\_CHANNEX\_ENDPOINT - url-encoded secure channex endpoint

\
All requests should contain an authentication header for Channex.\
Here are the endpoints you might be interested in.\
\
**Receive bookings**\
Endpoint: /api/v1/bookings\
Tokenisation profile: channex\
\
Example: POST [https://pci.vaultera.co/api/v1/capture?api\_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure.channex.io%2Fapi%2Fv1%2Fbookings](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbookings)\
\
**Receive specific booking**\
Endpoint: /api/v1/bookings/:id\
Tokenisation profile: channex\_entity\
\
Example: POST [https://pci.vaultera.co/api/v1/capture?api\_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\_entity\&method=get\&url=https%3A%2F%2F](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex_entity\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbookings%2Fc3f75a90-41a8-40eb-9f59-55dad5fccf3a)[secure.channex.io](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbookings)[%2Fapi%2Fv1%2Fbookings%2Fc3f75a90-41a8-40eb-9f59-55dad5fccf3a](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex_entity\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbookings%2Fc3f75a90-41a8-40eb-9f59-55dad5fccf3a)\
\
**Receive booking\_revisions**\
Endpoint: /api/v1/booking\_revisions\
Tokenisation profile: channex\
\
Example: POST [https://pci.vaultera.co/api/v1/capture?api\_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbooking_revisions)[.channex.io](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbookings)[%2Fapi%2Fv1%2Fbooking\_revisions](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbooking_revisions)\
\
**Receive booking\_revisions feed**\
Endpoint: /api/v1/booking\_revisions/feed\
Tokenisation profile: channex\
\
Example: POST [https://pci.vaultera.co/api/v1/capture?api\_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2F](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbooking_revisions%2Ffeed)[secure.channex.io](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbookings)[%2Fapi%2Fv1%2Fbooking\_revisions%2Ffeed](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbooking_revisions%2Ffeed)\
\
**Receive specific booking\_revision**\
Endpoint: /api/v1/booking\_revisions/:id\
Tokenisation profile: channex\_entity\
\
Example: POST [https://pci.vaultera.co/api/v1/capture?api\_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\_entity\&method=get\&url=https%3A%2F%2F](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex_entity\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbooking_revisions%2F7b727014-1d86-4419-98b6-2ac915881f45)[secure.channex.io](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbookings)[%2Fapi%2Fv1%2Fbooking\_revisions%2F7b727014-1d86-4419-98b6-2ac915881f45](https://pci.vaultera.co/api/v1/capture?api_key=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\&profile=channex_entity\&method=get\&url=https%3A%2F%2Fsecure.vaultera.co%2Fapi%2Fv1%2Fbooking_revisions%2F7b727014-1d86-4419-98b6-2ac915881f45)


# Walkthrough

Here we will walk you through how to get a card from Channex using Vaultera PCI and then show the card to the user with an Iframe.

## Create test booking with credit card

Sign up or login to your Channex Staging account staging.channex.io

Create a property, Room and rate plan

Create a "Open Channel" channel, map at least 1 room and rate and activate it

There may be some content you need to add to the channel to activate, please check readiness tab

Open the link in the channel once it is active and create booking. It should be created with test card inside.

## Channex auth

Use your API key to connect with Channex

## Get bookings from Channex through Vaultera PCI

To get bookings with card tokens for your account you need to take bookings from Channex via Vaultera PCI

For the Channex staging account you should tell Vaultera PCI to grab cards from [https://secure-staging.channex.io](https://secure-staging.channex.io/) domain. You cannot make direct calls to [secure-staging.channex.io](http://secure-staging.channex.io/) because in response there would be plain cards and to perform such action you need to be pci dss certified.

Instead you are making requests to [secure-staging.channex.io](http://secure-staging.channex.io/) through our PCI service which would take plain cards and tokenize them for your account.

```
curl -v -X POST -H "user-api-key: $CHANNEX_API_KEY" "https://pci.vaultera.co/api/v1/capture?api_key=$API_KEY&method=get&profile=channex&url=https%3A%2F%2Fsecure-staging.channex.io%2Fapi%2Fv1%2Fbooking_revisions%2Ffeed"
```

In response in bookings with cards there will be card tokens for your account. When you are looking to token please ensure that there is no "error" or "warning" field near token.

## Create one-off tokens for card show iframe

Create a card info session token

```
curl -v -X POST -H "Content-Type: application/json" -d '{"session_token":{"scope":"show_card"}}' "https://pci.vaultera.co/api/v1/session_tokens?api_key=$API_KEY"
```

Create a CVV session token

```
curl -v -X POST -H "Content-Type: application/json" -d '{"session_token":{"scope":"show_service_code"}}' "https://pci.vaultera.co/api/v1/session_tokens?api_key=$API_KEY"
```

## Embed card show iframe

On your frontend application place the code for the iframe, here is a test curl command to verify that you can receive iframe source

```
curl -v "https://pci.vaultera.co/api/v1/show_card?card_token=$CARD_TOKEN&session_token=$SESSION_TOKEN&service_code_token=$SERVICE_CODE_TOKEN"
```

If you follow this workflow step by step, in the end you should able to receive card show iframe. If some of steps are not clear or you have some concerns about steps, please let us know.


# Vaultera PCI Certification

Questions for certification and best practices

To certify your Vaultera PCI integration we would like to know more details of how you built your integration

**When do you delete cards from Vaultera PCI?  Do you delete cards after departure date? How long after?**

Best practice is up to 7 days after departure to remove the card from Vaultera PCI and delete your token also.

**When you send the card to a payment gateway and it is a success, do you auth the transaction with Vaultera PCI so we can remove the CVV number?**

Best Practice: PCI rules say that after a successful transaction the CVV must be removed

**Do you show card details to end users via the iframe? If yes how do you log the views?**

Best Practice: Only authorised users should be able to view cards, you can put a password on the feature since users might leave computer unattended. You should log all views of cards with timestamp and user details.

**Do you have 2FA (2 Factor Authentication) to log into your system?**

This is mandatory requirement if you use the iframe solution

**Do you receive cards from other sources like channel managers or channels? If yes have you integrated all of them or this is planned after you go live?**

You should let Vaultera know about all sources where you can get cards, we will have a profile ready for some partners but some we might have to create one for you


