# YoPlanning Payment Manager — API Documentation

### `POST /api/create-payment`

Crea un enlace de pago (Stripe) y devuelve una URL a la que redirigir al cliente.

**URL base**: `https://payment.yoplanning.pro`

***

### Autenticación

El gestor de pagos utiliza una **autenticación basada en tokens**, independiente del token principal de la API de YoPlanning.

```
Authorization: Token <PAYMENT_MANAGER_TOKEN>
Content-Type: application/json
```

> **Importante**: El token del Administrador de pagos **no** es el mismo que el token de la API de YoPlanning v3.1. Son dos tokens distintos. Usar el incorrecto devolverá el error `401 "Token no válido"`.

| Simbólico                     | Utilizado para                                              | Dónde encontrarlo                                             |
| ----------------------------- | ----------------------------------------------------------- | ------------------------------------------------------------- |
| Token de API de YoPlanning    | `yoplanning.pro/api/v3.1/*` (disponibilidad, pedidos, etc.) | Oficina administrativa > API > Tokens                         |
| **Token del gestor de pagos** | `payment.yoplanning.pro/api/*`                              | Oficina administrativa > Configuración de pago > Token de API |

***

### Pedido

```
POST https://payment.yoplanning.pro/api/create-payment
Authorization: Token <PAYMENT_MANAGER_TOKEN>
Content-Type: application/json
```

#### Parámetros corporales

| Campo                                          | Requerido | Amable        | Descripción                                                                                                |
| ---------------------------------------------- | --------- | ------------- | ---------------------------------------------------------------------------------------------------------- |
| `order_id`                                     | Sí        | cadena        | Su identificador de pedido (es decir, el UUID devuelto por `/order-typicalvalidation`)                     |
| `vendor_id`                                    | Sí        | cadena (UUID) | Tu identificador de proveedor (que encontrarás en la configuración de pagos de YoPlanning)                 |
| `precio`                                       | Sí        | número        | Importe total en la unidad monetaria principal (por ejemplo, `196,00` para 196 euros). **No en céntimos.** |
| `moneda`                                       | Sí        | cadena        | Código de moneda ISO 4217 (por ejemplo, `"EUR"`, `"USD"`)                                                  |
| `callback_url`                                 | Sí        | cadena (URL)  | URL de notificación IPN: debe ser de acceso público. Se invoca mediante POST cuando se completa el pago.   |
| `url_de_redirección`                           | No        | cadena (URL)  | ¿Dónde redirigir al cliente después de un pago exitoso?                                                    |
| `cancel_url`                                   | No        | cadena (URL)  | ¿Dónde redirigir al cliente si cancela?                                                                    |
| `correo_electrónico_del_pagador`               | No        | cadena        | Rellena automáticamente el campo de correo electrónico en la página de pago.                               |
| `nombre_del_titular_de_la_tarjeta`             | No        | cadena        | Rellena automáticamente el nombre del titular de la tarjeta.                                               |
| `apellido_del_titular_de_la_tarjeta`           | No        | cadena        | Rellena automáticamente el apellido del titular de la tarjeta.                                             |
| `línea_de_dirección_de_facturación1`           | No        | cadena        | Línea 1 de la dirección de facturación                                                                     |
| `línea_de_dirección_de_facturación2`           | No        | cadena        | Línea 2 de la dirección de facturación                                                                     |
| `ciudad_dirección_facturación`                 | No        | cadena        | Ciudad                                                                                                     |
| `código postal de la dirección de facturación` | No        | cadena        | Código Postal                                                                                              |
| `país_de_facturación`                          | No        | cadena        | País                                                                                                       |
| `billing_address_state`                        | No        | cadena        | Estado/Región                                                                                              |

#### Notas importantes

* **El campo se llama `price`, no `amount`.** Enviar `amount` en lugar de `price` dará como resultado un `500 Internal Server Error` porque el servidor recibe `price=None`.
* **El precio está en euros (o en su moneda), no en céntimos.** Envíe 196,00, no 19600.
* **`callback_url` es obligatorio**, incluso si no procesas activamente las notificaciones IPN. Si lo omites, se producirá un error de validación.
* El gestor de pagos es un **servicio de enlace de pago fijo**: toma el precio total, no el desglose de los artículos. Los artículos del pedido pertenecen a la API de reservas de YoPlanning (`/order-validation`), no a este servicio.

