No merchant KYC · Customers pay fiat, you get stablecoins · Onboarding is openApply now →

Docs / Merchant guide

Merchant guide

From your first login to your first payment. Menu names follow the dashboard; check the dashboard itself if a label differs.

1. Before you start: checklist

  • Your merchant account and the dashboard address. We send both after your application is approved.
  • A browser wallet, for example MetaMask. It becomes your "master account" and deploys the sweep contract.
  • A little native coin on each chain you will use. Deploying the contract costs gas once: ETH on Ethereum and Base, POL on Polygon.
  • A dedicated hot wallet. The platform does not provide one, so you prepare your own (see section 5) and put a little native coin on each chain, to pay sweep gas and payouts.
  • A cold wallet address that you control. All payments end up here. A hardware wallet is strongly recommended.

Never send your private key or seed phrase to anyone, including us. We will not ask. The only place a private key goes is the "Add Hot Wallet" step in the dashboard, and only for a newly created wallet that holds just a little gas money (see section 5).

2. Log in to the dashboard

Log in with the address and credentials in your onboarding email. Only sign in through the address we sent you, and do not follow links from unknown sources.

After your first login, change the initial password straight away and keep your credentials in a password manager.

3. Check the blockchain nodes

Path: Settings → Integrations → Node Configurations.

  • Each chain shows its number of nodes, how many are online and the latest block processed. Public nodes are preconfigured and usually work out of the box for testing and low volume.
  • Public nodes can be rate limited. For higher volume, or if you need uninterrupted operation, click Add Node and enter a node address from a provider such as Alchemy or Infura.
  • Node addresses usually contain a key. Keep them private.

4. Set up deposit wallets (master account and cold wallet)

First, four concepts:

ConceptRole
Master accountYour browser wallet account. Every customer deposit address is derived from it, and it deploys the sweep contract.
Deposit walletThe address a customer pays. One per order or per customer, all linked to the same master account.
Cold walletWhere funds finally land. It is never shown to customers.
Sweep contractDeployed once per chain. It moves funds from deposit addresses into the cold wallet automatically, without exposing any private key.

Steps

  1. In the left menu open Wallet management → Deposit wallet, click + Set Up Deposit Wallet and choose the network. EVM covers Ethereum, Base and Polygon together.
  2. Choose the project this wallet belongs to. A project that already has one shows "Wallet already present"; one that does not shows "Ready".
  3. Name the wallet and click Connect wallet, then authorise in your browser wallet. The master account deploys the contract and generates a unique deposit address for each customer.
  4. Enter your cold wallet address and click Deploy contract, then confirm the transaction in your wallet.
  5. When deployment finishes, the system generates a batch of unassigned deposit addresses. You can now click Create test payment link and verify the whole flow with 1 US dollar.
  6. Each deployment covers one chain. 1/3 ready means one of the three EVM chains is done. Repeat the steps for the others, connecting the same master wallet each time.

Check the cold wallet address again and again. Funds are swept to this address automatically and a wrong address cannot be recovered. Compare it digit by digit with the address on your hardware wallet screen, and enable one chain first, adding the others after a successful test.

What triggers a sweep? A deposit address must first reach a one-time minimum balance (by default roughly the equivalent of 5 US dollars) before the system deploys its smart wallet contract. Below that it stays dormant and nothing is swept. After that, a sweep is triggered by amount, address count or time, whichever condition is met. These thresholds can be adjusted. See SmartSweep explained.

5. Set up the hot wallet

The hot wallet is the only wallet in PayRam whose private key is stored, encrypted on the server. It does three things: pays the gas needed for sweeps, sends payouts, and covers the on-chain fees for those operations.

  1. In the left menu open Wallet management → Hot wallet and click + Add Hot Wallet.
  2. Choose the chain family: EVM (covers Ethereum, Base and Polygon) or Tron. One hot wallet per family.
  3. Enter the private key of a wallet on that chain, give it a name and save.
  4. On the wallet's row, click the edit icon next to the project count and choose which projects use it. Every project needs a hot wallet configured for the networks it receives on. There is no shared fallback.

Use a dedicated new wallet only. Do not use the key of your master account or cold wallet. Keep only enough for gas and near-term payouts, and top it up regularly. This is the only wallet in the whole system whose key is held on the server, and that server is operated by the platform. Treat it as petty cash and keep only an amount you are comfortable leaving there.

You prepare the hot wallet and you bear the gas. The platform does not provide a hot wallet and does not pay gas or payout funds for you. After creating the wallet, send it a little native coin (ETH on Ethereum and Base, POL on Polygon). Refunds and other payouts are also sent from this wallet, so it needs the matching coin too. When the balance runs out, the system cannot pay sweep gas or send payouts. We suggest turning on email alerts in "Settings" so you hear about low balances in time.

6. Create a test payment link

  1. Click Create Payment Link at the top of the left menu.
  2. Choose the customer: type in "Search member by email". The list is empty the first time, so click Add New Member, enter the customer's email and choose the project.
  3. Enter the amount to collect in US dollars and click Generate Payment Link.
  4. You can copy the link to the customer, or click to open it and see what the customer sees: the amount, the equivalent in a coin and a deposit address. The page keeps watching for the payment and updates automatically.

The customer picks a coin and network under "Pay with crypto". Once the required block confirmations are reached, the page shows the payment as complete. The first time, test with just 1 US dollar.

Optional: enable card and fiat payments

