Core guides

Pro Pay · Merchant checkout

Full partner setup so third parties (and OpenPay) let users pay with OpenPay Pro payment methods — earnings credit to the merchant’s Pro @username or wallet address. Auth, API, env, dashboard, copy-paste.

Partner API readyAuth · Pay · ReceiveDashboard earningsGet API keysRaw MarkdownQR Pay packAI Partner PackConnect & payments
How settlement works: PayButton /charges settle to your OpenPay partner wallet. To land OUSD on an OpenPay Pro @username / 0x, call inbound with pro_xfer:. The multi-rail Top Up screen (Pi, Banxa, MoonPay, …) is a deep-link into Pro — not provider API keys in your app.

00

Overview — three paths

A · Charges

POST /charges → PayButton → poll paid. Earnings on partner OpenPay balance.

B · Pro inbound

After paid, POST inbound to credit merchant @user / 0x on Pro.

C · Deep-link

Send buyers to /topup (full methods) then /pay/@merchant.

Buyer → Your checkout → POST /charges (opk_live_)
      → Pay on OpenPay → poll GET /charges/:id = paid
      → POST https://openpaypro.space/api/public/openpay/inbound
         { to: "@shop", note: "pro_xfer:@shop:r_order", openpay_tx_id }
      → Merchant Pro wallet +$OUSD

01

Set receive wallet (merchant dashboard)

Merchants configure where funds arrive. Store these in your partner dashboard:

  • Pro @username — Settings / profile on OpenPay Pro
  • Pro 0x wallet — Wallet screen address
  • Partner OpenPay owner — charge proceeds via Partner portal
  • Optional opdk_… at /developer (inbound to your own Pro wallet only)
{
  "merchant_id": "m_123",
  "pro_username": "@shop",
  "pro_wallet": "0x7bf2…851a",
  "openpay_client_id": "uuid…",
  "receive_mode": "pro_inbound"
}

02

Env & API keys

# Required — Partner Transfer
OPENPAY_CLIENT_ID="your-client-uuid"
OPENPAY_PARTNER_API_KEY="opk_live_..."
OPENPAY_PARTNER_API_BASE="https://araojncyittkahvvpdrn.supabase.co/functions/v1/partner-transfer-api"

# Optional — Connect OAuth
OPENPAY_REDIRECT_URI="https://yourapp.com/openpay/callback"

# Merchant receive (your dashboard)
MERCHANT_PRO_USERNAME="@shop"
MERCHANT_PRO_WALLET="0x..."
PRO_INBOUND_URL="https://openpaypro.space/api/public/openpay/inbound"

# Optional — Pro developer key (own wallet inbound only)
OPENPAY_PRO_DEVELOPER_KEY="opdk_..."

Never expose opk_ / opdk_ in browsers or VITE_ env.

03

Auth — Connect with OpenPay

Standard Authorization Code. Scopes: profile balance. Codes expire in 10 minutes; opa_live_ tokens last 30 days.
https://openpy.space/connect
  ?client_id=YOUR_CLIENT_ID
  &redirect_uri=https://yourapp.com/openpay/callback
  &scope=profile%20balance
  &state=RANDOM_CSRF
curl -X POST "https://araojncyittkahvvpdrn.supabase.co/functions/v1/partner-transfer-api/oauth/token" \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "opc_...",
    "redirect_uri": "https://yourapp.com/openpay/callback",
    "client_id": "YOUR_CLIENT_ID",
    "client_secret": "opk_live_YOUR_KEY"
  }'

Pro wallet sign-in methods (OpenPay, Telegram, Solana, Pi, Phantom, WalletConnect, MetaMask): /docs/auth.

04

Create checkout — PayButton charges

Buyer pays with OpenPay Balance. Funds credit your partner-app owner. Poll status — no partner webhooks yet.

curl -X POST "https://araojncyittkahvvpdrn.supabase.co/functions/v1/partner-transfer-api/charges" \
  -H "Authorization: Bearer opk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 250.00,
    "currency": "OUSD",
    "description": "Order #9001",
    "reference": "order_9001",
    "success_url": "https://yourapp.com/pay/thanks?ref=order_9001",
    "cancel_url": "https://yourapp.com/pay/cancel?ref=order_9001"
  }'
# → { id, checkout_url, status, expires_at }  · TTL ~2h
# Poll
curl -H "Authorization: Bearer opk_live_YOUR_KEY" \
  https://araojncyittkahvvpdrn.supabase.co/functions/v1/partner-transfer-api/charges/CHARGE_ID
# created | paid | canceled | expired

# Cancel unpaid
curl -X POST -H "Authorization: Bearer opk_live_YOUR_KEY" \
  https://araojncyittkahvvpdrn.supabase.co/functions/v1/partner-transfer-api/charges/CHARGE_ID/cancel

05

Credit Pro @username / wallet

After paid, land OUSD on the merchant’s Pro receive identity:

curl -X POST "https://openpaypro.space/api/public/openpay/inbound" \
  -H "Authorization: Bearer opk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "@shop",
    "amount": 250.00,
    "openpay_tx_id": "CHARGE_OR_TX_ID",
    "note": "pro_xfer:@shop:r_order_9001",
    "from_username": "buyer"
  }'

to accepts @user, 0x…, or uid_…. Idempotent on openpay_tx_id.

06

QR Pay · method openpay_pro

