# YoPlanning Payment Manager — API Documentation

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

Crea un link di pagamento (Stripe) e restituisce un URL a cui reindirizzare il cliente.

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

***

### Autenticazione

Il Gestore dei pagamenti utilizza l'autenticazione basata su token, separata dal token API principale di YoPlanning.

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

> **Importante**: Il token di Payment Manager **non** è lo stesso del token dell'API YoPlanning v3.1. Si tratta di due token distinti. L'utilizzo di quello sbagliato restituirà l'errore `401 "Token non valido".`.

| Token                               | Utilizzato per                                            | Dove trovarlo                                       |
| ----------------------------------- | --------------------------------------------------------- | --------------------------------------------------- |
| Token API di YoPlanning             | `yoplanning.pro/api/v3.1/*` (disponibilità, ordini, ecc.) | Back office > API > Token                           |
| **Token del gestore dei pagamenti** | `payment.yoplanning.pro/api/*`                            | Back office > Impostazioni di pagamento > Token API |

***

### Richiesta

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

#### Parametri corporei

| Campo                                      | Necessario | Tipo           | Descrizione                                                                                                       |
| ------------------------------------------ | ---------- | -------------- | ----------------------------------------------------------------------------------------------------------------- |
| `order_id`                                 | SÌ         | corda          | Il tuo identificativo d'ordine (ovvero l'UUID restituito da `/order-typicalvalidation`)                           |
| `vendor_id`                                | SÌ         | stringa (UUID) | Il tuo identificativo fornitore (lo trovi nelle impostazioni di pagamento di YoPlanning)                          |
| `prezzo`                                   | SÌ         | numero         | Importo totale nell'unità principale della valuta (ad esempio, `196,00` per 196 euro). **Non in centesimi.**      |
| valuta                                     | SÌ         | corda          | Codice valuta ISO 4217 (ad esempio "EUR", "USD")                                                                  |
| `callback_url`                             | SÌ         | stringa (URL)  | URL di notifica IPN: deve essere accessibile pubblicamente. Chiamata tramite POST al completamento del pagamento. |
| `redirection_url`                          | NO         | stringa (URL)  | Dove reindirizzare il cliente dopo un pagamento andato a buon fine                                                |
| `cancel_url`                               | NO         | stringa (URL)  | Dove reindirizzare il cliente in caso di cancellazione?                                                           |
| `payer_email`                              | NO         | corda          | Precompila il campo email nella pagina di pagamento                                                               |
| `nome_del_titolare_della_carta`            | NO         | corda          | Precompila il nome del titolare della carta                                                                       |
| cognome\_del\_titolare\_della\_carta       | NO         | corda          | Precompila il cognome del titolare della carta                                                                    |
| `billing_address_line1`                    | NO         | corda          | Indirizzo di fatturazione, riga 1                                                                                 |
| `indirizzo_di_fatturazione_riga2`          | NO         | corda          | Riga 2 dell'indirizzo di fatturazione                                                                             |
| `città_indirizzo_di_fatturazione`          | NO         | corda          | Città                                                                                                             |
| `codice_postale_indirizzo_di_fatturazione` | NO         | corda          | Codice Postale                                                                                                    |
| `paese_indirizzo_di_fatturazione`          | NO         | corda          | Paese                                                                                                             |
| `stato dell'indirizzo di fatturazione`     | NO         | corda          | Stato/Regione                                                                                                     |

#### Note importanti

* **Il campo si chiama `price`, non `amount`.** Inviare `amount` invece di `price` genererà un `500 Internal Server Error` perché il server riceve `price=None`.
* **Il prezzo è espresso in euro (o nella tua valuta), non in centesimi.** Invia `196.00`, non `19600`.
* **Il campo `callback_url` è obbligatorio**, anche se non si elaborano attivamente le notifiche IPN. Ometterlo genera un errore di validazione.
* Il Payment Manager è un **servizio di link di pagamento fisso**: accetta un prezzo totale, non una ripartizione per singolo articolo. Gli articoli dell'ordine appartengono all'API di prenotazione di YoPlanning (`/order-validation`), non a questa sezione.

***

### Risposta

