Date d'échéance du contrat (Contracts)
Contrats
Lire, créer, modifier et supprimer des contrats et des abonnements avec leurs attributs, leurs domaines, l'historique de leur statut et les factures associées. Le statut est modifié via un sous-point de terminaison dédié.
GET /Export/JSON/contracts
GET /Export/JSON/contract/{id}
POST /Import/JSON/contracts
PUT /Import/JSON/contracts
PUT /Import/JSON/contracts/{id}/status
DELETE /Delete/JSON/contract/{id}Points de terminaison
| Méthode | Point de terminaison | Portée | Description |
|---|---|---|---|
| GET | /Export/JSON/contracts | contracts:read | Tous les contrats, classés par ordre croissant d'ID (avec filtres) |
| GET | /Export/JSON/contract/{id} | contracts:read | Un contrat ; en l'absence de résultats, réponse HTTP 200 avec un corps vide data |
| GET | /Export/JSON/contracts/{von}:{bis}, /contracts/{von}: | contracts:read | plage d'ID ou plage ouverte |
| GET | /Export/JSON/contracts/{id} | contracts:read | ⚠️ Pluriel : tous les contrats à partir de cet ID, pas seulement un seul |
| POST | /Import/JSON/contracts | contracts:write | Créer de nouveaux contrats |
| PUT | /Import/JSON/contracts | contracts:write | Modifier des contrats existants |
| PUT | /Import/JSON/contracts/{id}/status | contracts:write | Modifier uniquement le statut, avec enregistrement dans l'historique des statuts |
| DELETE | /Delete/JSON/contract/{id} | contracts:delete | Supprimer un contrat, y compris ses attributs, ses domaines et son historique des statuts |
| DELETE | /Delete/JSON/contracts | contracts:delete | Supprimer plusieurs contrats via un JSON tronqué {"data": [{"contracts_id": …}]} |
/contracts/{von}:{bis}. Jusqu'à la v2.122.11, /contracts/10/20 renvoyait toujours les contrats à partir de 10 sans limite supérieure ; désormais, cela renvoie une erreur HTTP 400 INVALID_RANGE, tout comme tout autre segment qui n'est ni un nombre entier ni une plage (/contract/10x, /contract/10.0). Les espaces vides à la fin de l’ID ne sont pas pris en compte. Règles : API d’exportation, section « Segment de chemin ».Filtre de requête (GET)
| Paramètres | Description | Exemple |
|---|---|---|
?status= | ID d’un statut de contrat ; les statuts de la boutique figurent dans contracts_statuses[] de chaque réponse | ?status=1 |
?customer_id= | ID client | ?customer_id=42 |
?product_id= | ID du produit | ?product_id=100 |
?interval= | Fréquence de facturation par an : 1 annuellement, 2 semestriellement, 3 trois fois par an, 4 trimestriellement, 6 six fois par an, 12 mensuellement | ?interval=12 |
?date_from=, ?date_to= | Date du contrat (contracts_date) à partir de ou jusqu’au | ?date_from=2025-01-01 |
?active=1 | uniquement les contrats sans date de résiliation indiquée (contracts_cancellation_date_effective vide) ; une date de résiliation future exclut également le contrat | ?active=1 |
Plusieurs filtres agissent conjointement. Une valeur invalide génère un code HTTP 400 INVALID_FILTER_VALUE, par exemple ?interval=5 (depuis la v2.122.10). Depuis la v2.122.12, les espaces en bordure ne sont pas pris en compte ; une valeur vide signifie « non défini ».
Structure des données
Chaque contrat comporte ces champs. Les noms des statuts et des articles sont en allemand.
| Domaine | Champs |
|---|---|
| Identifiant et statut | contracts_id, contracts_status_id, contracts_status_name |
| Client | contracts_customers_id, customer_name, customer_email, contracts_customers_address_book_id, contracts_shipping_address_book_id |
| Article et prix | contracts_products_id, product_name, product_model, contracts_products_quantity, contracts_products_tax, contracts_price, contracts_final_price, contracts_discount, contracts_use_current_price |
| Facturation | contracts_interval et contracts_period_interval (valeurs telles que ?interval=, accompagnées chacune d’un champ …_text portant cette désignation), contracts_months, contracts_next_order_date, contracts_payment_class |
| Périodes | contracts_date; durée contracts_current_term_date_begin/_end, période de facturation contracts_current_period_date_begin/_end, dernière facturation contracts_last_billed_term_date_begin/_end et contracts_last_billed_period_date_begin/_end |
| Résiliation | contracts_cancellation_date_received, contracts_cancellation_date_effective |
| Domaine et licence | contracts_domain_id, contracts_domain_name, contracts_overwrite_domain, contracts_xolic_id |
| Divers | contracts_comment, contracts_template, contracts_error_flag, contracts_is_standalone |
Données imbriquées
| Liste | Contenu par entrée |
|---|---|
attributes[] | Caractéristiques de l'article du contrat : contracts_products_attributes_id, contracts_products_id, products_options, products_options_values, options_values_price, detail_id |
domains[] | contracts_domains_id, contracts_domains_domain_name, contracts_domains_date_paid, contracts_domains_date_termination, contracts_domains_provider, contracts_domains_exclusive, contracts_domains_cost |
status_history[] | les plus récents en premier : status_history_id, status_id, status_name, date_added, customer_notified, comments, user_id |
orders[] | factures associées, les plus récentes en premier : orders_id, date_created, date_purchased, orders_status |
En plus de data, chaque réponse contient contracts_statuses[] avec les statuts contractuels de la boutique, qui portent une désignation en allemand (status_id, status_name, status_label, status_active, status_is_default).
Importation (POST/PUT)
POSTcrée un enregistrement et nécessite les identifiants «contracts_customers_id» et «contracts_products_id» d’un client ou d’un article existant. Si l’identifiant «contracts_id» transmis existe déjà, l’enregistrement échoue.PUTmodifie et nécessite l’contracts_idd’un contrat existant. Seuls les champs envoyés sont mis à jour.- Les champs de la structure de données peuvent être modifiés, à l’exception des noms et des textes (
contracts_status_name,customer_name,customer_email,product_name,product_model,contracts_domain_name,…_text). Si l’on renvoie une exportation, l’importation signale ces champs comme inconnus (UNKNOWN_FIELD), de même que les listesstatus_history[]etorders[]ainsi que les identifiantscontracts_products_attributes_idetcontracts_products_iddansattributes[]etcontracts_domains_iddansdomains[]. L'importation les ignore et remplit les autres champs ; supprimez ces champs avant de renvoyer la requête, la réponse ne contiendra alors aucun avertissement. Les champs de date sous la formeYYYY-MM-DD, les champs des périodes de facturation (…_period_date_…) sous la formeYYYY-MM-DD HH:MM:SS;nullou vides les laisse vides. contracts_intervalN'accepte que1,2,3,4,6ou12; sinon, l'enregistrement échoue.attributes[]products_options, , , et utilisent la clé sans . Dans le cas de , une liste transmise remplace toutes les entrées existantes.products_options_valuesoptions_values_pricedetail_iddomains[]contracts_domains_…contracts_domains_idPUTstatusEn tant qu’objet{"status_id": …, "comments": "…", "customer_notified": 0}, cette commande définit le statut et ajoute une entrée dans l’historique des statuts. v2.122.13 Sistatus_idn’est pas un statut de contrat de la boutique (section « Statuts de contrat » ci-dessous), n’est pas un nombre entier ou est manquant, l’importation enregistre l’enregistrement sans le statut et génère l’avertissementCONTRACT_STATUS_UNKNOWN; l’enregistrement est considéré comme créé ou modifié.contracts_status_idLa modification directe du contrat définit le statut sans enregistrement dans l’historique des statuts. v2.122.13 Une valeur qui n’est pas un statut de contrat n’est pas enregistrée, contrairement aux autres champs, avec le même avertissement. Pour un changement de statut avec historique, utilisezstatusou le sous-point de terminaison/status.- ⚠️ Un statut «
contracts_cancellation_date_effective» défini peut avoir un effet lors de la prochaine exécution de la résiliation automatique du contrat.
Exemple
curl -s -X POST "https://shop.de/xpanel/xoport/Import/JSON/contracts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"type": "contracts",
"data": [{
"contracts_customers_id": 42,
"contracts_products_id": 100,
"contracts_interval": 12,
"contracts_price": "29.90",
"contracts_date": "2026-11-01",
"attributes": [
{"products_options": "Lizenztyp", "products_options_values": "Enterprise"}
],
"domains": [
{"contracts_domains_domain_name": "kunde.de"}
],
"status": {"status_id": 1, "comments": "Angelegt per API"}
}]
}'Modification du statut (PUT)
PUT /Import/JSON/contracts/{id}/status avec la portée contracts:write. Le champ status_id est obligatoire, ainsi que, au choix, comments et customer_notified. Sans status_id, la réponse est HTTP 400 MISSING_FIELD; pour une valeur status_id qui n’est pas un statut de contrat de la boutique ou un nombre entier, la réponse est HTTP 400 INVALID_STATUS avec les identifiants valides indiqués dans error.valid_status_ids (depuis la v2.122.13, section « Statut du contrat ») et, pour un contrat inconnu, HTTP 404 NOT_FOUND. Dans les trois cas, le contrat reste inchangé.
curl -s -X PUT "https://shop.de/xpanel/xoport/Import/JSON/contracts/1/status" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"status_id": 3, "comments": "Kündigung per API", "customer_notified": 0}'
# Antwort
{
"success": true,
"type": "contracts_status",
"contracts_id": 1,
"previous_status_id": 1,
"new_status_id": 3,
…
}Si le contrat comporte une date de résiliation effective, la réponse contient en outre warning: la résiliation automatique du contrat peut ultérieurement remplacer ce statut.
Statut du contrat v2.122.13
Pour status_id, status.status_id et contracts_status_id, tous les statuts de contrat de la boutique sont valables : les statuts du tableau status avec type = 'contracts', à partir desquels le backend effectue également ses lectures, dans toutes les langues, y compris ceux qui sont désactivés (status_active = 0) ; cela masque simplement la sélection dans le backend. Les statuts de commande (/order_statuses) ne sont pas des statuts contractuels. Les identifiants applicables varient d’une boutique à l’autre : consultez-les sur contracts_statuses[], sur GET /Export/JSON/contracts ou sur error.valid_status_ids. contracts_statuses[] ne mentionne que les statuts avec une désignation en allemand ; un statut sans désignation en allemand est néanmoins valable.
L’identifiant est un nombre entier, sous forme de chiffre ou de suite de chiffres (54, "54"; les espaces en marge ne comptent pas). true, [65], "54abc", "1e3", 54.9 ou 54.0 ne sont pas des identifiants.
| Adresse postale | Statut de contrat non valide |
|---|---|
PUT /Import/JSON/contracts/{id}/status | HTTP 400 INVALID_STATUS, error.valid_status_ids indique les identifiants valides ; le contrat reste inchangé |
Importation de contrat, status.status_id (également status sans status_id, par exemple "status": 54 ou "status": {}) | Enregistrement créé, statut et historique des statuts inchangés, avertissement « CONTRACT_STATUS_UNKNOWN » avec field = status.status_id ou status; "status": null est considéré comme non envoyé |
Importation de contrat, contracts_status_id | champ non renseigné (il reste vide lors de la création), autres champs renseignés, avertissement « CONTRACT_STATUS_UNKNOWN » avec « field » = contracts_status_id |
HTTP 400
{
"success": false,
"api_version": "2.122.13",
"error": {
"code": "INVALID_STATUS",
"message": "status_id 1 is not a contract status. Valid: 7, 3, 12 (…)",
"valid_status_ids": [7, 3, 12]
}
}Dans l’importation de contrats, l’enregistrement continue à être compté comme inserted ou updated. L’avertissement figure dans warnings[] de la réponse et dans l’entrée de l’enregistrement dans records[]:
"warnings": [
{
"type": "CONTRACT_STATUS_UNKNOWN",
"field": "status.status_id",
"entity": "contracts",
"contracts_id": 42,
"message": "Contract 42: status.status_id ignored — status.status_id 1 is not a contract status. Valid: 7, 3, 12 (…)",
"first_occurrence": "record 1"
}
]/status et l’objet status effectuaient une vérification par rapport aux statuts de commande (orders_status). Un statut de contrat qui n’existait pas également en tant que statut de commande générait un code HTTP 400 au niveau du sous-point de terminaison et était ignoré en silence lors de l’importation ; un identifiant n'existant qu'en tant que statut de commande était enregistré en tant que statut de contrat, au sous-point de terminaison portant le nom du statut de commande dans new_status_name. contracts_status_id était enregistré sans vérification ("abc" était considéré comme 0, true comme 1), et des valeurs telles que "1e3" ou 54.9 étaient considérées respectivement comme 1000 et 54. ⚠️ Si vous envoyez des identifiants de statut de commande en tant que statuts de contrat, vous recevrez désormais une réponse HTTP 400 ou l'avertissement suivant : veuillez utiliser les identifiants disponibles sur contracts_statuses[]. new_status_name indique désormais le nom du statut de contrat.Suppression (DELETE)
Le contrat, ses attributs et ses domaines, l’historique de son statut ainsi que ses liens vers les factures et les projets sont supprimés. Les factures et les projets eux-mêmes sont conservés.
orders[] de GET /Export/JSON/contract/{id}, chacune avec son statut de commande orders_status. Pour savoir si un statut est considéré comme « payé », consultez is_paid à l’adresse GET /Export/JSON/order_statuses (Commandes, section « Données de base du statut de commande »).# Ein Vertrag
curl -s -X DELETE "https://shop.de/xpanel/xoport/Delete/JSON/contract/1" \
-H "Authorization: Bearer $TOKEN"
# Mehrere Verträge
curl -s -X DELETE "https://shop.de/xpanel/xoport/Delete/JSON/contracts" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"data": [{"contracts_id": 1}, {"contracts_id": 2}]}'- Un contrat inconnu génère une erreur HTTP 404 lors d’un appel individuel :
NOT_FOUND. En traitement par lots, les ID supprimés se trouvent dansdeleted_ids, tandis que ceux introuvables apparaissent danserrors[]. - Un corps de requête sans
data[].contracts_id, par exemple{"ids": [1, 2]}, ne supprime rien et renvoie un code HTTP 400MISSING_DATA.
Portées OAuth2
| Portée | Autorisation |
|---|---|
contracts:read | Lire les contrats |
contracts:write | Créer et modifier des contrats, y compris leur statut |
contracts:delete | Supprimer des contrats |