Inspiration

In bulk payment I am a witness, of seeing workers being paid twice by accident(double-invoice), and some payment may not even occur to the right individuals.This may lead to an organisation loosing money, and to the contractors,it may raise dispute hence them being dissatisfied with work assigned.in the name of the project the PAP is a swahili sland word meaning fast, thats why i saw it necessary in the brand name "pay pap"

What it does

Upload. An admin uploads a CSV. Pay Pap maps the columns and checks every row against fixed rules, flagging duplicate invoices, rejected emails and unusual amounts. AI review. The Groq model turns each flag into a plain sentence, such as “this invoice is claimed twice”. The admin can filter the rows in plain English, by text or by voice through Whisper. The payout agent answers with row numbers. It can propose actions, but it cannot decide or approve anything. Decide. A person decides every warning,(in a different account) choosing pay or leave out. Approve. A different person approves the exact total, shown next to the live PayPal balance. The approval is signed and expires. Pay and reconcile. PayPal Payouts sends the batch with a fixed batch id, so a retry can never pay twice. Signed webhooks bring the statuses back: paid, unclaimed or failed. Emails PayPal rejected are blocked from future batches. Audit. Every step goes into a hash-chained, tamper-evident audit log.

How we built it

PayPal Payouts, with signature-checked webhooks, sends the money and reports the results. APIMatic’s PayPal SDK gives the backend a typed connection to PayPal. The approval card shows the live PayPal balance, and errors come back as structured results, so there is no hand-written PayPal client. FastAPI is the backend, hosted on Vercel. It holds the row rules, the five-tool agent, the signed approval and the fixed batch id. Supabase stores batches and the audit log. Its database guards re-check the approval before PayPal is ever called. Groq provides the model that explains flags and answers questions. Groq Whisper handles voice input. AG Grid powers the review and approval grid in the browser, with light and dark themes.

Challenges we ran into

Voice that actually hears you. Our first voice input treated any click as speech and stopped recording before people spoke. We added a minimum speech length, an adaptive noise floor and logging of what Whisper heard, and tested it with a recorded question.

Clocks and approvals. Our signed approvals expire, but a PC with a drifting clock made the database reject them. We now compute expiry from the database’s own clock, the same clock that checks it.

PayPal rejecting receivers. PayPal refused every payout to our bulk-created sandbox accounts. We added blocking rules that remember PayPal’s rejections and refuse those receivers at upload and again just before sending. The root cause is still unconfirmed.

Two PayPal balances. The sandbox dashboard and the Reporting API disagree, so the approval card shows the Reporting API balance, labeled as sandbox. A shortfall still blocks a live batch.

Honest SDK scope. APIMatic’s PayPal SDK has no Payouts API, so it reads the live balance and the payout call stays on a small client of ours.

Accomplishments that we're proud of

A system that learns from PayPal in its own memory. Two rules, PAYPAL_REJECTED_RECEIVER and PAYPAL_REJECTED_DOMAIN, come from real PayPal rejections. They block those receivers at upload and again just before sending Safety enforced by the database, not by the AI. The audit log is append-only and hash-chained. Submit refuses any batch without a valid signed approval, so a hand-made approval row can’t release money. The approver can’t be the uploader. Every batch carries a fixed id, so a retry can’t pay twice. APIMatic used the right way. The APIMatic PayPal SDK reads the balance and is built with the Context Plugin’s guidance. It passes mypy --strict and has 11 tests against a stub under the real SDK. You also noticed the SDK has no Payouts API, and the README says so. A polished product. The glass UI has light and dark themes, a desktop layout, voice input with specific error messages, a Rules page and a notifications menu.

What we learned

Put the AI’s limits in the system, not in the prompt. The agent can’t submit because the submit function refuses without an approval. Instructions alone would not have held. Don’t trust the machine’s clock. A drifting PC clock broke approvals and, earlier, npm’s certificate check. Expiry is now counted from the database’s clock. PayPal’s two balances disagree. The sandbox dashboard and the Reporting API don’t match, and unclaimed payouts count as paid because the money can still be claimed. Retries are the real double-payment risk. PayPal’s PayPal-Request-Id does not replay the original answer. The real guard is the fixed sender_batch_id, and the code reads the existing batch id from PayPal’s error. Webhooks arrive in a burst. A batch of 223 events overwhelmed a blocking endpoint, and a single shared HTTP/2 client failed under parallel load. The fix was a thread pool and one Supabase client per thread. Define terms for the model. The natural-language filter mixed up “blocked rows” and “blocked contractors” until the instructions defined each one. Serverless has no background worker. The webhooks, the batch page’s 15-second sync and a daily cron do that job.

What's next for PAY PAP

More users. Today there is one admin and one approver, so add roles and approval policies, such as a second approver above a set amount. Reconciliation and audit. Export the reconciliation, search the audit log, and clean up the 227 unclaimed sandbox payouts from 24 October. Forecasting and scheduling. Cash-flow forecasts and scheduled recurring batches. Faster AI. A paid Gemini AI tier removes the one-minute waits for explanations. Real-time status. Replace the daily cron and polling with webhook-driven updates once a background worker is affordable.

Built With

Share this project:

Updates

Submission history