Once enabled, customers without a crypto wallet can pay by card, Apple Pay, Google Pay, bank transfer and similar methods, depending on their region, and you still receive stablecoins. A regulated third-party provider does the conversion, and merchants do not need KYC / KYB for this.

  1. Open Settings → Payment Channels, click Activate next to Cards, then click Activate again in the pop-up. If you cannot find this entry in the dashboard, contact us.
  2. Make sure the network the provider settles on is enabled: PayRam Wallet settles on Base, Changelly on Ethereum, and Wert on Ethereum, Base and Polygon.
  3. Create a payment link as above and send it to the customer. The customer will see the fiat option.

On a first fiat purchase the customer completes a one-time basic KYC check with the provider. Provider fees are shown at checkout, and available methods, regions and limits are decided by the provider. See the card-to-crypto channel explained.

7. Create payments through the API

The base address (BASE_URL) is shown in the dashboard under Settings → Site URL. Generate an API key in the dashboard and keep it safe. Send it in the API-Key request header.

Create a payment

curl --location 'https://pay.payramhost.com/api/v1/payment' \
  --header 'API-Key: <your_api_key>' \
  --header 'Content-Type: application/json' \
  --data-raw '{
    "customerEmail": "buyer@example.com",
    "customerID": "1001",
    "amountInUSD": 10,
    "invoiceID": "INV-0090"
  }'
FieldRequiredNotes
customerEmailYesThe customer's email
customerIDYesA unique customer number in your system
amountInUSDYesAmount in US dollars
invoiceIDNoYour own order number. It comes back unchanged in the webhook's invoice_id, which helps reconciliation
expireNoExpiry time in RFC 3339 format. Defaults to 24 hours
currencyNoRestrict payment to one coin, for example USDC. If omitted the customer chooses
networkNoRestrict payment to one chain, for example BASE. Use it together with currency

The url in the response is the payment page to send to the customer, and reference_id is used to look the payment up later:

{
  "host": "https://pay.payramhost.com",
  "reference_id": "c80f5363-0397-4761-aa1a-3155c3a21470",
  "url": "https://pay.payramhost.com/payments?reference_id=c80f5363-...&host=https://pay.payramhost.com"
}

For the full integration flow see the API integration guide. Other endpoints, such as the status query, are documented in the official PayRam documentation.

8. Receive webhooks

When a payment is detected and progresses on-chain, the system sends a POST request to the address you registered, so you do not need to poll.

  1. In the dashboard go to Settings → Webhook and click Add Endpoint.
  2. Enter your HTTPS address (it must be reachable from the internet) and a short description, save it and set it to active.

Verify the signature (always do this)

The X-Payram-Signature header has the format sha256=<hex>. It is an HMAC-SHA256 of the raw request body using your project API key. Compute it over the bytes exactly as received, never over re-serialised parsed JSON.

const crypto = require('crypto');

function verifyPayramSignature(rawBody, signatureHeader, apiKey) {
  const expected =
    'sha256=' + crypto.createHmac('sha256', apiKey).update(rawBody).digest('hex');
  const a = Buffer.from(signatureHeader || '');
  const b = Buffer.from(expected);
  return a.length === b.length && crypto.timingSafeEqual(a, b);
}

Retries and idempotency

  • Your server must return 2xx. A response of 400 or above, or no response within 60 seconds, counts as a failure and is retried.
  • Final states (closed or cancelled) are retried quickly three times, then at 30 minutes, 1, 2, 4, 8, 24 and 48 hours. After the seventh long-term retry the delivery is marked failed and not sent again. Use the status endpoint to reconcile anything missed.
  • The same status can arrive more than once. De-duplicate by reference_id (or invoice_id) plus status.
  • While a deposit is confirming you also receive progress notifications with confirmation_current / confirmation_required (for example 3 / 12).

For the full treatment see the webhook guide, and for what each status value means see payment statuses.

9. Refunds and payouts

  • On-chain payments have no automatic chargeback and no automatic refund. You send a refund manually from the dashboard or through the API to the customer's address.
  • Payouts are sent from the project's hot wallet. If no hot wallet is configured for the project, you cannot send payouts.
  • If a customer underpays, the payment stays in a partially filled state until it is paid in full. If a customer overpays, the excess is shown in the dashboard and you decide how to handle it.

More detail is in refunds and payouts.

10. Security checklist

  • Only you know your private keys and seed phrases. Never send them to anyone.
  • Use a hardware wallet as the cold wallet and check the address against the hardware screen every time it is changed.
  • Keep only a small balance in the hot wallet, and only use a newly created wallet.
  • Keep API keys on your server only, never in a web page or a mobile app.
  • Always verify the signature when handling webhooks, and make handling idempotent by reference_id.
  • Only log in through the address we sent you. If you receive a message such as "urgent: change your wallet address", confirm it with us through another channel first.
  • PayRam tutorial: A PayRam tutorial for merchants: what PayRam is, self-hosting versus a hosted service, how a payment flows, choosing a chain and coin, five steps to your first USDT / USDC payment, and how to let customers pay by card.
  • Webhook guide: How to receive PayRam webhooks: register an endpoint, verify X-Payram-Signature, understand retry rules and payment states, handle duplicates, with Node.js and Python examples.
  • Create payments via API: Add crypto payments to your own site with the PayRam API: create a payment and get a payment link, send the customer to the payment page, confirm receipt with webhooks and the status endpoint, and reconcile by order number. With curl, Node.js and Python examples.
  • SmartSweep: How SmartSweep moves funds from customer deposit addresses into your cold wallet: the three triggers (amount, address count, time), why small test payments are not swept, who pays the gas, and why Bitcoin is different.