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

# Intégration d’une plateforme de réservation

Parcours d’une plateforme qui vend les véhicules d’un ou plusieurs loueurs Lexio avec une clé partenaire ([Deux types de clés](https://docs.lexio.rent/authentification.md)).

## Une clé par loueur

Il n’existe pas de clé multi-loueurs : chaque loueur crée la vôtre dans Lexio, avec votre code partenaire (`partnerCode`), et vous la transmet. Vérifiez-la par `GET /organization` : devise, fuseau, TVA, horaires d’ouverture, règles de réservation et scopes de la clé.

Le code partenaire délimite votre espace chez le loueur :

* vos locations, devis, fiches clients et événements portent ce code ; ceux du loueur ou d’un autre partenaire vous restent invisibles. Hors de votre espace, une location répond `404`, comme un identifiant inconnu ;
* les créneaux des autres locations n’apparaissent que comme des plages anonymes ;
* `partnerReference` est unique dans votre espace : deux partenaires peuvent utiliser la même référence ;
* un devis ne se consomme que par une clé du même code partenaire.

Scopes accordables : colonne « Clé partenaire » de la [table des scopes](https://docs.lexio.rent/authentification.md).

## Réserver

1. [`GET /availability`](https://docs.lexio.rent/api-reference/offre/list-availability) : véhicules réservables et prix sur la période, dans les horaires et règles de réservation du loueur (`422 BOOKING_RULE_VIOLATION`). Rien n’est garanti.
2. [`POST /quotes`](https://docs.lexio.rent/api-reference/offre/create-quote) : prix garanti 24 h (`expiresAt`), consommable une fois. Le véhicule n’est pas bloqué.
3. [`POST /rentals`](https://docs.lexio.rent/api-reference/locations/create-rental) avec `quoteId`, `partnerReference` (votre numéro de commande), `customer` (le titulaire) et une `Idempotency-Key`. Disponibilité et prix sont revérifiés : `409 VEHICLE_UNAVAILABLE` ou `409 PRICE_CHANGED`, et rien n’est créé.
4. Lisez le total dans `totalTTC` et le reste à payer dans `balance.dueAmount`.

**Titulaire.** Le client est cherché par email (casse ignorée) parmi les fiches de particuliers de votre espace. Trouvé (`effects.customerResolution: MATCHED`), sa fiche est reprise telle quelle : seuls ses champs vides sont complétés (nom, téléphone ou date de naissance déjà renseignés ne sont jamais remplacés) et l’âge du conducteur se juge sur la date de la fiche ; relisez `data.customer`. Sinon, une fiche est créée (`CREATED`). Un client bloqué par le loueur donne `409 BOOKING_REFUSED`, sans cause.

Pour retrouver une location : `GET /rentals?partnerReference=…` ou `GET /rentals?number=…` (numéro Lexio).

Une clé partenaire n’envoie jamais d’email de confirmation au client final ; le loueur est prévenu de chaque création.

## Encaisser le paiement

Le paiement en ligne s’encaisse sur le **compte Stripe du loueur**, connecté à Lexio. Lexio ne crée aucun paiement pour vous et ne publie pas l’identifiant de ce compte : une clé partenaire ne fait qu’**enregistrer** un paiement déjà encaissé.

**Qui crée le PaymentIntent.** Lexio ne le lit que sur le compte Stripe du loueur (créé sur le vôtre : `PI_NOT_FOUND`). Il est donc créé par le loueur, via sa propre intégration Stripe, ou par votre plateforme si Stripe vous donne accès à ce compte (par exemple si le loueur le connecte aussi à votre plateforme Stripe Connect, en-tête `Stripe-Account`) : une voie qui relève de Stripe et d’un accord avec le loueur, que Lexio n’organise pas et n’a pas validée. Sans cet accès, le loueur encaisse et enregistre le paiement dans Lexio ; vous suivez `balance` par les [événements](https://docs.lexio.rent/synchronisation.md).

Pour être enregistré, le PaymentIntent doit être :

* `succeeded`, dans la devise de la location (`currency`) ;
* d’un montant encaissé au plus égal au reste à payer (`balance.dueAmount`, prélèvement SEPA en cours déduit). Au-delà, `422 PAYMENT_EXCEEDS_DUE` et rien n’est enregistré, alors que l’argent est encaissé chez Stripe : créez-le pour le reste à payer, pas plus. Un montant inférieur est enregistré, le reste demeure dû ;
* rattaché à la location par sa metadata : `rentalId` égal à l’`id` de la location, à défaut `partnerCode` égal au vôtre ; une metadata qui désigne une autre organisation est refusée ;
* utilisé pour une seule location.

```bash theme={null}
curl -X POST "https://api.lexio.rent/api/external/v1/rentals/9c2d7e4a-5b1f-4d3c-8a6e-0f1b2c3d4e5f/payments" \
  -H "Authorization: Bearer lck_xxxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8b3e1d2c-4a5f-4c6b-9e7d-1f2a3b4c5d6e" \
  -d '{
    "type": "PAYMENT",
    "method": "STRIPE",
    "amount": 284.4,
    "stripePaymentIntentId": "pi_3Q1aBcDeFgHiJkLm0nOpQrSt"
  }'
```

`amount` est le montant encaissé exact (`amount_received`), en unités majeures. La date du paiement est celle de création du PaymentIntent (`paidAt` refusé) ; `notes` est réservé à l’équipe du loueur. Lexio relit le PaymentIntent chez Stripe avant d’écrire :

* déjà enregistré sur la même location : `409 ALREADY_EXISTS` ;
* Stripe indisponible : `503 SERVICE_UNAVAILABLE`, à renvoyer avec la même `Idempotency-Key` ;
* refusé : `422 PAYMENT_NOT_VERIFIED`, dont `reason` donne la cause :

| `reason` | Cause et remède |
| - | - |
| `PI_NOT_FOUND` | Le PaymentIntent n’existe pas sur le compte Stripe du loueur : il a été créé sur un autre compte (le vôtre, par exemple) ou dans l’autre mode (test au lieu de production). |
| `PI_NOT_SUCCEEDED` | Le paiement n’est pas encore encaissé chez Stripe : réessayez quand le PaymentIntent est `succeeded`. |
| `PI_ALREADY_USED` | Ce PaymentIntent règle déjà une autre location du loueur : un PaymentIntent ne paie qu’une location. |
| `PI_RENTAL_MISMATCH` | La metadata du PaymentIntent désigne une autre location ou une autre organisation, ou, pour une clé partenaire, ne porte ni le `rentalId` de la location ni votre `partnerCode`. |
| `CURRENCY_MISMATCH` | Le PaymentIntent n’est pas dans la devise de la location (`currency`). |
| `AMOUNT_MISMATCH` | `amount` diffère du montant encaissé par le PaymentIntent : envoyez le montant encaissé exact, en unités majeures. |
| `CONNECT_NOT_CONFIGURED` | Le loueur n’a pas connecté son compte Stripe à Lexio, ou l’a désactivé : il le fait dans Lexio. |

## Modifier, annuler, rembourser

* Suivez les changements par [`GET /events`](https://docs.lexio.rent/api-reference/evenements/list-events), puis relisez la location ([Synchronisation par événements](https://docs.lexio.rent/synchronisation.md)).
* Période : `reschedule` ; véhicule : `change-vehicle`. Aperçu par `?dryRun=true`, puis appel réel ancré par `expectedTotalTTC` ([Idempotence et reprise](https://docs.lexio.rent/idempotence.md)). Un total qui passe sous l’encaissé répond `409 OVERPAYMENT_RESOLUTION_REQUIRED` (`resolvableByKey: false`) : le loueur traite la baisse dans Lexio.
* `PATCH /rentals/{rentalId}` ne modifie que les notes et les lieux.
* Annulez par [`POST /rentals/{rentalId}/cancel`](https://docs.lexio.rent/api-reference/locations/cancel-rental) avec un `reason`. `effects.cancellation.refundDueAmount` donne la somme à rendre au client (l’API ne retient aucun frais) ; `null` si la location a été annulée hors de l’API, le loueur fixant alors le remboursement.
* **Remboursement.** Une clé partenaire ne rembourse pas. Un paiement Stripe se rembourse chez Stripe, sur le compte du loueur ; Lexio l’enregistre à réception de l’événement Stripe (sauf saisie manuelle préalable par l’équipe du loueur) et la location émet un `rental.updated` : suivez `balance.paidAmount`.

## Tester

Pas de bac à sable : demandez une organisation de test à [contact@lexio.rent](mailto:contact@lexio.rent) et prévisualisez les actions par `?dryRun=true`. Une location de test se termine par une annulation ; elle et sa fiche client restent visibles chez le loueur.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.