Skip to main content

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.

setup.json
{
"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​

  1. Check your merchant's payout settings and enabled payment rails.
  2. Select an available pricing plan if required: merchant tier --profile live --tier BASE or --tier PRO.
  3. Register your production HTTPS handler with webhooks create --profile live.
  4. Export the live credentials to your application's private environment configuration.
  5. Inspect onboarding get --profile live and 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​

SituationWhat to do
No saved profileRun peer-pay-cli login, or peer-pay-cli serve for local testing.
Session expiredRun login again for that profile. Email sessions normally refresh automatically.
Owner permission requiredSign in as the merchant owner. API keys cannot replace an owner session.
Wallet provisioning failedRetry merchant provision-wallets --profile live. Existing addresses are preserved.
Hosted API connection failedThe error names the API URL; check connectivity and the profile URL, then retry.
Local API connection failedThe error names the local URL; start peer-pay-cli serve and check the profile URL and port.
Sign-in configuration returns HTTP 404The 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 statusRetry or contact Peer Pay support with the status and endpoint URL.
Sign-in configuration returns HTTP 5xxTry signing in again shortly.
Unexpected sign-in configuration responseThe endpoint returned an invalid sign-in response; check the URL or contact Peer Pay support.
Email login requires a browser CAPTCHATerminal OTP cannot complete that challenge. Use the dashboard, or supply an existing valid access token through login --token-stdin.
Another command owns the profileThe 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.