Skip to content

Merchants

Use the invoice endpoints to charge your customers in any supported token and receive a different one in your own wallet. p3p handles the cross chain routing.

How it works

1
Register as a partnerGet your partner ID from the dashboard
2
Create an invoicePOST /invoice/create
3
Customer paysTo the deposit_address
4
You receive fundsSettled directly to your wallet

p3p never takes custody of your funds beyond the few seconds needed to route the swap. Refunds, when applicable, go to the deposit sender automatically.

1. Become a merchant

Register at the Partner Dashboard using a wallet you control. For swaps (/exchange/rate, /exchange/create), attribution and your fee come from authenticating with your partner api-keyopts.partner_id in the body is ignored. For invoices (/invoice/create), the merchant is identified by wallet_merchant.

There is no signup form, no email confirmation and no API token. The wallet is the credential.

Treat your merchant wallet like an API key

Anyone who controls the wallet controls the merchant account. Use a dedicated wallet for your business, separate from personal funds.

2. Create an invoice

Two ways to do this.

POST /invoice/create

ts
const invoice = await fetch("https://api.p3p.xyz/invoice/create", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    chain_from: "eth",  token_from: "usdt", amount_from: "50",
    chain_to:   "ton",  token_to:   "usdt",
    wallet_merchant: "UQYourMerchantTonWallet"
  }),
}).then(r => r.json())

console.log(invoice.deposit_address) // show to your customer

Response:

json
{
  "id": "in_ab12cd...",
  "invoice": true,
  "chain_from": "eth",  "token_from": "usdt", "amount_from": "50",
  "chain_to":   "ton",  "token_to":   "usdt",
  "amount_to":  "50.0",
  "wallet_merchant": "UQYourMerchantTonWallet",
  "deposit_address": "0xDepositAddressForCustomer",
  "rate":     "1.0",
  "duration": 60
}

Shareable URL (no integration needed)

For a checkout button, QR code or share link, you can build the invoice from a URL:

https://api.p3p.xyz/invoice/create/:merchantId/:pathFrom/:pathTo?

Examples:

# customer pays 100 USDT on TON, you receive USDT on TON
https://api.p3p.xyz/invoice/create/0xYourMerchantWallet/100:usdt.ton/usdt.ton

# customer pays 50 TON, you receive USDT on TON
https://api.p3p.xyz/invoice/create/acme/50:ton.ton/usdt.ton

# simple form: pay and receive the same asset
https://api.p3p.xyz/invoice/create/acme/100:usdt.ton

:merchantId may be:

  • the partner id returned during registration,
  • a partner name if you set one, or
  • a wallet address already registered as a merchant.

3. Show the deposit address

Render invoice.deposit_address and invoice.amount_from in your UI, ideally as a QR code:

ts
import QRCode from "qrcode"

const dataUrl = await QRCode.toDataURL(
  `${invoice.chain_from}:${invoice.deposit_address}?amount=${invoice.amount_from}`
)

The customer sends amount_from of token_from to that address. Anything else (wrong amount, wrong token, expired window) gets auto refunded.

4. Confirm payment

Poll /check/:id exactly like a regular exchange:

ts
async function waitForInvoicePayment(id: string) {
  while (true) {
    const s = await fetch(`https://api.p3p.xyz/check/${id}`).then(r => r.json())
    if (s.status === "complete") return s
    if (s.status === "failed" || s.status === "refunded") throw new Error(s.status)
    await new Promise(r => setTimeout(r, 4000))
  }
}

await waitForInvoicePayment(invoice.id)
// funds are now in wallet_merchant

5. Inspecting your earnings

Three partner endpoints are read only and require no authentication beyond knowing the partnerId. Earnings settle according to your configured payout settings (either instantly per swap or via USDT scheduled withdrawals) — configure this in the Partner Dashboard.

EndpointReturns
GET /partners/:partnerId/statsVolume, transaction count, revenue share
GET /partners/:partnerId/exchangesAll exchanges credited to this partner
GET /partners/:partnerId/invoicesAll invoices created for this partner
bash
curl https://api.p3p.xyz/partners/0xYourMerchantWallet/stats

Tips & gotchas

  • One wallet per chain: a partner accumulates wallets, one per chain. Use the right wallet for the destination chain in wallet_merchant.
  • Same chain + same token: skips the swap engine and acts as a plain forwarding address — useful for simple "pay me X USDT on TON" links.
  • Deposit window: invoices share the standard ~6 minute window. If the customer takes longer, call /check/:id?bump=true to refresh it.
  • Refunds: only available when the deposit is detected but the swap fails. For invoices without a wallet_refund, funds attempt to refund to the sender address detected on chain.

Endpoint reference

All merchant endpoints are open — no api-key header required. Your wallet is the credential.

1. Create Invoice

POST /invoice/create

FieldTypeRequiredDescription
chain_fromstringyesChain the customer pays from
token_fromstringyesToken the customer pays with
amount_fromstringyesAmount the customer pays
chain_tostringyesChain you receive funds on
token_tostringyesToken you receive
wallet_merchantstringyesYour wallet on the destination chain

Returns an invoice object including id, deposit_address, amount_from, amount_to, rate and duration.

2. Create Shareable Invoice URL

GET /invoice/create/:merchantId/:pathFrom/:pathTo?

Shareable invoice URL — drop it in a QR code or a button.

  • merchantId — partner id, partner name, or a wallet already registered as a merchant
  • pathFrom<amount>:<token>.<chain> (e.g. 100:usdt.ton)
  • pathTo — optional, <token>.<chain> if you want to convert; defaults to pathFrom

Returns the same object as POST /invoice/create.

3. Get Partner Stats

GET /partners/:partnerId/stats

Aggregate volume, transaction count and lifetime revenue share for the partner wallet.

4. Get Partner Exchanges

GET /partners/:partnerId/exchanges

Paginated list of exchanges credited to the partner.

5. Get Partner Invoices

GET /partners/:partnerId/invoices

Paginated list of invoices created for the partner.

Errors

json
{ "error": "merchant_id_required", "message": "..." }
CodeMeaning
invalid_jsonRequest body is not valid JSON
merchant_id_requiredInvoice GET endpoint called without a merchant identifier
partner_not_foundNo partner matches the given merchantId
merchant_wallet_not_foundPartner exists but has no wallet on the destination chain
amount_too_smallAmount below the supplier minimum
amount_too_bigAmount above the supplier maximum