> ## Documentation Index
> Fetch the complete documentation index at: https://docs.switch.vaultera.co/llms.txt
> Use this file to discover all available pages before exploring further.

# For PMS Systems

Welcome to the Vaultera Switch Getting Started guide. This document is intended for Property Management System (PMS) providers who want to integrate their Internet Booking Engine (IBE) with Vaultera Switch, our modern payment orchestration platform developed by Vaultera.

Vaultera Switch allows PMS systems to easily offer unified payment experiences for hotel guests — whether through embedded checkout forms or secure email payment links.

## Overview

Vaultera Switch enables PMSs to:

* Embed a secure, customizable unified checkout form within the PMS IBE.
* Generate payment request links to be sent to guests via email.
* Route payments across multiple payment processors intelligently.
* Maintain PCI compliance when combined with Vaultera PCI (optional, see appendix).

## Prerequisites

Before you begin, ensure that you:

* Have a Vaultera Switch API key (contact us to provision one per environment).
* Know your PMS client ID and any merchant configuration requirements.
* Understand how your IBE or frontend is structured (React, Vue, plain JS, etc.).

## Integration Options

You can integrate Vaultera Switch into your system using one or both of the following:

* Unified Checkout Form (for IBE payments)
* Payment Request Links (for email-based guest payments)
* Via Vaultera PCI

## Unified Checkout Form

The Unified Checkout Form is a secure, PCI compliant customizable checkout form that can be embedded within the PMS IBE. It allows guests to complete their payments directly within the PMS, providing a seamless and secure payment experience.

## Payment Request Links

Payment Request Links are secure links that can be sent to guests via email. They allow guests to complete their payments directly from their email, providing a convenient and secure payment experience.

## PCI Compliance

Vaultera PCI is an optional service that can be combined with Vaultera Switch to ensure PCI compliance for your PMS system.

## Integrating the Unified Checkout Form

### Step 1: Include the Vaultera JS SDK

```html theme={"system"}
<script src="https://sdk.test.switch.vaultera.co"></script>
```

This is for the test environment. For the production environment, use the following URL:

```html theme={"system"}
<script src="https://sdk.switch.vaultera.co"></script>
```

### Step 2: Create a Payment Intent on your backend

Your backend must create a Payment Intent by calling Vaultera Switch:
Make sure to include the following headers:

Endpoint: `{BASE_URL}/v1/payment_intents`
Method: POST

```bash theme={"system"}
api-key: <API_KEY>
Content-Type: application/json
```

You can use any programming language to create a Payment Intent. Here is an example using node.js using express.

```js theme={"system"}
async function createPaymentIntent() {
    /* Add respective env enpoints
     - Sandbox - https://api.test.switch.vaultera.co
     - Prod - https://api.switch.vaultera.co
    */
    const request = {
        "amount": 24500,
        "currency": "EUR",
        "description": "Hotel Booking #12345",
        "metadata": {
            "pms_booking_id": "ABC123",
            "hotel_id": "HOTEL_001"
        },
    }

    const url = process.env.SWITCH_URL || "https://api.test.switch.vaultera.co";
    const apiResponse = await fetch(`${url}/payments`, {
        method: "POST",
        headers: {
            "Content-Type": "application/json",
            Accept: "application/json",
            "api-key": process.env.API_KEY,
        },
        body: JSON.stringify(request),
    });
    const paymentIntent = await apiResponse.json();

    if (paymentIntent.error) {
        console.error("Error - ", paymentIntent.error);
        throw new Error(paymentIntent?.error?.message ?? "Something went wrong.");
    }
    return paymentIntent;
}
```

You’ll receive a response with the client\_secret and payment\_id:

```json theme={"system"}
{
  "payment_id": "pay_uJkyNEU7L0v9KwUg7tpj",
  "client_secret": "pay_uJkyNEU7L0v9KwUg7tpj_secret_VMHIiBCSEcDgh0m68WG6"
}
```

### Step 3: Render the Checkout Form

Load the SDK using the cdn endpoint and prepare the form

```html theme={"system"}
 <script src="https://sdk.test.switch.vaultera.co"></script>
 <body>
  <form id="payment-form">
    <div id="vaultera-checkout">
        <!--Vaultera Switch SDK injects the Unified Checkout-->
    </div>
  </form>
</body>
```

