Response to server-side API requests: 400: Bad request
billing_issue_detected_at_date_comparison_error
账单问题发生在订阅续费尝试失败时,因此它始终发生在交易日期(purchased_at)之后。
要解决此问题,请确保账单问题日期(billing_issue_detected_at)晚于交易日期(purchased_at)。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 简短错误名称。始终为 billing_issue_detected_at_date_comparison_error。 |
| status_code | Integer | HTTP 状态码。始终为 400。 |
响应示例
{
"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
用户无法购买已过期的订阅。因此,expires_at 日期(订阅到期时间)必须晚于 purchased_at 日期(交易发生时间)。
要解决此问题,请检查这两个日期,确保 expires_at 晚于 purchased_at。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称,固定为 expires_date_error。 |
| status_code | Integer | HTTP 状态码,固定为 400。 |
响应示例
{
"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
请求失败,原因是 is_family_shared 参数设置为 true,表示该访问等级已免费共享给家庭成员。但 Price 对象的 value 参数未设置为零。
如果 is_family_shared 应为 true,请确保将 Price 对象的 value 参数设置为 0。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 简短错误名称。始终为:family_share_price_error。 |
| status_code | Integer | HTTP 状态码。始终为 400。 |
响应示例
未找到用户画像
{
"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
请求失败,原因是 offer_type 参数设置为 free_trial,但 Price 对象的 value 参数未设置为零。
另一个可能的原因是 offer_id 参数被包含但设置为 null,而该参数不能为 null。在这种情况下,请为 offer_id 提供一个值,或将该参数完全移除。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 简短错误名称。始终为:free_trial_price_error。 |
| status_code | Integer | HTTP 状态码。始终为 400。 |
响应示例
未找到用户画像
{
"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
宽限期是您可以为用户提供的额外时间,以便他们在未能及时续订时延续订阅——例如,当信用卡扣款失败时。这有助于在用户解决问题期间保留其设置。提供宽限期是可选的。
如果您提供宽限期,其到期日期(grace_period_expires_at)应晚于订阅到期日期(expires_at)。如果不满足此条件,宽限期到期时间将与订阅到期时间一致。无论如何,宽限期到期时间不能早于订阅到期时间。
要解决此问题,请确保宽限期到期日期(grace_period_expires_at)晚于订阅到期日期(expires_at)。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 简短错误名称。固定值 grace_period_expires_date_error。 |
| status_code | Integer | HTTP 状态码。固定值 400。 |
响应示例
{
"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
宽限期的开始计为账单问题。因此,如果宽限期已经开始(通过 grace_period_expires_at 参数已填写来判断),则其开始日期应记录在 billing_issue_detected_at 参数中。
要解决此问题,请在 billing_issue_detected_at 中设置宽限期的开始日期;或者,如果宽限期尚未开始,请移除 grace_period_expires_at 参数。
Body
| 参数 | 类型 | 说明 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称,固定为 grace_period_billing_error。 |
| status_code | Integer | HTTP 状态码,固定为 400。 |
响应示例
{
"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
请求失败的原因是 offer_category 参数的值不是 introductory 或 offer_type,但请求中未包含 offer_id。此时,请提供 offer_id,或从请求中移除 offer_category 或 offer_type。
另一种可能的原因是 offer_id 参数已添加但值为 null,而该参数不允许为 null。如果是这种情况,请为 offer_id 赋值,或完全移除该参数。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称。可能的值:missing_offer_id。 |
| status_code | Integer | HTTP 状态码。固定值 400。 |
响应示例
未找到用户画像
{
"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
该请求失败,原因是为一次性购买提供了试用期。与订阅不同,一次性购买不支持试用期。要解决此问题,请检查 One-Time Purchase 对象中 Offer 对象内的 offer_type 字段。offer_type 的值不能为 free_trial。请修改 offer_type 字段的值,或改用 Subscription 对象替代 One-Time Purchase。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称。固定为 one_time_purchase_trial_error。 |
| status_code | Integer | HTTP 状态码。固定为 400。 |
响应示例
{
"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
对于续期订阅,系统会创建一条交易链。原始交易是该链中的第一笔交易,并将后续所有交易关联在一起。每次续订都是对原始交易的延续。如果某笔交易是首次购买,则它本身即为原始交易。
originally_purchased_at 时间戳标记原始购买的时间,而 purchased_at 标记当前交易的时间。因此,purchased_at 不可能早于 originally_purchased_at;对于第一笔交易,两者最多相等。
本次请求失败,原因是 originally_purchased_at 被设置为晚于 purchased_at 的日期。请确保其早于或等于 purchased_at。
Body
| Parameter | Type | Description |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称。始终为 originally_purchased_date_error。 |
| status_code | Integer | HTTP 状态码。始终为 400。 |
响应示例
{
"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
请求失败,因为在请求中找不到指定的访问等级。请仔细检查 access_level_id 是否有拼写错误,并确认其与正确的应用匹配。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 简短的错误名称。可能的值:paid_access_level_does_not_exist。 |
| status_code | Integer | HTTP 状态码。始终为 404。 |
响应示例
未找到访问等级。
{
"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
请求失败,因为在请求头中找不到对应的用户画像。请仔细检查请求头中的 profile_id 或 customer_user_id 是否有拼写错误,并确认其对应的应用是否正确。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称。可能的值:profile_does_not_exist。 |
| status_code | Integer | HTTP 状态码。固定值 400。 |
响应示例
未找到用户画像
{
"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
请求失败,因为请求中的用户画像与指定的访问等级不匹配。请检查请求头中的用户画像 ID 和请求体中的访问等级 ID 是否正确,并确认没有拼写错误。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称。固定值为 profile_paid_access_level_does_not_exist。 |
| status_code | Integer | HTTP 状态码。固定值为 400。 |
响应示例
{
"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
请求失败,原因是购买日期(purchased_at)早于或等于退款日期(refunded_at)。退款总是发生在购买之后,因为它是对该交易的撤销操作。
请检查 purchased_at 和 refunded_at 参数,确保退款日期晚于购买日期。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称。固定值为 refund_date_error。 |
| status_code | Integer | HTTP 状态码。固定值为 400。 |
响应示例
{
"errors": [
{
"source": "refunded_at",
"errors": [
"refunded_at must be later than purchased_at."
]
}
],
"error_code": "refund_date_error",
"status_code": 400
}
refund_fields_error
请求失败,原因是包含了 cancellation_reason 但未提供 refunded_at 日期,或者提供了 refunded_at 但未指定 cancellation_reason。
设置退款时,退款日期和退款原因必须同时指定。
请求体
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称,始终为 refund_fields_error。 |
| status_code | Integer | HTTP 状态码,始终为 400。 |
响应示例
{
"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
续订是对订阅的延续。用户可以取消订阅续订,之后也可以再次续订。这两个操作的时间均存储在 renew_status_changed_at 参数中,且该时间不能早于交易本身的时间。
要解决此问题,请确保 renew_status_changed_at 晚于交易时间(purchased_at)。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称,固定为 originally_purchased_date_error。 |
| status_code | Integer | HTTP 状态码,固定为 400。 |
响应示例
{
"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
请求失败,原因是你在请求中定义的 revoke_at 晚于当前访问等级的 expires_at 参数。如果你想延长访问等级,请使用 授予访问等级 请求。
Body
| 参数 | 类型 | 说明 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称。始终为 revocation_date_more_than_expiration_date。 |
| status_code | Integer | HTTP 状态码。始终为 400。 |
响应示例
{
"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
对于连续订阅,系统会生成一个订阅链。原始交易是该链中的第一笔交易,整个链通过它关联。链中的其他交易均为续费交易。如果某笔交易是订阅链中的第一次购买,它本身就可以作为自己的原始交易。
另一种情况是一次性购买。由于无法续费,它不会产生订阅链。对于一次性购买,store_transaction_id 始终与 store_original_transaction_id 相同。
您的请求失败,原因是 一次性购买 对象中的 store_transaction_id 值与其 store_original_transaction_id 不一致。要解决此问题,请将两者设为相同值,或者更换对象类型——使用 订阅 替代 一次性购买。
Body
| 参数 | 类型 | 说明 |
|---|---|---|
| errors | Object |
|
| error_code | String | 错误简称。固定值 store_transaction_id_error。 |
| status_code | Integer | HTTP 状态码。固定值 400。 |
响应示例
{
"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
请求失败,因为指定的撤销日期已过期。请将 revoke_at 设置为未来的日期,或设置为 null 以立即撤销访问权限。
Body
| 参数 | 类型 | 描述 |
|---|---|---|
| errors | Object |
|
| error_code | String | 简短错误名称。始终为 value_error。 |
| status_code | Integer | HTTP 状态码。始终为 400。 |
响应示例
{
"errors": [
{
"source": null,
"errors": [
"Must be greater than the current time or null"
]
}
],
"error_code": "value_error",
"status_code": 400
}