GET STARTED

Documentation

Install, accept payments and look after your server.

New here? Follow the step-by-step tutorials →

VPS requirements

Use a fresh Linux VPS with root access, not an existing website/database server. No Docker, compiler or blockchain nodes needed.

VPSMinimum
Light use
Recommended
CPU1 vCPU2 vCPU
RAM2 GB4 GB
SSD20 GB60 GB

The minimum is a light-use starting point for minimal Ubuntu/Debian images, not a performance guarantee. Disk sizes include Linux; leave at least 3 GiB free before setup, plus room for updates, history and backups.

The native installer requires x86-64, systemd 247+ and Python 3.9+. ARM64 and Alpine/OpenRC are not included.

Linux versions and sizing notes
  • Ubuntu 22.04+ or Debian 12+; Mint 21+ and Pop!_OS 22+.
  • Fedora 42+; Rocky, AlmaLinux, RHEL, Oracle Linux or CentOS Stream 9–10.
  • openSUSE Leap 16+ or Tumbleweed; Arch, Manjaro or EndeavourOS.

Choose a vendor-maintained release. Higher OS requirements take precedence: openSUSE Leap 16 calls for more than 40 GB of disk.

More chains and concurrent invoices may need more CPU and RAM. A bigger VPS does not remove RPC quotas. Setup flows have automated tests; full fresh-VPS testing is not complete for every distribution.

Install

Point these default hostnames at your VPS, or choose your own:

  • merchant.example.com: console
  • pay.example.com: checkout
  • api.example.com: API

Use DNS-only records during setup. Open TCP 80/443 in both firewalls and keep SSH accessible. Never expose PostgreSQL or the app on ports 5432/8080.

