Statuses And Lifecycles
Every status Kyshi can return, what it means, and what your system should do about it.
Kyshi objects move through defined states. This page is the complete reference for every status your integration can receive.
Treat any status not listed here as unrecognised: log it, do not give value, and check back with the verification endpoint for that object.
Transaction Status
Returned as status on transactions, charges, and collection records.
| Status | Meaning | What you should do |
|---|---|---|
PENDING | The payment has been created but no final result has arrived. | Wait. Do not give value. |
SUCCESS | The payment completed and funds are recognised. | Give value, once. |
FAILED | The payment did not complete. | Do not give value. Let the customer retry. |
IN_REVIEW | The payment needs manual review before it can be finalised. | Do not give value. The status will change without you retrying. |
REVERSAL | A previously recognised payment was reversed. | Reclaim value if you already released it. |
COLLECTED | Funds were collected against the record. | Treat as an accounting state, not a fulfilment signal. Verify before giving value. |
PENDING is the only state that is guaranteed to change. IN_REVIEW resolves on Kyshi's side, so polling harder will not speed it up.
Virtual Account Collection Status
Returned as collectionStatus on virtual accounts and their collection transactions. This is the status most integrations forget to handle, because it covers the cases where the customer does not pay exactly what you asked for.
| Status | Meaning | What you should do |
|---|---|---|
AWAITING | Account created, no payment received yet. This is the default on creation. | Show the account details to the customer. |
PARTIAL | The customer paid less than the expected amount. | Do not fulfil. Ask for the balance, or refund. |
COMPLETED | The expected amount was paid. | Fulfil. |
OVERPAID | The customer paid more than the expected amount. | Fulfil, then handle the excess. The excess is tracked separately. |
EXPIRED | The account or charge window lapsed before payment. | Issue a new account if the customer still wants to pay. |
REVIEW | The payment needs manual review. | Do not fulfil. See below. |
A collection is routed to REVIEW when any of the following is true:
- the payment arrived after the charge had already expired
- a payment arrived on an account that already recorded a successful transaction
- the account had no expected amount set
PARTIAL and OVERPAID are normal, not exceptional. Bank transfers are initiated by the customer in their own banking app, so you cannot constrain the amount they send. Build for both before you go live.
Payment Link Status
| Status | Meaning |
|---|---|
PENDING | Link created, not yet paid. |
OPENED | The customer opened the link but has not completed payment. |
SUCCESS | Payment completed. |
FAILED | Payment attempted and failed. |
COLLECTED | Funds collected against the link. |
OPENED is useful for abandonment metrics. It is not a payment signal.
Subscription Status
| Status | Meaning | What you should do |
|---|---|---|
PENDING | Created, first charge not yet settled. | Wait before granting access. |
ACTIVE | Billing normally. | Grant access. |
PAST_DUE | A renewal failed and retries are in progress. | Decide your grace policy. Access is your call, not Kyshi's. |
NON_RENEWING | Will not renew at period end, but is still active until then. | Keep access until the period ends. |
COMPLETED | Reached its invoice or payment limit and ended normally. | Revoke access at period end. |
CANCELLED | Ended before its natural end. | Revoke access. |
NON_RENEWING and CANCELLED are different. A NON_RENEWING subscription is still owed service for the period the customer already paid for.
Subscription Payment Attempt Status
Each billing attempt against an invoice records its own status.
| Status | Meaning |
|---|---|
PENDING | Attempt in flight. |
SUCCEEDED | The attempt collected the money. |
FAILED | The attempt did not collect. See Failure Codes. |
REQUIRES_ACTION | The customer must do something, such as complete authentication. |
REQUIRES_ACTION is not a failure. The attempt is waiting on the customer, so retrying it from your side will not help; the customer has to act.
Handling Unknown Statuses
New statuses can be added. Write your status handling so that anything unrecognised falls through to a safe default:
switch (transaction.status) {
case 'SUCCESS':
return fulfil(transaction);
case 'FAILED':
case 'REVERSAL':
return doNotFulfil(transaction);
default:
// PENDING, IN_REVIEW, COLLECTED, or anything new.
return waitAndVerifyLater(transaction);
}Never treat an unknown status as success.
Updated about 20 hours ago
