Create invoices, verify Stellar payments, and generate shareable receipts.
Live: payproof-five.vercel.app ·
CI: ·
License: MIT
I kept running into the same problem: someone would send a Stellar payment and the other party wanted proof it went through, but pointing them at a block explorer felt like handing someone a raw API response. I wanted something that looked like an actual receipt — something you could print or forward in an email without explanation. PayProof started as a weekend script and turned into this.
PayProof has two main flows:
Invoices — create an invoice with a title, amount (XLM or USDC), and your Stellar address. Share the payment link with your client. They see how much to send, to which address, and which memo to include. When they pay, you click "Check for payment" and PayProof queries the Horizon API to confirm it.
Verification and receipts — paste any Stellar transaction hash, choose mainnet or testnet, and PayProof fetches the details from the Horizon API — status, ledger, fee, payment operations (sender, receiver, amount, asset). From there you can generate a receipt page at a stable URL you can print, save as PDF, or share.
Everything runs in the browser. No backend, no data stored server-side, no accounts.
Quick test — paste this testnet hash on the live site:
980a03a11a6e212ac2d6a739188c89437f9cfb1b0302b8aeb58c573a06ef71d4
| Feature | Status |
|---|---|
Invoice creation (/invoice/create) |
✅ done |
Shareable invoice page (/invoice/[id]) |
✅ done |
| Payment detection via Horizon API | ✅ done |
Invoice list (/invoice) |
✅ done |
| USDC asset support | |
| SEP-7 payment links | ✅ done |
| Transaction verification (mainnet + testnet) | ✅ done |
| payment, path_payment_strict_receive, path_payment_strict_send | ✅ done |
Receipt pages at /receipt/{hash}-{index} |
✅ done |
| Fee in XLM and stroops | ✅ done |
| QR code on receipts | ✅ done |
| PDF export | ✅ done |
| Print-friendly layout (dark mode safe) | ✅ done |
| JSON export | ✅ done |
| Light/dark theme | ✅ done |
| Responsive mobile layout | ✅ done |
| Network encoded in receipt URL | ✅ done (v0.1.1) |
| Verify page URL state | ✅ done (v0.1.1) |
| path_payment amount resolution | |
| Test suite | ❌ not yet (issues #5, #6) |
Browser
│
├── /verify Hash input + NetworkSelector
│ │
│ └── lib/stellar.ts (StellarService)
│ │
│ ├── horizon.stellar.org (mainnet)
│ └── horizon-testnet.stellar.org (testnet)
│
├── /invoice/[id] Invoice view + payer view
│ │
│ ├── lib/sep7.ts (buildInvoiceSep7Uri)
│ │ └── components/pay-with-wallet-button.tsx
│ │
│ └── lib/invoices.ts (payment detection)
│
└── /receipt/[id] Parses {hash}-{operationIndex} from URL
│
└── components/receipt-card.tsx
├── ReceiptQRCode (qrcode → canvas)
└── PDF export (html2canvas + jsPDF, loaded lazily)
Key files:
| File | What it does |
|---|---|
lib/stellar.ts |
Horizon queries, operation filtering, fee conversion |
lib/sep7.ts |
SEP-7 URI builder (buildSep7PayUri, buildInvoiceSep7Uri) |
types/stellar.ts |
Shared TypeScript interfaces for Stellar types |
types/sep7.ts |
SEP-7 types, network passphrases, USDC issuer constants |
components/pay-with-wallet-button.tsx |
"Pay with Wallet" button that opens a SEP-7 URI |
components/transaction-results.tsx |
Displays verification results |
components/receipt-card.tsx |
Receipt layout, PDF export, QR code, share/print |
components/receipt-qrcode.tsx |
Renders a QR code canvas from a URL |
app/receipt/[id]/page.tsx |
Loads receipt data from URL, handles network detection |
git clone https://github.com/PayProofLabs/payproof.git
cd payproof
npm install
npm run devApp runs at http://localhost:3000. No environment variables required — defaults to testnet.
To default to mainnet, create .env.local:
NEXT_PUBLIC_STELLAR_NETWORK=mainnet
Available commands:
npm run dev # development server with HMR
npm run build # production build
npm run start # serve production build
npm run lint # ESLint
npm run type-check # tsc --noEmit
npm test # run unit tests (vitest)- Next.js 15 (App Router, client components for Horizon queries)
- TypeScript
- Tailwind CSS + shadcn/ui (Radix primitives)
@stellar/stellar-sdk— Horizon.Server client and hash validationqrcode— QR code generation to canvasjspdf+html2canvas— client-side PDF export (lazy-loaded)next-themes— light/dark mode
git clone https://github.com/PayProofLabs/payproof.git
cd payproof
npm install
cp .env.example .env.local
npm run devThe app talks directly to the Stellar Horizon API from the browser. No backend to run, no API keys needed. Defaults to testnet.
The issues in .github/ISSUES.md are written to be directly actionable — each one has acceptance criteria, the files you'll need to touch, and what the reviewer will check. They're labelled by complexity:
- Trivial — under an hour, good for a first PR: issues #3, #7, #10, #11, #12, #14, #15
- Medium — half a day, some design decisions involved: issues #1, #2, #4, #5, #6, #8, #9, #13
- High — full day+, coordinate in an issue first before starting
If you want to work on something, leave a comment on the issue so others know it's taken.
- Fork, then
git checkout -b fix/brief-description - Make the change. Keep commits focused — one logical change per commit.
- Run
npm run lint && npm run type-checkbefore pushing. - If the change touches verification or receipts, test it against a real testnet transaction.
- Open a PR. The template will prompt you for what to include.
Commit style: fix: correct fee display, feat: encode network in receipt URL, docs: add memo_type to contributing guide.
Some non-obvious things about this codebase:
transaction.ledgerin the Stellar SDK is a function, not a value. The sequence number is attransaction.ledger_attr. UsingString(transaction.ledger)produces[Function (anonymous)].- All Stellar queries happen in the browser — there's nothing server-side to worry about.
- The
receipt/[id]page is a client component that fetches on mount. It guesses the network (testnet-first) because the network isn't in the URL yet — fixing that is issue #1. - PDF export (
html2canvas+jsPDF) is lazy-loaded so it doesn't bloat the initial bundle. The dynamic imports are inreceipt-card.tsx.
See CONTRIBUTING.md for the full setup guide including how to get a testnet transaction to work with.
See ROADMAP.md for what's planned and why.
MIT — see LICENSE.
PayProof is an independent project and is not affiliated with the Stellar Development Foundation.