bash <(curl -fsSL https://releases.whollycrypto.com/setup_wholly.sh)

Setup verifies downloads and configures PostgreSQL, Nginx, HTTPS and services. Prefer containers? See the optional Docker installation.

Check first or resume setup

Need a specific release? On a fresh VPS, add --version 7.8.1 to install that exact signed version. Without it, setup uses the latest stable release.

Resume keeps the selected release and completed steps, including with GitHub fallback. It never downgrades an existing installation.

Inspect the installer. Add --check to the command for a compatibility check without installing, or --help for options.

Resume saved progress without replacing keys or settings:

bash <(curl -fsSL https://releases.whollycrypto.com/setup_wholly.sh) --resume

Additional base domains can use the same service names. Any IPv6 records must also point to this VPS. Enable a Cloudflare proxy only after domain validation.

First-time setup

  1. Enter the HTTP Basic login. Create your admin account, choose language/timezone and review the license and privacy policy.
  2. Check Settings → Chain connections. Use healthy, independent fallback providers that support payment scanning.
  3. Create a project, then its first store.
  4. Back up the project wallets. In the store, select accepted chains and verified tokens.
  5. Set currency, confirmations, expiry, spread and tolerance. Check your credit balance before creating invoices.

QRs request the full outstanding amount. Tolerance only accepts shortfalls; confirmations still apply.

Stablecoin amounts

New recognized stablecoin quotes round up: 1.321 USDC → 1.33 USDC, even with zero tolerance. Minimum: 0.01 token.

Existing invoices, balances and partial-payment remainders stay exact. Other/custom tokens keep normal precision.

Automatic activation

Admin signup automatically registers your credit account using your email, with a one-time 10 USD equivalent welcome credit. No activation code needed.

Create an invoice. Pending activation retries automatically; reconnects never grant credit again.

Login details and defaults

Your Basic Auth login is saved in /root/whollycrypto/config/setup-credentials.txt. It is separate from the console email/password.

New projects inherit system currency and timezone defaults; stores use the project currency. Existing account timezones are managed separately in Settings → Account.

whollycrypto welcome shows your console URL.

Merchant or operator mode

Fresh installations from 7.0.0 choose a mode during first-admin setup. This cannot be undone; changing mode needs a new installation. Pre-7 installations stay in merchant mode, even without an administrator.

Merchant: run your own projects and stores. Operator: host separate merchant businesses on one installation and charge your own prepaid processing fee. Your own business is included without an internal operator fee.

Set up hosted merchants
  1. Shared nodes, rates, domains, installation credits and updates belong in the Operator panel.
  2. Open Wallets → Create receiving wallets for BTC, ETH and Ethereum USDC/USDT. Back up both independent recovery phrases. This dedicated project cannot issue sales invoices; an existing receiving store is preserved.
  3. Add a merchant with a credit currency, fee and administrator email. Share the invitation and merchant Basic Auth privately. They choose their password. Never share operator Basic Auth.
  4. Merchants top up through your checkout, or you record an explained credit adjustment. Credit is required before creating projects/stores. Manage users and credit history under Merchants → Manage.

Operator setup asks for a fourth address, such as operator.example.com, and its own Basic Auth username and password. Choose your label, point DNS to the VPS, check DNS and activate HTTPS. The panel opens directly on that address. Your merchant, checkout and API addresses stay separate.

Use the new operator Basic Auth login, then your administrator email/password. Merchant Basic Auth stays unchanged. Setup can resume after DNS or certificate errors. Operators upgrading from 7.0.0 complete this step too; existing live addresses stay available.

Fees, isolation and responsibility

At 3%, a 100 EUR invoice costs 3 EUR of merchant credit. If its credit currency differs, the creation-time fiat rate is saved with the fee.

The operator pays the normal Wholly Crypto installation fee separately. Customer funds are not split on-chain. Credit purchases are not charged again.

Only automatically verified settlement credits a top-up. Opening a checkout or manually accepting an invoice does not. Reversals create ledger entries; a reversed top-up that returns requires operator review.

Low hosted credit pauses IPN, webhooks, sweeps and creation of new projects/stores. Existing customer invoices and receiving continue. Low installation credit can pause automation across hosted businesses. Disabling a merchant also blocks login and new invoices, while old payments remain monitored.

This is application-level isolation, not a separate VPS for every merchant. Merchants cannot access each other's projects, wallets, API credentials, exchanges or credits. The server administrator can access hosted hot-wallet keys. Tell merchants before onboarding; use trusted hosting, independent backups and suitable capacity for shared workloads.

Operator finances & invitations

Available in Operator mode from 7.1.0.

Wallets and finances

From 7.2.0, Wallets manages receiving balances, addresses and backups; Sweep handles sends and automatic rules. Keep ETH for token fees. Merchant top-ups tracks their purchases. Header credits pay installation fees separately. My business opens your own console in a new tab.

Open Finances for fees earned, verified installation charges, estimated margin and current merchant credits. Filter by date, merchant or reporting currency; export CSV.

Reports group invoices by first settlement and reflect their latest fee reversals. Prepaid balances are not revenue. Own-business charges stay separate. Pending charges or missing rates leave affected margins unavailable. Converted amounts use current cached fiat rates; gas and running costs are not included.

Invite users or reset passwords

Add merchant creates an invitation. From 7.3.0, choose a free starting credit in the merchant's credit currency; zero is allowed. This does not refill your operator balance. Send invitation by email is checked by default.

Configure your SMTP provider in Settings → Invitation email first, using TLS or STARTTLS. The connection test sends no email. Alternatively, uncheck email and share the link privately. A failed email keeps the account and credit; do not create the merchant again.

For another link or a password reset, open Merchants → Manage → User accounts. SMTP acceptance is not guaranteed inbox delivery. Share merchant Basic Auth separately, never operator credentials.

Invitations last 48 hours; resets last one hour. Each works once. Replace or revoke a link from the same screen. A reset signs out existing sessions but keeps 2FA enabled. Merchant Basic Auth is still required.

Operator API

Automate hosted merchants with SDK 2.6.0 and Wholly Crypto 7.4.0+. Enable Operator → Settings → Operator API, then create a scoped, server-side key.

Onboarding, permissions and safe retries

Create accounts directly with a password or send invitations. Manage users, projects, stores, fees and local prepaid credits; read reports and subscribe to signed lifecycle events. First-login custody consent, 2FA and tenant isolation stay in place.

Every write needs a saved idempotency key. Credit grants are local account adjustments, not installation top-ups. Wallet secrets, sending and server configuration stay out of this API.

Use api.your-domain.com/v1/operator. Keep Operator keys on your backend, never in a browser or with a hosted merchant.

Operator API reference & permissions → · Official SDKs & examples →

Wallets & tokens

Settings → Tokens loads 250 tokens first, then the remaining catalog.

Project → Wallets → Backup all exports TXT or searchable offline HTML with QR codes. Both expose keys and recovery phrases. Keep a private copy off-server; never share or upload it.

Root can access keys. Wallet recovery guides explain invoice addresses, native gas and external Monero/Lightning backups.

Saved addresses & fresh balances

Settings → Address book: save a chain/address. Native coins and matched CoinGecko tokens appear automatically. Read-only, admin-managed; checkout acceptance stays unchanged.

Token readers cover 22 chains. Private balances and Bitcoin/CashTokens/Kaspa overlays need separate access or indexers. Failed reads show errors, not zeroes.

Collect invoice balances into another wallet with manual sending or automatic sweeps. Token transfers also need the chain's native coin for fees.

Price unavailable concerns rates, not balances.

Add a custom token
  1. Store → Payment methods → EVM or Solana → Custom token.
  2. Enter contract/mint, name and ticker. Choose fixed USD or automatic DEX pricing.

Network/decimals are checked. Project-wide prices leave existing quotes unchanged. A catalog match alone does not enable checkout.

Automatic pricing

DEX Screener requires an exact-contract pool, $10,000 liquidity and a trade within an hour. Rates refresh each minute; failed or five-minute-old rates block new quotes.

DEX prices can be manipulated; checks are not audits. Use trusted standard ERC-20 or classic SPL tokens. Token-2022/extensions are unsupported. Without a suitable pool, use fixed pricing.

Currency & timezone

Settings → System → Regional defaults sets new-project currency/timezone and new-account timezone. Existing settings and credits stay unchanged; dashboard currency remains overridable.

Personal timezone: Settings → Account → Edit user.

Create an invoice

Use Payment methods → Choose for this invoice to narrow accepted chains/tokens. All store payment methods keeps the defaults.

  1. Open Project → Invoices → Create invoice.
  2. Choose the store, fiat currency and amount.
  3. Share the checkout link. Your customer chooses an available chain/token and sees the QR, remaining amount, expiry and confirmations.

Test a small payment on every method before going live. Check the invoice before fulfilling an order: a return URL is not proof of payment.

For integrations, verify signed IPN/webhooks and confirm status through the invoice API. Treat duplicate events as the same event.

API: filter payment_methods by chain_slug and asset_tickers. Inactive choices are ignored; no matches means store defaults. Chain-only includes all active assets. Shared tickers need asset IDs. Wallets and rates remain required.

Amounts and confirmations

Scanner offline? Invoices keep configured methods while detection waits. Check supported APIs in Chain connections; healthy doesn’t mean scanner-compatible. Default: two independent providers.

Wallets/rates remain required. Monero/Lightning services must issue payment requests.

API/MCP errors include error.details.payment_methods. SDK 2.4.0 adds safe explanations: PHP getPaymentMethodIssues(), Python payment_method_issues, Node paymentMethodIssues. Error reference →

Crypto quotes round upward and include the store's spread. A fiat-priced invoice does not convert the received crypto into a bank balance.

Zero confirmations settles on detection, without network-confirmation protection. Native EVM payments are detected as direct transfers. Review unusual or uncertain payments under Needs attention.

Scanner APIs

Check Chain connections for compatible APIs, complete history and independent providers. Raw-node catch-up takes time. All receive APIs →

Payments, balances and maintenance share provider budgets. Idle checks slow down. Older invoices retain late-payment/reorg monitoring, up to hourly after catch-up. Available WSS hints complement HTTP scanning. Closing checkout never stops detection. Public nodes still have limits; Wholly Crypto runs no nodes.

Zero-amount invoices

Blocked by default. Enable Stores → Invoice → Allow zero-amount invoices to allow manual/API zero totals. They complete immediately, without a payment, receiving address, transaction or processing fee.

Checkout

Store → Checkout: colors, logos, methods, links, Intro/Outro font sizes and project/store name visibility. New stores inherit the default store’s design. Changes autosave.

Previews cannot accept payments. No custom HTML/CSS/JavaScript.

Try the demo.

IPN & webhooks

IPN sends every invoice event to the store URL or invoice ipn_url. Webhooks send selected events. Both POST the same JSON snapshot.

When should I fulfil? For event-based handling, use event_type = invoice.settled with status = settled. Verify the current invoice and your order, then fulfil once. payment.received alone is not enough.

Status vs events: Ethereum and Solana examples

status is the invoice state at event creation; event_type tells you what happened.

  • Ethereum example: payment.received + processing, then invoice.settled + settled.
  • Solana example: already final when detected, so payment.received and invoice.settled both carry settled.

Either flow can happen on other chains. These are distinct events, not necessarily two payments. They can share sequence but have different event_id values. Delivery order is not guaranteed; do not require processing first.

Statuses and callback data
Invoice statusMeaning
newAwaiting payment
processingPartial payment or awaiting finality
settledAccepted under invoice rules, or manually
expiredDeadline passed; late monitoring can continue
invalidPayment needs review or was rejected
cancelledCancelled, not refunded

Events: invoice.created, payment.received, invoice.processing, invoice.settled, invoice.expired, invoice.invalid, invoice.cancelled. Full event table and exception rules →

amount_status: none, partial, paid, overpaid. paid includes tolerance, not finality. timing_status: on_time or late. resolution: automatic, manually_settled or manually_invalidated. Apply your exception policy when requires_review is true.

invoice_id matches the API response. amount, currency and order_id describe your original order. payment_info adds transfers, exact crypto amounts, locked quote/spread/tolerance and advisory rates. Customer data and metadata are private.

paid_chain, paid_asset, paid_payment_method_id, paid_asset_amount, paid_asset_amount_received and settlement_exchange_rate summarize settlement. They stay frozen; missing evidence/history stays null. For later receipts use payment_info or the payments API.

Use decimal strings. Never combine assets or treat unconfirmed funds as missing. Handle exceptions explicitly; a warning alone never authorizes fulfilment or refund. Verified internal gas top-ups are not customer payments and do not trigger payment.received.

Signing secrets, retries and delivery history

Separate signing secrets: Store → IPN signs IPN deliveries, including an invoice's custom ipn_url. Each endpoint in Store → Webhooks has its own secret, shown when created or rotated.

Both use Wholly-Signature and the same SDK verifier, but need the matching secret, not an API key. Rotating the IPN secret does not change webhook secrets.

Verify raw body, timestamp and project/store scope. Save durably, then return HTTP 2xx. A worker checks the current invoice through your configured API host and fulfils once in a database transaction. Headers are unsigned; use version 2's signed body identity.

Event-based: deduplicate signed event_id, then filter invoice.settled. SDK state-based: collapse project + invoice_id + sequence, then check state regardless of event type. Do not add an event filter after this collapse. Both need separate order-level duplicate protection.

Retries keep the original body and event ID. Older revisions must not overwrite newer ones. IPN makes up to eight attempts; webhook retries are optional. Low credits pause deliveries, not payments.

Store → IPN / Webhooks → History → Details shows the saved body and result. Payloads expire after 90 days. Resend is not proof of settlement.

Full payload, event table and receiver examples →

Exchange conversion

Send supported assets to Kraken, Binance or Coinbase. Keep the coin or convert credited deposits. Fiat stays on the exchange.

Deposit minimums apply per transaction, not per sweep. Below-minimum deposits stop the plan. Consolidate small balances to your own wallet first; extra network fees apply.

Connect and choose a route
  1. Settings → Exchanges: connect a dedicated key, check balances and grant projects. No withdrawal permissions; restrict the key to your VPS IP.
  2. Project → Sweep: verify asset, network, address and token contract. For each chain/token, choose either another wallet or one exchange.

Markets refresh every two minutes. Only matched, credited deposits can convert; stale markets stop new orders. A 1% source reserve stays at the exchange for fees/rounding, separate from processing credits.

Keep minimum amount reserves coins/tokens project-wide after automatic sweeps. Separate from the trigger; zero keeps none. Fees use the excess. Manual sends stay unchanged.

Resume uncertain transfers; never replace them. Wallets stay reserved until confirmation or unused-quote expiry. Large sweeps need batches.

Exchange custody, KYC, regional limits and fees apply. No bank payouts or leverage. Low credits pause new conversions; submitted orders still reconcile.

Processing credits

You still receive payments when credits run out. Existing stores keep invoices, checkout and payment monitoring. A missing verified billing connection or account suspension is different and can block new invoices.

Still availablePaused without usable credit
Invoices, checkout and confirmationsIPN/webhooks, including retries
Wallets, balances and backupsSweep: sends, gas, refunds and new exchange conversions
Reports, read APIs and existing settingsCreating projects and stores
Update checks and interrupted-update recoveryInstalling new versions

Top up through the credit icon. After verified recovery, enabled automation resumes, including sweep rules that send funds. Disable rules you do not want to resume.

Automatic credit top-ups

Open Auto top-up after Requests. Choose a backed-up receiving wallet, threshold, purchase amount, daily limit and network-fee cap. Authorize and save. It starts off.

Use BTC, ETH or Ethereum USDC/USDT when offered. Token sending addresses need ETH; this rule does not fund missing gas. Operators use dedicated receiving wallets; hosted merchants pay their Operator.

The approved top-up can run while low credits pause Sweep. Only the receiving service confirms credit. One automatic purchase runs at a time. Disabling stops unsent work, not submitted transactions.

Recover an automatic payment

In Auto top-up, use Check payment. Resume the same valid payment, or close a verified failed Ethereum transfer and pause the rule. Pending or uncertain payments stay on hold to prevent duplicate sending. An expired quote is not proof of failure.

Fees and restoring full access

The default 1% uses the settled invoice's original fiat value. Customer crypto payments are not split.

Fees continue accruing into a negative balance. Clear the negative amount and restore usable credit above your account's grace threshold. Balance changes normally appear within 10–15 seconds on a healthy connection.

Installing updates requires verified credit above zero, even with an automation grace allowance. Top-ups never install updates automatically.

Paused notifications consume no attempts. Retained deliveries resume; normal expiry still applies. Reconcile missed events through the invoice API.

If the operator disables processing fees, no new processing fees or credit restrictions apply. Previous charges remain in history. An unpaired installation can configure projects/stores, but needs verified billing to issue invoices. Already issued invoices remain monitored.

Reports

Revenue charts and filters stay above tabs: Projects & stores, Invoices, Wallets and Sweeps. Search below. Projects & stores includes CSV exports. Custom dates cover up to 366 days. Wallets use cached balances.

How report figures work
  • Revenue shows settled invoice values before fees/refunds, using settlement dates. It is not wallet balance or profit.
  • Conversions use current cached rates, not historical accounting rates. Original currency totals remain available if rates are missing.
  • Invoice-status charts use invoice creation dates. Needs-attention figures show current unresolved issues.

AI assistants · MCP

Opt-in, project-scoped access at api.example.com/mcp. Read payments or approve invoice creation. MCP setup & permissions →

Shop plugins

PrestaShop → · OpenCart → · All plugins →

SDKs

Use our official SDKs to create invoices, check payments and verify IPN/webhooks.

PHP SDK

PHP 7.4+

Add crypto payments to your PHP app with Composer.

composer require whollycrypto/php-sdk
GitHub & examples ↗

Python SDK

Python 3.10+

Connect your Python app or backend with no runtime dependencies.

python -m pip install whollycrypto
GitHub & examples ↗

Node.js SDK

Node.js 22+

JavaScript or TypeScript, one npm package with built-in types.

npm install whollycrypto
GitHub & examples ↗

Use your installation’s API domain and keep API keys server-side. All SDKs are MIT licensed.

Payment tools

Open Project → Payment tools and choose a store. Share a reusable payment link, take payments at a point of sale, or schedule payment requests by email.

Choose the price and payment flow
  • Fixed fiat: each new checkout uses current crypto rates and the store spread, then locks the quote until expiry.
  • Fixed crypto: request exact units of one accepted on-chain asset. A fresh fiat value, rounded up, is recorded for reporting and fees; no spread changes the crypto amount.
  • Donations: let customers enter an amount within your limits. Add quick amounts and optional name/email fields.
  • Point of sale: enter an amount or order reference and show the checkout QR. Wait for settled, not just payment detected.
  • Scheduled requests: send once, weekly or monthly in your chosen timezone. Customers pay each invoice themselves. No automatic wallet debits.

Store appearance, confirmations and callbacks still apply. Pausing a tool stops new requests, not existing payments. History links to each invoice. Missed periods do not create an email burst; resending reuses the same unpaid, unexpired invoice.

Customer checkout, payment links and scheduled emails support English, German, Spanish, Brazilian Portuguese, Italian, Russian, Simplified Chinese, French, Korean and Japanese.

Store → Invoice → Checkout language sets the default. Override per invoice or payment tool. Emails and resends keep the invoice language. Your text stays unchanged; Merchant and Operator consoles stay English.

Outgoing email

In Settings → System, below Source IP restrictions, enable SMTP with your provider’s public hostname, login, sender and optional reply-to. Use TLS on port 465 or STARTTLS on 587.

Save, test the connection, then send a test email to yourself. Set up SPF/DKIM with your provider. SMTP acceptance does not guarantee inbox delivery.

Scheduled requests use system SMTP. Notification channels can choose it too; existing channel and Operator invitation settings stay unchanged. Only the installation administrator manages these encrypted credentials. Email submission failures need an explicit resend.

Notifications & alerts

The bell opens your notification inbox. Theme choices are in the settings menu.

Set up channels and rules
  1. Open Settings → Notifications & alerts. Console notifications are built in.
  2. For email or Telegram, add a channel, send a verification code and enter it. Then enable the channel and select it on your rules.
  3. Choose alerts for payment exceptions, failed callbacks, transfer issues, low gas, delayed scanning, low credits or failed backups. Settled-payment alerts are optional.

Repeated issues are grouped. History lasts 30 days; project permissions still apply. Reading an alert does not resolve the issue. Human alerts do not replace store IPN or webhooks.

Marketplace

Enable Project → Marketplace, choose stores and register vendors with independently verified destinations. Create one invoice with exact vendor shares; approve payouts manually or set bounded automatic policies.

Set up multi-vendor payments

Bitcoin mainnet and supported EVM coins/ERC-20 only. Customers pay project-controlled wallets first, not vendors directly. Keep free native coins for fees. Ordinary sweeps exclude protected receiving addresses.

The processing fee applies once to the original invoice, separately from your commission. Underpayments and uncertain receipts need review. Refunds after vendor payout require separate funds, not an automatic clawback.

Set up multi-vendor payments · Marketplace API reference

Accounting

Open Settings → Accounting for Reports, Transactions, Exports and Checks. The dashboard stays separate.

Prepare an accountant report
  1. Choose a period, reporting currency and timezone. Filter by project or store, then search invoice, order, asset or transaction references.
  2. Review missing rates, fees and payment exceptions in Checks. Details link back to the existing invoice or transfer.
  3. Download an accountant ZIP with a printable summary and detailed CSV files. Up to 10,000 records per download; use a shorter period for larger histories.

Confirmed receipts, refunds and recorded costs are separate from wallet transfers and prepaid credit purchases. Invoice totals are counted once, even with multiple payments.

Historical values use retained evidence, not today's prices. Older rates and actual fees may be unavailable; missing costs are never assumed zero. Incomplete evidence keeps the net total unavailable.

This covers records tracked by Wholly Crypto, not every external wallet or exchange transaction. It is a bookkeeping aid, not a tax return or profit statement. Share exports securely: they can contain customer emails.

Sweep

Move received funds to your chosen destination. Manage rules and history in Project → Sweep.

Send native coins on 29 chains; Monero stays view-only. Tokens: verified ERC-20 and classic SPL. Manual sending and automatic sweeps use the same safeguards.

Manual send: prepare, review, approve

BTC, EVM, SOL and TRX are joined by 18 native adapters. Use a submission-capable provider. ZEC is transparent-only; ADA retains token outputs; DOT uses Asset Hub; HBAR needs a relay. Outgoing memo/tag/comment destinations need an external wallet.

  1. Open Project → Wallets → asset → Send. Choose an address-book entry or enter a destination. Check the full address and network.
  2. Choose an exact amount or sweep available, then a fee level. For supported tokens, Use project ETH for gas (or the chain's native coin) can fund missing fees from the same project/chain.
  3. Click Prepare transfer. Review sources, destination, amount, maximum fees and any gas allocation. Approve & send authorizes this plan; preparation alone sends nothing.

Gas funding, confirmations and token sending continue in the background after approval. Follow Transfer activity, even after closing the window. Broadcast is not confirmation.

Keep in project wallet ETH: 0 adds no reserve; it does not spend all your ETH. 0.005 keeps at least 0.005 ETH for later, so you need additional funds for this workflow. Saved automatic rules stay unchanged.

Automatic sweep setup
  1. Open Automatic Sweep Setup → asset → Setup. Choose a wallet address or supported exchange destination, not both.
  2. Set the sweep minimum and Keep minimum amount. Example: trigger at 100 USDC, keep 20 USDC, send up to 80 USDC. The reserve is project-wide, not per address.
  3. For tokens, review Use project ETH for gas and enter a Daily funding limit. Turn on Auto sweep, then Save rule and confirm. Opening Setup alone enables nothing.

The daily limit caps native gas allocated per token rule over a rolling 24 hours. €1 can be a starting limit for light use, not a guaranteed cost or daily charge. Funding transactions also have fees. Maximum network fee % can limit combined funding/transfer fees.

Checks run automatically. Only eligible token-holding addresses receive gas; empty addresses do not. An underfunded address below the sweep minimum waits. Gas limits explained →

Best practices & paused transfers
  • Back up wallets and test a small transfer. Send tokens before draining native coins. ETH elsewhere in the project must first reach each token address; unused gas stays in your wallets.
  • Use fresh balances, healthy providers and sufficient native funds. Automatic rules need an active, backed-up wallet and the asset enabled in an enabled store. Low processing credits can pause sending.
  • In Transfer activity, inspect progress, Gas funding and explorer links. On an uncertain result, refresh the same transfer; do not create a replacement. Resume only after reviewing the reason and limits.

Sending disabled? Check whollycrypto transfers status. Review every enabled rule before whollycrypto transfers enable: it applies server-wide and may run saved rules immediately. Stopping future steps cannot reverse broadcasts.

Domains

Settings → System: choose Manage or Add domain. Save, review DNS, publish. Unchanged hosts skip DNS/SSL checks.

Store domains

Store → Basic: choose active merchant/pay/API hosts. Links prefer store → default store → system; retired names fall back. Configure SDK hosts separately. Signed retries keep their original links.

HTTPS is automatic. Toggle Cloudflare after setup; Let's Encrypt stays active.

Cloudflare checklist
  • Use Full (strict), not Flexible; no API key needed.
  • Disable caching and browser/bot challenges for console, checkout and API.
  • Allow /.well-known/acme-challenge/ on port 80 without redirects/challenges for renewals.

Checks query authoritative DNS and verify the origin: Direct or Cloudflare. Visitors may cache older DNS.

Console saves/deletes use POST since 5.6.2; no “Not GET or POST” exception needed. Login and CSRF stay active. On api.*, allow the public API’s documented methods.

Account security

Set up 2FA under Settings → Account. Project-only users use My security in the footer. Confirm your password, scan the TOTP QR/key and enter a six-digit code.

Try Verifyr Authenticator for iOS or Android, or another standard TOTP app. Save the one-use recovery codes separately from your password. Keep HTTP Basic protection enabled.

Recovery and appearance

Replacing codes or disabling 2FA needs your password and an authenticator or unused recovery code. Other sessions are signed out. Keep phone/server clocks synchronized; 2FA does not secure a compromised server.

The theme icon cycles Light → Dim → Dark and remembers this browser's choice. Store checkout themes are separate.

Server security

  • Use SSH keys and restrict SSH to trusted IPs. Keep a tested recovery connection.
  • Enable Cloudflare proxy after setup, using Full (strict).
  • In Settings → System → Source IP restrictions, allow trusted IPs/ranges per live merchant.* or api.* hostname. Current console IP must stay allowed.
  • Normally leave pay.* open: customers need to pay from anywhere.
Cloudflare and lockout recovery

Optionally add Cloudflare access rules. Exempt HTTPS renewal challenges; avoid interactive login challenges on API and checkout. Proxy mode alone is not an IP restriction.

Locked out? Run whollycrypto access-reset --domain merchant.example.com over SSH. Only that hostname reopens, within five seconds; account authentication stays enabled.

Fix HTTPS

whollycrypto ssl
whollycrypto ssl --fix

The first command checks active certificates. --fix repairs TLS support files and renews missing/expiring certificates. Nginx must be running; keep ports 80/443 open.

Reissue one certificate

Run whollycrypto ssl --domain merchant.example.com --reissue for a forced replacement. Issuance limits apply. If Cloudflare blocks the HTTP challenge, temporarily use DNS-only. Wallets, authentication and domains stay unchanged.

Daily checks

  • Under Needs attention, select invoices or the current page to mark reviewed, add a note or rescan. Financial decisions stay individual.
  • Monitor disk space, scanner lag and independent node fallbacks. Public endpoints have no capacity guarantee.
  • Keep Linux current, restrict SSH and scope users/API keys to the required projects and permissions.

Decisions need a reason. Refunds require a separate confirmed transfer; invoice status changes never send money.

Updates & backups

Read the release notes, then use Settings → System → Software updates or the CLI. Updates verify signatures, create backups and check health. Checkout pauses during installation.

whollycrypto update --check
whollycrypto update

Updates wait up to two minutes for background jobs; checkout stays online. Timeouts restore timers.

Upgrading from 0.1.31 or earlier

Older updater blocked? Run this once. Your installed key verifies the helper.

bash <(curl -fsSL https://releases.whollycrypto.com/update_wholly.sh)

Keep tested off-server backups of PostgreSQL, configuration, wallet encryption keys and wallet exports. Local recovery archives are unencrypted.

Restore matching database/configuration backups together. Never interrupt migrations or run older binaries against newer databases. Credit rules still apply.

GitHub download fallback

Setup and updates automatically try the official GitHub mirror. Signature, checksum and credit checks remain required.

Server CLI

Root commands over SSH.

whollycrypto status
whollycrypto doctor
whollycrypto backup
All commands
CommandPurpose
whollycrypto versionInstalled version.
whollycrypto statusApp and database health.
whollycrypto logsLast 80 app log lines.
whollycrypto restartRestart and check health.
whollycrypto doctorRead-only installation checks.
whollycrypto doctor --fixRepair managed permissions and a missing CLI link.
whollycrypto htaccessReset a Basic Auth login.
whollycrypto admin-resetReset an administrator password.
whollycrypto 2fa-resetReset one account’s authenticator without changing its password.
whollycrypto transfers status
whollycrypto transfers enable
whollycrypto transfers disable
Check, enable or pause sending for all projects. Enable restarts the app and can run saved rules immediately; confirmation is required. Updates preserve pauses.
whollycrypto sslCheck HTTPS; add --fix to repair.
whollycrypto access-reset --domain HOSTRemove one hostname's IP restriction.
whollycrypto update --checkCheck for signed updates.
whollycrypto updateBack up, update and restart.
whollycrypto backupRoot-only archive in /root/whollycrypto/backups/releases/.
whollycrypto recoverRecover interrupted maintenance or an update with unchanged schema. Never restores a database automatically.
whollycrypto resetChoose one project, all business projects, or repair only.
whollycrypto uninstall --check
whollycrypto uninstall
Preview, then remove the native runtime. Database, keys and backups stay.
whollycrypto welcomeConsole URL and links.
whollycrypto --helpCommands; add --help after one for its options.
Diagnose installation problems

Checks are read-only, with a non-zero exit when attention is needed. --fix only repairs managed permissions and a missing CLI link. It never changes billing, deletes data or restarts services.

Choose a reset scope
whollycrypto reset
# Preview without changing anything:
whollycrypto reset --scope business --check
whollycrypto reset --scope project --project YOUR_PROJECT_IDENTIFIER --check

Choose one project, all business projects, or repair only. Project resets permanently erase the selected projects, stores, wallet records and payment history. Repair only checks and fixes managed permissions and the CLI link.

Disable selected projects, resolve open payments/transfers and move known wallet balances first. Accounts, domains, nodes, credits, billing identity and installation mode stay. Operator receiving wallets and hosted credit records are protected. This does not reopen the setup wizard.

A destructive reset requires a typed confirmation and creates a verified recovery backup before erasure. Keep an off-server wallet backup too: old addresses can still receive funds, but deleted projects stop tracking them. Cached balances do not prove wallets are empty.

Remove a native installation
whollycrypto uninstall --check
whollycrypto uninstall

Stops checkout, API and workers; removes runtime files and managed server integration after backup and typed confirmation. Pending payments or transfers block removal. Files move into the recovery backup rather than being wiped.

Database, configuration, keys and backups remain. Shared Nginx/PostgreSQL packages and TLS certificates are untouched. The command prints an offline recovery command; do not run fresh setup over retained data.

Reset/removal commands are for native VPS installs, not Docker or Umbrel. For containers, use your integration’s backup and stop commands; keep the volumes. Neither destructive command accepts --yes.

Reset the Basic Auth login
whollycrypto htaccess

Select a user, choose a name/password and confirm. This resets the browser's first login prompt, not your console account. Other users and API credentials stay unchanged.

Reset an administrator password
whollycrypto admin-reset

Choose an admin by email and confirm the new password. Sessions and account login locks are cleared; IP restrictions remain.

Normal resets keep 2FA. If both authenticator and recovery codes are lost, explicitly run whollycrypto admin-reset --email admin@example.com --reset-2fa. Set up 2FA again after login.

Needs the database, not the app or old password. Other accounts, wallets and permissions stay unchanged; disabled accounts stay disabled.

Reset 2FA

Lost both authenticator and recovery codes? Choose an account as root.

whollycrypto 2fa-reset
# Or select the account directly:
whollycrypto 2fa-reset --email user@example.com

Removes sessions, authenticator and recovery codes. Log in with the existing password and configure 2FA again. Permissions, wallets and Basic Auth stay unchanged; disabled accounts stay disabled.

Requires the database, not the app or credits. Non-interactive: --email and --yes.

Generated passwords and automation

Enter generates a password in /root/whollycrypto/config/credential-resets/: private, unencrypted, usable after success. Manually entered passwords aren't saved.

whollycrypto htaccess --user admin --new-user operator
whollycrypto admin-reset --email admin@example.com

Without a terminal, specify the existing account plus --generate or --password-file /root/private-password.txt, and --yes. Password files must be root-owned, mode 600. Never put passwords in commands or environment variables.

--yes skips confirmation only. Finish interrupted-update recovery first; concurrent account changes stop resets.