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

# Manual Integration

If the [Virtual Card SDK](./automated) is not a viable option, the manual integration will guide you through the steps to complete a virtual card session in your checkout.

<Warning>
  The manual integration delivers the **full card number (PAN) and CVV** directly to your frontend JavaScript via `postMessage`. This places your frontend in PCI DSS scope. If you want to minimize PCI exposure, consider the [Virtual Card SDK](./automated) with the [`card_response_format: "token"` option](./automated#oncomplete-with-tokenization), which keeps card data out of the browser.
</Warning>

## Overview

1. Create a [virtual card session](/docs/api/core/sessions/virtual/postv2sessioncard)
2. Add a window event listener with type `message` to the checkout page
3. Open the card session `dashboard_url` using the mode provided in the create card session request
4. Sezzle will post a message to the listener when the user has completed the card session
5. Verify the message `event.origin` matches the expected Sezzle domain
6. Verify message `event.data` exists
7. Verify `event.data.szl_source` `=` `v_card`
8. Verify `event.data.card` and `event.data.holder` both exist
   * If they exist
     * Use card and holder data to submit the order by credit card
   * If they don't exist
     * The user did not provide virtual card data

## Example Javascript

```javascript [expandable] theme={"system"}
var SEZZLE_ORIGIN = "https://dashboard.sezzle.com";

window.addEventListener("message", function (event) {
    // Validate the message origin for security
    if (event.origin !== SEZZLE_ORIGIN) {
        return;
    }

    var data = event.data || Object.create(null);

    if (data.szl_source !== "v_card") {
        return;
    }

    var card = data.card;
    var holder = data.holder;
    if (!card && !holder) {
        console.log("failed virtual card session");
        return;
    }

    // Submit card and holder data to your payment processor.
    // IMPORTANT: Do not log or store raw card data (PAN, CVV)
    // in your frontend. Send it directly to your server or
    // payment gateway for processing.
    submitToPaymentGateway({
        card: {
            number: card.pan,
            cvv: card.cvv,
            expiryMonth: card.expiryMonth,
            expiryYear: card.expiryYear,
            firstName: card.firstName,
            lastName: card.lastName,
        },
        billingAddress: {
            email: holder.email,
            phone: holder.phone,
            firstName: holder.firstName,
            lastName: holder.lastName,
            address1: holder.address1,
            address2: holder.address2,
            city: holder.city,
            state: holder.state,
            country: holder.country,
            postalCode: holder.postalCode,
        },
    });
});
```
