Merchant setup from the terminal
Install the CLI, then sign in with your business email:
peer-pay-cli login --profile live --email owner@example.com
--profile live is optional and names the profile used in this guide. Without it,
login derives the name from your merchant. Either way, login makes that profile
active, so subsequent commands can omit --profile.
Enter the verification code at the hidden prompt. First-time login creates a
merchant account. Existing merchants keep their permissions and settings.
Owner wallets are provisioned automatically on first sign-in by the server,
regardless of which client signs in. Later owner sign-ins retry missing wallets
while preserving existing payout addresses. If the login response reports
walletsProvisioned: false, sign-in still succeeded; use
peer-pay-cli merchant provision-wallets --profile live as the manual retry.
Use the same email you use in the dashboard. If you can access several merchants, login lists those memberships; select one with:
peer-pay-cli login --profile live --email owner@example.com --merchant-id MERCHANT_ID
Configure your merchant
peer-pay-cli setup
Setup is hosted-only. In a terminal, a missing, local, or API-key-only profile offers sign-in
first and continues here after authentication. In scripts, run peer-pay-cli login
in a terminal first, then peer-pay-cli setup --file setup.json --dry-run or
peer-pay-cli setup --file setup.json --yes.
The wizard asks for:
- Business name, logo, industry, and integration path.
- Fiat payment rails and whether to accept crypto.
- Default currency, fee payer (MERCHANT, PAYEE, or SPLIT), and settlement chain/token.
- Buyer share of total fees in basis points when SPLIT is selected (5000 = 50%; 0 to 10000 in steps of 1000).
- Settlement sweep preference.
- Pricing plan, when self-service selection is available.
- Production webhook URL, which you can leave blank until your handler is deployed.
Use Up/Down arrow keys (or k/j, Ctrl+P/Ctrl+N) to move through menu questions,
then press Enter or Space to choose. The current value is highlighted initially; Enter
keeps it. For fiat rails, Space toggles the highlighted rail and a selects or
clears all; Enter confirms the selected set. Navigation wraps around, and long menus scroll with more-item indicators.
Escape, Ctrl+C, or Ctrl+D cancels. Yes/no confirmations use the same controls and default
to No. Menu headers show only the question label, without control hints. Menus
appear on stderr, keeping stdout clean for --json. Set NO_COLOR
to disable styling; the > marker still identifies the active item. For scripts,
use --file with --yes or --dry-run instead of the wizard. The wizard shows
the complete plan and asks before writing settings. Existing Concierge merchants
keep their plan. Logos must be PNG, JPEG, WebP, or GIF, up to 2 MB.
Inspect the result:
peer-pay-cli merchant get --profile live
peer-pay-cli onboarding get --profile live
The onboarding checklist comes from the backend. Some steps, including an actual hosted webhook delivery, require work beyond saving settings.
Use a setup file
Use a JSON file for repeatable setup. Fields omitted from settings retain their
current values. profile.name and settings are required; logoFile, tier, and
webhook are optional. To enable split fees, set settings.feePayer to "SPLIT"
and include settings.buyerFeeShareBps, for example 5000 for a 50% buyer share of fees (50:50 buyer:merchant).
The rate applies to fiat, Apple Pay, and crypto for new orders; see
split payment fees.
{
"profile": {
"name": "Example Store",
"industryType": "ecommerce",
"integrationPath": "CUSTOM_API"
},
"settings": {
"enabledRails": ["venmo", "revolut"],
"defaultPaymentCurrency": "USD",
"feePayer": "MERCHANT",
"destinationChainId": "8453",
"destinationToken": "USDC",
"sweepEnabled": false
},
"logoFile": "./logo.png",
"webhook": {
"url": "https://merchant.example/webhooks/peer-pay",
"events": ["ORDER_FULFILLED"]
}
}
Preview and apply:
peer-pay-cli setup --profile live --file setup.json --dry-run
peer-pay-cli setup --profile live --file setup.json --yes
--dry-run validates the input before reading current state, makes no changes,
and does not provision a sandbox. It omits the onboarding checklist because that
read can change hosted state. Guided pricing-plan selection is deferred until you
choose to apply; a file can include an explicit tier.
--yes applies it without the final confirmation prompt. File paths are relative
to your current working directory.
Setup checks your current role before any changes; see setup for what managers and cashiers can do.
Setup updates a webhook with the same URL rather than creating a duplicate. If
several existing webhooks share the URL, choose one explicitly with webhooks update before rerunning setup. Writes are sequential; if one fails, earlier
changes remain applied. Resolve the error and rerun the same setup file.
Settings use the backend's field names. merchantCheckoutTheme is replaced as a
whole when supplied in a JSON file, so include any theme values you want to keep.
The interactive wizard preserves the existing theme when changing the crypto switch.
Verify the hosted sandbox
Run peer-pay-cli sandbox enable to enable, save, and activate <profile>-sandbox.
Use peer-pay-cli use NAME to return to the merchant profile. merchant sandbox
remains a plain API call.
Setup enables the sandbox too, and both commands return the chosen
sandboxProfile; see sandbox enable for the role
requirement and the naming and reuse rules. Use that name in the commands below.
Check available profiles:
peer-pay-cli profiles
Register a public HTTPS handler on that profile and run a test order:
peer-pay-cli webhooks create --profile live-sandbox \
--url https://staging.example/webhooks/peer-pay \
--events ORDER_FULFILLED
peer-pay-cli test-order --profile live-sandbox
peer-pay-cli status --profile live-sandbox
peer-pay-cli webhooks deliveries WEBHOOK_ID --profile live-sandbox
webhooks create shows the signing secret in full once and saves it in the
profile; see credential output for the redaction
rules. To write the saved webhook secret to an env file later, run
peer-pay-cli credentials export --output FILE --webhook-id <id> with the same
profile selected.
Use the sandbox webhook's signing secret when verifying staging requests. A live
webhook has its own secret. A connectivity test (webhooks test) sends empty
business entities; test-order exercises a real sandbox fulfillment payload.
For localhost-only testing, add --local to your commands, or run peer-pay-cli use local. You do not need a
tunnel. Local tests do not satisfy the hosted onboarding checklist.
Go live
- Check your merchant's payout settings and enabled payment rails.
- Select an available pricing plan if required:
merchant tier --profile live --tier BASEor--tier PRO. - Register your production HTTPS handler with
webhooks create --profile live. - Export the live credentials to your application's private environment configuration.
- Inspect
onboarding get --profile liveand complete the remaining integration steps.
peer-pay-cli credentials export --profile live \
--output .env.peer-pay.production --webhook-id WEBHOOK_ID
Do not commit the exported file. Live commands use the existing backend permissions; the CLI does not grant extra owner, manager, or admin access.
Sessions and troubleshooting
| Situation | What to do |
|---|---|
| No saved profile | Run peer-pay-cli login, or peer-pay-cli serve for local testing. |
| Session expired | Run login again for that profile. Email sessions normally refresh automatically. |
| Owner permission required | Sign in as the merchant owner. API keys cannot replace an owner session. |
| Wallet provisioning failed | Retry merchant provision-wallets --profile live. Existing addresses are preserved. |
| Hosted API connection failed | The error names the API URL; check connectivity and the profile URL, then retry. |
| Local API connection failed | The error names the local URL; start peer-pay-cli serve and check the profile URL and port. |
| Sign-in configuration returns HTTP 404 | The error names the full /api/v1/auth/cli-config URL; check --api-url or the profile URL. |
| Sign-in configuration returns HTTP 401/403 or another unexpected status | Retry or contact Peer Pay support with the status and endpoint URL. |
| Sign-in configuration returns HTTP 5xx | Try signing in again shortly. |
| Unexpected sign-in configuration response | The endpoint returned an invalid sign-in response; check the URL or contact Peer Pay support. |
| Email login requires a browser CAPTCHA | Terminal OTP cannot complete that challenge. Use the dashboard, or supply an existing valid access token through login --token-stdin. |
| Another command owns the profile | The error names the PID and blocked command. Wait for the live owner to finish; dead, malformed, and empty profile locks recover automatically. |
Email sessions refresh automatically for management requests; see sessions for exactly when.
Credentials live in ~/.config/peer-pay/config.json, or the path in
PEER_PAY_CONFIG / --config. Files use mode 0600. Keep credentials private.
If the credentials file cannot be read as JSON or is not in the expected format,
the error names its path. Restore it from a backup, or move it aside and run
peer-pay-cli login to sign in again. Moving it aside loses saved profiles.
If the file was written by a newer peer-pay-cli, the error reports the file and
supported versions; keep the file and upgrade with
npm install -g @zkp2p/peer-pay-cli. A missing file is normal and starts with no profiles.
See profiles for selection precedence and the active-profile rules.
logout --profile live removes the saved profile and clears active selection if needed; it does not rotate API keys or
sign out other devices. Tokens supplied with --token-stdin have no refresh session.
Continue with your coding agent
After merchant setup, let Codex, Claude Code, OpenCode, or Gemini CLI integrate Peer Pay into your application:
peer-pay-cli handoff --profile live --harness codex --project ./my-store --launch
To continue immediately after applying guided setup:
peer-pay-cli setup --profile live --harness codex --project ./my-store --launch
See handoff options for the supported agents, the questions asked in a terminal, portable prompts, and what the instructions contain.
Merchant referrals
If another merchant referred you, supply their code when creating your account:
peer-pay-cli login --profile live --email owner@example.com --referral-code ABCD2345
peer-pay-cli merchant referral --profile live
The first command applies the code only when a new merchant is created. The second shows your own referral program after wallet setup, including the reward recipient, rates by referred merchant tier, and referred merchants. Base referrals pay 0.30%, Pro 0.50%, and Concierge 1.00% of fiat volume; the referrer's own tier does not affect the rate. New referrals start at the Base rate until selecting a plan. The referrer's split follows every later tier change, including rates an admin edited; a split an admin removed stays removed. Existing order snapshots retain their original fees. Referral programs are unavailable in sandbox.
Checkout payment recovery
The local server supports GET /api/v1/orders/:orderId/recovery-history
with an optional cursor and 20 attempts per page. It returns historical
recipient, method, status and snapshotted requested amount; old attempts without
an amount snapshot return amount: null. Fiat payment responses retain this
snapshot as quote.recoveryDisplayAmount, a decimal string, matching the hosted
API. Fresh quotes and historical payments may omit it. Reading history creates no payment.
Fiat recipients use the readable handle saved in the original quote, not the
on-chain maker hash. If an old attempt has only a hash and no saved handle,
the recipient is Recipient unavailable. Readable stored recipients and crypto
addresses remain unchanged.
POST /api/v1/orders/:orderId/recover-order accepts targetOrderId and
targetOrderToken. It verifies the original order's access token and requires
the same merchant, returning only the target order ID. Wrong tokens, unknown
orders and other merchants receive the same 404. Open the original checkout in
its own support session; this endpoint does not merge chats or settle payments.
The local simulator has no live support chat or production discovery access.