Response to server-side API requests: 400: Bad request
billing_issue_detected_at_date_comparison_error
Un problème de facturation survient lorsqu’il y a un problème lors d’une tentative de renouvellement d’abonnement, il se produit donc toujours après la date de transaction (purchased_at).
Pour résoudre ce problème, assurez-vous que la date du problème de facturation (billing_issue_detected_at) est postérieure à la date de transaction (purchased_at).
Body
| Parameter | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours billing_issue_detected_at_date_comparison_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "billing_issue_detected_at",
"errors": [
"billing_issue_detected_at must be later than purchased_at."
]
}
],
"error_code": "billing_issue_detected_at_date_comparison_error",
"status_code": 400
}
expires_date_error
Un utilisateur ne peut pas acheter un abonnement déjà expiré. Par conséquent, la date expires_at (date d’expiration de l’abonnement) doit toujours être postérieure à la date purchased_at (date de la transaction).
Pour corriger ce problème, vérifiez ces dates et assurez-vous que expires_at est bien après purchased_at.
Body
| Parameter | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours expires_date_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "expires_at",
"errors": [
"expires_at must be later than purchased_at."
]
}
],
"error_code": "expires_date_error",
"status_code": 400
}
family_share_price_error
La requête a échoué car le paramètre is_family_shared est défini sur true, ce qui signifie que le niveau d’accès est partagé gratuitement avec un membre de la famille. Cependant, le paramètre value de l’objet Price n’est pas défini sur zéro.
Si is_family_shared doit être true, assurez-vous de définir le paramètre value de l’objet Price sur 0.
Body
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours : family_share_price_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
Le profil est introuvable
{
"errors": [
{
"source": "is_family_shared",
"errors": [
"If is_family_shared is true, price.value must be 0."
]
}
],
"error_code": "family_share_price_error",
"status_code": 400
}
free_trial_price_error
La requête a échoué car le paramètre offer_type est défini sur free_trial, mais le paramètre value de l’objet Price n’est pas à zéro.
Une autre raison possible est que le paramètre offer_id a été inclus mais laissé à null, alors qu’il ne peut pas être null. Dans ce cas, fournissez une valeur pour offer_id ou supprimez entièrement le paramètre.
Body
| Parameter | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours : free_trial_price_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
Le profil est introuvable
{
"errors": [
{
"source": "offer_type",
"errors": [
"If offer_type is 'free_trial', price.value must be 0."
]
}
],
"error_code": "free_trial_price_error",
"status_code": 400
}
grace_period_expires_date_error
Le délai de grâce est une période supplémentaire que vous pouvez accorder aux clients pour prolonger leur abonnement s’ils n’ont pas pu le renouveler à temps — par exemple, si leur carte bancaire a été refusée. Cela permet de conserver leurs paramètres intacts le temps qu’ils règlent le problème. Proposer un délai de grâce est facultatif.
Si vous proposez un délai de grâce, la date d’expiration de celui-ci (grace_period_expires_at) doit être postérieure à la date d’expiration de l’abonnement (expires_at). Sinon, la date d’expiration du délai de grâce correspondra à celle de l’abonnement. Dans tous les cas, la date d’expiration du délai de grâce ne peut pas être antérieure à celle de l’abonnement.
Pour corriger cela, assurez-vous que la date d’expiration du délai de grâce (grace_period_expires_at) est postérieure à la date d’expiration de l’abonnement (expires_at).
Body
| Parameter | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours grace_period_expires_date_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "grace_period_expires_at",
"errors": [
"grace_period_expires_at must be later or equal to expires_at."
]
}
],
"error_code": "grace_period_expires_date_error",
"status_code": 400
}
grace_period_billing_error
Le début d’un délai de grâce est considéré comme un problème de facturation. Par conséquent, si le délai de grâce a commencé (ce qu’indique le paramètre grace_period_expires_at renseigné), sa date de début doit être enregistrée dans le paramètre billing_issue_detected_at.
Pour corriger cela, soit définissez le début du délai de grâce dans billing_issue_detected_at, soit, si le délai de grâce n’a pas encore commencé, supprimez le paramètre grace_period_expires_at.
Body
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours grace_period_billing_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "grace_period_billing_error",
"errors": [
"If grace_period_expires_at is specified, billing_issue_detected_at must also be specified."
]
}
],
"error_code": "grace_period_billing_error",
"status_code": 400
}
missing_offer_id
La requête a échoué car le paramètre offer_category a une valeur autre que introductory ou offer_type, mais n’inclut pas d’offer_id. Dans ce cas, fournissez un offer_id ou supprimez offer_category ou offer_type de la requête.
Une autre raison possible est que le paramètre offer_id a été ajouté mais laissé à null, alors qu’il ne peut pas être nul. Dans ce cas, ajoutez une valeur pour offer_id ou supprimez entièrement le paramètre.
Body
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Valeur possible : missing_offer_id. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
Le profil est introuvable
{
"errors": [
{
"source": "offer_category",
"errors": [
"offer_id must be specified for all offer types except 'introductory'."
]
}
],
"error_code": "missing_offer_id",
"status_code": 400
}
one_time_purchase_trial_error
La requête a échoué car un essai a été fourni avec un achat unique. Contrairement aux abonnements, les achats uniques ne peuvent pas avoir d’essai. Pour corriger cela, vérifiez le champ offer_type dans l’objet Offer au sein de l’objet One-Time Purchase. La valeur de offer_type ne peut pas être free_trial. Modifiez la valeur du champ offer_type ou utilisez l’objet Subscription à la place de One-Time Purchase.
Body
| Parameter | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours one_time_purchase_trial_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "offer.type",
"errors": [
"One-time purchase cannot have a trial."
]
}
],
"error_code": "one_time_purchase_trial_error",
"status_code": 400
}
originally_purchased_date_error
Pour les abonnements prolongés, une chaîne de transactions est créée. La transaction originale est la première de cette chaîne et relie toutes les transactions suivantes. Chaque renouvellement est simplement une extension de cette transaction originale. Si la transaction est le premier achat, elle sert elle-même de transaction originale.
L’horodatage originally_purchased_at indique la date du premier achat, tandis que purchased_at correspond à la date de la transaction en cours. De ce fait, purchased_at ne peut jamais être antérieur à originally_purchased_at ; tout au plus, ils peuvent être identiques pour la toute première transaction.
La requête a échoué car originally_purchased_at est défini à une date postérieure à purchased_at. Assurez-vous qu’il est antérieur ou égal à purchased_at.
Body
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours originally_purchased_date_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "originally_purchased_at",
"errors": [
"originally_purchased_at must be earlier than or equal to purchased_at."
]
}
],
"error_code": "originally_purchased_date_error",
"status_code": 400
}
paid_access_level_does_not_exist
La requête a échoué car le niveau d’accès spécifié dans la requête est introuvable. Vérifiez qu’il n’y a pas de fautes de frappe dans access_level_id et qu’il correspond à la bonne application.
Body
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Valeur possible : paid_access_level_does_not_exist. |
| status_code | Integer | Statut HTTP. Toujours 404. |
Exemple de réponse
Le niveau d’accès est introuvable.
{
"errors": [
{
"source": "non_field_errors",
"errors": [
"Paid access level `premium` does not exist"
]
}
],
"error_code": "paid_access_level_does_not_exist",
"status_code": 400
}
profile_does_not_exist
La requête a échoué car le profil indiqué dans l’en-tête de la requête est introuvable. Vérifiez qu’il n’y a pas de fautes de frappe dans le profile_id ou le customer_user_id saisi dans l’en-tête, et assurez-vous qu’il correspond à la bonne application.
Corps
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Valeur possible : profile_does_not_exist. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
Le profil est introuvable
{
"errors": [
{
"source": "non_field_errors",
"errors": [
"Profile not found"
]
}
],
"error_code": "profile_does_not_exist",
"status_code": 400
}
profile_paid_access_level_does_not_exist
La requête a échoué car le profil dans la requête ne correspond pas au niveau d’accès spécifié. Vérifiez que l’ID de profil dans l’en-tête et l’ID de niveau d’accès dans le corps sont corrects, et assurez-vous qu’il n’y a pas de fautes de frappe.
Corps
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours profile_paid_access_level_does_not_exist. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "non_field_errors",
"errors": [
"Profile `478b2e7f-d557-4b8b-9c5f-cbd46fc2dee2` has no `premium` access level"
]
}
],
"error_code": "profile_paid_access_level_does_not_exist",
"status_code": 400
}
refund_date_error
La requête a échoué car la date d’achat (purchased_at) est antérieure ou égale à la date de remboursement (refunded_at). Un remboursement intervient toujours après un achat, puisqu’il annule la transaction.
Pour corriger ce problème, vérifiez les paramètres purchased_at et refunded_at et assurez-vous que la date de remboursement est postérieure à la date d’achat.
Body
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours refund_date_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "refunded_at",
"errors": [
"refunded_at must be later than purchased_at."
]
}
],
"error_code": "refund_date_error",
"status_code": 400
}
refund_fields_error
La requête a échoué car elle contient cancellation_reason sans date refunded_at, ou refunded_at sans cancellation_reason.
Lorsqu’un remboursement est défini, la date et la raison du remboursement doivent toutes les deux être renseignées.
Corps
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours refund_fields_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "refunded_at",
"errors": [
"refunded_at and cancellation_reason=refund must be specified together."
]
}
],
"error_code": "refund_fields_error",
"status_code": 400
}
renew_status_changed_date_error
Le renouvellement est une prolongation d’un abonnement. L’utilisateur peut annuler la prolongation de l’abonnement, puis la reprendre. La date de ces deux actions est stockée dans le paramètre renew_status_changed_at. Elle ne peut jamais être antérieure à la transaction elle-même.
Pour corriger le problème, assurez-vous que renew_status_changed_at est postérieur à la date de la transaction (purchased_at).
Body
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours originally_purchased_date_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "renew_status_changed_at",
"errors": [
"renew_status_changed_at must be later than purchased_at."
]
}
],
"error_code": "renew_status_changed_date_error",
"status_code": 400
}
revocation_date_more_than_expiration_date
La requête a échoué car le paramètre revoke_at défini dans la requête est postérieur au paramètre expires_at du niveau d’accès actuel. Si vous souhaitez prolonger le niveau d’accès, utilisez la requête Accorder un niveau d’accès.
Body
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours revocation_date_more_than_expiration_date. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "revoke_at",
"errors": [
"Revocation date (2029-08-29 09:33:42+00:00) is more than current expiration date (2028-08-29 09:33:42+00:00)"
]
}
],
"error_code": "revocation_date_more_than_expiration_date",
"status_code": 400
}
store_transaction_id_error
Dans le cas d’abonnements prolongés, une chaîne d’abonnements est générée. La transaction d’origine est la toute première transaction de cette chaîne, et la chaîne y est liée. Les autres transactions de la chaîne sont des prolongations. Si la transaction est le tout premier achat dans la chaîne d’abonnement, elle peut être sa propre transaction d’origine.
Un autre cas est celui d’un achat unique. Il ne crée jamais de chaînes car il ne peut pas avoir de prolongations. Pour lui, le store_transaction_id est toujours identique au store_original_transaction_id.
Votre requête a échoué car la valeur store_transaction_id de l’objet Achat unique diffère de son store_original_transaction_id. Pour résoudre le problème, soit rendez-les identiques, soit changez l’objet — utilisez Abonnement à la place de l’Achat unique.
Corps
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours store_transaction_id_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": "store_transaction_id",
"errors": [
"store_transaction_id must be equal to store_original_transaction_id for purchase."
]
}
],
"error_code": "store_transaction_id_error",
"status_code": 400
}
value_error
La requête a échoué car la date de révocation spécifiée est dans le passé. Définissez revoke_at à une date future ou à null pour révoquer l’accès immédiatement.
Body
| Paramètre | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | Nom court de l’erreur. Toujours value_error. |
| status_code | Integer | Statut HTTP. Toujours 400. |
Exemple de réponse
{
"errors": [
{
"source": null,
"errors": [
"Must be greater than the current time or null"
]
}
],
"error_code": "value_error",
"status_code": 400
}