Nylon PayNylon Pay

Transaction Lifecycle

How a payment moves from start to finish

Every transaction goes through these statuses.

State Diagram

pending -> processing -> successful
                   -> failed
                   -> cancelled

Status Definitions

pending

The transaction has been created in the Nylon Pay system but has not yet been sent to the payment provider. This is the initial state for all new transactions.

Note: During this state, you can still modify certain transaction details before it moves forward.

processing

The transaction has been submitted to the payment provider and is awaiting completion. For mobile money payments, this typically means the customer has received a PIN prompt or is completing authentication.

Note: Transactions in processing state may take minutes or hours to complete depending on the payment method and customer action.

successful

The payment provider has confirmed the transaction. Funds have moved (or will move shortly) and the transaction is complete.

Terminal state: No further status changes will occur for this transaction.

failed

The payment was rejected by the provider or the customer declined to complete payment. Common reasons include insufficient funds, invalid credentials, or provider-side errors.

Terminal state: Failed transactions may be eligible for retry with corrected details.

cancelled

The transaction was cancelled before completion. Cancellation can occur through explicit user action, merchant cancellation via API, or system cancellation due to timeout.

Terminal state: Cancelled transactions cannot be restarted.


Operator Transaction ID

When a payment reaches a terminal status (successful or failed), the transaction record may include an operatorTid field. This is the transaction identifier from the underlying payment operator (the telco or bank that processed the payment).

Use operatorTid to cross-validate customer payment claims. A customer who says they paid can provide their operator receipt, and you can match the ID against the operatorTid on the transaction.

The field is null until the operator reports it, and may not be available for all payment methods.


Status Summary

StatusMeaningTerminalCan Retry
pendingCreated, not yet sentNoN/A
processingSent to provider, awaiting customerNoN/A
successfulPayment confirmedYesNo
failedPayment rejectedYesYes (with corrections)
cancelledCancelled before completionYesNo

Transition Triggers

TransitionTrigger
pending -> processingSDK submits transaction to provider
processing -> successfulProvider confirms payment
processing -> failedProvider rejects or customer declines
processing -> cancelledTimeout reached or explicit cancellation
pending -> cancelledExplicit cancellation before submission

SDK Event Mapping

The SDK exposes events that correspond to these status changes:

Status ChangeSDK EventWhen to Use
Transaction created(initial state)Log transaction start
pending -> processingpayment.on('processing', ...)Show "Processing" UI
processing -> successfulpayment.on('success', ...)Fulfill order, show success
processing -> failedpayment.on('failed', ...)Show error, offer retry
processing -> cancelledpayment.on('cancelled', ...)Show cancellation message
Any errorpayment.on('error', ...)Log error, notify support

Example: Handling Status Changes

const payment = await nylonPay.collectPayment({
  amount: 5000,
  currency: 'UGX',
  description: 'Product purchase',
  customer: {
    name: 'John Doe',
    phoneNumber: '+256700000000'
  },
  reference: crypto.randomUUID(),
});

payment.on('processing', () => {
  // Update UI: "Awaiting customer confirmation"
  updateOrderStatus('waiting_for_payment');
});

payment.on('success', ({ transaction }) => {
  // Fulfill order
  if (transaction) {
    fulfillOrder(transaction.reference);
  }
  sendConfirmationEmail();
});

payment.on('failed', () => {
  // Show error message
  showErrorMessage('Payment failed. Please try again.');
});

payment.on('cancelled', () => {
  // Clean up
  cancelOrder();
  showMessage('Payment was cancelled.');
});

payment.on('error', (data) => {
  // Log for debugging
  console.error('Payment error:', data.error);
  notifySupport(data);
});

On this page