Error Handling
Checkout and order endpoints signal business failures inside the response body, not through HTTP status codes. The error envelope and codes are identical to the Direct Merchant integration.
Error envelope
Branch on error_code, not HTTP status
Business failures return HTTP 200 with a non-zero error_code — a numeric code serialized as a JSON string ("0" is success). HTTP 4xx/5xx appears only for malformed requests or infrastructure problems.
Error response
{
"error_code": "801",
"errors": [
"an order with this order_reference_id already exists"
],
"message": "Order already exists",
"data": null
}Two endpoints use different envelopes: Check Eligibility returns HTTP 400 with { is_error: true, message } for business failures, and Get Customer Invoices signals failures with success: false and a message, with no numeric code. Each endpoint page documents its own envelope.
Error code reference
| Code | Name | Description | Resolution |
|---|---|---|---|
400 | INVALID_PARAMS | A required field is missing or a value failed validation (e.g. totals don't reconcile, invalid phone format, unknown field value). | Check errors[] for the failing field. Ensure order.total_amount equals the sum of items[].total_amount plus shipping_amount minus discount_amount. |
500 | INTERNAL_ERROR | An unexpected failure occurred on FINA's side. | Retry with backoff; contact FINA support if it persists. |
801 | ORDER_ALREADY_EXISTS | An order with the same order_reference_id already exists. order_reference_id is the idempotency anchor. | Use a fresh order_reference_id for new orders; reuse the existing order for retries. |
802 | SELLER_NOT_VALID | The merchant resolved from the bearer token is not recognised for this operation. | Verify the bearer token belongs to the correct merchant account. |
803 | SELLER_INACTIVE | The merchant account exists but is not active. | Contact the FINA team to activate the merchant account. |
804 | ANOTHER_CHECKOUT_IN_PROGRESS | A concurrent checkout for the same buyer is already in flight. | Wait for the in-flight checkout to finish, then retry. |
805 | CUSTOMER_NOT_ONBOARDED | The buyer has not completed FINA onboarding. | Run Check Eligibility and take the buyer through the signup_url onboarding flow. |
806 | CUSTOMER_CREDIT_LIMIT_EXCEEDED | The buyer's available credit does not cover this order. | Offer a plan with a down payment, reduce the order amount, or hide FINA for this purchase. |
808 | INVALID_ORDER | No order was found for the given order_id / order_number. | Use the order_id returned by Initiate Checkout. |
809 | OTP_VERIFICATION_FAILED | The OTP is wrong or has expired. Buyers get 3 verification attempts. | Ask the buyer to re-enter the code, or call Resend OTP and retry Authorise Checkout. |
810 | ANOTHER_ACTION_IN_PROGRESS | A concurrent action on the same order is already in flight. | Wait for the in-flight action to finish, then retry. |
811 | INVALID_ORDER_STATE | The order is not in a state that allows this operation (e.g. authorising an expired order, confirming delivery on an unauthorised order). | Check the order lifecycle; only perform operations valid for the order's current status. |
812 | NOTIFICATION_FAILED | The OTP SMS could not be sent to the buyer. | Retry Resend OTP; verify the buyer's phone number. |
813 | INVALID_FILE | The invoice file could not be downloaded or is not a valid PDF. | Ensure invoice_url is publicly reachable and points to a valid PDF. |
876 | MISSING_PLAN_SELECTION | No repayment plan could be resolved for the order. | Pass a repayment_config_id returned by Repayment Plan Options. |
877 | INVALID_PLAN_SELECTION | The repayment_config_id is invalid, or commission_config.tenure_in_days / merchant_share do not match the selected plan. | Send a repayment_config_id from Repayment Plan Options and keep commission_config consistent with that plan. |
878 | PLAN_NOT_CONFIGURED | No repayment plan is configured for the requested tenure_in_days / channel. | Only offer plans returned by Repayment Plan Options; contact FINA to configure more. |
881 | BG_DOC_EXPIRED | The buyer's credit agreement document has expired. | Send the buyer through onboarding again via Check Eligibility's signup_url. |