Skip to content

About

Merchant dashboard and subscriber portal for the Payflow protocol on Stellar.

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Repository files navigation

Payflow — Frontend

Merchant dashboard and subscriber portal for the Payflow protocol on Stellar.

CI Next.js React License

Livedemo: https://mmm-pay.github.io/payflow-frontend/ · Docs: https://mmm-pay.github.io/payflow-docs/


What this is

The user-facing half of Payflow — pull-based recurring payments on Stellar. Four pages:

Route Who it is for What it does
/ everyone Explains the mandate model, shows protocol counters and live contract IDs
/subscribe subscribers Browse published plans and open a mandate. A shared link (?plan=12) opens one plan
/account subscribers Fund and withdraw from the vault, pause or cancel subscriptions
/merchant merchants Publish plans, track revenue, settle due mandates manually, discount or end a subscriber's mandate

Two data paths, on purpose

                  writes (signed by wallet)
  browser ──────────────────────────────────────► Soroban RPC ──► contracts
     │
     │            reads (lists, history, revenue)
     └──────────────────────────► payflow-backend ──► SQLite projection

Contract writes go straight from the browser to Soroban RPC. The backend is never in the path of a payment and never holds a key.

Contract reads that need sorting or aggregation come from the indexer, because Soroban cannot answer "list every mandate for this merchant." Every one of those calls is allowed to fail: src/lib/api.ts returns null instead of throwing, and the pages fall back to reading contract state directly. The app still works with the backend switched off — you lose the lists, not the ability to pay.

Quick start

npm install
cp .env.example .env.local   # already points at the deployed testnet contracts
npm run dev

Open http://localhost:3000 and connect Freighter (or any wallet the Stellar Wallets Kit supports) set to Testnet.

To see plans and history, run payflow-backend alongside it on port 8080.

Wallet support

The lazy browser-only kit retains its built-in Freighter, xBull, Albedo, Lobstr, Hana, Rabet, HOT and Klever modules. Wallet availability depends on the user's installed extension or the wallet's web/mobile support.

WalletConnect is optional: set NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID to your public Reown project ID, allowlist the deployed origin in that project, and rebuild. Metadata uses the current origin plus NEXT_PUBLIC_BASE_PATH, so the GitHub Pages deployment under /payflow-frontend is supported. It requests stellar_signXDR only; Payflow submits through its existing RPC path. A blank project ID or a custom network outside Testnet/Public omits the bridge while leaving default wallets available. No backend is required.

Automated mocked connection/signing checks cover xBull, Albedo, Lobstr and Hana, plus registration, optional-bridge configuration, sign-only permissions, and static-site metadata. These verify application delegation, not real wallet signatures. Live Testnet signing with three wallets remains a manual release check; no live wallet run is claimed here. Use funded Testnet accounts, connect and sign a known test transaction with each wallet, and record wallet/version, network and transaction evidence before release. Never use a real-value wallet for this unaudited demo. Existing network/account-change and signature-error checks remain in the shared WalletProvider.

Environment

Every variable is NEXT_PUBLIC_* and therefore inlined at build time. Changing one on your host requires a redeploy, not a restart — this is the usual reason a deployed frontend keeps calling localhost.

Variable Purpose
NEXT_PUBLIC_SOROBAN_RPC_URL RPC endpoint the browser signs against
NEXT_PUBLIC_NETWORK_PASSPHRASE Network id passed to the wallet
NEXT_PUBLIC_PLAN_REGISTRY_ID Deployed registry contract
NEXT_PUBLIC_VAULT_ID Deployed vault contract
NEXT_PUBLIC_SUBSCRIPTION_ID Deployed subscription contract
NEXT_PUBLIC_TOKEN_ID SEP-41 token used for plans (native XLM SAC by default)
NEXT_PUBLIC_API_URL payflow-backend base URL. Empty means read contract state directly
NEXT_PUBLIC_WALLETCONNECT_PROJECT_ID Optional public Reown project ID; empty disables WalletConnect
NEXT_PUBLIC_READ_SOURCE Any existing account, used as the source for read-only simulations before a wallet connects
NEXT_PUBLIC_SITE_URL Origin the canonical link and the social preview URLs are built from
NEXT_PUBLIC_BASE_PATH Path the static export is served from. GitHub Pages serves a project site from /<repo>; Vercel and local dev serve from the root and set nothing

Titles, descriptions and link previews

Every route has its own title, description and share image. The page list lives in src/lib/pages.json; src/lib/metadata.ts turns it into the metadata, and scripts/generate-og.mjs draws the 1200×630 preview image of each page into public/og/. The images are drawn before every build (npm run og), because Next's own image route writes a file without an extension, which GitHub Pages then serves as application/octet-stream — a type the link-preview crawlers refuse.

Set NEXT_PUBLIC_SITE_URL and NEXT_PUBLIC_BASE_PATH to the host and the path the site is served from, so the canonical link and the image URL are absolute and still carry the base path.

Deploying to Vercel

  1. Import the repo. Framework preset Next.js; defaults are correct.
  2. Add every variable above under Settings → Environment Variables.
  3. Set NEXT_PUBLIC_API_URL to your deployed backend URL — not localhost.
  4. Set CORS_ORIGIN on the backend to this app's URL.
  5. Redeploy after any variable change.

Project layout

src/
  app/            routes: /, /subscribe, /account, /merchant, /m, /plans/[id]
  components/     presentational pieces (ui.tsx, WalletButton.tsx)
  lib/
    payflow.ts    contract SDK — read via simulation, write via wallet
    api.ts        payflow-backend client (fails soft)
    wallet.tsx    Stellar Wallets Kit context
    format.ts     stroop/decimal conversion, period and address formatting
    config.ts     env access
    discount.ts   per-mandate discounts: rate, remaining charges, price

src/lib/payflow.ts is the piece worth reading first: it maps every public contract function to a typed call and translates raw Error(Contract, #N) codes into sentences a user can act on.

Related repositories

Repo Role
payflow-contract Soroban contracts this app calls
payflow-backend Indexer and API this app reads
payflow-frontend This repo
payflow-docs Protocol documentation

Contributing

See CONTRIBUTING.md. CI runs lint, typecheck, test and build. Changes are recorded in CHANGELOG.md.

Security

See SECURITY.md. Unaudited, testnet only.

Maintainers

Name Role Contact
Victor Adeleke Lead maintainer @titilope12

Contributors

License

Apache-2.0.

About

Merchant dashboard and subscriber portal for the Payflow protocol on Stellar.

Topics

Resources

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages