---
title: "WordPress"
description: "Add a seating chart to a WordPress page with a block or shortcode, and take payment through your own Stripe or Razorpay account."
---

The SeatLayer plugin puts a live seating chart on any WordPress page or post.
The
[WordPress seating chart plugin](https://seatlayer.io/integrations/wordpress/)
page covers what it does before you install it.
Visitors pick seats and pay through **your own** Stripe or Razorpay account —
SeatLayer never holds the money.

<Aside type="note" title="What this plugin is">
  An embed for an existing SeatLayer account. Venues, charts, and events are still
  designed in the SeatLayer dashboard; the plugin renders one of your events and
  hands buyers to checkout. It is not a standalone seating designer.
</Aside>

## Before you start

You need three things, in this order:

<Steps>

1. **A published chart and an event.** Create both at
   [app.seatlayer.io](https://app.seatlayer.io). Note the event key — it is the
   `slug` you chose, and it is what the plugin needs.

2. **A connected payment account.** In the dashboard, go to **Payments** and
   connect Stripe or Razorpay. Until you do, the chart will render but buyers will
   see "this event is not taking online payments yet".

3. **The plugin, installed and activated** on your WordPress site. Search for
   *SeatLayer Seating Charts* under **Plugins → Add New**, or install it from
   [wordpress.org/plugins/seatlayer-seating-charts](https://wordpress.org/plugins/seatlayer-seating-charts/).

</Steps>

## Add a chart to a page

Use the **SeatLayer seating chart** block, choose your event, and publish.

If you prefer a shortcode, or you are on the classic editor:

```text title="Shortcode"
[seatlayer_chart event="summer-fest"]
```

Optional attributes:

| Attribute | Default | What it does |
|---|---|---|
| `event` | — | Required. Your event key. |
| `height` | `640` | Container height in pixels (320–2000). |
| `max_selection` | `10` | Most seats one buyer may select (1–50). |
| `locale` | buyer's browser | Any of the 37 supported languages, e.g. `de`, `ja`, `zh-Hant`. Omit it and each buyer gets their own browser language, English if we do not ship theirs. |
| `currency` | event default | ISO code, e.g. `USD`. |

```text title="With options"
[seatlayer_chart event="summer-fest" height="720" max_selection="4"]
```

## The secret key is optional

The seating chart works with only the event key, which is not a credential — the
buyer surface is deliberately keyless.

A secret key under **Settings → SeatLayer** does exactly one thing: it lets the
block editor list your events in a dropdown instead of you pasting keys.

<Aside type="caution" title="Where the key is stored">
  A secret key saved here lives in your WordPress database, like any other plugin
  setting, and it can create and modify events. Anyone with database or
  administrator access to that site can read it. If that is not acceptable, leave
  it blank and type event keys by hand — nothing else in the plugin needs one.
</Aside>

## How checkout works

The boundary is worth understanding, because it is what keeps a WordPress site out
of the payment path:

<Steps>

1. The buyer selects seats on your page. The widget creates a **hold** on
   SeatLayer's servers, so nobody else can take those seats.

2. On checkout, the buyer is sent to SeatLayer's hosted payment page, carrying only
   the hold id. **No amount is passed** — the server recomputes the total from its
   own hold records, so nothing on your site can change what a buyer pays.

3. They pay through your connected Stripe or Razorpay account. The money goes to
   you; SeatLayer is never the merchant of record.

4. Once the payment provider confirms, the seats are booked and the buyer is
   emailed their tickets. Replies to that email reach **you**, not SeatLayer.

</Steps>

Because payment confirmation comes from a signed provider webhook rather than the
buyer's browser, a closed tab or lost connection mid-payment cannot lose an order.

## Refunds

Refund in your own Stripe or Razorpay dashboard, as you would for anything else.
SeatLayer receives the webhook and puts the seats back on sale.

A **partial** refund does not release seats — a partial amount cannot say which
seat it was for — so cancel those explicitly in the dashboard.

## Performance

The chart's JavaScript loads only on pages that contain a chart, so embedding one
on a single ticket page does not add weight to the rest of the site.

## What this plugin does not do yet

<Aside type="note" title="WooCommerce">
  Seats are not WooCommerce products, and checkout does not run through your Woo
  gateways, cart, or order records. Buyers pay through SeatLayer's hosted checkout
  using your own payment account. A WooCommerce-native integration is planned
  separately.
</Aside>

Also not included: assigned-seat QR codes, door check-in, and box-office sales.
Confirmation emails carry seat labels and an order reference.

## Troubleshooting

**The chart area is blank.** Check the event key, and that the chart is
*published* — a draft chart has no buyer-facing version. Your browser console will
name the failure.

**"This event is not taking online payments yet."** No gateway is connected for
this event's mode. Connect one under **Payments** in the dashboard, and note that a
`test`-mode event needs test credentials.

**Buyers pay but never get tickets, and orders stay unconfirmed.** For Razorpay,
this is almost always a missing webhook. Copy the webhook URL shown on the
Payments screen into your Razorpay dashboard and subscribe to
`payment.captured`, `payment.failed` and `refund.processed`. Payment confirmation
depends on it.

**The event dropdown is empty in the editor.** Either no secret key is saved
(expected — type the key instead), or the saved key was rejected. The editor shows
which.