Give your agent a wallet you control.
Let your agents pay online using one-time-use cards or with machine payment protocols. You approve every request.
Invoicing and payments for freelancers: manage clients, send invoices, and get paid online.
FinanceGitHub @avshr1OnlineOwner unconfirmed
Have you tried it? One tap is enough. No sign-in needed.
Repository information has not been collected yet.
No updates detected yet. GitHub releases will appear here.
Paydesk: full-stack invoicing & payments app for freelancers. Clients, invoices, Stripe Checkout + webhooks, email, PDFs, and a revenue dashboard. Next.js, TypeScript, Prisma, PostgreSQL.
Taken from the repository README
Loading the full README.
Read the full README ↗Paydesk is a full-stack invoicing and payments app where freelancers manage clients, create invoices, email them, and get paid online through Stripe. Clients pay from a public link without creating an account.
🚧 Status: In active development, built in phases. See the roadmap for progress.
🔗 Live demo: paydesk-theta.vercel.app · Payments run in Stripe test mode, so no real money moves.
| Area | Technology |
|---|---|
| Framework | Next.js (App Router), React, TypeScript (strict mode) |
| Styling | Tailwind CSS |
| Database | PostgreSQL (Prisma Postgres) with Prisma ORM |
| Auth | Auth.js (Credentials + Google) |
| Payments | Stripe Checkout + webhooks |
| Resend | |
| Validation | Zod on every form and API route |
| Testing | Vitest (unit), Playwright (end-to-end) |
| CI/CD | GitHub Actions, deployed on Vercel |
These are the decisions I'd point to in this codebase:
825 = 8.25%), and quantities as hundredths (150 = 1.5 hours). This avoids floating-point errors like 0.1 + 0.2 = 0.30000000000000004.StripeEvent table in the same database transaction that marks the invoice paid, so a duplicate event is never processed twice.erDiagram
User ||--o{ Client : owns
User ||--o{ Invoice : owns
Client ||--o{ Invoice : "is billed on"
Invoice ||--|{ LineItem : contains
Invoice ||--o{ Payment : "is paid by"
Invoice ||--o{ EmailLog : "has emails"
StripeEvent {
string id PK "Stripe event id (idempotency)"
}
The full schema is in prisma/schema.prisma.
git clone https://github.com/avshr1/paydesk.git
cd paydesk
npm install
cp .env.example .env # then fill in the values
docker compose up -d # start local Postgres
npx prisma migrate dev # create the database tables
npm run dev # http://localhost:3000
In a second terminal, forward Stripe webhooks to your local server:
stripe listen --forward-to localhost:3000/api/webhooks/stripe
Pay test invoices with card 4242 4242 4242 4242, any future expiry date, and any CVC.
| Variable | Purpose |
|---|---|
DATABASE_URL | Pooled Postgres connection string |
DIRECT_URL | Direct Postgres connection (used for migrations) |
AUTH_SECRET | Secret for signing Auth.js tokens |
AUTH_GOOGLE_ID / AUTH_GOOGLE_SECRET | Google OAuth credentials |
STRIPE_SECRET_KEY | Stripe API key (test mode) |
STRIPE_WEBHOOK_SECRET | Used to verify webhook signatures |
RESEND_API_KEY | Sends transactional email |
EMAIL_FROM | Sender address for invoices |
CRON_SECRET | Protects the overdue-reminder endpoint |
APP_URL | Base URL used in emailed links |
npm run test # Vitest unit tests (invoice math, webhook handling)
npm run test:e2e # Playwright end-to-end tests
MIT