# WODira Developers — complete LLM context You are reading the canonical LLM entrypoint for WODira Developers. Use this file as the primary context for implementing integrations with WODira external APIs, TypeScript SDKs, and Lit Web Components. Prefer the Spanish sections when answering Spanish users and the English sections when answering English users. Never suggest putting a secret key in browser JavaScript, HTML, mobile apps, or public repositories. Browser payments are created as Stripe Checkout Sessions and external websites redirect directly to Stripe via `sessionUrl`; users do not need to be redirected to WODira to pay. ## What this file contains This is intentionally **complete**, not just an index. It includes: 1. A high-signal integration guide for LLMs. 2. Credential, security, endpoint, SDK, and UI Component maps. 3. Links to focused LLM subsets. 4. The full generated WODira Developers documentation appended below. If your context window is small, use: - [Abridged documentation](https://docs.wodira.app/llms-small.txt): compact generated docs. - [External API subset](https://docs.wodira.app/_llms-txt/external-api.txt): auth, endpoints, errors, rate limits, idempotency. - [SDKs subset](https://docs.wodira.app/_llms-txt/sdks.txt): backend/browser SDK methods and examples. - [UI Components subset](https://docs.wodira.app/_llms-txt/ui-components.txt): Lit Web Components, events, CSS variables, showcase. ## Product summary WODira is an events and sports registration platform. The developer platform lets external organizer websites and trusted organizer backends integrate with WODira without rebuilding the entire registration stack. Core integration surfaces: | Surface | Package / path | Runtime | Credential | Main purpose | | --- | --- | --- | --- | --- | | Browser API | `/external/v1/browser` | Public frontend | `wpk_live_...` publishable key + allowed `Origin` | Read public events/pricing and create Stripe Checkout Sessions | | Organizer API | `/external/v1/organizer` | Trusted backend | `wd_live_...` secret key | Server-to-server event, pricing, and registration operations | | Browser SDK | `@wodira/browser` | Public frontend | `wpk_live_...` | Type-safe wrapper around Browser API | | Backend SDK | `@wodira/sdk` | Trusted backend | `wd_live_...` | Type-safe wrapper around Organizer API | | UI Components | `@wodira/browser/ui` | Public frontend | `wpk_live_...` | Reusable Lit Web Components for organizer websites | Production API origin: ```txt https://api.wodira.app ``` Documentation origin: ```txt https://docs.wodira.app ``` ## Decision tree for implementers 1. If the code runs in a browser, use **publishable keys** (`wpk_live_...`) and either `@wodira/browser` or `@wodira/browser/ui`. 2. If the code runs on a trusted backend, use **secret keys** (`wd_live_...`) and `@wodira/sdk`. 3. If the organizer wants a fast no-UI-build integration, use `@wodira/browser/ui` Web Components. 4. If the organizer has a custom design system, use `@wodira/browser` and render custom UI. 5. If the integration manages private data or server-to-server registrations, do it from backend with `@wodira/sdk`. 6. For public checkout from an organizer website, create a WODira Browser Checkout Session and redirect directly to the returned Stripe `sessionUrl`. ## Credential model ### Secret keys - Prefix: `wd_live_...` - Use only in trusted backends. - Authenticate with `Authorization: Bearer wd_live_...` or `x-api-key`. - Grant scoped access to Organizer API endpoints. - Never expose in JavaScript bundles, HTML, logs, mobile apps, screenshots, docs, or repositories. - Store in a secret manager or server-only environment variable such as `WODIRA_API_KEY`. Scopes: | Scope | Allows | | --- | --- | | `events:read` | Read events, categories, fields, waivers, sponsors, active supplements | | `pricing:read` | Read pricing cards, quotas, active prices | | `registrations:read` | Search/read registrations | | `registrations:write` | Create, update, cancel/delete registrations | ### Publishable keys - Prefix: `wpk_live_...` - Safe to expose in frontend only because they are restricted to Browser API and validated against allowed origins. - Authenticate with `x-publishable-key: wpk_live_...`. - Browser requests must include an `Origin` header that matches the key's `allowedOrigins`. - `successUrl` and `cancelUrl` must belong to an allowed origin. - Use HTTPS origins in production. ## How organizers get API keys Keys are created in WODira from the private organizer dashboard: 1. Sign in with an organizer account. 2. Open the organization. 3. Go to **Organization profile → API**. 4. Choose **Secret key (backend)** or **Publishable key (frontend)**. 5. For secret keys, select minimum required scopes. 6. For publishable keys, add allowed origins such as `https://organizador.com` and `https://www.organizador.com`. 7. Optionally set expiration. 8. Create the key and copy it immediately; WODira only shows the full key once. ## Browser checkout flow Recommended frontend flow: 1. Create a publishable key with the external organizer website in `allowedOrigins`. 2. Install `@wodira/browser` or `@wodira/browser/ui`. 3. Read public event details with `getEvent()`. 4. Read public pricing cards with `getPricingCards()`. 5. Optionally calculate a reactive total with `getRegistrationSummary()`. 6. Create a Stripe Checkout Session with `createRegistrationCheckoutSession()`. 7. Redirect to `session.sessionUrl`. Minimal example: ```ts import { createWodiraBrowserClient } from '@wodira/browser'; const wodira = createWodiraBrowserClient({ publishableKey: 'wpk_live_...', }); const session = await wodira.createRegistrationCheckoutSession({ eventId: 'event_123', categoryId: 'cat_123', purchaserEmail: 'buyer@example.com', purchaserName: 'Buyer Name', termsAccepted: true, waiversAccepted: { waiver_123: true }, idempotencyKey: crypto.randomUUID(), successUrl: 'https://organizador.com/gracias', cancelUrl: 'https://organizador.com/cancelado', athletes: [ { fullname: 'Ada Lovelace', email: 'ada@example.com', phone: '+34600000000', idNumber: '12345678A', gender: 'FEMALE', birthDate: '1990-01-01', }, ], }); window.location.href = session.sessionUrl; ``` Important: do **not** redirect to WODira for payment. Redirect directly to Stripe Checkout using the returned `sessionUrl`. ## Endpoint map ### Browser API endpoints Base path: `https://api.wodira.app/external/v1/browser` | Method | Path | SDK method | Purpose | | --- | --- | --- | --- | | `POST` | `/events/search` | `@wodira/browser.searchEvents` | List/search public events | | `GET` | `/events/:eventId` | `@wodira/browser.getEvent` | Read public event details | | `GET` | `/events/:eventId/pricing-cards` | `@wodira/browser.getPricingCards` | Read public categories, prices, quotas | | `POST` | `/checkout/registration/summary` | `@wodira/browser.getRegistrationSummary` | Calculate pre-checkout total | | `POST` | `/checkout/registration/session` | `@wodira/browser.createRegistrationCheckoutSession` | Create Stripe Checkout Session | ### Organizer API endpoints Base path: `https://api.wodira.app/external/v1/organizer` | Method | Path | Required scope | SDK method | Purpose | | --- | --- | --- | --- | --- | | `POST` | `/events/search` | `events:read` | `@wodira/sdk.searchEvents` | Search organizer events | | `GET` | `/events/:eventId` | `events:read` | `@wodira/sdk.getEvent` | Read event details | | `GET` | `/events/:eventId/pricing-cards` | `pricing:read` | `@wodira/sdk.getPricingCards` | Read pricing cards | | `POST` | `/registrations` | `registrations:write` | `@wodira/sdk.createRegistration` | Create registration server-to-server | | `POST` | `/registrations/search` | `registrations:read` | `@wodira/sdk.searchRegistrations` | Search registrations | | `PATCH` | `/registrations/:ticketId` | `registrations:write` | `@wodira/sdk.updateRegistration` | Update registration | | `DELETE` | `/registrations/:ticketId` | `registrations:write` | `@wodira/sdk.deleteRegistration` | Cancel/delete registration | ## SDK method map ### `@wodira/browser` - `createWodiraBrowserClient({ publishableKey, baseUrl?, fetch? })` - `searchEvents({ search?, limit?, offset? })` - `getEvent(eventId)` - `getPricingCards(eventId)` - `getRegistrationSummary(input)` - `createRegistrationCheckoutSession(input)` - Error class: `WodiraBrowserApiError` ### `@wodira/sdk` - `createWodiraClient({ apiKey, baseUrl?, fetch? })` - `searchEvents(input?)` - `getEvent(eventId)` - `getPricingCards(eventId)` - `createRegistration(input)` - `searchRegistrations(input?)` - `updateRegistration(ticketId, input)` - `deleteRegistration(ticketId)` - Error class: `WodiraApiError` ## UI Components map Import and register: ```ts import { defineWodiraElements } from '@wodira/browser/ui'; defineWodiraElements(); ``` Available Web Components: | Component | Purpose | | --- | --- | | `` | Render one event card | | `` | Search/list public events | | `` | Render categories/pricing cards | | `` | Collect purchaser/athlete/waiver data | | `` | End-to-end public checkout flow | Core UI integration: ```html ``` The components are Lit Web Components, framework-agnostic, reactive, and customizable with CSS variables/CSS parts. They use the Browser API and must use publishable keys, never secret keys. ## Production safety checklist - Use `wd_live_...` only on trusted servers. - Use `wpk_live_...` only with explicit `allowedOrigins`. - Use HTTPS origins in production. - Validate `successUrl` and `cancelUrl` against allowed origins. - Send `idempotencyKey` for checkout session creation. - Handle `429` rate limits with backoff. - Catch typed SDK errors and inspect `status`, `statusText`, and `payload`. - Revoke leaked or unused keys. - Rotate keys periodically. - Do not log full API keys or personal registration data. ## Focused generated documentation Generated files currently available: | File | Purpose | Approx. words | | --- | --- | ---: | | [`/llms-full.txt`](https://docs.wodira.app/llms-full.txt) | Full generated documentation | 7738 | | [`/llms-small.txt`](https://docs.wodira.app/llms-small.txt) | Compact documentation | 7738 | | [`/_llms-txt/external-api.txt`](https://docs.wodira.app/_llms-txt/external-api.txt) | API/auth/endpoints/errors | 2780 | | [`/_llms-txt/sdks.txt`](https://docs.wodira.app/_llms-txt/sdks.txt) | SDK reference | 1983 | | [`/_llms-txt/ui-components.txt`](https://docs.wodira.app/_llms-txt/ui-components.txt) | UI Components reference | 1363 | --- # Complete generated documentation This is the full developer documentation for WODira Developers --- # WODira Developers > Documentación para integrar webs y backends externos con WODira. Developer platform # WODira Developers API pública, SDKs y Web Components para que organizadores vendan inscripciones desde sus propias webs con Stripe Checkout. [Empezar →](/getting-started/)[Ver UI Components](/ui-components/overview/) checkout-session.ts ``` // Frontend: publishable key + origin allowlist import { createWodiraBrowserClient } from ‘@wodira/browser’; const wodira = createWodiraBrowserClient({ publishableKey: ‘wpk_live_…’ }); const session = await wodira.createRegistrationCheckoutSession({ eventId, categoryId, athletes, termsAccepted: true, successUrl: 'https://organizador.com/gracias', cancelUrl: 'https://organizador.com/cancelado' }); window.location.href = session.sessionUrl; ``` ### Modelo tipo Stripe, adaptado a eventos deportivos Secret keys en backend, publishable keys en frontend, redirects directos a Stripe Checkout y componentes UI listos para incrustar. **2 SDKs**backend + browser **LLM**llms.txt + sets **UI**Lit Web Components ## Copiar contexto para LLMs [Sección titulada «Copiar contexto para LLMs»](#copiar-contexto-para-llms) LLM-ready ### Documentación lista para ChatGPT, Cursor, Claude o agentes Copia el índice general o un set específico para dar contexto exacto sobre la API externa, SDKs y UI Components de WODira. **Índice LLM**Entrada recomendada para empezar.[Abrir](/llms.txt) **SDKs**Métodos, ejemplos y credenciales.[Abrir](/_llms-txt/sdks.txt) **API externa**Auth, endpoints, errores y rate limits.[Abrir](/_llms-txt/external-api.txt) **UI Components**Web Components, eventos y CSS variables.[Abrir](/_llms-txt/ui-components.txt) ## Elige tu superficie de integración [Sección titulada «Elige tu superficie de integración»](#elige-tu-superficie-de-integración) ### [API externa](/api/overview/) [Endpoints versionados para eventos, pricing, registros, errores e idempotencia.](/api/overview/) [/external/v1Scopes](/api/overview/) ### [SDKs TypeScript](/sdks/overview/) [Clientes ligeros para backends confiables y navegadores con origins permitidos.](/sdks/overview/) [@wodira/sdk@wodira/browser](/sdks/overview/) ### [UI Components](/ui-components/overview/) [Web Components Lit customizables con CSS variables, DOM events y checkout completo.](/ui-components/overview/) [LitCSS parts](/ui-components/overview/) ## Arquitectura recomendada [Sección titulada «Arquitectura recomendada»](#arquitectura-recomendada) ### Backend del organizador Usa `wd_live_...` solo en servidores. Lee datos privados, gestiona inscripciones server-to-server y conserva control operacional. Bearer authregistrations:writeNo browser ### Web pública del organizador Usa `wpk_live_...` con `allowedOrigins`. Lista eventos publicados, calcula resumen y crea Stripe Checkout Sessions. Origin requiredStripe CheckoutNo secretos ## Rutas rápidas [Sección titulada «Rutas rápidas»](#rutas-rápidas) * [API externa](/api/overview/) * [Autenticación](/api/authentication/) * [SDK backend](/sdks/backend-sdk/) * [SDK browser](/sdks/browser-sdk/) * [Checkout Flow Web Component](/ui-components/checkout-flow/) * [Checklist de producción](/security/production-checklist/) --- # Primeros pasos > Elige la integración correcta para tu web o backend externo. ## Elige el camino correcto [Sección titulada «Elige el camino correcto»](#elige-el-camino-correcto) | Caso de uso | Usa | Credencial | | ------------------------------------------------ | ------------------------------------------------ | ----------------------------------- | | Backend propio que crea o gestiona inscripciones | [`@wodira/sdk`](/sdks/backend-sdk/) | Secret key `wd_live_...` | | Web pública que muestra eventos y crea checkout | [`@wodira/browser`](/sdks/browser-sdk/) | Publishable key `wpk_live_...` | | Web pública sin construir UI desde cero | [`@wodira/browser/ui`](/ui-components/overview/) | Publishable key `wpk_live_...` | | Integración sin SDK | HTTP directo | Secret o publishable según endpoint | ## Obtener tus API keys en WODira [Sección titulada «Obtener tus API keys en WODira»](#obtener-tus-api-keys-en-wodira) Las claves se crean desde el panel privado del organizador, en **Perfil de organización → API**. [`Secret key`Para backends propios con scopes y `wd_live_...`.](/api/secret-keys/#crear-una-secret-key-en-wodira)[`Publishable key`Para webs públicas con allowed origins y `wpk_live_...`.](/api/publishable-keys/#crear-una-publishable-key-en-wodira) 1. Entra en WODira con una cuenta organizadora. 2. Abre tu organización y ve a **Perfil de organización**. 3. Selecciona la pestaña **API**. Ruta orientativa: `/organizer/{organizationId}/profile?tab=api`. 4. En **Nueva clave**, elige el tipo: * **Secret key (backend)** para usar [`@wodira/sdk`](/sdks/backend-sdk/) o la Organizer API. * **Publishable key (frontend)** para usar [`@wodira/browser`](/sdks/browser-sdk/), [`@wodira/browser/ui`](/ui-components/overview/) o la Browser API. 5. Pon un nombre reconocible, por ejemplo `web oficial`, `backend producción` o `landing 2026`. 6. Si es publishable, añade **Orígenes permitidos**: un dominio por línea, por ejemplo `https://organizador.com` y `https://www.organizador.com`. 7. Si es secret, selecciona los scopes mínimos necesarios. 8. Opcionalmente configura una fecha de caducidad y pulsa **Crear clave**. 9. Copia la clave completa en ese momento: WODira solo la muestra una vez. Importante Si pierdes una clave, revócala desde **Claves existentes** y crea otra. No compartas secret keys por email, Slack ni JavaScript público. ## Flujo browser recomendado [Sección titulada «Flujo browser recomendado»](#flujo-browser-recomendado) 1. Crear una publishable key con el dominio de la web externa en `allowedOrigins`. 2. Instalar `@wodira/browser` o `@wodira/browser/ui`. 3. Leer evento y categorías públicas con [`getEvent`](/sdks/browser-sdk/#getevent) y [`getPricingCards`](/sdks/browser-sdk/#getpricingcards). 4. Crear una Checkout Session con [`createRegistrationCheckoutSession`](/sdks/browser-sdk/#createregistrationcheckoutsession), `termsAccepted`, waivers requeridos e `idempotencyKey`. 5. Redirigir a `sessionUrl` de Stripe Checkout. ```ts import { createWodiraBrowserClient } from '@wodira/browser'; const wodira = createWodiraBrowserClient({ publishableKey: 'wpk_live_...' }); const event = await wodira.getEvent('event_...'); const pricing = await wodira.getPricingCards(event.id); ``` --- # Getting started > Choose the right integration path for your website or backend. ## Choose the right path [Section titled “Choose the right path”](#choose-the-right-path) | Use case | Use | Credential | | ------------------------------------------------ | --------------------------------------------------- | ------------------------------------------- | | Trusted backend creates or manages registrations | [`@wodira/sdk`](/en/sdks/backend-sdk/) | Secret key `wd_live_...` | | Public website lists events and creates checkout | [`@wodira/browser`](/en/sdks/browser-sdk/) | Publishable key `wpk_live_...` | | Public website without building UI from scratch | [`@wodira/browser/ui`](/en/ui-components/overview/) | Publishable key `wpk_live_...` | | No SDK | Direct HTTP | Secret or publishable depending on endpoint | ## Get your API keys in WODira [Section titled “Get your API keys in WODira”](#get-your-api-keys-in-wodira) Keys are created from the private organizer dashboard under **Organization profile → API**. [`Secret key`For trusted backends with scopes and `wd_live_...`.](/en/api/secret-keys/#create-a-secret-key-in-wodira)[`Publishable key`For public websites with allowed origins and `wpk_live_...`.](/en/api/publishable-keys/#create-a-publishable-key-in-wodira) 1. Sign in to WODira with an organizer account. 2. Open your organization and go to **Organization profile**. 3. Select the **API** tab. Example route: `/organizer/{organizationId}/profile?tab=api`. 4. In **New key**, choose the type: * **Secret key (backend)** for [`@wodira/sdk`](/en/sdks/backend-sdk/) or the Organizer API. * **Publishable key (frontend)** for [`@wodira/browser`](/en/sdks/browser-sdk/), [`@wodira/browser/ui`](/en/ui-components/overview/), or the Browser API. 5. Add a recognizable name, for example `official website`, `production backend`, or `2026 landing`. 6. For publishable keys, add **Allowed origins**: one domain per line, such as `https://organizer.com` and `https://www.organizer.com`. 7. For secret keys, select the minimum scopes needed. 8. Optionally set an expiration date and click **Create key**. 9. Copy the full key immediately: WODira only shows it once. Important If you lose a key, revoke it from **Existing keys** and create a new one. Do not share secret keys over email, Slack, or public JavaScript. ## Recommended browser flow [Section titled “Recommended browser flow”](#recommended-browser-flow) 1. Create a publishable key with the external website domain in `allowedOrigins`. 2. Install `@wodira/browser` or `@wodira/browser/ui`. 3. Read the public event and categories with [`getEvent`](/en/sdks/browser-sdk/#getevent) and [`getPricingCards`](/en/sdks/browser-sdk/#getpricingcards). 4. Create a Checkout Session with [`createRegistrationCheckoutSession`](/en/sdks/browser-sdk/#createregistrationcheckoutsession), `termsAccepted`, required waivers, and `idempotencyKey`. 5. Redirect to the Stripe Checkout `sessionUrl`. --- # Overview de API externa > Base paths, credenciales y capacidades disponibles en la API pública de WODira. WODira expone dos superficies externas. Si estás leyendo endpoints HTTP, cada operación enlaza también a su método de SDK recomendado en la [referencia de endpoints](/api/endpoints/). ## Organizer API [Sección titulada «Organizer API»](#organizer-api) Base path: `/external/v1/organizer` Usa secret keys `wd_live_...` y está pensada para backends de confianza. Permite leer eventos, consultar pricing y gestionar inscripciones según scopes. Consulta los métodos de [`@wodira/sdk`](/sdks/backend-sdk/). ## Browser API [Sección titulada «Browser API»](#browser-api) Base path: `/external/v1/browser` Usa publishable keys `wpk_live_...` y está pensada para frontend. Permite leer eventos públicos, consultar pricing público y crear Stripe Checkout Sessions para inscripciones. Consulta los métodos de [`@wodira/browser`](/sdks/browser-sdk/). ## Producción [Sección titulada «Producción»](#producción) Origen de producción: ```txt https://api.wodira.app ``` Todas las respuestas no-2xx siguen el formato estándar de errores de la API WODira con `statusCode`, `message` y `error` cuando aplica. --- # External API overview > Base paths, credentials, and capabilities in WODira's public external API. WODira exposes two external API surfaces. If you are reading raw HTTP endpoints, each operation also links to its recommended SDK method in the [endpoint reference](/en/api/endpoints/). ## Organizer API [Section titled “Organizer API”](#organizer-api) Base path: `/external/v1/organizer` Uses secret keys `wd_live_...` and is designed for trusted backends. It can read events, inspect pricing, and manage registrations depending on scopes. See the [`@wodira/sdk` methods](/en/sdks/backend-sdk/). ## Browser API [Section titled “Browser API”](#browser-api) Base path: `/external/v1/browser` Uses publishable keys `wpk_live_...` and is designed for frontend code. It can read public events, inspect public pricing, and create Stripe Checkout Sessions for registrations. See the [`@wodira/browser` methods](/en/sdks/browser-sdk/). ## Production origin [Section titled “Production origin”](#production-origin) ```txt https://api.wodira.app ``` --- # SDK para navegador > Cliente frontend para eventos públicos y Stripe Checkout. @wodira/browserFrontend · publishable keys · Stripe Checkout ## Instalación [Sección titulada «Instalación»](#instalación) ```bash pnpm add @wodira/browser ``` ## Uso básico [Sección titulada «Uso básico»](#uso-básico) ```ts import { createWodiraBrowserClient } from '@wodira/browser'; const wodira = createWodiraBrowserClient({ publishableKey: 'wpk_live_...' }); const session = await wodira.createRegistrationCheckoutSession({ eventId: 'event_...', categoryId: 'cat_...', purchaserEmail: 'buyer@example.com', purchaserName: 'Buyer Name', teamName: 'Team Name', termsAccepted: true, waiversAccepted: { waiver_123: true }, idempotencyKey: crypto.randomUUID(), successUrl: 'https://organizador.com/gracias', cancelUrl: 'https://organizador.com/cancelado', athletes: [ { fullname: 'Ada Lovelace', idNumber: '12345678A', email: 'ada@example.com', phone: '+34600000000', gender: 'FEMALE', birthDate: '1990-01-01', }, ], }); if (session.sessionUrl) window.location.href = session.sessionUrl; ``` ## Métodos [Sección titulada «Métodos»](#métodos) [`searchEvents`Listar eventos públicos](#searchevents)[`getEvent`Leer detalle público de evento](#getevent)[`getPricingCards`Mostrar categorías y precios](#getpricingcards)[`getRegistrationSummary`Previsualizar total del checkout](#getregistrationsummary)[`createRegistrationCheckoutSession`Crear Stripe Checkout Session](#createregistrationcheckoutsession) ### `searchEvents` [Sección titulada «searchEvents»](#searchevents) Lista eventos publicados disponibles para la publishable key. Úsalo en webs de organizadores para mostrar carreras, competiciones o eventos vendibles. ```ts const events = await wodira.searchEvents({ search: 'Madrid', limit: 20 }); ``` * **Endpoint:** [`POST /external/v1/browser/events/search`](/api/endpoints/#buscar-eventos) * **Credencial:** `wpk_live_...` con `Origin` permitido ### `getEvent` [Sección titulada «getEvent»](#getevent) Obtiene el detalle público de un evento, incluyendo categorías, campos públicos, waivers y suplementos activos. ```ts const event = await wodira.getEvent('event_123'); ``` * **Endpoint:** [`GET /external/v1/browser/events/:eventId`](/api/endpoints/#detalle-de-evento) * **Credencial:** `wpk_live_...` con `Origin` permitido ### `getPricingCards` [Sección titulada «getPricingCards»](#getpricingcards) Devuelve cards de precio públicas para pintar categorías, cupos, precio activo y tiers antes de iniciar el formulario. ```ts const pricing = await wodira.getPricingCards('event_123'); ``` * **Endpoint:** [`GET /external/v1/browser/events/:eventId/pricing-cards`](/api/endpoints/#pricing-cards) * **Credencial:** `wpk_live_...` con `Origin` permitido ### `getRegistrationSummary` [Sección titulada «getRegistrationSummary»](#getregistrationsummary) Calcula un resumen del checkout antes de redirigir a Stripe: precio base, suplementos seleccionados, cupón aplicado, total y moneda. ```ts const summary = await wodira.getRegistrationSummary({ categoryId: 'cat_123', purchaserEmail: 'buyer@example.com', selectedSupplementIds: ['supp_123'], promocode: 'EARLY', }); ``` * **Endpoint:** [`POST /external/v1/browser/checkout/registration/summary`](/api/endpoints/#checkout-summary) * **Uso recomendado:** resumen reactivo en el formulario antes de pagar ### `createRegistrationCheckoutSession` [Sección titulada «createRegistrationCheckoutSession»](#createregistrationcheckoutsession) Crea una Stripe Checkout Session para inscripciones públicas. La web externa debe redirigir a `sessionUrl`; no se redirige a WODira para pagar. ```ts const session = await wodira.createRegistrationCheckoutSession({ eventId: 'event_123', categoryId: 'cat_123', purchaserEmail: 'buyer@example.com', purchaserName: 'Buyer Name', termsAccepted: true, waiversAccepted: { waiver_123: true }, idempotencyKey: crypto.randomUUID(), successUrl: 'https://organizador.com/gracias', cancelUrl: 'https://organizador.com/cancelado', athletes: [{ fullname: 'Ada Lovelace', email: 'ada@example.com' }], }); window.location.href = session.sessionUrl; ``` * **Endpoint:** [`POST /external/v1/browser/checkout/registration/session`](/api/endpoints/#checkout-session) * **Seguridad:** `successUrl` y `cancelUrl` deben pertenecer a un origin permitido * **Alternativa UI:** [``](/ui-components/checkout-flow/) si prefieres Web Components completos --- # Browser SDK > Frontend client for public events and Stripe Checkout. ## Install [Section titled “Install”](#install) ```bash pnpm add @wodira/browser ``` ## Quickstart [Section titled “Quickstart”](#quickstart) ```ts import { createWodiraBrowserClient } from '@wodira/browser'; const wodira = createWodiraBrowserClient({ publishableKey: 'wpk_live_...' }); const session = await wodira.createRegistrationCheckoutSession({ eventId: 'event_...', categoryId: 'cat_...', purchaserEmail: 'buyer@example.com', purchaserName: 'Buyer Name', teamName: 'Team Name', termsAccepted: true, waiversAccepted: { waiver_123: true }, idempotencyKey: crypto.randomUUID(), successUrl: 'https://organizer.com/success', cancelUrl: 'https://organizer.com/cancel', athletes: [ { fullname: 'Ada Lovelace', idNumber: '12345678A', email: 'ada@example.com', phone: '+34600000000', gender: 'FEMALE', birthDate: '1990-01-01', }, ], }); if (session.sessionUrl) window.location.href = session.sessionUrl; ``` ## Methods [Section titled “Methods”](#methods) [`searchEvents`List public events](#searchevents)[`getEvent`Read public event details](#getevent)[`getPricingCards`Render categories and prices](#getpricingcards)[`getRegistrationSummary`Preview checkout total](#getregistrationsummary)[`createRegistrationCheckoutSession`Create Stripe Checkout Session](#createregistrationcheckoutsession) ### `searchEvents` [Section titled “searchEvents”](#searchevents) Lists published events available to the publishable key. Use it on organizer websites to render races, competitions, or sellable events. ```ts const events = await wodira.searchEvents({ search: 'Madrid', limit: 20 }); ``` * **Endpoint:** [`POST /external/v1/browser/events/search`](/en/api/endpoints/#search-events) * **Credential:** `wpk_live_...` with an allowed `Origin` ### `getEvent` [Section titled “getEvent”](#getevent) Reads public event details, including categories, public fields, waivers, and active supplements. ```ts const event = await wodira.getEvent('event_123'); ``` * **Endpoint:** [`GET /external/v1/browser/events/:eventId`](/en/api/endpoints/#event-details) * **Credential:** `wpk_live_...` with an allowed `Origin` ### `getPricingCards` [Section titled “getPricingCards”](#getpricingcards) Returns public pricing cards for rendering categories, quotas, active prices, and tiers before showing the form. ```ts const pricing = await wodira.getPricingCards('event_123'); ``` * **Endpoint:** [`GET /external/v1/browser/events/:eventId/pricing-cards`](/en/api/endpoints/#pricing-cards) * **Credential:** `wpk_live_...` with an allowed `Origin` ### `getRegistrationSummary` [Section titled “getRegistrationSummary”](#getregistrationsummary) Calculates a checkout summary before redirecting to Stripe: base price, selected supplements, applied coupon, total, and currency. ```ts const summary = await wodira.getRegistrationSummary({ categoryId: 'cat_123', purchaserEmail: 'buyer@example.com', selectedSupplementIds: ['supp_123'], promocode: 'EARLY', }); ``` * **Endpoint:** [`POST /external/v1/browser/checkout/registration/summary`](/en/api/endpoints/#checkout-summary) * **Recommended use:** reactive summary in the registration form before payment ### `createRegistrationCheckoutSession` [Section titled “createRegistrationCheckoutSession”](#createregistrationcheckoutsession) Creates a Stripe Checkout Session for public registrations. The external website should redirect to `sessionUrl`; users do not go to WODira to pay. ```ts const session = await wodira.createRegistrationCheckoutSession({ eventId: 'event_123', categoryId: 'cat_123', purchaserEmail: 'buyer@example.com', purchaserName: 'Buyer Name', termsAccepted: true, waiversAccepted: { waiver_123: true }, idempotencyKey: crypto.randomUUID(), successUrl: 'https://organizer.com/success', cancelUrl: 'https://organizer.com/cancel', athletes: [{ fullname: 'Ada Lovelace', email: 'ada@example.com' }], }); window.location.href = session.sessionUrl; ``` * **Endpoint:** [`POST /external/v1/browser/checkout/registration/session`](/en/api/endpoints/#checkout-session) * **Security:** `successUrl` and `cancelUrl` must belong to an allowed origin * **UI alternative:** [``](/en/ui-components/checkout-flow/) if you prefer complete Web Components --- # Checkout Flow > Incrusta un flujo completo de inscripción y pago con Stripe Checkout. ## HTML [Sección titulada «HTML»](#html) ```html ``` ## JS factory [Sección titulada «JS factory»](#js-factory) ```ts import { createWodiraCheckoutFlow } from '@wodira/browser/ui'; createWodiraCheckoutFlow(document.querySelector('#checkout')!, { publishableKey: 'wpk_live_...', eventId: 'event_...', successUrl: 'https://organizador.com/gracias', cancelUrl: 'https://organizador.com/cancelado', }); ``` ## Atributos [Sección titulada «Atributos»](#atributos) * `publishable-key` * `base-url` * `event-id` * `success-url` * `cancel-url` * `locale` * `auto-redirect` --- # Checkout Flow > Embed a complete registration and Stripe Checkout flow. ## HTML [Section titled “HTML”](#html) ```html ``` ## JS factory [Section titled “JS factory”](#js-factory) ```ts import { createWodiraCheckoutFlow } from '@wodira/browser/ui'; createWodiraCheckoutFlow(document.querySelector('#checkout')!, { publishableKey: 'wpk_live_...', eventId: 'event_...', successUrl: 'https://organizer.com/success', cancelUrl: 'https://organizer.com/cancel', }); ``` --- # Autenticación > Diferencias entre secret keys y publishable keys. ## Dónde se crean las keys [Sección titulada «Dónde se crean las keys»](#dónde-se-crean-las-keys) Las API keys se crean en WODira desde **Perfil de organización → API**. Necesitas acceder como organizador o miembro con permisos para administrar la organización. 1. Abre WODira y entra en el dashboard de tu organización. 2. Ve a **Perfil de organización**. 3. Abre la pestaña **API**. También puedes llegar con una ruta como `/organizer/{organizationId}/profile?tab=api`. 4. En **Nueva clave**, elige **Secret key (backend)** o **Publishable key (frontend)**. 5. Configura nombre, scopes u orígenes permitidos y pulsa **Crear clave**. 6. Copia la clave completa cuando aparezca. Por seguridad no volverá a mostrarse. Después de crearla, WODira solo muestra el prefijo/últimos caracteres, tipo, permisos, último uso y acciones como revocar. ## Secret keys [Sección titulada «Secret keys»](#secret-keys) Las secret keys empiezan por `wd_live_...` y se envían desde backend: ```bash curl -H "Authorization: Bearer wd_live_..." \ https://api.wodira.app/external/v1/organizer/events/search ``` También se acepta `x-api-key`. ## Publishable keys [Sección titulada «Publishable keys»](#publishable-keys) Las publishable keys empiezan por `wpk_live_...` y se envían desde navegador: ```http x-publishable-key: wpk_live_... Origin: https://organizador.com ``` El backend exige que `Origin` esté en `allowedOrigins` de la clave. ## Reglas importantes [Sección titulada «Reglas importantes»](#reglas-importantes) * Nunca pongas una secret key en JavaScript público. * Las publishable keys pueden estar en frontend, pero solo sirven para endpoints browser. * `successUrl` y `cancelUrl` deben pertenecer a un origin permitido. * Las claves caducadas o revocadas dejan de autenticar inmediatamente. --- # Referencia de endpoints > Resumen operativo de endpoints externos. ## Buscar eventos [Sección titulada «Buscar eventos»](#buscar-eventos) [`@wodira/browser.searchEvents`Listar eventos públicos desde frontend](/sdks/browser-sdk/#searchevents)[`@wodira/sdk.searchEvents`Buscar eventos desde backend](/sdks/backend-sdk/#searchevents) ### Browser API [Sección titulada «Browser API»](#browser-api) ```http POST /external/v1/browser/events/search x-publishable-key: wpk_live_... ``` Body: ```json { "search": "Madrid", "limit": 20, "offset": 0 } ``` ### Organizer API [Sección titulada «Organizer API»](#organizer-api) ```http POST /external/v1/organizer/events/search Authorization: Bearer wd_live_... ``` Permite además filtrar por `status` si la secret key tiene scope `events:read`. ## Detalle de evento [Sección titulada «Detalle de evento»](#detalle-de-evento) [`@wodira/browser.getEvent`Detalle público del evento](/sdks/browser-sdk/#getevent)[`@wodira/sdk.getEvent`Detalle completo server-to-server](/sdks/backend-sdk/#getevent) ```http GET /external/v1/browser/events/event_123 x-publishable-key: wpk_live_... ``` ```http GET /external/v1/organizer/events/event_123 Authorization: Bearer wd_live_... ``` ## Pricing cards [Sección titulada «Pricing cards»](#pricing-cards) [`@wodira/browser.getPricingCards`Categorías y precios públicos](/sdks/browser-sdk/#getpricingcards)[`@wodira/sdk.getPricingCards`Categorías, cupos y precios desde backend](/sdks/backend-sdk/#getpricingcards) ```http GET /external/v1/browser/events/event_123/pricing-cards x-publishable-key: wpk_live_... ``` Devuelve categorías, cupo, inscritos, precio base, precio activo y tiers. ```http GET /external/v1/organizer/events/event_123/pricing-cards Authorization: Bearer wd_live_... ``` ## Checkout summary [Sección titulada «Checkout summary»](#checkout-summary) [`@wodira/browser.getRegistrationSummary`Resumen reactivo antes de pagar](/sdks/browser-sdk/#getregistrationsummary) ```http POST /external/v1/browser/checkout/registration/summary x-publishable-key: wpk_live_... ``` ```json { "categoryId": "cat_123", "purchaserEmail": "buyer@example.com", "selectedSupplementIds": ["supp_123"], "promocode": "EARLY" } ``` ## Checkout session [Sección titulada «Checkout session»](#checkout-session) [`@wodira/browser.createRegistrationCheckoutSession`Crear Stripe Checkout Session](/sdks/browser-sdk/#createregistrationcheckoutsession) ```http POST /external/v1/browser/checkout/registration/session x-publishable-key: wpk_live_... ``` ```json { "eventId": "event_123", "categoryId": "cat_123", "purchaserEmail": "buyer@example.com", "purchaserName": "Buyer Name", "teamName": "Team Name", "termsAccepted": true, "waiversAccepted": { "waiver_123": true }, "idempotencyKey": "checkout_123", "successUrl": "https://organizador.com/gracias", "cancelUrl": "https://organizador.com/cancelado", "athletes": [ { "fullname": "Ada Lovelace", "email": "ada@example.com", "phone": "+34600000000", "idNumber": "12345678A", "gender": "FEMALE", "birthDate": "1990-01-01" } ] } ``` La respuesta incluye `sessionId` y `sessionUrl`; redirige a `sessionUrl` para abrir Stripe Checkout. ## Inscripciones server-to-server [Sección titulada «Inscripciones server-to-server»](#inscripciones-server-to-server) Usa la Organizer API solo desde backend. [`@wodira/sdk.createRegistration`Crear inscripción](/sdks/backend-sdk/#createregistration)[`@wodira/sdk.searchRegistrations`Buscar inscripciones](/sdks/backend-sdk/#searchregistrations)[`@wodira/sdk.updateRegistration`Actualizar inscripción](/sdks/backend-sdk/#updateregistration)[`@wodira/sdk.deleteRegistration`Cancelar/eliminar inscripción](/sdks/backend-sdk/#deleteregistration) | Método | Ruta completa | Scope | | -------- | ------------------------------------------------ | --------------------- | | `POST` | `/external/v1/organizer/registrations` | `registrations:write` | | `POST` | `/external/v1/organizer/registrations/search` | `registrations:read` | | `PATCH` | `/external/v1/organizer/registrations/:ticketId` | `registrations:write` | | `DELETE` | `/external/v1/organizer/registrations/:ticketId` | `registrations:write` | --- # Errores, rate limits e idempotencia > Cómo manejar errores y reintentos seguros. ## Errores [Sección titulada «Errores»](#errores) Los SDKs lanzan errores tipados: * `WodiraApiError` en `@wodira/sdk`. * `WodiraBrowserApiError` en `@wodira/browser`. Ambos incluyen `status`, `statusText` y `payload`. ```ts try { await wodira.getEvent('event_missing'); } catch (error) { if (error instanceof WodiraBrowserApiError) { console.error(error.status, error.payload); } } ``` ## Rate limits [Sección titulada «Rate limits»](#rate-limits) La creación de Checkout Session con publishable keys tiene rate limit por key y por IP. Si recibes `429`, espera antes de reintentar. ## Idempotencia [Sección titulada «Idempotencia»](#idempotencia) Envía `idempotencyKey` al crear una Checkout Session desde navegador. Reutiliza la misma clave para reintentos de la misma intención de compra. ```ts idempotencyKey: crypto.randomUUID(); ``` --- # Publishable keys y Browser API > Endpoints frontend disponibles con `wpk_live_...`. Usa publishable keys en webs públicas de organizadores. ## Crear una publishable key en WODira [Sección titulada «Crear una publishable key en WODira»](#crear-una-publishable-key-en-wodira) Usa publishable keys para código frontend. Son seguras para exponer en navegador solo porque WODira valida el `Origin` y limita estas claves a endpoints browser. 1. En WODira, entra en **Perfil de organización → API**. 2. En **Nueva clave**, selecciona **Publishable key (frontend)**. 3. Escribe un nombre reconocible, por ejemplo `web oficial producción`. 4. En **Orígenes permitidos**, añade un dominio por línea: ```txt https://organizador.com https://www.organizador.com ``` 5. Para desarrollo local puedes usar `http://localhost:4200` o el puerto de tu app local. No uses `http://` en producción. 6. Opcionalmente añade fecha de caducidad. 7. Pulsa **Crear clave** y copia la clave `wpk_live_...` inmediatamente. Guárdala en la configuración pública de tu frontend, por ejemplo en variables de entorno de build. No te da acceso a endpoints backend ni a datos privados de la organización. ## Validaciones de seguridad [Sección titulada «Validaciones de seguridad»](#validaciones-de-seguridad) 1. La clave empieza por `wpk_live_...`. 2. La clave no está revocada ni caducada. 3. La cabecera `Origin` es obligatoria. 4. El origin debe estar en `allowedOrigins`. 5. `successUrl` y `cancelUrl` deben pertenecer a un origin permitido. 6. Solo se exponen eventos y categorías publicados y no privados. ## Endpoints [Sección titulada «Endpoints»](#endpoints) | Método | Ruta | Método SDK | | ------ | -------------------------------- | ------------------------------------------------------------------------------------------- | | `POST` | `/events/search` | [`searchEvents`](/sdks/browser-sdk/#searchevents) | | `GET` | `/events/:eventId` | [`getEvent`](/sdks/browser-sdk/#getevent) | | `GET` | `/events/:eventId/pricing-cards` | [`getPricingCards`](/sdks/browser-sdk/#getpricingcards) | | `POST` | `/checkout/registration/summary` | [`getRegistrationSummary`](/sdks/browser-sdk/#getregistrationsummary) | | `POST` | `/checkout/registration/session` | [`createRegistrationCheckoutSession`](/sdks/browser-sdk/#createregistrationcheckoutsession) | ## Checkout directo a Stripe [Sección titulada «Checkout directo a Stripe»](#checkout-directo-a-stripe) La web externa recibe `sessionUrl` y redirige directamente a Stripe Checkout. WODira confirma la inscripción mediante webhooks de Stripe. --- # Secret keys y Organizer API > Endpoints backend disponibles con `wd_live_...`. Usa secret keys para integraciones server-to-server. ## Crear una secret key en WODira [Sección titulada «Crear una secret key en WODira»](#crear-una-secret-key-en-wodira) Usa secret keys solo en backends de confianza. Nunca las incluyas en bundles frontend, HTML, apps móviles públicas ni repositorios. 1. En WODira, entra en **Perfil de organización → API**. 2. En **Nueva clave**, selecciona **Secret key (backend)**. 3. Escribe un nombre reconocible, por ejemplo `backend producción` o `sync CRM`. 4. Selecciona solo los scopes necesarios para esa integración. 5. Opcionalmente añade fecha de caducidad. 6. Pulsa **Crear clave**. 7. Copia la clave `wd_live_...` inmediatamente y guárdala en un secret manager o variable de entorno. Ejemplo recomendado: ```bash WODIRA_API_KEY=wd_live_... ``` Si una secret key se filtra o ya no se usa, revócala desde **Claves existentes** y crea una nueva. ## Scopes [Sección titulada «Scopes»](#scopes) | Scope | Permiso | | --------------------- | -------------------------------------------------------------------------- | | `events:read` | Leer eventos, categorías, campos, waivers, sponsors y suplementos activos. | | `pricing:read` | Leer cards de tarifas, cupos y precio activo. | | `registrations:read` | Buscar inscripciones. | | `registrations:write` | Crear, actualizar y cancelar inscripciones. | ## Endpoints [Sección titulada «Endpoints»](#endpoints) | Método | Ruta | Scope | Método SDK | | -------- | -------------------------------- | --------------------- | --------------------------------------------------------------- | | `POST` | `/events/search` | `events:read` | [`searchEvents`](/sdks/backend-sdk/#searchevents) | | `GET` | `/events/:eventId` | `events:read` | [`getEvent`](/sdks/backend-sdk/#getevent) | | `GET` | `/events/:eventId/pricing-cards` | `pricing:read` | [`getPricingCards`](/sdks/backend-sdk/#getpricingcards) | | `POST` | `/registrations` | `registrations:write` | [`createRegistration`](/sdks/backend-sdk/#createregistration) | | `POST` | `/registrations/search` | `registrations:read` | [`searchRegistrations`](/sdks/backend-sdk/#searchregistrations) | | `PATCH` | `/registrations/:ticketId` | `registrations:write` | [`updateRegistration`](/sdks/backend-sdk/#updateregistration) | | `DELETE` | `/registrations/:ticketId` | `registrations:write` | [`deleteRegistration`](/sdks/backend-sdk/#deleteregistration) | ## Ejemplo [Sección titulada «Ejemplo»](#ejemplo) ```ts import { createWodiraClient } from '@wodira/sdk'; const wodira = createWodiraClient({ apiKey: process.env.WODIRA_API_KEY! }); const events = await wodira.searchEvents({ status: 'PUBLISHED', limit: 20 }); ``` --- # WODira Developers > Documentation for integrating external websites and backends with WODira. Developer platform # WODira Developers Public APIs, SDKs, and Web Components for organizer websites that sell registrations through Stripe Checkout. [Get started →](/en/getting-started/)[View UI Components](/en/ui-components/overview/) checkout-session.ts ``` // Frontend: publishable key + origin allowlist import { createWodiraBrowserClient } from ‘@wodira/browser’; const wodira = createWodiraBrowserClient({ publishableKey: ‘wpk_live_…’ }); const session = await wodira.createRegistrationCheckoutSession({ eventId, categoryId, athletes, termsAccepted: true, successUrl: 'https://organizer.com/success', cancelUrl: 'https://organizer.com/cancel' }); window.location.href = session.sessionUrl; ``` ### Stripe-like model, tailored to sports events Secret keys on backends, publishable keys in browsers, direct redirects to Stripe Checkout, and embeddable UI components. **2 SDKs**backend + browser **LLM**llms.txt + sets **UI**Lit Web Components ## Copy context for LLMs [Section titled “Copy context for LLMs”](#copy-context-for-llms) LLM-ready ### Docs ready for ChatGPT, Cursor, Claude, or agents Copy the general index or a focused set to give an LLM exact context about WODira external APIs, SDKs, and UI Components. **LLM index**Recommended starting point.[Open](/llms.txt) **SDKs**Methods, examples, and credentials.[Open](/_llms-txt/sdks.txt) **External API**Auth, endpoints, errors, and rate limits.[Open](/_llms-txt/external-api.txt) **UI Components**Web Components, events, and CSS variables.[Open](/_llms-txt/ui-components.txt) ## Choose your integration surface [Section titled “Choose your integration surface”](#choose-your-integration-surface) ### [External API](/en/api/overview/) [Versioned endpoints for events, pricing, registrations, errors, and idempotency.](/en/api/overview/) [/external/v1Scopes](/en/api/overview/) ### [TypeScript SDKs](/en/sdks/overview/) [Lightweight clients for trusted backends and browsers restricted by allowed origins.](/en/sdks/overview/) [@wodira/sdk@wodira/browser](/en/sdks/overview/) ### [UI Components](/en/ui-components/overview/) [Customizable Lit Web Components with CSS variables, DOM events, and checkout flow.](/en/ui-components/overview/) [LitCSS parts](/en/ui-components/overview/) ## Recommended architecture [Section titled “Recommended architecture”](#recommended-architecture) ### Organizer backend Use `wd_live_...` only on servers. Read private data, manage server-to-server registrations, and keep operational control. Bearer authregistrations:writeNo browser ### Public organizer website Use `wpk_live_...` with `allowedOrigins`. List published events, calculate summaries, and create Stripe Checkout Sessions. Origin requiredStripe CheckoutNo secrets ## Quick routes [Section titled “Quick routes”](#quick-routes) * [External API](/en/api/overview/) * [Authentication](/en/api/authentication/) * [Backend SDK](/en/sdks/backend-sdk/) * [Browser SDK](/en/sdks/browser-sdk/) * [Checkout Flow Web Component](/en/ui-components/checkout-flow/) * [Production checklist](/en/security/production-checklist/) --- # Authentication > Secret keys versus publishable keys. ## Where keys are created [Section titled “Where keys are created”](#where-keys-are-created) API keys are created in WODira under **Organization profile → API**. You must sign in as an organizer or as a member with permission to manage the organization. 1. Open WODira and enter your organization dashboard. 2. Go to **Organization profile**. 3. Open the **API** tab. You can also use a route such as `/organizer/{organizationId}/profile?tab=api`. 4. In **New key**, choose **Secret key (backend)** or **Publishable key (frontend)**. 5. Configure the name, scopes or allowed origins, then click **Create key**. 6. Copy the full key when it appears. For security, it will not be shown again. After creation, WODira only shows the prefix/last characters, type, permissions, last use, and actions such as revoke. ## Secret keys [Section titled “Secret keys”](#secret-keys) Secret keys start with `wd_live_...` and are sent from backends: ```bash curl -H "Authorization: Bearer wd_live_..." \ https://api.wodira.app/external/v1/organizer/events/search ``` `x-api-key` is also accepted. ## Publishable keys [Section titled “Publishable keys”](#publishable-keys) Publishable keys start with `wpk_live_...` and are sent from browsers: ```http x-publishable-key: wpk_live_... Origin: https://organizer.com ``` The backend requires `Origin` to match one of the key’s `allowedOrigins`. ## Rules [Section titled “Rules”](#rules) * Never expose a secret key in public JavaScript. * Publishable keys only work with browser endpoints. * `successUrl` and `cancelUrl` must belong to an allowed origin. * Revoked or expired keys stop authenticating immediately. --- # Endpoint reference > Operational summary of external endpoints. ## Search events [Section titled “Search events”](#search-events) [`@wodira/browser.searchEvents`List public events from the frontend](/en/sdks/browser-sdk/#searchevents)[`@wodira/sdk.searchEvents`Search events from a backend](/en/sdks/backend-sdk/#searchevents) ### Browser API [Section titled “Browser API”](#browser-api) ```http POST /external/v1/browser/events/search x-publishable-key: wpk_live_... ``` ```json { "search": "Madrid", "limit": 20, "offset": 0 } ``` ### Organizer API [Section titled “Organizer API”](#organizer-api) ```http POST /external/v1/organizer/events/search Authorization: Bearer wd_live_... ``` Also supports `status` filters when the secret key has the `events:read` scope. ## Event details [Section titled “Event details”](#event-details) [`@wodira/browser.getEvent`Public event detail](/en/sdks/browser-sdk/#getevent)[`@wodira/sdk.getEvent`Full server-to-server event detail](/en/sdks/backend-sdk/#getevent) ```http GET /external/v1/browser/events/event_123 x-publishable-key: wpk_live_... ``` ```http GET /external/v1/organizer/events/event_123 Authorization: Bearer wd_live_... ``` ## Pricing cards [Section titled “Pricing cards”](#pricing-cards) [`@wodira/browser.getPricingCards`Public categories and prices](/en/sdks/browser-sdk/#getpricingcards)[`@wodira/sdk.getPricingCards`Categories, quotas, and prices from a backend](/en/sdks/backend-sdk/#getpricingcards) ```http GET /external/v1/browser/events/event_123/pricing-cards x-publishable-key: wpk_live_... ``` Returns categories, quotas, registrations, base price, active price, and tiers. ```http GET /external/v1/organizer/events/event_123/pricing-cards Authorization: Bearer wd_live_... ``` ## Checkout summary [Section titled “Checkout summary”](#checkout-summary) [`@wodira/browser.getRegistrationSummary`Reactive summary before payment](/en/sdks/browser-sdk/#getregistrationsummary) ```http POST /external/v1/browser/checkout/registration/summary x-publishable-key: wpk_live_... ``` ```json { "categoryId": "cat_123", "purchaserEmail": "buyer@example.com", "selectedSupplementIds": ["supp_123"], "promocode": "EARLY" } ``` ## Checkout session [Section titled “Checkout session”](#checkout-session) [`@wodira/browser.createRegistrationCheckoutSession`Create a Stripe Checkout Session](/en/sdks/browser-sdk/#createregistrationcheckoutsession) ```http POST /external/v1/browser/checkout/registration/session x-publishable-key: wpk_live_... ``` ```json { "eventId": "event_123", "categoryId": "cat_123", "purchaserEmail": "buyer@example.com", "purchaserName": "Buyer Name", "teamName": "Team Name", "termsAccepted": true, "waiversAccepted": { "waiver_123": true }, "idempotencyKey": "checkout_123", "successUrl": "https://organizer.com/success", "cancelUrl": "https://organizer.com/cancel", "athletes": [ { "fullname": "Ada Lovelace", "email": "ada@example.com", "phone": "+34600000000", "idNumber": "12345678A", "gender": "FEMALE", "birthDate": "1990-01-01" } ] } ``` The response includes `sessionId` and `sessionUrl`; redirect to `sessionUrl` to open Stripe Checkout. ## Server-to-server registrations [Section titled “Server-to-server registrations”](#server-to-server-registrations) Use the Organizer API only from a backend. [`@wodira/sdk.createRegistration`Create a registration](/en/sdks/backend-sdk/#createregistration)[`@wodira/sdk.searchRegistrations`Search registrations](/en/sdks/backend-sdk/#searchregistrations)[`@wodira/sdk.updateRegistration`Update a registration](/en/sdks/backend-sdk/#updateregistration)[`@wodira/sdk.deleteRegistration`Cancel/delete a registration](/en/sdks/backend-sdk/#deleteregistration) | Method | Full path | Scope | | -------- | ------------------------------------------------ | --------------------- | | `POST` | `/external/v1/organizer/registrations` | `registrations:write` | | `POST` | `/external/v1/organizer/registrations/search` | `registrations:read` | | `PATCH` | `/external/v1/organizer/registrations/:ticketId` | `registrations:write` | | `DELETE` | `/external/v1/organizer/registrations/:ticketId` | `registrations:write` | --- # Errors, rate limits, and idempotency > How to handle failures and safe retries. ## Errors [Section titled “Errors”](#errors) SDKs throw typed errors: * `WodiraApiError` in `@wodira/sdk`. * `WodiraBrowserApiError` in `@wodira/browser`. Both include `status`, `statusText`, and `payload`. ## Rate limits [Section titled “Rate limits”](#rate-limits) Creating Checkout Sessions with publishable keys is rate-limited per key and IP. If you receive `429`, wait before retrying. ## Idempotency [Section titled “Idempotency”](#idempotency) Send `idempotencyKey` when creating a browser Checkout Session. Reuse the same key for retries of the same purchase intent. --- # Publishable keys and Browser API > Frontend endpoints available with `wpk_live_...`. Use publishable keys in public organizer websites. ## Create a publishable key in WODira [Section titled “Create a publishable key in WODira”](#create-a-publishable-key-in-wodira) Use publishable keys for frontend code. They can be exposed in the browser because WODira validates the `Origin` and limits these keys to browser endpoints. 1. In WODira, go to **Organization profile → API**. 2. In **New key**, select **Publishable key (frontend)**. 3. Add a recognizable name, for example `official website production`. 4. In **Allowed origins**, add one domain per line: ```txt https://organizer.com https://www.organizer.com ``` 5. For local development, you can use `http://localhost:4200` or the port of your local app. Do not use `http://` in production. 6. Optionally set an expiration date. 7. Click **Create key** and copy the `wpk_live_...` key immediately. Store it in your frontend public configuration, for example build-time environment variables. It does not grant access to backend endpoints or private organization data. ## Security checks [Section titled “Security checks”](#security-checks) 1. The key starts with `wpk_live_...`. 2. The key is not revoked or expired. 3. The `Origin` header is required. 4. The origin must be in `allowedOrigins`. 5. `successUrl` and `cancelUrl` must belong to an allowed origin. 6. Only public, published events and categories are exposed. ## Endpoints [Section titled “Endpoints”](#endpoints) | Method | Path | SDK method | | ------ | -------------------------------- | ---------------------------------------------------------------------------------------------- | | `POST` | `/events/search` | [`searchEvents`](/en/sdks/browser-sdk/#searchevents) | | `GET` | `/events/:eventId` | [`getEvent`](/en/sdks/browser-sdk/#getevent) | | `GET` | `/events/:eventId/pricing-cards` | [`getPricingCards`](/en/sdks/browser-sdk/#getpricingcards) | | `POST` | `/checkout/registration/summary` | [`getRegistrationSummary`](/en/sdks/browser-sdk/#getregistrationsummary) | | `POST` | `/checkout/registration/session` | [`createRegistrationCheckoutSession`](/en/sdks/browser-sdk/#createregistrationcheckoutsession) | --- # Secret keys and Organizer API > Backend endpoints available with `wd_live_...`. Use secret keys for server-to-server integrations. ## Create a secret key in WODira [Section titled “Create a secret key in WODira”](#create-a-secret-key-in-wodira) Use secret keys only in trusted backends. Never include them in frontend bundles, HTML, public mobile apps, or repositories. 1. In WODira, go to **Organization profile → API**. 2. In **New key**, select **Secret key (backend)**. 3. Add a recognizable name, for example `production backend` or `CRM sync`. 4. Select only the scopes required by that integration. 5. Optionally set an expiration date. 6. Click **Create key**. 7. Copy the `wd_live_...` key immediately and store it in a secret manager or environment variable. Recommended example: ```bash WODIRA_API_KEY=wd_live_... ``` If a secret key leaks or is no longer used, revoke it from **Existing keys** and create a new one. ## Scopes [Section titled “Scopes”](#scopes) | Scope | Permission | | --------------------- | -------------------------------------------------------------------------------- | | `events:read` | Read events, categories, form fields, waivers, sponsors, and active supplements. | | `pricing:read` | Read pricing cards, quotas, and active prices. | | `registrations:read` | Search registrations. | | `registrations:write` | Create, update, and cancel registrations. | ## Endpoints [Section titled “Endpoints”](#endpoints) | Method | Path | Scope | SDK method | | -------- | -------------------------------- | --------------------- | ------------------------------------------------------------------ | | `POST` | `/events/search` | `events:read` | [`searchEvents`](/en/sdks/backend-sdk/#searchevents) | | `GET` | `/events/:eventId` | `events:read` | [`getEvent`](/en/sdks/backend-sdk/#getevent) | | `GET` | `/events/:eventId/pricing-cards` | `pricing:read` | [`getPricingCards`](/en/sdks/backend-sdk/#getpricingcards) | | `POST` | `/registrations` | `registrations:write` | [`createRegistration`](/en/sdks/backend-sdk/#createregistration) | | `POST` | `/registrations/search` | `registrations:read` | [`searchRegistrations`](/en/sdks/backend-sdk/#searchregistrations) | | `PATCH` | `/registrations/:ticketId` | `registrations:write` | [`updateRegistration`](/en/sdks/backend-sdk/#updateregistration) | | `DELETE` | `/registrations/:ticketId` | `registrations:write` | [`deleteRegistration`](/en/sdks/backend-sdk/#deleteregistration) | --- # Backend SDK > Server-to-server client for the Organizer API. ## Install [Section titled “Install”](#install) ```bash pnpm add @wodira/sdk ``` ## Quickstart [Section titled “Quickstart”](#quickstart) ```ts import { createWodiraClient } from '@wodira/sdk'; const wodira = createWodiraClient({ apiKey: process.env.WODIRA_API_KEY!, }); const events = await wodira.searchEvents({ status: 'PUBLISHED', limit: 20 }); const pricing = await wodira.getPricingCards(events.data[0].id); ``` ## Methods [Section titled “Methods”](#methods) [`searchEvents`Search organizer events](#searchevents)[`getEvent`Read full event details](#getevent)[`getPricingCards`Read categories, quotas, and prices](#getpricingcards)[`createRegistration`Create server-to-server registration](#createregistration)[`searchRegistrations`Search registrations/tickets](#searchregistrations)[`updateRegistration`Update a registration](#updateregistration)[`deleteRegistration`Cancel/delete a registration](#deleteregistration) ### `searchEvents` [Section titled “searchEvents”](#searchevents) Searches events for the authenticated organizer. Use it to sync catalogs, show internal listings, or find an `eventId` before reading pricing or registrations. ```ts const events = await wodira.searchEvents({ search: 'Madrid', status: 'PUBLISHED', limit: 20, offset: 0, }); ``` * **Endpoint:** [`POST /external/v1/organizer/events/search`](/en/api/endpoints/#search-events) * **Required scope:** `events:read` ### `getEvent` [Section titled “getEvent”](#getevent) Reads full event details, including categories, form fields, waivers, sponsors, and active supplements. ```ts const event = await wodira.getEvent('event_123'); ``` * **Endpoint:** [`GET /external/v1/organizer/events/:eventId`](/en/api/endpoints/#event-details) * **Required scope:** `events:read` ### `getPricingCards` [Section titled “getPricingCards”](#getpricingcards) Returns sellable event categories with quota, registered count, base price, active price, and tiers. Use it before creating a registration. ```ts const pricing = await wodira.getPricingCards('event_123'); const firstCategory = pricing.cards[0]; ``` * **Endpoint:** [`GET /external/v1/organizer/events/:eventId/pricing-cards`](/en/api/endpoints/#pricing-cards) * **Required scope:** `pricing:read` ### `createRegistration` [Section titled “createRegistration”](#createregistration) Creates a registration from a trusted backend using a secret key. Do not use this method in the browser; for public checkout use [`createRegistrationCheckoutSession`](/en/sdks/browser-sdk/#createregistrationcheckoutsession) from `@wodira/browser`. ```ts const order = await wodira.createRegistration({ eventId: 'event_123', categoryId: 'cat_123', purchaserEmail: 'buyer@example.com', purchaserName: 'Buyer Name', termsAccepted: true, athletes: [{ fullname: 'Ada Lovelace', email: 'ada@example.com' }], }); ``` * **Endpoint:** [`POST /external/v1/organizer/registrations`](/en/api/endpoints/#server-to-server-registrations) * **Required scope:** `registrations:write` ### `searchRegistrations` [Section titled “searchRegistrations”](#searchregistrations) Searches registrations/tickets for reconciliation, support, or syncing with external systems. ```ts const registrations = await wodira.searchRegistrations({ eventId: 'event_123', search: 'ada@example.com', limit: 50, }); ``` * **Endpoint:** [`POST /external/v1/organizer/registrations/search`](/en/api/endpoints/#server-to-server-registrations) * **Required scope:** `registrations:read` ### `updateRegistration` [Section titled “updateRegistration”](#updateregistration) Updates an existing registration from a backend when the integrator owns support or edit flows. ```ts const ticket = await wodira.updateRegistration('ticket_123', { purchaserName: 'Ada L.', }); ``` * **Endpoint:** [`PATCH /external/v1/organizer/registrations/:ticketId`](/en/api/endpoints/#server-to-server-registrations) * **Required scope:** `registrations:write` ### `deleteRegistration` [Section titled “deleteRegistration”](#deleteregistration) Cancels or deletes a registration from a backend according to WODira operational rules. ```ts await wodira.deleteRegistration('ticket_123'); ``` * **Endpoint:** [`DELETE /external/v1/organizer/registrations/:ticketId`](/en/api/endpoints/#server-to-server-registrations) * **Required scope:** `registrations:write` --- # SDK overview > Differences between the backend SDK and browser SDK. WODira offers two TypeScript SDKs with the same mental model as Stripe: a secure server library and a browser-ready client. [`@wodira/sdk`Secret keys, scopes, and server-to-server operations.](/en/sdks/backend-sdk/)[`@wodira/browser`Publishable keys, Origin allowlist, and Stripe Checkout.](/en/sdks/browser-sdk/) | Package | Runtime | Credential | Reference | | ----------------- | ---------------- | -------------- | ------------------------------------------------ | | `@wodira/sdk` | Backend/server | `wd_live_...` | [Backend methods](/en/sdks/backend-sdk/#methods) | | `@wodira/browser` | Browser/frontend | `wpk_live_...` | [Browser methods](/en/sdks/browser-sdk/#methods) | ## Quick method map [Section titled “Quick method map”](#quick-method-map) | I need to… | Recommended method | | --------------------------------------------- | -------------------------------------------------------------------------------------------------------------- | | List public events on a website | [`@wodira/browser.searchEvents`](/en/sdks/browser-sdk/#searchevents) | | Read public event details | [`@wodira/browser.getEvent`](/en/sdks/browser-sdk/#getevent) | | Render categories and prices | [`@wodira/browser.getPricingCards`](/en/sdks/browser-sdk/#getpricingcards) | | Preview the checkout total before payment | [`@wodira/browser.getRegistrationSummary`](/en/sdks/browser-sdk/#getregistrationsummary) | | Create a Stripe Checkout Session | [`@wodira/browser.createRegistrationCheckoutSession`](/en/sdks/browser-sdk/#createregistrationcheckoutsession) | | Sync events from a backend | [`@wodira/sdk.searchEvents`](/en/sdks/backend-sdk/#searchevents) | | Create or manage registrations from a backend | [`@wodira/sdk.createRegistration`](/en/sdks/backend-sdk/#createregistration) | | Search/update/cancel tickets from a backend | [`@wodira/sdk.searchRegistrations`](/en/sdks/backend-sdk/#searchregistrations) | The backend SDK throws if it detects browser execution. The browser SDK does not accept secret keys. --- # Production checklist > Minimum review before publishing an external integration. ## Keys [Section titled “Keys”](#keys) * [ ] Secret keys only run in backends. * [ ] Publishable keys only include required origins. * [ ] Unused keys are revoked. * [ ] Expiration is configured when appropriate. ## Checkout [Section titled “Checkout”](#checkout) * [ ] `successUrl` and `cancelUrl` belong to an allowed origin. * [ ] `idempotencyKey` is sent for each purchase attempt. * [ ] Terms and required waivers are accepted. * [ ] 4xx/5xx and 429 errors are handled. ## UI Components [Section titled “UI Components”](#ui-components) * [ ] Tested in Chrome, Safari, and Firefox. * [ ] Theme reviewed with CSS variables. * [ ] Flow tested with a real test publishable key. * [ ] Stripe webhook is configured in WODira to confirm orders. --- # Visual customization > CSS variables and parts for organizer branding. ## CSS variables [Section titled “CSS variables”](#css-variables) ```css wodira-checkout-flow { --wodira-color-primary: #111827; --wodira-color-accent: #f97316; --wodira-radius: 18px; --wodira-font-family: Inter, system-ui, sans-serif; } ``` ## Parts [Section titled “Parts”](#parts) ```css wodira-checkout-flow::part(button) { text-transform: uppercase; } ``` Main parts: `card`, `event-card`, `pricing-card`, `registration-form`, `summary`, `button`, `input`, `select`, `textarea`, `checkbox`, `label`, `title`, `price`, `meta`, `hint`, `error`, `field-error`, `loader`, `empty`, `waiver`, `supplement`. --- # DOM events > CustomEvents emitted by Web Components. Events bubble and are composed. | Event | When | | ------------------------- | --------------------------------------------- | | `wodira:event-select` | User selects an event. | | `wodira:category-select` | User selects a category. | | `wodira:checkout-start` | Checkout Session creation starts. | | `wodira:checkout-created` | WODira returns a session. | | `wodira:redirect` | The component is about to redirect to Stripe. | | `wodira:error` | A recoverable error occurs. | --- # UI Components overview > Reusable Web Components for organizer websites. `@wodira/browser/ui` includes Lit Web Components that embed WODira in any website, with or without a framework. ## Components [Section titled “Components”](#components) * ``: full event → category → registration → Stripe Checkout flow. * ``: published event list. * ``: reusable event card. * ``: categories, prices, and selection. * ``: registration form. See them rendered with safe mock data in the [interactive showcase](/en/ui-components/showcase/). ## Register components [Section titled “Register components”](#register-components) ```ts import { defineWodiraElements } from '@wodira/browser/ui'; defineWodiraElements(); ``` --- # Interactive showcase > Real @wodira/browser/ui Web Component previews with safe mock data and a real demo API flow. This page renders the real components shipped by `@wodira/browser/ui`. The first previews use an in-browser mock backend to test states without external effects. The **Live checkout demo** block uses WODira’s demo API, a real origin-limited publishable key, and the `DOCSDEMO100` coupon to create a complete registration without a Stripe card. Web Components en vivo ## Componentes reales de @wodira/browser/ui Estos previews renderizan los mismos Web Components Lit que publica el browser SDK. Los componentes interactivos usan la Browser API demo real; la card de evento mantiene datos estáticos de ejemplo. API demo real Event card `` Lista de eventos `` Pricing cards `` Envío de comprobante `` API demo real Este bloque usa el evento demo real y la Browser API real. Prueba un email con inscripción completada como docs-live-1779433120411\@example.com. Formulario de inscripción `` Checkout flow `` Demo de reserva real `` API demo real Este bloque usa el evento real de demo, la Browser API real y los Web Components reales. El cupón demo DOCSDEMO100 se rellena automáticamente para completar la inscripción sin tarjeta Stripe. ## What this demo validates [Section titled “What this demo validates”](#what-this-demo-validates) * Custom elements are registered with [`defineWodiraElements`](/en/ui-components/checkout-flow/#html). * Mock previews use the browser SDK public API against `https://docs.wodira.local`. * The live demo uses `http://localhost:3000` locally and `https://api.demo.wodira.app` when docs are deployed. * DOM events and selection states are the same ones an integrator receives. * WODira theme CSS variables are applied to real components, not screenshots. * The live flow creates a registration visible in the demo organizer dashboard. ## Base code [Section titled “Base code”](#base-code) ```html ``` To connect it to production, create a [publishable key](/en/api/publishable-keys/) with your domains in allowed origins and replace the mock IDs with real WODira IDs. --- # SDK para backend > Cliente server-to-server para Organizer API. @wodira/sdkServer-to-server · secret keys · scopes ## Instalación [Sección titulada «Instalación»](#instalación) ```bash pnpm add @wodira/sdk ``` ## Uso básico [Sección titulada «Uso básico»](#uso-básico) ```ts import { createWodiraClient } from '@wodira/sdk'; const wodira = createWodiraClient({ apiKey: process.env.WODIRA_API_KEY!, }); const events = await wodira.searchEvents({ status: 'PUBLISHED', limit: 20 }); const pricing = await wodira.getPricingCards(events.data[0].id); ``` ## Métodos [Sección titulada «Métodos»](#métodos) [`searchEvents`Buscar eventos del organizador](#searchevents)[`getEvent`Leer detalle completo de evento](#getevent)[`getPricingCards`Consultar categorías, cupos y precios](#getpricingcards)[`createRegistration`Crear inscripción server-to-server](#createregistration)[`searchRegistrations`Buscar inscripciones/tickets](#searchregistrations)[`updateRegistration`Actualizar una inscripción](#updateregistration)[`deleteRegistration`Cancelar/eliminar inscripción](#deleteregistration) ### `searchEvents` [Sección titulada «searchEvents»](#searchevents) Busca eventos del organizador autenticado. Úsalo para sincronizar catálogos, mostrar listados internos o localizar el `eventId` antes de consultar pricing o inscripciones. ```ts const events = await wodira.searchEvents({ search: 'Madrid', status: 'PUBLISHED', limit: 20, offset: 0, }); ``` * **Endpoint:** [`POST /external/v1/organizer/events/search`](/api/endpoints/#buscar-eventos) * **Scope requerido:** `events:read` ### `getEvent` [Sección titulada «getEvent»](#getevent) Obtiene el detalle de un evento concreto, incluyendo categorías, campos de formulario, waivers, sponsors y suplementos activos. ```ts const event = await wodira.getEvent('event_123'); ``` * **Endpoint:** [`GET /external/v1/organizer/events/:eventId`](/api/endpoints/#detalle-de-evento) * **Scope requerido:** `events:read` ### `getPricingCards` [Sección titulada «getPricingCards»](#getpricingcards) Devuelve las categorías vendibles de un evento con cupo, inscritos, precio base, precio activo y tiers. Es el método recomendado antes de crear una inscripción. ```ts const pricing = await wodira.getPricingCards('event_123'); const firstCategory = pricing.cards[0]; ``` * **Endpoint:** [`GET /external/v1/organizer/events/:eventId/pricing-cards`](/api/endpoints/#pricing-cards) * **Scope requerido:** `pricing:read` ### `createRegistration` [Sección titulada «createRegistration»](#createregistration) Crea una inscripción desde un backend de confianza usando secret key. No uses este método desde navegador; para checkout público usa [`createRegistrationCheckoutSession`](/sdks/browser-sdk/#createregistrationcheckoutsession) en `@wodira/browser`. ```ts const order = await wodira.createRegistration({ eventId: 'event_123', categoryId: 'cat_123', purchaserEmail: 'buyer@example.com', purchaserName: 'Buyer Name', termsAccepted: true, athletes: [{ fullname: 'Ada Lovelace', email: 'ada@example.com' }], }); ``` * **Endpoint:** [`POST /external/v1/organizer/registrations`](/api/endpoints/#inscripciones-server-to-server) * **Scope requerido:** `registrations:write` ### `searchRegistrations` [Sección titulada «searchRegistrations»](#searchregistrations) Busca inscripciones/tickets para conciliación, soporte o sincronización con sistemas propios. ```ts const registrations = await wodira.searchRegistrations({ eventId: 'event_123', search: 'ada@example.com', limit: 50, }); ``` * **Endpoint:** [`POST /external/v1/organizer/registrations/search`](/api/endpoints/#inscripciones-server-to-server) * **Scope requerido:** `registrations:read` ### `updateRegistration` [Sección titulada «updateRegistration»](#updateregistration) Actualiza datos de una inscripción existente desde backend cuando el integrador mantiene flujos de soporte o edición propios. ```ts const ticket = await wodira.updateRegistration('ticket_123', { purchaserName: 'Ada L.', }); ``` * **Endpoint:** [`PATCH /external/v1/organizer/registrations/:ticketId`](/api/endpoints/#inscripciones-server-to-server) * **Scope requerido:** `registrations:write` ### `deleteRegistration` [Sección titulada «deleteRegistration»](#deleteregistration) Cancela o elimina una inscripción desde backend según las reglas operativas de WODira. ```ts await wodira.deleteRegistration('ticket_123'); ``` * **Endpoint:** [`DELETE /external/v1/organizer/registrations/:ticketId`](/api/endpoints/#inscripciones-server-to-server) * **Scope requerido:** `registrations:write` ## Seguridad [Sección titulada «Seguridad»](#seguridad) Guarda `wd_live_...` en variables de entorno o secret manager. Nunca la envíes al navegador. --- # Overview de SDKs > Diferencias entre el SDK backend y el SDK browser. WODira ofrece dos SDKs TypeScript con el mismo modelo mental que Stripe: una librería segura para servidor y otra preparada para navegador. [`@wodira/sdk`Secret keys, scopes y operaciones server-to-server.](/sdks/backend-sdk/)[`@wodira/browser`Publishable keys, Origin allowlist y Stripe Checkout.](/sdks/browser-sdk/) | Paquete | Runtime | Credencial | Referencia | | ----------------- | ---------------- | -------------- | ------------------------------------- | | `@wodira/sdk` | Backend/server | `wd_live_...` | [Métodos backend](/sdks/backend-sdk/) | | `@wodira/browser` | Browser/frontend | `wpk_live_...` | [Métodos browser](/sdks/browser-sdk/) | ## Mapa rápido de métodos [Sección titulada «Mapa rápido de métodos»](#mapa-rápido-de-métodos) | Necesito… | Método recomendado | | ------------------------------------------------ | ----------------------------------------------------------------------------------------------------------- | | Listar eventos públicos en una web | [`@wodira/browser.searchEvents`](/sdks/browser-sdk/#searchevents) | | Leer detalle público de un evento | [`@wodira/browser.getEvent`](/sdks/browser-sdk/#getevent) | | Mostrar categorías y precios | [`@wodira/browser.getPricingCards`](/sdks/browser-sdk/#getpricingcards) | | Previsualizar el total antes de pagar | [`@wodira/browser.getRegistrationSummary`](/sdks/browser-sdk/#getregistrationsummary) | | Crear una Stripe Checkout Session | [`@wodira/browser.createRegistrationCheckoutSession`](/sdks/browser-sdk/#createregistrationcheckoutsession) | | Sincronizar eventos desde backend | [`@wodira/sdk.searchEvents`](/sdks/backend-sdk/#searchevents) | | Crear o gestionar inscripciones desde backend | [`@wodira/sdk.createRegistration`](/sdks/backend-sdk/#createregistration) | | Buscar/actualizar/cancelar tickets desde backend | [`@wodira/sdk.searchRegistrations`](/sdks/backend-sdk/#searchregistrations) | El SDK backend lanza error si detecta ejecución en navegador. El SDK browser no acepta secret keys. --- # Checklist de producción > Revisión mínima antes de publicar una integración externa. ## Claves [Sección titulada «Claves»](#claves) * [ ] Secret keys solo en backend. * [ ] Publishable keys solo con origins necesarios. * [ ] Claves revocadas si ya no se usan. * [ ] Caducidad configurada cuando aplique. ## Checkout [Sección titulada «Checkout»](#checkout) * [ ] `successUrl` y `cancelUrl` pertenecen al origin permitido. * [ ] Se envía `idempotencyKey` por intento de compra. * [ ] Se aceptan términos y waivers requeridos. * [ ] Se manejan errores 4xx/5xx y 429. ## UI Components [Sección titulada «UI Components»](#ui-components) * [ ] Probado en Chrome, Safari y Firefox. * [ ] Tema revisado con CSS variables. * [ ] Flujo probado con una publishable key real de test. * [ ] Webhook Stripe configurado en WODira para confirmar pedidos. --- # Personalización visual > CSS variables y parts para adaptar los componentes a la marca del organizador. ## CSS variables [Sección titulada «CSS variables»](#css-variables) ```css wodira-checkout-flow { --wodira-color-primary: #111827; --wodira-color-accent: #f97316; --wodira-radius: 18px; --wodira-font-family: Inter, system-ui, sans-serif; } ``` Variables soportadas: * `--wodira-color-primary` * `--wodira-color-primary-contrast` * `--wodira-color-accent` * `--wodira-color-surface` * `--wodira-color-muted` * `--wodira-color-border` * `--wodira-color-text` * `--wodira-color-text-muted` * `--wodira-color-danger` * `--wodira-radius` * `--wodira-radius-sm` * `--wodira-space` * `--wodira-font-family` * `--wodira-shadow` ## Parts [Sección titulada «Parts»](#parts) ```css wodira-checkout-flow::part(button) { text-transform: uppercase; } wodira-checkout-flow::part(card) { border-width: 2px; } ``` Parts principales: `card`, `event-card`, `pricing-card`, `registration-form`, `summary`, `button`, `input`, `select`, `textarea`, `checkbox`, `label`, `title`, `price`, `meta`, `hint`, `error`, `field-error`, `loader`, `empty`, `waiver`, `supplement`. --- # Eventos DOM > CustomEvents emitidos por los Web Components. Los componentes emiten eventos con `bubbles: true` y `composed: true`. | Evento | Cuándo se emite | | ------------------------- | ---------------------------------------- | | `wodira:event-select` | El usuario selecciona un evento. | | `wodira:category-select` | El usuario selecciona una categoría. | | `wodira:checkout-start` | Empieza la creación de Checkout Session. | | `wodira:checkout-created` | WODira devuelve una sesión. | | `wodira:redirect` | El componente va a redirigir a Stripe. | | `wodira:error` | Ocurre un error recuperable. | ```ts document.addEventListener('wodira:error', (event) => { console.error(event.detail.message); }); ``` --- # Overview de UI Components > Web Components reutilizables para webs de organizadores. `@wodira/browser/ui` incluye Web Components basados en Lit para incrustar WODira en cualquier web, con o sin framework. ## Componentes [Sección titulada «Componentes»](#componentes) * ``: embudo completo evento → categoría → inscripción → Stripe Checkout. * ``: lista eventos publicados. * ``: tarjeta de evento. * ``: categorías, precios y selección. * ``: formulario de inscripción. Puedes verlos renderizados con datos mock seguros en el [showcase interactivo](/ui-components/showcase/). ## Registrar componentes [Sección titulada «Registrar componentes»](#registrar-componentes) ```ts import { defineWodiraElements } from '@wodira/browser/ui'; defineWodiraElements(); ``` --- # Showcase interactivo > Previews reales de los Web Components de @wodira/browser/ui con mock seguro y demo API real. Esta página renderiza los componentes reales publicados por `@wodira/browser/ui`. Los primeros ejemplos usan un backend mock en memoria dentro del navegador para probar estados sin efectos externos. El bloque **Demo de reserva real** usa la API demo de WODira, una publishable key real limitada por origen y el cupón `DOCSDEMO100` para crear una inscripción completa sin tarjeta Stripe. Web Components en vivo ## Componentes reales de @wodira/browser/ui Estos previews renderizan los mismos Web Components Lit que publica el browser SDK. Los componentes interactivos usan la Browser API demo real; la card de evento mantiene datos estáticos de ejemplo. API demo real Event card `` Lista de eventos `` Pricing cards `` Envío de comprobante `` API demo real Este bloque usa el evento demo real y la Browser API real. Prueba un email con inscripción completada como docs-live-1779433120411\@example.com. Formulario de inscripción `` Checkout flow `` Demo de reserva real `` API demo real Este bloque usa el evento real de demo, la Browser API real y los Web Components reales. El cupón demo DOCSDEMO100 se rellena automáticamente para completar la inscripción sin tarjeta Stripe. ## Qué valida esta demo [Sección titulada «Qué valida esta demo»](#qué-valida-esta-demo) * Los custom elements se registran con [`defineWodiraElements`](/ui-components/checkout-flow/#html). * Los previews mock usan la API pública del browser SDK contra `https://docs.wodira.local`. * La demo real usa `http://localhost:3000` en local y `https://api.demo.wodira.app` al desplegar docs. * Los eventos DOM y estados de selección son los mismos que verá un integrador. * Las CSS variables del theme WODira se aplican sobre componentes reales, no sobre capturas. * El flujo real crea una inscripción visible en el panel del organizador de demo. ## Código base [Sección titulada «Código base»](#código-base) ```html ``` Para conectarlo a producción, crea una [publishable key](/api/publishable-keys/) con tus dominios en allowed origins y reemplaza los IDs mock por IDs reales de WODira.