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 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

<script src="https://sdk.staging.switch.vaultera.co"></script>
This is for the staging environment. For the production environment, use the following URL:
<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
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.
async function createPaymentIntent() {
    /* Add respective env enpoints
     - Sandbox - https://api.staging.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.staging.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:
{
  "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
 <script src="https://sdk.staging.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 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.
<script>
    const vaultera_switch = Switch("<PUBLISHABLE_KEY>", {
        customBackendUrl: "https://api.staging.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. 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
{
  "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:
{
  "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:
{
  "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 support@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.staging.switch.vaultera.co%2Fpayments 🔐 Replace with your PCI token and 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

{
  "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.