Skip to main content

PAY.ID — Programmable Payment Policy

One ID · Rule-based · Non-custodial · On-chain Enforced

PAY.ID is a programmable payment system for EVM blockchains. It lets receivers (merchants, creators, DAOs) define Rules that control who can pay them, how much, and under what conditions — enforced automatically on-chain without running a server.


The Simple Idea

Imagine you're a merchant. You want to accept payments, but only under certain conditions:

  • Only stablecoins (USDC, USDT)
  • Only between $10–$500
  • Only from KYC-verified users

Normally, enforcing these rules requires a backend server, a database, and custom off-chain code. PAY.ID lets you define these rules as simple JSON and enforces them on-chain.

PAY.ID answers one fundamental question before every payment: "Should this transaction be allowed?"


How It Works

Context → Rules (WASM engine) → Decision → Proof (EIP-712) → On-chain Verify
StepWhat Happens
ContextPayment details: who's paying, what token, how much, when
RulesYour rules evaluated in a WASM sandbox — deterministic, auditable
DecisionALLOW ✅ or REJECT ❌
ProofIf ALLOW, an EIP-712 signed proof is generated (payer signs with their wallet)
VerifySmart contract checks the proof, then executes the transfer or reverts

The contracts never run your rules on-chain — they only verify the signed proof. This keeps gas costs low.


Choose Your Integration Path

Path A — React / Frontend (payid-react)

Install one package, wrap your app in a provider, and use a single hook. Recommended for most dApps.

import { usePayIDFlow } from 'payid-react'

function CheckoutButton() {
const { execute, status, txHash } = usePayIDFlow()

return (
<button onClick={() => execute({
receiver: '0xMerchant...',
asset: '0xUSDC...',
amount: 50_000_000n, // 50 USDC
payId: 'pay.id/my-store',
})}>
{status === 'idle' && 'Pay 50 USDC'}
{status === 'proving' && 'Sign in wallet...'}
{status === 'success' && '✅ Paid!'}
</button>
)
}

React Quick Start →


Path B — Node.js / Backend (payid)

For servers, APIs, automated bots, and ERC-4337 bundlers. The server wallet signs proofs.

import { createPayIDServer } from 'payid/server'
import { Wallet } from 'ethers'

const payid = createPayIDServer({
signer: new Wallet(process.env.PRIVATE_KEY!),
})

const { result, proof } = await payid.evaluateAndProve({
context, payId, payer, receiver, asset, amount,
verifyingContract, ruleAuthority, chainId, blockTimestamp,
})

Server Guide →


The 4 Core Concepts

🪪 1. Payment Identity (pay.id/yourname)

Not just a wallet address — it carries your payment rules. When someone pays pay.id/my-store, PAY.ID automatically fetches and evaluates the rules attached to that identity.

📋 2. Rules (JSON configs)

Rules define your payment policy. They are stored on IPFS with their hash committed on-chain. Three formats: SimpleRule, MultiConditionRule, NestedRule. → Rule Basics →

🔐 3. Decision Proof (EIP-712)

Every approved payment generates a cryptographic receipt signed by the payer's own wallet. No trusted third party needed — the blockchain verifies it.

⛓️ 4. On-chain Enforcement

Smart contracts verify the proof (never execute rules). This keeps contracts simple and cheap to audit.


What PAY.ID Is NOT

❌ Not✅ But
A walletA policy layer for payments
A payment gatewayA cryptographic proof generator
A custodianAn identity + rules protocol
A blockchain or L2Works on any EVM chain

Packages

PackageDescriptionInstall
payidCore SDK — rule engine, proof generationnpm i payid ethers
payid-reactReact hooks — wallet integrationnpm i payid-react wagmi viem ethers

What's New


Getting Started