Payment Rails
PEAC receipts can carry payment evidence from any supported rail. Each rail adapter extracts settlement references from the payment processor and produces a standardized PaymentEvidence object that you attach to a receipt at issuance time.
Supported rails
| Rail | Package | Evidence source | Status |
|---|---|---|---|
| x402 (Coinbase) | @peac/rails-x402 | x402 payment headers | Stable |
| Stripe | @peac/rails-stripe | PaymentIntent, CryptoPaymentIntent | Stable |
| Razorpay | @peac/rails-razorpay | UPI, cards, netbanking, wallets | Stable |
| Card networks | @peac/rails-card | Visa, Mastercard, Amex | Stable |
x402 (Coinbase)
The x402 adapter extracts payment evidence from Coinbase's HTTP 402 payment headers. It supports USDC and other stablecoins on Base, Ethereum, and other EVM chains.
pnpm add @peac/rails-x402
import { fromX402Payment } from '@peac/rails-x402';
const evidence = fromX402Payment({
paymentHeader: req.headers['x-402-payment'],
amount: '0.001',
currency: 'USDC',
network: 'base',
});
Stripe
The Stripe adapter supports both traditional fiat payments via PaymentIntent and crypto payments via CryptoPaymentIntent.
pnpm add @peac/rails-stripe
From PaymentIntent
Use fromStripePaymentIntent for standard card and bank-based Stripe payments.
import { fromStripePaymentIntent } from '@peac/rails-stripe';
// Pass the Stripe PaymentIntent object directly
const evidence = fromStripePaymentIntent(paymentIntent);
From CryptoPaymentIntent
Use fromCryptoPaymentIntent for Stripe's crypto payment flow. Added in v0.10.11.
import { fromCryptoPaymentIntent } from '@peac/rails-stripe';
// Pass the Stripe CryptoPaymentIntent object directly
const evidence = fromCryptoPaymentIntent(cryptoPaymentIntent);
Razorpay
The Razorpay adapter supports UPI, cards, netbanking, and wallet payments across the Indian payment ecosystem.
pnpm add @peac/rails-razorpay
import { fromRazorpayPayment } from '@peac/rails-razorpay';
const evidence = fromRazorpayPayment({
paymentId: 'pay_abc123',
orderId: 'order_xyz789',
method: 'upi',
amount: 1000,
currency: 'INR',
});
Card networks
The card adapter works with raw authorization data from Visa, Mastercard, and Amex.
pnpm add @peac/rails-card
import { fromCardPayment } from '@peac/rails-card';
const evidence = fromCardPayment({
network: 'visa',
authorizationCode: 'AUTH123',
last4: '4242',
amount: 1999,
currency: 'USD',
});
PaymentEvidence interface
All rail adapters produce a standardized PaymentEvidence object. This is the common type that gets attached to a receipt regardless of which rail generated it.
interface PaymentEvidence {
rail: string; // 'x402' | 'stripe' | 'razorpay' | 'card'
amount: string; // Amount as string (avoids floating-point)
currency: string; // ISO 4217 or token symbol (e.g., 'USD', 'USDC')
settlement_ref?: string; // Rail-specific settlement reference
evidence: Record<string, unknown>; // Rail-specific details
}
Attaching payment evidence to a receipt
Once you have a PaymentEvidence object from any rail adapter, attach it to a receipt during issuance.
import { issueReceipt } from '@peac/protocol';
import { fromStripePaymentIntent } from '@peac/rails-stripe';
const paymentEvidence = fromStripePaymentIntent(paymentIntent);
const receipt = await issueReceipt({
privateKey: process.env.PEAC_PRIVATE_KEY,
kid: 'peac-2026-02',
claims: {
iss: 'https://api.example.com',
sub: 'user:customer-456',
peac: {
type: 'payment',
attestation_type: 'payment',
status: 'executed',
payment: paymentEvidence,
},
},
});
The status field tracks the payment lifecycle. Use proposed for pending payments, executed for completed payments, and denied for rejected payments.