PayzCore Docs

Hosted Payment Page

Let customers choose the network and token on a PayzCore-hosted page. Create a payment without a network, share payment_url, and receive webhooks as usual.

Hosted Payment Page

Every payment created through the API has a hosted page at https://pay.payzcore.com/{payment_id}. The API returns this link as payment_url. You can send customers there instead of building your own payment screen.

The hosted page shows the amount, the deposit address with a QR code, a countdown until expiry and the live status. The funds still go straight to your wallet address. PayzCore only watches the blockchain and notifies you.

Two Ways to Use It

FlowYou send network?What the customer sees
Fixed networkYes (e.g. TRC20)Address and QR code right away
Customer selectsNoA network/token picker first, then the address and QR code

Customer-selects flow

  1. Create a payment without network (and without token):
curl -X POST https://api.payzcore.com/v1/payments \
  -H "x-api-key: pk_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{"amount": 50, "external_ref": "customer-123", "external_order_id": "ORD-456"}'
  1. The response has no address yet. address, network, token and qr_code are null, and available_networks lists what your wallet supports:
{
  "success": true,
  "payment": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "address": null,
    "amount": "50.00",
    "network": null,
    "token": null,
    "status": "pending",
    "expires_at": "2026-10-15T13:00:00.000Z",
    "external_order_id": "ORD-456",
    "qr_code": null,
    "payment_url": "https://pay.payzcore.com/550e8400-e29b-41d4-a716-446655440000",
    "available_networks": [
      { "network": "TRC20", "name": "Tron", "tokens": ["USDT"], "confirmations": 19, "explorer": "https://tronscan.org" },
      { "network": "BEP20", "name": "BSC", "tokens": ["USDT", "USDC"], "confirmations": 15, "explorer": "https://bscscan.com" }
    ]
  }
}
  1. Redirect the customer to payment_url. They pick a network and token, and the page assigns a deposit address from your wallet (using your project's address mode).
  2. From then on the payment behaves like any other: GET /v1/payments/:id returns the address and network, and you receive the usual webhooks.

While no network is selected, GET /v1/payments/:id returns "awaiting_network": true.

If you do not pass external_order_id, PayzCore generates one (PAY-…) for network-less payments.

What the Customer Sees

  • Store name and logo from your Project Settings (see Store Branding)
  • Verified badge if PayzCore has verified your project. Unverified projects show an "Unverified merchant" label instead of the store name, to protect buyers from impersonation. Contact support to get your project verified.
  • Amount, token and network, deposit address, QR code (black-on-white) and a countdown
  • Live status. The page checks the status every 10 seconds and shows the final state (paid, partial, overpaid, expired, cancelled).
  • In pool + txid mode, a field to paste the transaction hash after sending (see Address Modes)

The page never asks for wallet keys or card data. It only displays where to send funds.

Network Selection Endpoint

The hosted page calls this endpoint when the customer picks a network. It is served on pay.payzcore.com only (not on api.payzcore.com) and needs no API key:

POST https://pay.payzcore.com/api/pay/{payment_id}/select-network
Content-Type: application/json

{ "network": "TRC20", "token": "USDT" }
StatusResponse
200{ "success": true, "address", "network", "token", "amount", "qr_code" }
400network and token are required, USDC is not supported on TRC20, X on Y is not available for this merchant, No addresses available for this network, This merchant is currently not accepting payments
404Payment not found
409Payment is not in pending state or Network already selected for this payment
410Payment has expired
429Too many requests (5 per minute per IP, 3 per minute per payment) or Payment capacity exceeded. Please try again later.

A network can be selected once. You normally do not call this endpoint yourself; build your own picker with POST /v1/payments + network instead.

Expiry

The payment window is expires_in seconds (300–86,400) from creation. If you omit it, your project's payment expiry setting applies (60 minutes unless changed). Picking a network does not extend the window.

No payment.expired webhook without a network. A payment that expires before the customer selects a network has no address. It moves to expired (visible in GET /v1/payments/:id and the list endpoint), but no payment.expired webhook is sent for it. If your order flow depends on expiry (for example to release stock), also poll GET /v1/payments?status=expired&updated_after=… or check the payment when your own timer runs out.

The hosted page and GET /v1/payments/:id show a pending payment as expired only 3 minutes after expires_at, so a last-second transfer still has a chance to be detected.

Hosted Payment PagePayment Links
Created byYour server, via POST /v1/paymentsYou, in the dashboard (no code)
URLpay.payzcore.com/{payment_id} (one per payment)pay.payzcore.com/l/{slug} (reusable)
AmountSet by your serverFixed or entered by the buyer
Buyer infoNoOptional email, name, note

Both flows send the same webhooks. Payment-link payments also include buyer_email, buyer_name, buyer_note, payment_link_id and payment_link_slug.

See Also

On this page