Get the publishable key from the [dashboard](https://app.test.switch.vaultera.co/dashboard/developer-api-keys) and use it to initialize the SDK.
As soon as the page is loaded, create a payment intent on your backend and use the client secret and publishable key to initialize the SDK.
In place of `<SERVER_BACKEND_URL>` use your server backend URL.
In place of `<PMS_URL>` use your PMS URL, where the guest will be redirected after the payment is complete.

```html theme={"system"}
<script>
    const vaultera_switch = Switch("<PUBLISHABLE_KEY>", {
        customBackendUrl: "https://api.test.switch.vaultera.co",
    });

    async function initialize() {
        const response = await fetch("http://<SERVER_BACKEND_URL>/create-payment", {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify({ items: [{ id: "xl-tshirt" }], country: "US" }),
        });
        const jsonResponse = await response.json();

        widgets = vaultera_switch.widgets({ clientSecret: jsonResponse.client_secret });

        const unifiedCheckoutOptions = {
            layout: "tabs",
            wallets: {
                walletReturnUrl: "https://<PMS_URL>/complete"
            },
            sdkHandleConfirmPayment: {
                handleConfirm: true,
                buttonText: "Pay Now",
                confirmParams: {
                    return_url: "https://<PMS_URL>/complete",
                },
            },
        };

        const unifiedCheckout = widgets.create("payment", unifiedCheckoutOptions);
        unifiedCheckout.mount("#vaultera-checkout");
    }

    initialize();
</script>
```

You can style and customize the form via CSS or SDK options.

## Creating Payment Request Links

These are typically used when hotels email payment links to guests.

### Step 1: Create a Payment Intent with request\_link: true

POST /payments
Authorization: Bearer `<API_KEY>`
Content-Type: application/json

```json theme={"system"}
{
  "amount": 15000,
  "currency": "eur",
  "description": "Balance for Hotel Booking #56789",
  "payment_link": true,
  "customer": {
    "email": "guest@example.com"
  }
}
```

### Step 2: Extract the Payment URL

Response:

```json theme={"system"}
{
  "id": "pi_56789",
  "payment_link": {
    "link": "https://api.stating.switch.vaultera.co/payment_links/pay_uJkyNEU7L0v9KwUg7tpj",
  }
}
```

You can then send this link to the guest.

## Webhooks

Implement webhook handling for important events:

payment\_intent.succeeded
payment\_intent.failed
payment\_intent.cancelled
Example webhook payload:

```json theme={"system"}
{
  "event": "payment_intent.succeeded",
  "data": {
    "id": "pi_1XYZ",
    "amount": 24500,
    "metadata": {
      "pms_booking_id": "ABC123"
    }
  }
}
```

Use this to mark bookings as paid in your PMS.

## Security & Compliance

Vaultera Switch is PCI DSS Level 1 compliant. Tokenization, card vaulting, and proxying are available through Vaultera PCI for handling OTA-sourced cards via Channel Managers.

## Support

Need help? Contact your integration manager or reach out to [switch@vaultera.com](mailto:switch@vaultera.com).

## Appendix: Optional Vaultera PCI Integration

In some scenarios, hotels receive guest credit card details through Channel Managers that provide OTA (Online Travel Agency) reservations — for example, from platforms like Booking.com or Expedia. To stay PCI compliant, PMS systems should not store or process these raw card details directly.
Vaultera PCI enables secure handling of these OTA-provided cards by:

* Tokenizing the card details upon receipt via the Channel Manager.
* Storing the tokens in Vaultera PCI’s secure vault.
* Proxying charge requests through Vaultera PCI to Vaultera Switch using those tokens — avoiding direct handling of sensitive data by the PMS or hotel systems.
  This approach allows hotels to manually charge OTA cards when needed (e.g., for deposits, no-shows, or post-checkout charges) while maintaining full PCI compliance.

Vaultera PCI allows PMS systems to:

* Accept and tokenize credit cards received via Channel Managers.
* Store these securely in Vaultera PCI’s vault.
* Later proxy charge requests to Vaultera Switch without storing sensitive data.

## Example: Detokenize & Charge via Vaultera PCI

This example shows how to detokenize a card token and send a charge request to Vaultera Switch using Vaultera PCI’s send action:

### Step 1: Prepare the HTTP Request

POST `https://pci.vaultera.co/api/v1/cards/{CARD_TOKEN}/send?api_key={VAULTERA_PCI_API_KEY}&method=post&url=https%3A%2F%api.test.switch.vaultera.co%2Fpayments`
🔐 Replace {CARD_TOKEN} with your PCI token and {VAULTERA_PCI_API_KEY} with your API key of Vaultera PCI ( not the api key of Vaultera Switch). The url must be URL-encoded.

### Step 2: Include Headers

Use the api key of Vaultera Switch to send the request to Vaultera PCI.

```
Content-Type: application/json
api-key: {VAULTERA_SWITCH_API_KEY}
```

### Step 3: Define the JSON Payload

```json theme={"system"}
{
  "amount": 6540,
  "currency": "USD",
  "capture_method": "automatic",
  "confirm": true,
  "payment_method": "card",
  "payment_method_data": {
    "card": {
      "card_number": "%CARD_NUMBER%",
      "cardholder_name": "%CARDHOLDER_NAME%",
      "card_exp_year": "%EXPIRATION_YY%",
      "card_exp_month": "%EXPIRATION_MM%",
      "card_cvc": "%SERVICE_CODE%"
    }
  }
}
```

Vaultera PCI will replace the placeholders with the actual card data associated with the token and forward the complete request to Vaultera Switch.