For OpenPay’s QR Pay / checkout UI, register method openpay_pro. Same settle path as Path A+B: PayButton charge → poll → inbound to Pro receive wallet.
Method idopenpay_pro
LabelOpenPay Pro
Pay railOpenPay Balance via POST /charges
Receive@username and/or 0x… on OpenPay Pro
Notepro_xfer:@shop:r_order_9001
# Create charge for QR Pay order
curl -X POST "https://araojncyittkahvvpdrn.supabase.co/functions/v1/partner-transfer-api/charges" \
  -H "Authorization: Bearer opk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "amount": 25.00,
    "currency": "OUSD",
    "description": "QR Pay order_9001",
    "reference": "qr_order_9001",
    "success_url": "https://openpy.space/qrpay/thanks?ref=qr_order_9001",
    "cancel_url": "https://openpy.space/qrpay/cancel?ref=qr_order_9001"
  }'
# Show checkout_url (or QR of that URL) to buyer
# Poll until paid, then inbound:
curl -X POST "https://openpaypro.space/api/public/openpay/inbound" \
  -H "Authorization: Bearer opk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "@shop",
    "amount": 25.00,
    "openpay_tx_id": "CHARGE_OR_TX_ID",
    "note": "pro_xfer:@shop:r_qr_order_9001"
  }'

07

OpenPay Pro payment methods

Same catalog as the Pro Top Up → Pay with screen. Partners deep-link buyers to Pro; they do not embed provider secrets.
MethodLabelDescription
piPi Network (π)Pay with Pi · live π price → OUSD ($1) credited instantly
openpay_balanceOpenPay BalancePay from your connected OpenPay account · real debit
moonpayMoonPayCard / Apple Pay / Google Pay · MoonPay → OUSD
usdcUSDC PayPay with USDC · MoonPay Commerce → OUSD
helioCrypto DepositSOL / crypto · MoonPay Commerce → OUSD
solana_paySolana PayCommerce Kit · wallet connect, PaymentButton, Solana Pay QR → OUSD
circle_mintCircle DepositCircle Mint · USDC payin (payment intent + list payments) → OUSD
cash_payPay with CASHPhantom CASH (Solana SPL) · ledger balance or Solana Pay QR → OUSD 1:1
wallet_usdtWallet USDTPay with your OpenPay Pro USDT balance → OUSD 1:1
wallet_usdcWallet USDCPay with your OpenPay Pro USDC balance → OUSD 1:1
wallet_solWallet SOLPay with your OpenPay Pro SOL balance · live Solana price → OUSD
banxa_apple_payApple PayBanxa · Apple Pay (Face ID / Touch ID) → crypto settle → OUSD
banxa_google_payGoogle PayBanxa · Google Pay → crypto settle → OUSD
banxa_cardCardBanxa · debit / credit card → crypto settle → OUSD
banxa_bankBank TransferBanxa · bank transfer (ACH / SEPA / Faster Payments / PayID) → OUSD
scan_payScan to payMulti-chain QR · SOL / USDC / USDT / CASH stables → verify TX → OUSD on OpenLedger

09

Dashboard & earnings

Partner portal — keys, redirects, owner balance

GET /me · /balance — server earnings after charges

Pro wallet / activity — OUSD after inbound

Ledger API — reconcile buy / receive

curl -H "Authorization: Bearer opk_live_YOUR_KEY" \
  https://araojncyittkahvvpdrn.supabase.co/functions/v1/partner-transfer-api/balance

10

Copy-paste Node

const API = process.env.OPENPAY_PARTNER_API_BASE || "https://araojncyittkahvvpdrn.supabase.co/functions/v1/partner-transfer-api";
const KEY = process.env.OPENPAY_PARTNER_API_KEY;
const INBOUND = process.env.PRO_INBOUND_URL || "https://openpaypro.space/api/public/openpay/inbound";
const MERCHANT = process.env.MERCHANT_PRO_USERNAME || "@shop";

export async function createCheckout({ amount, reference, success_url, cancel_url }) {
  const res = await fetch(`${API}/charges`, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      amount,
      currency: "OUSD",
      description: reference,
      reference,
      success_url,
      cancel_url,
    }),
  });
  if (!res.ok) throw new Error(await res.text());
  return res.json(); // { id, checkout_url }
}

export async function waitUntilPaid(chargeId) {
  for (;;) {
    const res = await fetch(`${API}/charges/${chargeId}`, {
      headers: { Authorization: `Bearer ${KEY}` },
    });
    const data = await res.json();
    if (data.status === "paid") return data;
    if (data.status === "canceled" || data.status === "expired") {
      throw new Error(`Charge ${data.status}`);
    }
    await new Promise((r) => setTimeout(r, 2000));
  }
}

export async function creditMerchantPro({ amount, openpay_tx_id, reference }) {
  const res = await fetch(INBOUND, {
    method: "POST",
    headers: {
      Authorization: `Bearer ${KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      to: MERCHANT,
      amount,
      openpay_tx_id,
      note: `pro_xfer:${MERCHANT}:r_${reference}`,
    }),
  });
  if (!res.ok) throw new Error(await res.text());
  return res.json();
}

11

Launch checklist

Ready for production
  • Partner app + opk_live_ on server only
  • Merchant Pro @username and/or 0x saved in your dashboard
  • Connect redirect URIs exact-matched (if using OAuth)
  • Charges create → redirect → poll paid
  • Inbound credits Pro receive wallet (Path B)
  • QR Pay method openpay_pro wired (if using OpenPay QR)
  • /topup + /pay/@merchant tested (Path C)
  • Earnings via GET /balance and/or Pro wallet