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

# Bookable quickstart

> Crea una oferta reservable en una llamada, lista slots, crea un booking checkout y confirma la reserva por webhook.

Este quickstart crea una oferta programada con capacidad, obtiene slots y crea un checkout de reserva.

## 1. Variables

```bash terminal theme={"theme":{"light":"github-light","dark":"github-dark"}}
export SIMPLEPAY_API_BASE="https://api.simplepay.mx"
export SIMPLEPAY_API_KEY="spk_sandbox_..."
```

## 2. Lee el contrato Bookable

```bash terminal theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sS "$SIMPLEPAY_API_BASE/v1/bookable-payments/config" \
  -H "Authorization: Bearer $SIMPLEPAY_API_KEY"
```

La respuesta describe use cases, scopes, eventos, blueprints y pasos de readiness.

## 3. Crea el setup en una llamada

```bash terminal theme={"theme":{"light":"github-light","dark":"github-dark"}}
SETUP="$(
  curl -sS -X POST "$SIMPLEPAY_API_BASE/v1/bookable-payments/setup" \
    -H "Authorization: Bearer $SIMPLEPAY_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: scheduled_offer_setup_v1" \
    -d '{
      "use_case": "scheduled_offer",
      "name": "Experiencia Isla",
      "capacity": 100,
      "time_zone": "America/Cancun",
      "price": {
        "amount": 90000,
        "currency": "mxn"
      },
      "resource": {
        "name": "Shared inventory",
        "kind": "inventory_pool"
      },
      "schedule": {
        "weekdays": [0, 1, 2, 3, 4, 5, 6],
        "start_time": "09:00",
        "end_time": "17:00"
      }
    }'
)"

PRODUCT_ID="$(echo "$SETUP" | jq -r '.product.id')"
EVENT_TYPE_ID="$(echo "$SETUP" | jq -r '.event_type.id')"
```

El preset `scheduled_offer` crea producto, precio, recurso, schedule, reglas y event type con pago requerido.

## 4. Registra el customer en el Customer Hub

```bash terminal theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sS -X POST "$SIMPLEPAY_API_BASE/v1/customer-hub/customers" \
  -H "Authorization: Bearer $SIMPLEPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: customer_platform_user_123_create_v1" \
  -d '{
    "type": "person",
    "email": "guest@example.com",
    "name": "Guest One",
    "external_ref": {
      "provider": "customer_platform",
      "external_id": "user_123"
    }
  }'
```

El Customer Hub es la fuente de verdad del perfil del cliente; no guarda contrasenas, sesiones ni tokens de login. La proyeccion al provider (Stripe Customer) ocurre solo dentro del adapter aprobado, nunca desde este endpoint. Las llamadas Bookable de abajo referencian al customer por `external_provider`/`external_id`.

## 5. Lista slots

```bash terminal theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sS \
  "$SIMPLEPAY_API_BASE/v1/bookable-payments/event_types/$EVENT_TYPE_ID/slots?start=2026-07-10T14:00:00.000Z&end=2026-07-10T23:00:00.000Z&time_zone=America/Cancun&quantity=2&view=bookable&group_by=date" \
  -H "Authorization: Bearer $SIMPLEPAY_API_KEY"
```

Un slot bookable incluye:

```json slot theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "startsAt": "2026-07-10T15:00:00.000Z",
  "endsAt": "2026-07-10T23:00:00.000Z",
  "date": "2026-07-10",
  "available": 98,
  "resourceId": "00000000-0000-4000-8000-000000000001",
  "status": "available",
  "timeZone": "America/Cancun"
}
```

## 6. Crea booking checkout atomico

```bash terminal theme={"theme":{"light":"github-light","dark":"github-dark"}}
curl -sS -X POST "$SIMPLEPAY_API_BASE/v1/bookable-payments/bookings" \
  -H "Authorization: Bearer $SIMPLEPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: booking_user_123_20260710_v1" \
  -d "{
    \"event_type_id\": \"$EVENT_TYPE_ID\",
    \"starts_at\": \"2026-07-10T15:00:00.000Z\",
    \"quantity\": 2,
    \"success_url\": \"https://merchant.example.com/bookings/success\",
    \"cancel_url\": \"https://merchant.example.com/bookings/cancel\",
    \"customer\": {
      \"external_provider\": \"customer_platform\",
      \"external_id\": \"user_123\",
      \"email\": \"guest@example.com\"
    },
    \"metadata\": {
      \"cart_id\": \"cart_789\"
    }
  }"
```

La respuesta contiene un booking `pending`, un hold y una Checkout Session:

```json response theme={"theme":{"light":"github-light","dark":"github-dark"}}
{
  "booking": {
    "id": "00000000-0000-4000-8000-000000000010",
    "status": "pending",
    "paymentStatus": "unpaid"
  },
  "checkout_session": {
    "id": "spcs_0123456789abcdef0123456789abcdef",
    "url": "https://checkout.simplepay.mx/checkout/spcs_0123456789abcdef0123456789abcdef"
  }
}
```

## 7. Espera confirmacion

Tu handler de webhook debe persistir:

* SimplePay event id.
* `booking.id`.
* `booking.status`.
* `booking.payment_status`.
* `booking.simplepay_checkout_session_id`.
* `booking.starts_at`, `booking.ends_at`, `booking.quantity`.

<Check>
  Solo entrega voucher, QR, acceso o confirmacion final despues de
  `booking.confirmed`.
</Check>

## Flujo split: hold luego pago

Si quieres separar seleccion de slot y pago:

```bash terminal theme={"theme":{"light":"github-light","dark":"github-dark"}}
HOLD_ID="$(
  curl -sS -X POST "$SIMPLEPAY_API_BASE/v1/bookable-payments/holds" \
    -H "Authorization: Bearer $SIMPLEPAY_API_KEY" \
    -H "Content-Type: application/json" \
    -H "Idempotency-Key: hold_user_123_20260710_v1" \
    -d "{
      \"event_type_id\": \"$EVENT_TYPE_ID\",
      \"starts_at\": \"2026-07-10T15:00:00.000Z\",
      \"quantity\": 2,
      \"customer\": {
        \"external_provider\": \"customer_platform\",
        \"external_id\": \"user_123\"
      }
    }" | jq -r '.id'
)"

curl -sS -X POST "$SIMPLEPAY_API_BASE/v1/bookable-payments/holds/$HOLD_ID/payment" \
  -H "Authorization: Bearer $SIMPLEPAY_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: hold_user_123_20260710_payment_v1" \
  -d '{
    "success_url": "https://merchant.example.com/bookings/success",
    "cancel_url": "https://merchant.example.com/bookings/cancel"
  }'
```
