Merchant Onboarding
Sign up for PincerPay, generate wallets, and mint API keys, entirely from the terminal. No browser required.
PincerPay merchants get from zero to live in three commands. The flow is terminal-only: signup, email verification, wallet generation, merchant creation, and API key minting all happen via CLI prompts. No browser, no dashboard click-through.
Non-custodial. PincerPay never sees your mnemonic or private keys. Wallet generation runs entirely on your machine. Only public addresses are persisted server-side.
Quick start
# 1. Create an account.
npx @pincerpay/cli signup
# 2. Generate wallets, create merchant, mint API key.
npx @pincerpay/cli bootstrap-merchant --name "Acme Co" --chains "solana,polygon"
Done. The second command prints a paste-ready env-var block:
PINCERPAY_API_KEY=pp_live_...
PINCERPAY_MERCHANT_ADDRESS_SOLANA=...
PINCERPAY_MERCHANT_ADDRESS_POLYGON=0x...
Pipe those into vercel env add (or your env manager) and your app accepts agent payments.
How signup works (no browser)
$ npx @pincerpay/cli signup
Email: dan@example.com
Password (8+ chars): ••••••••
Confirm password: ••••••••
We sent a verification code to dan@example.com.
Check your inbox and paste the code below.
Verification code: 123456
✓ Verified and signed in as dan@example.com.
Credentials saved to /Users/dan/.pincerpay/credentials.json.
Token expires 2026-06-01 14:23:11.
The OTP is a 6-digit code delivered by email. You paste it back into the CLI. No URL clicks, no port binding, no browser tabs.
After signup the CLI saves a long-lived bearer token at ~/.pincerpay/credentials.json (with 0600 permissions on POSIX). All subsequent commands use that token automatically.
Three paths
| Path | When to use |
|---|---|
@pincerpay/cli (CLI) |
First-time setup, server provisioning, multi-environment workflow, CI |
@pincerpay/mcp (MCP) |
LLM-driven onboarding inside Claude Code, Cursor, Windsurf, etc |
@pincerpay/onboarding (library) |
Custom signup flows you build yourself |
All three sit on top of the same authenticated facilitator API. After running pincerpay login, the MCP server picks up the same ~/.pincerpay/credentials.json automatically: one auth ceremony for everything.
CLI commands
Account lifecycle
pincerpay signup # create account
pincerpay login # sign in to existing account
pincerpay logout # revoke this CLI session
pincerpay whoami # show user + merchant info
pincerpay recover # send password recovery code
pincerpay reset-password # use code to reset password
pincerpay change-password # change password while logged in
Onboarding (one-shot)
pincerpay bootstrap-merchant \
--name "Acme Co" \
--chains "solana,polygon" \
[--webhook-url https://your-app.com/webhooks/pincerpay] \
[--api-key-label "production"]
Generates non-custodial wallets, creates the merchant record (idempotent and safe to re-run), mints an initial API key, and prints the env-var block. All in one command.
Wallet-only (no signup needed)
pincerpay create-wallets [--strength 12|24] [--json] [--no-private-keys]
Pure crypto: runs locally, never talks to PincerPay. Useful for previewing addresses before signup, or for any merchant who wants to bring their own wallet to the dashboard flow.
Manage existing merchant
pincerpay api-keys create [--label]
pincerpay api-keys list
pincerpay api-keys rotate <id>
pincerpay api-keys revoke <id>
pincerpay wallet set --solana <addr> --evm <addr>
pincerpay sessions list
pincerpay sessions revoke <id>
pincerpay env # print env-var template
MCP commands
If you've connected @pincerpay/mcp to your AI client, the same operations are available as MCP tools:
> Generate non-custodial PincerPay wallets for me.
→ bootstrap-wallets
> I just ran `pincerpay login`. Bootstrap a merchant called "Acme Co".
→ bootstrap-merchant (public mode, uses ~/.pincerpay/credentials.json)
> Show me my current PincerPay setup.
→ whoami
> I'm getting auth errors from the onboarding tools.
→ login-instructions
See the MCP server docs for the full tool list.
Security model
- Non-custodial wallets. BIP-39 mnemonic generation runs client-side via
@pincerpay/onboarding. Phantom-compatible Solana derivation (m/44'/501'/0'/0') and MetaMask-compatible EVM derivation (m/44'/60'/0'/0/0) from a single mnemonic. - Email-OTP verification. Signup verifies your email via a 6-digit code (Supabase
auth.verifyOtp), not a click-link. The OTP is the authentication; the email address is just the delivery channel. - Bearer tokens. Successful signup or login mints a
pp_cli_*token with a 30-day default lifetime. Stored in~/.pincerpay/credentials.json(0600perms on POSIX, current-user ACL on Windows). Tokens are HMAC-SHA256 hashed server-side with a server pepper. - Audit logging. Every signup, login, key creation, wallet change, and session revocation writes a row to
audit_events. Surfaced viapincerpay sessions listand the dashboard security page. - Self-revocation.
pincerpay logoutcalls the server-side revoke endpoint before deleting local credentials, so a compromised laptop can be locked out by runningpincerpay logoutfrom any other authenticated machine.
Configuration
| Variable | Default | Purpose |
|---|---|---|
PINCERPAY_FACILITATOR_URL |
https://facilitator.pincerpay.com |
Override facilitator endpoint |
Or pass --facilitator-url <url> to any command.
Recovery
If you lose access to your credentials:
- Run
pincerpay recover --email <your-email>from any machine. - Check inbox for a recovery code.
- Run
pincerpay reset-password --email <your-email>and paste the code. - Run
pincerpay loginwith the new password.
If you lose your mnemonic, USDC sent to those wallet addresses is unrecoverable. Save the mnemonic in a password manager when bootstrap-merchant prints it.
Troubleshooting
"Not logged in. Run pincerpay login first."
Your credentials file is missing or expired. Run pincerpay login (or pincerpay signup).
"token_checksum_invalid" or "token_format_invalid"
The credentials file is corrupted. Delete ~/.pincerpay/credentials.json and re-authenticate.
"email_not_verified"
You haven't completed the OTP step. Run pincerpay signup again with the same email, and Supabase will email a fresh code.
"email_delivery_unavailable" (503 on signup)
The deployment has not confirmed a working email provider, so signup fails loudly
instead of pretending a code was sent. The operator must configure SMTP on the
Supabase project (Resend is free up to 3k/mo) and set SUPABASE_SMTP_CONFIGURED=true
on the facilitator. Until then, email verification is unavailable. (Signup also
no longer reports verification_email_sent for an email that already has an
account, so it stays silent to avoid leaking account existence.)
Email never arrives
Check spam. Recovery emails come from noreply@<your-supabase-project>.supabase.co.
Supabase's built-in email service is rate-limited and drops most mail, so production
deployments must configure a real SMTP sender in the Supabase dashboard.
Companion docs
- @pincerpay/cli: full CLI reference
- MCP server: onboarding via LLM tools
- Merchant SDK: using your API key + addresses to accept payments
- Quickstart: Merchant: end-to-end first-payment walkthrough