***

### Respuesta

#### Éxito (`200`)

```
{
  "success": true,
  "payment_id": "179384e3-4e32-4f03-b6ea-2fdc998e2c6c",
  "customer_id": null,
  "vakario_fee": "0.00",
  "payment_solution": "Stripe",
  "payment_url": "https://payment.yoplanning.pro/pay/8edf6170-5495-432d-8b04-6717ccb8ad68"
}
```

| Campo              | Amable        | Descripción                                                |
| ------------------ | ------------- | ---------------------------------------------------------- |
| `éxito`            | booleano      | `true` si se creó el enlace de pago                        |
| `payment_id`       | cadena (UUID) | identificador de pago único                                |
| `customer_id`      | cadena o nulo | Identificación del cliente si se reconoce                  |
| `vakario_fee`      | cadena        | Tarifa de la plataforma (cadena decimal)                   |
| `solución_de_pago` | cadena        | Proveedor de pago utilizado (“Stripe”)                     |
| `url_de_pago`      | cadena (URL)  | **Redirigir al cliente a esta URL para completar el pago** |

#### Error de validación (`400`)

```
{
  "success": false,
  "errors": {
    "callback_url": ["This field is required."]
  }
}
```

#### Error de autenticación (`401`)

No hay encabezado `Authorization`:

```
{"detail": "Authentication credentials were not provided."}
```

Token incorrecto (por ejemplo, usar el token de la API de YoPlanning en lugar del token del Administrador de pagos):

```
{"detail": "Invalid token."}
```

#### Error del servidor (`500`)

Devuelve una página de error HTML (no JSON) con el mensaje *"La plataforma de pago está temporalmente fuera de servicio."*

Esto **no** es una interrupción real de la plataforma. En la práctica, los errores 500 son causados ​​por:

| Causa principal                                | Error del servidor                                                                                 | Arreglar                                                                                          |
| ---------------------------------------------- | -------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------- |
| El campo `price` no está presente o es `null`. | `TypeError: '>' no es compatible entre instancias de 'NoneType' e 'int'` en `checkPaymentSolution` | Asegúrese de que `price` sea un número en el cuerpo JSON. El campo se llama `price`, no `amount`. |
| `vendor_id` falta o es inválido.               | Varios errores de formulario de Django                                                             | Asegúrese de que `vendor_id` sea una cadena UUID válida.                                          |

> La respuesta 500 devuelve HTML, no JSON. Analice la respuesta con precaución si espera JSON.

***

### Devolución de llamada IPN

Cuando se completa el pago (o falla), el Administrador de pagos envía una solicitud `POST` a su `callback_url`:

```
{
  "success": true,
  "payed": true,
  "order_id": "your-order-id",
  "payment_solution": "Stripe",
  "payer_lang": "fr"
}
```

| Campo              | Amable   | Descripción                                       |
| ------------------ | -------- | ------------------------------------------------- |
| `éxito`            | booleano | Si el pago se realizó correctamente               |
| `pagado`           | booleano | Si el pago fue cobrado                            |
| `order_id`         | cadena   | El `order_id` que proporcionaste al crear el pago |
| `solución_de_pago` | cadena   | Proveedor utilizado                               |
| `payer_lang`       | cadena   | Idioma del navegador del pagador                  |

Requisitos para `callback_url`:

* Debe ser de acceso público (sin autenticación).
* Debe aceptar solicitudes POST
* Debe devolver un código de estado 2xx.

***

### Ejemplo completo

#### rizo

```
curl -X POST "https://payment.yoplanning.pro/api/create-payment" \
  -H "Authorization: Token YOUR_PAYMENT_MANAGER_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "order_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "vendor_id": "your-vendor-uuid",
    "price": 196.00,
    "currency": "EUR",
    "payer_email": "customer@example.com",
    "cardholder_first_name": "Jean",
    "cardholder_last_name": "Dupont",
    "callback_url": "https://yoursite.com/api/payment-callback",
    "redirection_url": "https://yoursite.com/confirmation?status=success",
    "cancel_url": "https://yoursite.com/confirmation?status=cancelled"
  }'
```

