ST Pay Merchant APIST Pay Merchant API
Guide
API
Error codes
Back office
AI-assisted integration
  • 繁體中文
  • 简体中文
  • English
Guide
API
Error codes
Back office
AI-assisted integration
  • 繁體中文
  • 简体中文
  • English
  • Getting started

    • Overview
    • Request and response format
    • Authentication and IP whitelist
    • Signature
    • Merchant back office
    • AI-assisted integration
  • API

    • Create a collection order
    • Create a payout order
    • Order query
    • Callback notifications
  • Reference

    • Order status and amounts
    • Duplicate requests and confirming results
    • Error codes
    • Bank codes
    • Go-live checklist

Order query

Query the current status and amounts of an order. Use an order query to confirm the result in the following cases:

  • You did not receive a Callback.
  • A collection order received a late credit (no Callback is sent).
  • Your order creation request timed out, or you received internal_error. For a pending order, the response also includes the payment details, so the payer can still pay that order (see below).
  • Order creation returned merchant_order_no_duplicate, and you want to know the status of the existing order.

An order query is a read-only operation and can be called repeatedly.

Request fields

Collection order queries and payout order queries use the same request fields:

FieldRequiredDescription
api_identityYesThe API identity issued by ST Pay
order_noEither oneST Pay order number
merchant_order_noEither oneYour merchant order number
timestampYesThe time the request is sent (UTC+8, yyyy-MM-dd HH:mm:ss). Rejected if it differs from the ST Pay server time by more than 5 minutes. See Request and response format
signYesSee Signature
  • If neither is sent, missing_parameter is returned.
  • If both are sent, they must refer to the same order. If they refer to different orders, query_conflict is returned; if either of them cannot be found, order_not_found is returned.
  • You can only query your own orders. If the order does not exist, belongs to another merchant, or has been deleted after 6 months, order_not_found is returned in every case.

Possible errors: invalid_signature, timestamp_expired, ip_not_allowed, missing_parameter, invalid_parameter, query_conflict, order_not_found, internal_error.

Query a collection order

POST /api/v1/collect/orders/query

Request example

{
  "api_identity": "qp_Xk3vT9aLm2QwE7rB1nZc",
  "merchant_order_no": "MO20261013-0001",
  "timestamp": "2026-10-13 10:35:00",
  "sign": "c29089b08a6fdcd3d9c17a404cae90a4aaa0a79210778e53997e4f9f43bb6462"
}

Response fields

FieldDescription
order_noST Pay order number
merchant_order_noMerchant order number
channel_typefps or bank_transfer
statuspending, success, rejected, or late_credited; see Order status
amountOriginal amount
payable_amountPayable amount (the original amount plus the tail)
received_amountReceived amount. Has a value only for success and late_credited; null for other statuses
feeFee. Has a value for success and late_credited; "0.00" for rejected; null for pending
settlement_amountSettlement amount (the amount added to your balance). Has a value only for success and late_credited; null for other statuses
created_atOrder creation time
finished_atCompletion time; null for pending
reject_reasonThe rejection reason text for rejected: when rejected manually by ST Pay, the reason that was selected (null if no reason was selected); when rejected on expiry by the system, 「訂單已逾時」 ("order expired"). This is text for humans to read, not a code. Ignore this field for other statuses
payment_urlPayment page URL, the same as in the order creation response. Present only for orders that are pending and not yet expired and were created in url mode
bank_name, bank_codeBank name and code. Present only for orders that are pending and not yet expired and were created in json mode with channel bank_transfer
account_no, account_nameFull receiving account number and account name (or payee name). Present only for orders that are pending and not yet expired and were created in json mode
expires_atExpiry time. Present only for orders that are pending and not yet expired
signResponse signature, computed with the key used for this request. See Verifying responses

If your order creation request timed out and you did not get a response, query by merchant order number: if the order is pending and the payment details above are present, you can send the payer to payment_url (or show the receiving account) to pay that order, instead of creating a new order with a new merchant order number. The expiry time stays the original expires_at and is not extended; once the order has expired or ended, the payment details are no longer returned. Verify the signature first, and use these details only if it passes.

