SDKs: Backend and browser TypeScript SDK usage. --- # 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 --- # 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. --- # 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.