# C2B Non-STK Completed Integration

## Summary
This document captures the completed work for the C2B non-STK integration between relay.sportinoti.com and the LendCore app.

## What was implemented
- Deployed the relay-box endpoint to `https://relay.sportinoti.com`.
- Configured relay-box to forward M-Pesa C2B non-STK callback payloads to LendCore.
- Set the relay target URLs to:
  - `https://relay.sportinoti.com/c2b/validation`
  - `https://relay.sportinoti.com/c2b/confirmation`
- Added a cron/web runner script to invoke queue processing via PHP every 10 seconds from the project.
- Created test scripts to simulate payloads for:
  - non-STK confirmation: `temp_post_relaybox.php`
  - non-STK validation: `temp_post_relaybox_validation.php`
- Added recovery tooling to replay failed payloads and save missing transactions into suspense.

## Configuration updates
- Updated relay-box `.env` to use the correct production PHP binary and queue worker runner.
- Updated LendCore `.env` with a fresh M-Pesa production access token: `MPESA_ACCESS_TOKEN_PRODUCTION=XRsrh07SzLuvYktJve2eoCKbkcHz`
- Updated registration logic to use the actual configured shortcode `MPESA_SHORTCODE=787306`.

## Registration
- Registered the following M-Pesa callback URLs manually and via the script:
  - `https://relay.sportinoti.com/c2b/validation`
  - `https://relay.sportinoti.com/c2b/confirmation`
- Confirmed the registration endpoint on Safaricom responds and the URLs are active.

## Failed payload recovery
- Identified failed confirmation callbacks caused by the database being inactive.
- Replayed failed payloads through `/api/payment/c2b/nonstk/confirmation` using a recovery script.
- The following failed payloads were moved into suspense because the corresponding `BillRefNumber` values did not match existing users:
  - `UFJ0R8UTKT` — `BillRefNumber=34199884`
  - `UFJ9Y868VE` — `BillRefNumber=24808904`
  - `UFJ3L93ANI` — `BillRefNumber=26899833`
  - `UFJS2BQRFS` — `BillRefNumber=26899833`

## Current state
- Relay-box is receiving callbacks and forwarding jobs via queue.
- LendCore receives non-STK confirmation callbacks and applies payment logic.
- Unmatched confirmations are correctly captured in `suspense_transactions` for manual review.

## Next actions
- Create or verify users for the suspense `BillRefNumber` values.
- Reprocess suspense entries once matching users exist.
- Monitor `relay_transactions`, queue logs, and application logs for successful processing.
- Optionally add a status endpoint for the queue runner and webhook health.

## Update: queue-worker processing issue (2026-07-01)
- Two recent non-STK confirmations were left in suspense as unmatched even though the callback payloads were received and queued successfully.
- The affected transactions were:
  - `UG1BCA32XZ` with `BillRefNumber=28092557936` and `Name=CATHERINE`
  - `UG145A1WTT` with `BillRefNumber=10889384530` and `Name=JANNET`
- Investigation showed the callbacks reached the endpoint and were accepted into the queue, but no later queue-processing log entry was emitted for those jobs.
- This points to a queue-worker execution gap rather than a payload-formatting issue.
- A new automatic queue-trigger mechanism was added so web/API requests can start the C2B queue worker when pending jobs exist, reducing the chance of callbacks remaining stuck in the database queue.
- The matching logic for non-STK confirmations now uses the shared user-matching service so legitimate payments are less likely to be misclassified as unmatched when the BillRefNumber or related identifier is formatted differently.