Response examples

Pending (url mode)
{
  "code": "OK",
  "message": "成功",
  "data": {
    "order_no": "C202610131000051230000",
    "merchant_order_no": "MO20261013-0001",
    "channel_type": "fps",
    "status": "pending",
    "amount": "1000.00",
    "payable_amount": "1000.37",
    "received_amount": null,
    "fee": null,
    "settlement_amount": null,
    "created_at": "2026-10-13 10:00:05",
    "finished_at": null,
    "reject_reason": null,
    "payment_url": "https://pay.vincoterra.com/pay/QzIwMjYxMDEzMTAwMDA1MTIzMDAwMA.v3Kd9QeLr7Zp1sWm4XyT8bN2cF6hJ0aG5uE-iOkRtYw",
    "expires_at": "2026-10-13 10:30:05",
    "sign": "8cba06866fc16ea3b585309cd13d851d7bda49bf2e95605275f2d99047620487"
  }
}
Success
{
  "code": "OK",
  "message": "成功",
  "data": {
    "order_no": "C202610131000051230000",
    "merchant_order_no": "MO20261013-0001",
    "channel_type": "fps",
    "status": "success",
    "amount": "1000.00",
    "payable_amount": "1000.37",
    "received_amount": "1000.37",
    "fee": "25.00",
    "settlement_amount": "975.37",
    "created_at": "2026-10-13 10:00:05",
    "finished_at": "2026-10-13 10:12:30",
    "reject_reason": null,
    "sign": "889c767037b6748de1d9fa399129b97012c85f3599a0cce9aff289cf79477626"
  }
}
Rejected on expiry
{
  "code": "OK",
  "message": "成功",
  "data": {
    "order_no": "C202610131001178820000",
    "merchant_order_no": "MO20261013-0002",
    "channel_type": "bank_transfer",
    "status": "rejected",
    "amount": "2000.00",
    "payable_amount": "2000.58",
    "received_amount": null,
    "fee": "0.00",
    "settlement_amount": null,
    "created_at": "2026-10-13 10:01:17",
    "finished_at": "2026-10-13 10:31:17",
    "reject_reason": "訂單已逾時",
    "sign": "6a99a7a5085900260830aee441271fb2a0e94d88d33e49b15bfb5a46d6a6e05e"
  }
}
Order not found
{
  "code": "order_not_found",
  "message": "查無此單",
  "data": null
}

Query a payout order

POST /api/v1/payout/orders/query

Request example

{
  "api_identity": "qp_Xk3vT9aLm2QwE7rB1nZc",
  "order_no": "P202610131005224410000",
  "timestamp": "2026-10-13 10:40:00",
  "sign": "adae0ba479bd688b63425e34dcb77cbf5114b34bee68e266ba045ea69748f2b9"
}

Response fields

FieldDescription
order_noST Pay order number
merchant_order_noMerchant order number
channel_typefps or bank_transfer
statuspending, paid, or rejected; see Order status
amountPayout amount
feeFee. Has a value for paid; "0.00" for rejected; null for pending
total_deductedTotal deducted (the payout amount plus the fee). Has a value only for paid; null for other statuses
created_atOrder creation time
finished_atCompletion time; null for pending
reject_reasonThe rejection reason text for rejected (null if no reason was selected). Ignore this field for other statuses
signResponse signature, computed with the key used for this request. See Verifying responses

Response example

{
  "code": "OK",
  "message": "成功",
  "data": {
    "order_no": "P202610131005224410000",
    "merchant_order_no": "PO20261013-0001",
    "channel_type": "fps",
    "status": "paid",
    "amount": "500.00",
    "fee": "7.50",
    "total_deducted": "507.50",
    "created_at": "2026-10-13 10:05:22",
    "finished_at": "2026-10-13 10:20:41",
    "reject_reason": null,
    "sign": "67d2dfa30d5df0d5456f706400e22faaf5acbb22b164885d5e08f1102e8538a7"
  }
}
Prev
Create a payout order
Next
Callback notifications