#### JavaScript (obtener)

```
const response = await fetch('https://payment.yoplanning.pro/api/create-payment', {
  method: 'POST',
  headers: {
    'Authorization': 'Token YOUR_PAYMENT_MANAGER_TOKEN',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    order_id: orderId,
    vendor_id: 'your-vendor-uuid',
    price: 196.00,       // euros, NOT cents
    currency: 'EUR',
    payer_email: 'customer@example.com',
    callback_url: 'https://yoursite.com/api/payment-callback',
    redirection_url: 'https://yoursite.com/confirmation?status=success',
    cancel_url: 'https://yoursite.com/confirmation?status=cancelled',
  }),
});
​
const data = await response.json();
​
if (data.success && data.payment_url) {
  // Redirect customer to payment page
  window.open(data.payment_url, '_blank');
}
```

#### Python (solicitudes)

```
import requests
​
response = requests.post(
    "https://payment.yoplanning.pro/api/create-payment",
    headers={
        "Authorization": "Token YOUR_PAYMENT_MANAGER_TOKEN",
        "Content-Type": "application/json",
    },
    json={
        "order_id": order_id,
        "vendor_id": "your-vendor-uuid",
        "price": 196.00,
        "currency": "EUR",
        "payer_email": "customer@example.com",
        "callback_url": "https://yoursite.com/api/payment-callback",
        "redirection_url": "https://yoursite.com/confirmation?status=success",
        "cancel_url": "https://yoursite.com/confirmation?status=cancelled",
    },
)
​
data = response.json()
payment_url = data.get("payment_url")
```

***

### Flujo de integración típico

```
1. Customer selects dates and products
         │
         ▼
2. Check availability
   GET yoplanning.pro/api/v3.1/teams/{team}/online-products/{product}/availabilities/
         │
         ▼
3. Validate the order
   POST yoplanning.pro/api/v3.1/teams/{team}/order-validation
   → Returns order ID
         │
         ▼
4. Create payment link
   POST payment.yoplanning.pro/api/create-payment
   → Returns payment_url
         │
         ▼
5. Redirect customer to payment_url (Stripe checkout)
         │
         ▼
6. Customer pays → redirected to redirection_url
   Payment Manager POSTs to callback_url (IPN)
```

***

### CORS

La API del Administrador de Pagos **no** devuelve encabezados CORS. Las llamadas directas desde un navegador serán bloqueadas por la política de mismo origen del navegador.

**Soluciones**:

* Utilice un proxy del lado del servidor (por ejemplo, Cloudflare Worker, backend de Node.js, función sin servidor) para reenviar las solicitudes.
* Llama a la API desde tu backend, no desde JavaScript del lado del cliente.

***

### Preguntas frecuentes

**P: Recibo el error `401 "Token no válido"`, pero mi token funciona en la API de YoPlanning.** R: El Administrador de pagos tiene su propio token, distinto del token de la API de YoPlanning v3.1. Verifica la configuración de pagos en el panel de administración para asegurarte de tener el token correcto.

**P: Recibo una página de error HTML `500` en lugar de JSON.** R: Esto casi siempre significa que falta un campo obligatorio o que es `null`. Compruebe que `price` (no `amount`) sea un número en el cuerpo de su solicitud. Verifique también que `vendor_id` esté presente y sea válido.

**P: Mi `callback_url` aún no es accesible. ¿Puedo omitirlo?** R: No, `callback_url` es obligatorio. Puedes indicarle una URL de marcador de posición que devuelva 200, pero el campo debe estar presente.

**P: ¿Necesito pasar los detalles de las líneas de pedido al Administrador de pagos?** R: No. El Administrador de pagos solo gestiona el pago; recibe un precio fijo. Los detalles de las líneas pertenecen a la API de pedidos de YoPlanning (`/order-validation`).

**P: ¿El precio está en centavos o en la unidad monetaria principal de la divisa?** R: En la unidad monetaria principal. Para euros, envíe 196,00, no 19600.