#### Successo (`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                    | Tipo           | Descrizione                                                            |
| ------------------------ | -------------- | ---------------------------------------------------------------------- |
| successo                 | booleano       | `true` se il link di pagamento è stato creato                          |
| `payment_id`             | stringa (UUID) | Identificativo univoco di pagamento                                    |
| `customer_id`            | stringa o null | ID cliente se riconosciuto                                             |
| `tassa_vakario`          | corda          | Commissione della piattaforma (stringa decimale)                       |
| `soluzione_di_pagamento` | corda          | Fornitore di pagamento utilizzato ("Stripe")                           |
| `payment_url`            | stringa (URL)  | **Reindirizzare il cliente a questo URL per completare il pagamento.** |

#### Errore di convalida (`400`)

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

#### Errore di autenticazione (`401`)

Nessuna intestazione `Authorization`:

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

Token errato (ad esempio, si sta utilizzando il token API di YoPlanning anziché il token di Payment Manager):

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

#### Errore del server (`500`)

Restituisce una pagina di errore HTML (non JSON) con il messaggio "La piattaforma di pagamento è momentaneamente non disponibile."

Questo **non** è un vero e proprio guasto della piattaforma. In pratica, gli errori 500 sono causati da:

| Causa ultima                      | Errore lato server                                                                          | Aggiustare                                                                                     |
| --------------------------------- | ------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- |
| campo `price` mancante o `null`   | `TypeError: '>' non supportato tra istanze di 'NoneType' e 'int'` in `checkPaymentSolution` | Assicurati che `price` sia un numero nel corpo JSON. Il campo si chiama `price`, non `amount`. |
| `vendor_id` mancante o non valido | Vari errori nei moduli di Django                                                            | Assicurati che `vendor_id` sia una stringa UUID valida                                         |

> La risposta 500 restituisce HTML, non JSON. Se ti aspetti un JSON, esegui un'analisi difensiva.

***

### Richiamata IPN

Quando il pagamento viene completato (o fallisce), il Gestore dei pagamenti invia una richiesta `POST` al tuo `callback_url`:

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

| Campo                    | Tipo     | Descrizione                                                            |
| ------------------------ | -------- | ---------------------------------------------------------------------- |
| successo                 | booleano | Se il pagamento è andato a buon fine                                   |
| pagato                   | booleano | Se il pagamento è stato riscosso                                       |
| `order_id`               | corda    | L'`order_id` che hai inserito al momento della creazione del pagamento |
| `soluzione_di_pagamento` | corda    | Fornitore utilizzato                                                   |
| `payer_lang`             | corda    | Lingua del browser del pagatore                                        |

Requisiti per `callback_url`:

* Deve essere accessibile al pubblico (senza autenticazione).
* Deve accettare le richieste POST
* Deve restituire un codice di stato 2xx

***

### Esempio completo

#### arricciare

```
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 (fetch)

```
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 (richieste)

```
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")
```

***

### Flusso di integrazione tipico

```
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

L'API Payment Manager **non** restituisce intestazioni CORS. Le chiamate dirette da un browser verranno bloccate dalla politica same-origin del browser.

**Soluzioni**:

* Utilizza un proxy lato server (ad esempio Cloudflare Worker, backend Node.js, funzione serverless) per inoltrare le richieste.
* Chiama l'API dal tuo backend, non dal codice JavaScript lato client.

***

### FAQ

**D: Ricevo l'errore `401 "Token non valido"` ma il mio token funziona con l'API di YoPlanning.** R: Il Payment Manager ha un proprio token, separato dal token dell'API di YoPlanning v3.1. Verifica le impostazioni di pagamento nel back office per il token corretto.

**D: Ricevo una pagina di errore HTML `500` invece di JSON.** R: Questo significa quasi sempre che manca un campo obbligatorio o che è `null`. Verifica che `price` (non `amount`) sia un numero nel corpo della richiesta. Verifica inoltre che `vendor_id` sia presente e valido.

**D: Il mio `callback_url` non è ancora raggiungibile. Posso ometterlo?** R: No, `callback_url` è obbligatorio. Puoi impostarlo su un URL segnaposto che restituisca 200, ma il campo deve essere presente.

**D: Devo passare le voci dell'ordine al Gestore dei pagamenti?** R: No. Il Gestore dei pagamenti si occupa solo del pagamento: accetta un prezzo fisso. Le voci dell'ordine appartengono all'API degli ordini di YoPlanning (`/order-validation`).

**D: Il prezzo è espresso in centesimi o nell'unità principale della valuta?** R: Nell'unità principale. Per l'EUR, inviare `196.00`, non `19600`.
