Inspiration
African freelancers and SMEs lose hours every week doing something that should be automatic: matching bank/Paystack payments against open invoices. Customers pay with mangled references ("PMT final tunde"), pay in parts, or pay from unexpected accounts — and money gets lost not to fraud, but to someone forgetting to chase an overdue invoice. I wanted an agent that actually closes that loop end-to-end, not another chatbot wrapper.
What it does
Recona ingests Paystack charge.success webhooks, asks a Qwen-powered matching engine which invoice a payment settles (with a confidence score and reasoning), and then makes an autonomous decision: high-confidence exact matches auto-close the invoice immediately; everything else — partial payments, currency mismatches, or genuine uncertainty — escalates to the business owner over Telegram with one-tap Approve/Reject. A daily cron sweep also drafts and sends Qwen-written payment reminders at 3/7/14 days overdue, in an escalating tone, and never reminds about an invoice that's already been paid. Every decision, agent or human, lands in an audit trail.
How I built it
- Cloudflare Workers + D1 handle ingestion, orchestration, and the cron sweep — signature-verified webhooks, idempotent against duplicate delivery (UNIQUE constraints, not best-effort checks).
- Alibaba Cloud SAS, running a Dockerized Node service, hosts all the Qwen reasoning — matching and reminder-drafting — independently deployable from the ingestion layer.
- The reconciler exposes its engine both as plain REST (used by the Worker) and as MCP tools (
match_transaction_to_invoice,draft_payment_reminder) over streamable HTTP, so any MCP client can call it directly. - Telegram is the human-in-the-loop surface — no custom dashboard, because the actual job here is workflow automation, not another web app to log into.
The core design decision: the LLM proposes, deterministic code disposes. Auto-closing an invoice requires all three — exact amount, matching currency, and model confidence above threshold — enforced in code after the model runs, not trusted from the prompt.
Challenges I ran into
The most interesting one wasn't technical infrastructure — it was Qwen's own behavior. I expected a scripted demo where the model would confidently identify an invoice for a partial payment and get overruled by my guards. In testing against the real, live model, Qwen was more cautious than that: given a payment with a matching email but no reference hint, it consistently returned 30% confidence and no committed invoice ID, even when its own reasoning text discussed the right candidate. Rather than force the original script, I let the demo show what actually happened — which turned out to be a better story: the system doesn't just override a wrong answer, it correctly recognizes when it doesn't have enough signal to answer at all.
Separately, Alibaba Cloud identity verification took two submission attempts (the first was rejected for the wrong document format), which I treated as a scheduling risk and worked around by developing the rest of the system against a local + tunnel setup while waiting.
Accomplishments that I'm proud of
Every part of this is a real, live system, not a demo shell — the Cloudflare Worker, the D1 database, the Telegram bot, and the Alibaba-hosted reconciler are all genuinely deployed and were used to record the actual demo footage (real Paystack test payments, real Qwen calls, real Telegram messages).
What I learned
Letting an LLM touch real money is easy to get wrong in the "obvious" way (asking the model and doing what it says) and easy to get wrong in the opposite way too (never trusting it, so a human has to review everything). The useful middle is making the model's own uncertainty a first-class, machine-readable signal — and building the guardrails around that, not around trying to make the model always right.
What's next for Recona
Flutterwave support (stretch scope from day one), direct-to-customer reminder delivery instead of owner-forwards, and packaging the reconciliation engine as a standalone MCP server other agent builders can point at their own invoice data.
Built With
- alibaba-cloud
- cloudflare-d1
- cloudflare-workers
- docker
- javascript
- mcp
- node.js
- paystack
- qwen
- telegram-bot-api
Log in or sign up for Devpost to join the conversation.