Payment Models
Detailed documentation for payment models in the core package.
PaymentRequest
The PaymentRequest class represents a payment request from a server.
Properties
class PaymentRequest {
maxAmountRequired: string; // Maximum payment amount required
assetType: string; // Asset type (e.g., "SPL")
assetAddress: string; // Token mint address or "native" for SOL
paymentAddress: string; // Recipient wallet address
network: string; // Blockchain network identifier
expiresAt: Date; // Payment request expiration time
nonce: string; // Unique nonce for this request
paymentId: string; // Unique payment identifier
resource: string; // Resource path being requested
description?: string; // Optional description
}Creating a Payment Request
import { PaymentRequest } from '@shade402/core';
const request = new PaymentRequest({
max_amount_required: '0.01',
asset_type: 'SPL',
asset_address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
payment_address: 'RecipientWalletAddress',
network: 'solana-devnet',
expires_at: new Date(Date.now() + 600000),
nonce: crypto.randomUUID(),
payment_id: crypto.randomUUID(),
resource: '/api/premium-data',
description: 'Premium data access',
});Methods
isExpired()
isExpired()Check if the payment request has expired:
if (request.isExpired()) {
console.log('Payment request expired');
}toDict()
toDict()Convert to dictionary format:
const dict = request.toDict();
// {
// max_amount_required: '0.01',
// asset_type: 'SPL',
// ...
// }toJSON()
toJSON()Convert to JSON string:
const json = request.toJSON();
// '{"max_amount_required":"0.01",...}'fromDict()
fromDict()Create from dictionary:
const request = PaymentRequest.fromDict({
max_amount_required: '0.01',
asset_type: 'SPL',
// ... other fields
});Validation
The PaymentRequest constructor validates all fields using Zod schemas:
try {
const request = new PaymentRequest(data);
} catch (error) {
if (error instanceof InvalidPaymentRequestError) {
console.error('Invalid payment request:', error.message);
}
}PaymentAuthorization
The PaymentAuthorization class represents proof of payment.
Properties
class PaymentAuthorization {
paymentId: string; // Links to payment request
actualAmount: string; // Amount actually paid
paymentAddress: string; // Recipient address
assetAddress: string; // Token mint address
network: string; // Blockchain network
timestamp: Date; // When payment was made
signature: string; // Transaction signature
publicKey: string; // Payer's public key
transactionHash?: string; // Transaction hash (optional)
}Creating a Payment Authorization
import { PaymentAuthorization } from '@shade402/core';
const authorization = new PaymentAuthorization({
payment_id: 'unique-payment-id',
actual_amount: '0.01',
payment_address: 'RecipientWalletAddress',
asset_address: 'EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v',
network: 'solana-devnet',
timestamp: new Date(),
signature: 'transaction-signature',
public_key: 'PayerPublicKey',
transaction_hash: 'transaction-hash',
});Methods
toHeaderValue()
toHeaderValue()Convert to header value (base64-encoded JSON):
const headerValue = authorization.toHeaderValue();
// Use in X-Payment-Authorization headerfromHeader()
fromHeader()Create from header value:
const headerValue = req.headers['x-payment-authorization'];
const authorization = PaymentAuthorization.fromHeader(headerValue);toDict()
toDict()Convert to dictionary:
const dict = authorization.toDict();toJSON()
toJSON()Convert to JSON string:
const json = authorization.toJSON();Validation
The PaymentAuthorization constructor validates all fields:
try {
const authorization = new PaymentAuthorization(data);
} catch (error) {
if (error instanceof InvalidPaymentRequestError) {
console.error('Invalid authorization:', error.message);
}
}Usage Examples
Creating Payment Request on Server
import { PaymentRequest } from '@shade402/core';
function createPaymentRequest(
amount: string,
paymentAddress: string,
tokenMint: string,
resource: string
): PaymentRequest {
return new PaymentRequest({
max_amount_required: amount,
asset_type: 'SPL',
asset_address: tokenMint,
payment_address: paymentAddress,
network: 'solana-devnet',
expires_at: new Date(Date.now() + 600000), // 10 minutes
nonce: crypto.randomUUID(),
payment_id: crypto.randomUUID(),
resource: resource,
description: 'Payment for resource access',
});
}Parsing Payment Authorization on Server
import { PaymentAuthorization } from '@shade402/core';
function parseAuthorization(req: Request): PaymentAuthorization {
const headerValue = req.headers['x-payment-authorization'] as string;
if (!headerValue) {
throw new Error('Missing payment authorization');
}
return PaymentAuthorization.fromHeader(headerValue);
}Validating Payment Authorization
function validateAuthorization(
request: PaymentRequest,
authorization: PaymentAuthorization
): boolean {
// Check payment ID matches
if (authorization.paymentId !== request.paymentId) {
return false;
}
// Check amount is sufficient
if (parseFloat(authorization.actualAmount) < parseFloat(request.maxAmountRequired)) {
return false;
}
// Check addresses match
if (authorization.paymentAddress !== request.paymentAddress) {
return false;
}
// Check token mint matches
if (authorization.assetAddress !== request.assetAddress) {
return false;
}
// Check network matches
if (authorization.network !== request.network) {
return false;
}
return true;
}Type Definitions
interface PaymentRequestData {
max_amount_required: string;
asset_type: string;
asset_address: string;
payment_address: string;
network: string;
expires_at: Date | string;
nonce: string;
payment_id: string;
resource: string;
description?: string;
}
interface PaymentAuthorizationData {
payment_id: string;
actual_amount: string;
payment_address: string;
asset_address: string;
network: string;
timestamp: Date | string;
signature: string;
public_key: string;
transaction_hash?: string;
}Next Steps
Learn about Solana Processor for payment creation
Check out Core Package overview
See Examples for usage
Last updated
