PayzCore Docs

Address Modes

Choose between 4 address modes: per_payment and per_user (HD wallet with xPub), or dedicated and pool (static addresses). Each mode fits different payment flows.

Address Modes

PayzCore supports four address modes, configured at the project level when creating a project. Each mode determines how blockchain addresses are assigned to payments and how incoming transfers are matched.

Overview

HD Wallet (xPub required)Static Wallet (manual addresses)
Modesper_payment, per_userdedicated, pool

HD Wallet Modes

These modes require an xPub key (extended public key). PayzCore derives unique watch-only addresses from it using BIP-44 HD derivation. Your private keys never leave your wallet.

How xPub Works

Your wallet generates two keys from the same seed:

  • Private Key — stays in your wallet, NEVER shared. Signs transactions and moves funds.
  • xPub Key — public, shared with PayzCore. Can only derive addresses and read balances.

PayzCore uses your xPub to derive addresses at sequential indexes:

IndexAddressUsage
0Address AReserved for gas/fees (not used for payments)
1Address BFirst payment
2Address CSecond payment
NAddress ...Continues sequentially

Address families:

  • EVM xPub → BEP20, ERC20, Polygon, Arbitrum addresses (path: m/44'/60'/0'/0/index)
  • Tron xPub → TRC20 addresses (path: m/44'/195'/0'/0/index)

One xPub can serve multiple networks in the same family. You need at most 2 xPub keys (one EVM, one Tron) to cover all 5 networks.

per_payment (Default)

A new unique address is derived for each payment request. The address is deactivated when the payment resolves (paid, expired, or cancelled).

CustomerOrderAddressIndex
Customer AOrder #1Address X1 (new)
Customer AOrder #2Address Y2 (new)
Customer BOrder #3Address Z3 (new)

Flow: You call POST /v1/payments → PayzCore increments the derivation counter → derives a new address at the next index → returns the unique address → customer sends exact amount → payment resolves → address deactivated.

Best for: E-commerce checkout, one-time purchases, invoice payments.

Pros: Maximum privacy, no address reuse, simple matching (any transfer to this address = this payment).

Cons: More addresses to sweep, slightly higher derivation index over time.

per_user

The same address is reused for the same external_ref on a given network+token. Only one pending payment per address+token is allowed at a time.

CustomerOrderAddressIndexNote
aliceOrder #1Address X1New address derived
aliceOrder #2Address X1Same address reused
bobOrder #3Address Y2New address derived

Flow: You call POST /v1/payments { external_ref: "alice", network: "TRC20" }. First time: PayzCore derives a new address and assigns it to alice+TRC20. Next time: reuses the same address. The customer always sends to their personal address.

Best for: User wallets, deposit addresses, subscription payments, repeat customers.

Pros: Fewer addresses to manage, customers can bookmark their deposit address.

Cons: Must wait for pending payment to resolve before creating another for the same user+network+token.

While a payment is in progress (pending, confirming or partial) for the same external_ref + network + token:

  • the same order (same amount, and same external_order_id if you send one) returns the existing payment with "existing": true;
  • a different order returns 409 This customer already has a payment in progress on this network… with existing_payment_id and existing_amount. Cancel that payment (PATCH /v1/payments/{id} with {"status":"cancelled"}) or wait for it to finish. The same rule applies to dedicated mode.

Optional: rotation_threshold — When set on the project, if the cumulative received amount on an address exceeds this threshold, a new address is derived for the user on the next payment.

Static Wallet Modes

These modes use manually registered addresses. No xPub key is required. You add your existing wallet addresses to PayzCore and it monitors them.

dedicated

One static address permanently assigned to each customer. Each unique external_ref gets its own address from your static address pool.

CustomerAddressNote
alice0x1234...Permanently assigned
bob0x5678...Permanently assigned
alice (again)0x1234...Same address, always

Flow: You call POST /v1/payments { external_ref: "alice" }. First time: PayzCore assigns the next available static address to alice. Next time: returns the same address. Any transfer to this address = matched to alice.

You can also pre-assign an address via the address parameter:

{
  "amount": 50,
  "network": "TRC20",
  "external_ref": "alice",
  "address": "TXyz...abc"
}

Best for: Fixed customer deposit addresses, businesses with pre-existing address mappings, exchanges.

Pros: No xPub needed, permanent addresses, simple customer experience.

Cons: Need enough addresses for all customers, addresses can't be rotated.

pool

Shared addresses across multiple customers, with a matching strategy to identify which payment a transfer belongs to. Requires fewer addresses but needs a way to distinguish payments.

Pool + micro_amount

A micro-offset is automatically added to the payment amount to make each payment unique per address.

CustomerRequestedPayzCore ReturnsSendsResult
Customer A$50.00$50.003$50.003Matched to A
Customer B$50.00$50.017$50.017Matched to B

Configuration:

  • micro_amount_decimals: 1-4 (default: 3). Controls the precision of the offset.
    • 1 decimal: offsets like $0.1-$0.9 (9 unique values)
    • 2 decimals: offsets like $0.01-$0.99 (99 unique values)
    • 3 decimals: offsets like $0.001-$0.999 (999 unique values, default)
    • 4 decimals: offsets like $0.0001-$0.9999 (9999 unique values)

API Response includes:

{
  "payment": {
    "amount": "50.003",
    "original_amount": "50.00",
    "notice": "Please send exactly 50.003 USDT to the address below."
  }
}

Matching logic: PayzCore looks for a single transaction on the address where |tx_amount - expected_amount| < 0.0001. This is an exact match within floating-point precision.

Best for: High volume with limited addresses, marketplaces, donation platforms.

Important: The customer must send the exact modified amount. Even $0.01 difference will prevent matching.

The offset is a surcharge. It is always added, never subtracted, so the customer pays up to (10^d − 1) / 10^d more than the base amount (for example up to $0.999 more with 3 decimals). Plan your prices for it, or use fewer decimals.

Base amount precision: the amount you send must not have more decimals than micro_amount_decimals (with 3 decimals, 50.5 is fine, 50.1234 returns 400 Amount has more decimal places than this project's micro-amount precision allows).

Freed offsets: an offset released by an expired or cancelled payment is not reused for 6 hours, so a late transfer cannot be matched to a new customer.

Overpaid handling: If the customer sends more than 1% above the expected micro-adjusted amount, the payment status will be overpaid and a payment.overpaid webhook will fire.

Pool + txid

The customer sends the exact requested amount, then submits their blockchain transaction hash. PayzCore verifies the hash on-chain.

  1. You create a payment via POST /v1/payments — the response includes requires_txid: true and a confirm endpoint.
  2. Customer sends $50 USDT to the pool address.
  3. Customer copies their transaction hash from the blockchain.
  4. You (or your customer) submit the hash via POST /v1/payments/{id}/confirm { tx_hash: "abc123..." }.
  5. PayzCore verifies the transaction on-chain and matches it to the payment.

Confirm endpoint:

curl -X POST https://api.payzcore.com/v1/payments/PAYMENT_ID/confirm \
  -H "x-api-key: pk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "tx_hash": "abc123def456..." }'

Response (verified immediately):

{
  "success": true,
  "status": "confirming",
  "verified": true,
  "amount_received": "50.00",
  "message": "Transaction verified on blockchain. Waiting for confirmations."
}

Response (not yet on blockchain):

{
  "success": true,
  "status": "pending",
  "verified": false,
  "message": "Transaction hash recorded. It will be verified automatically."
}

Accepted hash formats: hex, case-insensitive, 0x prefix optional. EVM hashes (BEP20, ERC20, Polygon, Arbitrum) are stored as 0x + 64 lowercase hex; TRC20 hashes as 64 lowercase hex without 0x.

Safeguards:

  • A tx hash can only be submitted once per payment
  • A tx hash cannot be used on multiple payments (first valid claim wins; later ones get 409)
  • The transfer must go to this payment's address, on its network, inside the payment window (after the address was assigned and before expiry), and be above the dust threshold
  • Several transfers can be combined: if the customer sends 25 + 25 for a 50 payment, both confirmed transfers count

Security note: txid mode cannot prove who sent a transfer. On a shared pool address, anyone who sees a transfer to that address (block explorers are public) during their own payment window could submit its hash first. For shared pools with untrusted customers, prefer micro_amount; use txid where customers are known (OTC, manual verification).

Best for: Manual verification flows, OTC desks, peer-to-peer transactions.

Comparison Table

Featureper_paymentper_userdedicatedpool (micro)pool (txid)
xPub requiredYesYesNoNoNo
Address reuseNeverPer customerPer customerSharedShared
MatchingAny tx on addrAny tx on addrAny tx on addrExact amountTx hash
Customer actionSend exact amtSend exact amtSend exact amtSend exact modified amtSend + submit hash
Max concurrent paymentsUnlimited1 per user+network+token1 per user+network+tokenLimited by offset spaceUnlimited
Sweep complexityHigh (many addrs)MediumLowLowLow
PrivacyBestGoodGoodLowerLower

Choosing the Right Mode

Use CaseRecommended ModeWhy
E-commerce checkoutper_paymentClean: 1 address per order, no reuse
User deposits/top-upsper_userCustomers get a permanent deposit address
Fixed customer accountsdedicatedKnown customer base with static addresses
High-volume marketplacepool + micro_amountFew addresses, automatic matching
OTC / manual flowpool + txidCustomer submits proof of payment

Changing Address Mode

Address mode is set when creating a project and can be changed in project settings. However, changing the mode while there are pending payments is not allowed — all pending payments must resolve first.

On this page