Response to server-side API requests: 400: Bad request
billing_issue_detected_at_date_comparison_error
Sự cố thanh toán xảy ra khi có vấn đề trong quá trình gia hạn gói đăng ký, vì vậy nó luôn xảy ra sau ngày giao dịch (purchased_at).
Để khắc phục, hãy đảm bảo ngày phát hiện sự cố thanh toán (billing_issue_detected_at) muộn hơn ngày giao dịch (purchased_at).
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi rút gọn. Luôn là billing_issue_detected_at_date_comparison_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ response
{
"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
Người dùng không thể mua một gói đăng ký đã hết hạn. Vì vậy, ngày expires_at (khi gói đăng ký hết hạn) phải luôn muộn hơn ngày purchased_at (khi giao dịch xảy ra).
Để khắc phục, hãy kiểm tra các ngày này và đảm bảo rằng expires_at sau purchased_at.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Luôn là expires_date_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ phản hồi
{
"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
Yêu cầu thất bại vì tham số is_family_shared được đặt thành true, nghĩa là mức độ truy cập được chia sẻ miễn phí với thành viên gia đình. Tuy nhiên, tham số value của đối tượng Price chưa được đặt về 0.
Nếu is_family_shared cần là true, hãy đảm bảo đặt tham số value của đối tượng Price thành 0.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Luôn là: family_share_price_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ phản hồi
Không tìm thấy hồ sơ người dùng
{
"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
Yêu cầu thất bại vì tham số offer_type được đặt thành free_trial, nhưng tham số value của đối tượng Price không được đặt về zero.
Một nguyên nhân khác có thể là tham số offer_id được thêm vào nhưng để giá trị null, trong khi tham số này không được phép null. Trong trường hợp này, hãy cung cấp giá trị cho offer_id hoặc xóa hoàn toàn tham số này.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Luôn là: free_trial_price_error. |
| status_code | Integer | Mã trạng thái HTTP. Luôn là 400. |
Ví dụ phản hồi
Không tìm thấy hồ sơ người dùng
{
"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
Thời gian ân hạn là khoảng thời gian bổ sung bạn có thể cấp cho khách hàng để gia hạn gói đăng ký khi họ không thể gia hạn đúng hạn—ví dụ, khi thẻ tín dụng của họ bị từ chối. Điều này giúp giữ nguyên các cài đặt của họ trong khi họ xử lý vấn đề. Việc cung cấp thời gian ân hạn là tùy chọn.
Nếu bạn cung cấp thời gian ân hạn, ngày hết hạn của nó (grace_period_expires_at) phải muộn hơn ngày hết hạn gói đăng ký (expires_at). Nếu không, thời điểm hết hạn của thời gian ân hạn sẽ trùng với thời điểm hết hạn gói đăng ký. Trong mọi trường hợp, thời điểm hết hạn của thời gian ân hạn không thể sớm hơn thời điểm hết hạn gói đăng ký.
Để khắc phục, hãy đảm bảo ngày hết hạn thời gian ân hạn (grace_period_expires_at) muộn hơn ngày hết hạn gói đăng ký (expires_at).
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi rút gọn. Luôn là grace_period_expires_date_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ response
{
"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
Việc bắt đầu thời gian ân hạn được tính là một sự cố thanh toán. Vì vậy, nếu thời gian ân hạn đã bắt đầu (được xác định bởi tham số grace_period_expires_at đã được điền), ngày bắt đầu của nó phải được ghi lại trong tham số billing_issue_detected_at.
Để khắc phục, hãy đặt ngày bắt đầu của thời gian ân hạn vào billing_issue_detected_at hoặc, nếu thời gian ân hạn chưa bắt đầu, hãy xóa tham số grace_period_expires_at.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi rút gọn. Luôn là grace_period_billing_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ phản hồi
{
"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
Yêu cầu thất bại vì tham số offer_category có giá trị khác introductory hoặc offer_type nhưng không bao gồm offer_id. Trong trường hợp này, hãy cung cấp offer_id hoặc xóa offer_category hay offer_type khỏi yêu cầu.
Một nguyên nhân khác có thể là tham số offer_id đã được thêm vào nhưng để là null, trong khi tham số này không được phép là null. Nếu vậy, hãy thêm giá trị cho offer_id hoặc xóa hoàn toàn tham số này.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Giá trị có thể có: missing_offer_id. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ phản hồi
Không tìm thấy hồ sơ người dùng
{
"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
Yêu cầu thất bại vì đã cung cấp trial cho sản phẩm mua một lần. Không giống như gói đăng ký, sản phẩm mua một lần không thể có trial. Để khắc phục, hãy kiểm tra offer_type trong đối tượng Offer bên trong đối tượng One-Time Purchase. Giá trị của offer_type không được là free_trial. Hãy thay đổi giá trị của trường offer_type hoặc chuyển sang sử dụng đối tượng Subscription thay vì One-Time Purchase.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Luôn là one_time_purchase_trial_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ response
{
"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
Đối với các gói đăng ký dài hạn, một chuỗi giao dịch sẽ được tạo ra. Giao dịch gốc là giao dịch đầu tiên trong chuỗi này và liên kết tất cả các giao dịch tiếp theo. Mỗi lần gia hạn chỉ đơn giản là sự kéo dài của giao dịch gốc đó. Nếu giao dịch là lần mua đầu tiên, nó chính là giao dịch gốc của chính nó.
Timestamp originally_purchased_at đánh dấu thời điểm mua hàng gốc, còn purchased_at là thời điểm của giao dịch hiện tại. Vì vậy, purchased_at không bao giờ có thể sớm hơn originally_purchased_at; trong trường hợp tốt nhất, chúng bằng nhau ở giao dịch đầu tiên.
Yêu cầu thất bại vì originally_purchased_at được đặt muộn hơn purchased_at. Hãy đảm bảo giá trị này sớm hơn hoặc bằng purchased_at.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi rút gọn. Luôn là originally_purchased_date_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ response
{
"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
Yêu cầu thất bại do không tìm thấy mức độ truy cập trong yêu cầu. Hãy kiểm tra lại xem access_level_id có bị nhập sai không và liệu nó có khớp với đúng ứng dụng không.
Body
| Tham số | Loại | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi rút gọn. Giá trị có thể có: paid_access_level_does_not_exist. |
| status_code | Integer | HTTP status. Luôn là 404. |
Ví dụ phản hồi
Không tìm thấy mức độ truy cập.
{
"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
Yêu cầu thất bại vì không tìm thấy hồ sơ người dùng trong header của yêu cầu. Hãy kiểm tra lại xem có lỗi đánh máy nào trong profile_id hoặc customer_user_id bạn đã nhập vào header hay không, và đảm bảo rằng đó là thông tin của đúng ứng dụng.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi rút gọn. Giá trị có thể có: profile_does_not_exist. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ phản hồi
Không tìm thấy hồ sơ người dùng
{
"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
Yêu cầu thất bại do hồ sơ người dùng trong yêu cầu không khớp với mức độ truy cập đã chỉ định. Hãy kiểm tra lại ID hồ sơ người dùng trong header và ID mức độ truy cập trong body, đồng thời đảm bảo không có lỗi đánh máy nào.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi rút gọn. Luôn là profile_paid_access_level_does_not_exist. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ phản hồi
{
"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
Yêu cầu thất bại vì ngày mua (purchased_at) sớm hơn hoặc bằng ngày hoàn tiền (refunded_at). Hoàn tiền luôn xảy ra sau khi mua, vì nó đảo ngược giao dịch.
Để khắc phục, hãy kiểm tra các tham số purchased_at và refunded_at và đảm bảo rằng ngày hoàn tiền muộn hơn ngày mua.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Luôn là refund_date_error. |
| status_code | Integer | Trạng thái HTTP. Luôn là 400. |
Ví dụ phản hồi
{
"errors": [
{
"source": "refunded_at",
"errors": [
"refunded_at must be later than purchased_at."
]
}
],
"error_code": "refund_date_error",
"status_code": 400
}
refund_fields_error
Yêu cầu thất bại do bao gồm cancellation_reason mà không có ngày refunded_at, hoặc có refunded_at mà không có cancellation_reason.
Khi thiết lập hoàn tiền, cần chỉ định cả ngày hoàn tiền lẫn lý do hoàn tiền.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Luôn là refund_fields_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ phản hồi
{
"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
Renewal là việc gia hạn gói đăng ký. Người dùng có thể hủy gia hạn gói đăng ký và sau đó gia hạn lại. Thời điểm của cả hai hành động này được lưu trong tham số renew_status_changed_at. Và giá trị này không thể xảy ra trước thời điểm giao dịch.
Để khắc phục sự cố, hãy đảm bảo renew_status_changed_at sau thời điểm giao dịch (purchased_at).
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Luôn là originally_purchased_date_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ response
{
"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
Yêu cầu thất bại vì revoke_at bạn định nghĩa trong yêu cầu muộn hơn tham số expires_at của mức độ truy cập hiện tại. Nếu bạn muốn gia hạn mức độ truy cập, hãy sử dụng yêu cầu Grant access level.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Luôn là revocation_date_more_than_expiration_date. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ phản hồi
{
"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
Trong trường hợp các gói đăng ký gia hạn liên tục, một chuỗi giao dịch sẽ được tạo ra. Giao dịch gốc là giao dịch đầu tiên trong chuỗi này và toàn bộ chuỗi được liên kết qua đó. Các giao dịch còn lại trong chuỗi là các lần gia hạn. Nếu giao dịch là lần mua đầu tiên trong chuỗi gói đăng ký, nó có thể là giao dịch gốc của chính nó.
Trường hợp khác là sản phẩm mua một lần. Loại này không bao giờ tạo chuỗi vì không thể có gia hạn. Với loại này, store_transaction_id luôn giống với store_original_transaction_id.
Yêu cầu của bạn thất bại vì giá trị store_transaction_id trong đối tượng Sản phẩm mua một lần khác với store_original_transaction_id của nó. Để khắc phục, hãy đặt chúng bằng nhau, hoặc thay đổi đối tượng — dùng Subscription thay vì Sản phẩm mua một lần.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Luôn là store_transaction_id_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ phản hồi
{
"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
Yêu cầu thất bại vì ngày thu hồi được chỉ định đã ở trong quá khứ. Hãy đặt revoke_at thành một ngày trong tương lai hoặc null để thu hồi quyền truy cập ngay lập tức.
Body
| Tham số | Kiểu | Mô tả |
|---|---|---|
| errors | Object |
|
| error_code | String | Tên lỗi ngắn gọn. Luôn là value_error. |
| status_code | Integer | HTTP status. Luôn là 400. |
Ví dụ Response
{
"errors": [
{
"source": null,
"errors": [
"Must be greater than the current time or null"
]
}
],
"error_code": "value_error",
"status_code": 400
}