> For the complete documentation index, see [llms.txt](https://docs.yoplanning.support/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.yoplanning.support/en/developpeur/tutoriel-dacces-au-catalogue/yoplanning-payment-manager-api-documentation.md).

# YoPlanning Payment Manager — API Documentation

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

Creates a payment link (Stripe) and returns a URL to redirect the customer to.

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

***

### Authentication

The Payment Manager uses **token-based authentication**, separate from the main YoPlanning API token.

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

> **Important**: The Payment Manager token is **not** the same as the YoPlanning API v3.1 token. They are two distinct tokens. Using the wrong one will return `401 "Invalid token."`.

| Token                     | Used for                                                 | Where to find it                           |
| ------------------------- | -------------------------------------------------------- | ------------------------------------------ |
| YoPlanning API Token      | `yoplanning.pro/api/v3.1/*` (availability, orders, etc.) | Back office > API > Tokens                 |
| **Payment Manager Token** | `payment.yoplanning.pro/api/*`                           | Back office > Payment settings > API Token |

***

### Request

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

#### Body parameters

| Field                         | Required | Kind          | Description                                                                                 |
| ----------------------------- | -------- | ------------- | ------------------------------------------------------------------------------------------- |
| `order_id`                    | Yes      | string        | Your order identifier (ly the UUID returned by `/order-typicalvalidation`)                  |
| `vendor_id`                   | Yes      | string (UUID) | Your vendor identifier (found in your YoPlanning payment settings)                          |
| `price`                       | Yes      | number        | Total amount in the currency's main unit (e.g. `196.00` for 196 euros). **Not in cents.**   |
| `currency`                    | Yes      | string        | ISO 4217 currency code (e.g. `"EUR"`, `"USD"`)                                              |
| `callback_url`                | Yes      | string (URL)  | IPN notification URL — must be publicly accessible. Called via POST when payment completes. |
| `redirection_url`             | No       | string (URL)  | Where to redirect the customer after a successful payment                                   |
| `cancel_url`                  | No       | string (URL)  | Where to redirect the customer if they cancel                                               |
| `payer_email`                 | No       | string        | Pre-fills the email field on the payment page                                               |
| `cardholder_first_name`       | No       | string        | Pre-fills the cardholder first name                                                         |
| `cardholder_last_name`        | No       | string        | Pre-fills the cardholder last name                                                          |
| `billing_address_line1`       | No       | string        | Billing address line 1                                                                      |
| `billing_address_line2`       | No       | string        | Billing address line 2                                                                      |
| `billing_address_city`        | No       | string        | City                                                                                        |
| `billing_address_postal_code` | No       | string        | Postal code                                                                                 |
| `billing_address_country`     | No       | string        | Country                                                                                     |
| `billing_address_state`       | No       | string        | State / Region                                                                              |

#### Important notes

* **The field is called `price`, not `amount`.** Sending `amount` instead of `price` will result in a `500 Internal Server Error` because the server receives `price=None`.
* **`price` is in euros (or your currency), not in cents.** Send `196.00`, not `19600`.
* **`callback_url` is required**, even if you don't actively process IPN notifications. Omitting it returns a validation error.
* The Payment Manager is a **flat payment link service** — it takes a total price, not a line-item breakdown. Order items belong to the YoPlanning booking API (`/order-validation`), not here.

***

### Response

#### Success (`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"
}
```

| Field              | Kind           | Description                                               |
| ------------------ | -------------- | --------------------------------------------------------- |
| `success`          | boolean        | `true` if the payment link was created                    |
| `payment_id`       | string (UUID)  | Unique payment identifier                                 |
| `customer_id`      | string or null | Customer ID if recognized                                 |
| `vakario_fee`      | string         | Platform fee (decimal string)                             |
| `payment_solution` | string         | Payment provider used (“Stripe”\`)                        |
| `payment_url`      | string (URL)   | **Redirect the customer to this URL to complete payment** |

#### Validation error (`400`)

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

#### Authentication error (`401`)

No `Authorization` header:

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

Wrong token (e.g. using the YoPlanning API token instead of the Payment Manager token):

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

#### Server error (`500`)

Returns an HTML error page (not JSON) with the message *"The payment platform is down for a moment."*

This is **not** an actual platform outage. In practice, 500 errors are caused by:

| Root cause                      | Server-side error                                                                                  | Fix                                                                                     |
| ------------------------------- | -------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `price` field missing or `null` | `TypeError: '>' not supported between instances of 'NoneType' and 'int'` in `checkPaymentSolution` | Ensure `price` is a number in the JSON body. The field is called `price`, not `amount`. |
| `vendor_id` missing or invalid  | Various Django form errors                                                                         | Ensure `vendor_id` is a valid UUID string                                               |

> The 500 response returns HTML, not JSON. Parse defensively if you expect JSON.

***

### IPN Callback

When the payment is completed (or fails), the Payment Manager sends a `POST` request to your `callback_url`:

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

| Field              | Kind    | Description                                         |
| ------------------ | ------- | --------------------------------------------------- |
| `success`          | boolean | Whether the payment succeeded                       |
| `paid`             | boolean | Whether the payment was collected                   |
| `order_id`         | string  | The `order_id` you passed when creating the payment |
| `payment_solution` | string  | Provider used                                       |
| `payer_lang`       | string  | Language of the payer's browser                     |

Requirements for `callback_url`:

* Must be publicly accessible (no authentication)
* Must accept POST requests
* Must return a 2xx status code

***

### Complete example

#### cURL

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

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

***

### Typical integration flow

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

The Payment Manager API does **not** return CORS headers. Direct calls from a browser will be blocked by the browser's same-origin policy.

**Solutions**:

* Use a server-side proxy (e.g. Cloudflare Worker, Node.js backend, serverless function) to relay requests
* Call the API from your backend, not from client-side JavaScript

***

### FAQ

**Q: I get `401 "Invalid token"` but my token works on the YoPlanning API.** A: The Payment Manager has its own token, separate from the YoPlanning API v3.1 token. Check your payment settings in the back office for the correct token.

**Q: I get a `500` HTML error page instead of JSON.** A: This almost always means a required field is missing or `null`. Check that `price` (not `amount`) is a number in your request body. Also verify `vendor_id` is present and valid.

**Q: My `callback_url` isn't reachable yet. Can I skip it?** A: No, `callback_url` is required. You can point it to a placeholder URL that returns 200, but the field must be present.

**Q: Do I need to pass order line items to the Payment Manager?** A: No. The Payment Manager only handles payment — it takes a flat `price`. Line items belong to the YoPlanning order API (`/order-validation`).

**Q: Is `price` in cents or in the currency's main unit?** A: Main unit. For EUR, send `196.00`, not `19600`.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.yoplanning.support/en/developpeur/tutoriel-dacces-au-catalogue/yoplanning-payment-manager-api-documentation.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
