Skip to main content
Version: v0.16.4

Payment Rails

PEAC records what happened during commerce flows. Each rail mapping extracts upstream artifacts, preserves them as-is, and produces a PEAC receipt with typed commerce extensions. PEAC never executes payments, coordinates checkout, or manages wallets.

Supported rails​

RailPackageWhat it recordsStatus
Paymentauth / MPP@peac/mappings-paymentauthHTTP 402 challenges, credentials, upstream receiptsStable
x402@peac/adapter-x402Offer/receipt verification, v1/v2 headers, upstream artifact separationStable
Stripe@peac/rails-stripePayment intent observation, SPT delegation lifecycleSource-only
Razorpay@peac/rails-razorpayUPI, cards, netbanking, walletsSource-only
Card networks@peac/rails-cardVisa, Mastercard, Amex authorizationSource-only

Paymentauth / MPP​

Envelope-first parsing for the HTTP Payment authentication scheme (draft-ryan-httpauth-payment). Extracts Challenge, Credential, and Receipt envelopes with raw artifact preservation.

Terminal
pnpm add @peac/mappings-paymentauth
paymentauth-evidence.ts
import { parsePaymentauthChallenges, parsePaymentauthReceipt } from '@peac/mappings-paymentauth';

// Parse 402 challenges from the WWW-Authenticate header
const challenges = parsePaymentauthChallenges(wwwAuthenticateHeader);

// Parse the upstream receipt from the Payment-Receipt header
const receipt = parsePaymentauthReceipt(paymentReceiptHeader);

Carrier coexistence: PEAC-Receipt (PEAC compact JWS) and Payment-Receipt (upstream receipt) coexist without conflict. JSON-RPC error helpers (-32042, -32043) and MCP extraction functions included.


x402​

Four-layer adapter architecture (A1/A2/B/C) with 5-layer verification API. Reads v1 (X-PAYMENT-RESPONSE) and v2 (PAYMENT-RESPONSE) headers alongside PEAC-Receipt.

Terminal
pnpm add @peac/adapter-x402
x402-evidence.ts
import { extractReceiptArtifactFromHeaders } from '@peac/adapter-x402';

const artifact = extractReceiptArtifactFromHeaders(headers);
// artifact.receipt_jws: PEAC compact JWS only
// artifact.upstreamArtifact: raw upstream data (preserved as-is)
// artifact.artifactFormat: 'peac' | 'x402-v1' | 'x402-v2'

Stripe​

Payment intent observation and SPT delegation evidence. Commerce event fields are set only when the upstream PaymentIntent explicitly proves the claimed payment state.

Source-only

@peac/rails-stripe is not published to npm in v0.15.0; build it from the repository (packages/rails/stripe).

Payment intent observation​

stripe-observation.ts
import { fromStripePaymentIntentObservation } from '@peac/rails-stripe';

const evidence = fromStripePaymentIntentObservation(paymentIntent);
// succeeded -> commerce event: settlement
// requires_capture -> commerce event: authorization
// processing, canceled -> no commerce event

SPT delegation lifecycle​

Delegation events record token lifecycle, not payment finality:

EventTypeCommerce event
delegated_payment_grantedDelegation lifecycleNone
delegated_payment_presentedDelegation lifecycleNone
delegated_payment_deactivatedDelegation lifecycleNone

Razorpay​

India payment adapter supporting UPI, cards, netbanking, and wallet payments.

Source-only

@peac/rails-razorpay is not published to npm in v0.15.0; build it from the repository (packages/rails/razorpay).

razorpay-evidence.ts
import { normalizeRazorpayPayment, type RazorpayConfig } from '@peac/rails-razorpay';

const config: RazorpayConfig = {
webhookSecret: process.env.RAZORPAY_WEBHOOK_SECRET!,
};

// event is the verified, parsed webhook payload (after verifyWebhookSignature)
const event = {
entity: 'event',
account_id: 'acc_abc123',
event: 'payment.captured',
contains: ['payment'],
payload: {
payment: {
entity: {
id: 'pay_abc123',
entity: 'payment',
amount: 1000,
currency: 'INR',
status: 'captured',
order_id: 'order_xyz789',
international: false,
method: 'upi',
amount_refunded: 0,
captured: true,
vpa: 'user@upi',
},
},
},
created_at: 1700000000,
};

const evidence = normalizeRazorpayPayment(event, config);

Card networks​

Generic card billing bridge for Visa, Mastercard, and Amex.

Source-only

@peac/rails-card is not published to npm in v0.15.0; build it from the repository (packages/rails/card).

card-evidence.ts
import { toPaymentEvidence, type CardBillingEvent } from '@peac/rails-card';

const event: CardBillingEvent = {
eventId: 'evt_abc123',
eventType: 'invoice.paid',
payload: {}, // provider-specific raw event object
billingSnapshot: {
provider: 'stripe',
customerExternalId: 'cus_xyz789',
planSlug: 'pro-monthly',
entitlements: [{ feature: 'api-calls', limit: 10000 }],
capturedAt: '2026-08-11T00:00:00Z',
},
amountMinorUnits: 1999,
currency: 'USD',
env: 'live',
};

const evidence = toPaymentEvidence(event);

Commerce extension (Interaction Record format)​

All commerce evidence uses the org.peacprotocol/commerce extension group:

issue-commerce-receipt.ts
import { issue } from '@peac/protocol';

const { jws } = await issue({
iss: 'https://api.example.com',
kind: 'evidence',
type: 'org.peacprotocol/payment',
pillars: ['commerce'],
extensions: {
'org.peacprotocol/commerce': {
payment_rail: 'stripe',
amount_minor: '2500',
currency: 'USD',
event: 'settlement',
},
},
privateKey: process.env.PEAC_PRIVATE_KEY,
kid: 'peac-2026-03',
});

The event field is a 6-value closed enum (authorization, settlement, void, refund, chargeback, observation) and is observational metadata only. It records what the upstream system reported, not more.


Semantic boundary​

PEAC mappings preserve raw upstream artifacts and never synthesize payment finality:

  • An ACP session "completed" does not prove payment settled
  • An SPT "grant" does not prove payment authorized
  • A paymentauth receipt proves what the upstream server attested, not more
  • event fields are set only when the upstream artifact explicitly proves the claimed state