DocsReference

Status codes

Every Syok2Pay response carries a status_code (and, on the HTTP layer, a matching status). Use the status_code — not the HTTP status alone — to decide what to do next. Each row below tells you what happened and what to do.

Success

OK

The request was accepted. For PENDING, the final result arrives later via callback or inquiry.

SUCCESSHTTP 200

Request completed successfully.

Proceed — read data from the response body.

PENDINGHTTP 200

Accepted; awaiting the bank or payment provider.

Wait for the callback, or poll Inquiry. Do not re-initiate.

Validation & parameters

Fix request

The request was rejected before processing. Fix the request and send it again.

PARAM_MISSINGHTTP 400

A required field is missing.

Add the missing field (e.g. amount, currency) and retry.

PARAM_INVALIDHTTP 400

A field value is invalid.

Check the format — amount is a 2-dp string, currency is an ISO code.

INVALID_AMOUNTHTTP 400

The amount is not a valid positive value.

Send amount as a positive decimal string, e.g. "3.00".

INVALID_CURRENCYHTTP 400

The currency is missing or unsupported.

Use a supported currency code such as MYR.

DUPLICATE_REFERENCEHTTP 400

This reference_no was already used.

Use a unique reference_no per order. Reusing one is treated as a duplicate.

FUNCTION_NOT_SUPPORTEDHTTP 400

The operation isn't available for this product or channel.

Check the product's capabilities or pick a supported payment method.

Authentication

Check credentials

The request could not be authenticated. These never succeed on retry until the credentials or signature are corrected.

UNAUTHORIZEDHTTP 401

Missing or invalid API key.

Send the Authorization header as 'Bearer pk_…'.

INVALID_SIGNATUREHTTP 401

The X-Signature did not match.

Rebuild the signing string, sign with your secret key, and check X-Timestamp is fresh.

INVALID_API_KEYHTTP 401

The API key is not recognised.

Verify the key and that your merchant account is active.

EXPIRED_API_KEYHTTP 401

The API key has expired.

Generate a new key in the merchant dashboard.

FORBIDDENHTTP 403

Authenticated, but not allowed to access this resource.

Ensure merchant_code matches your account and you own the transaction.

IP_NOT_ALLOWEDHTTP 403

Your server IP is not whitelisted.

Add the calling IP to your merchant IP allowlist.

MERCHANT_INACTIVEHTTP 403

The merchant account is inactive or suspended.

Contact support to reactivate the account.

Not found

Not found

The referenced resource does not exist (or is no longer retrievable).

SESSION_NOT_FOUNDHTTP 404

No session matches that session_id.

Check the session_id; create a new session if it has been purged.

TRANSACTION_NOT_FOUNDHTTP 404

No transaction matches that id.

Verify the txn_id, or look it up via Inquiry using your reference_no.

INVALID_MERCHANTHTTP 400

The merchant_code is unknown.

Confirm the merchant_code is correct and registered.

INVALID_PRODUCTHTTP 400

The product_code is unknown or not linked to you.

Use a valid product_code that is enabled for your account.

Session & transaction state

Check state

The resource exists but its current state does not allow this operation. Check the state first, then act.

SESSION_EXPIREDHTTP 400

The session passed its expiry time.

Create a new session — sessions are short-lived.

SESSION_COMPLETEDHTTP 400

The session is already paid.

Do not reuse it; start a new session for a new payment.

SESSION_CANCELLEDHTTP 400

The session was cancelled.

Create a new session if the customer wants to retry.

VOID_NOT_ALLOWEDHTTP 400

This transaction can't be voided in its current state.

Only authorised or pending transactions can be voided.

REFUND_NOT_ALLOWEDHTTP 400

This transaction can't be refunded in its current state.

Only captured transactions can be refunded.

Payment declined

Customer action

The payment was attempted but not completed. The customer usually needs to take action.

PAYMENT_FAILEDHTTP 400

Payment processing failed.

Let the customer retry; create a new session if needed.

PAYMENT_DECLINEDHTTP 400

The bank or provider declined the payment.

Ask the customer to try another card, bank, or method.

PAYMENT_CANCELLEDHTTP 400

The customer cancelled at the payment page.

Offer a new session to try again.

Server & transient

Retry

Something went wrong on our side, or a dependency was briefly unavailable. These are safe to retry idempotently with the same reference_no.

INTERNAL_ERRORHTTP 500

Unexpected server error.

Retry with backoff; if it persists, contact support with the trace_id.

BACKEND_UNAVAILABLEHTTP 503

The payment processor is unreachable.

Retry after 30–60s; check the status page.

TIMEOUTHTTP 504

The backend did not respond in time.

Retry idempotently using the same reference_no.

Retrying safely

Always retry with the same reference_no. Initiate is idempotent on reference_no, so a retried request returns the original session instead of creating a duplicate charge. Only Server & transient errors should be retried automatically — use exponential backoff (1s, 2s, 4s…).

Every error response also includes a trace_id. Include it when contacting support so we can find the exact request in our logs.