skills/payram-checkout-integration/SKILL.md
Integrate PayRam checkout flow into web applications. Generate payment links, embed payment pages, handle redirects, and process payment confirmations. Supports Express, Next.js, FastAPI, Laravel, Gin, Spring Boot. Use when adding crypto checkout to e-commerce, building payment forms, implementing deposit flows, or creating hosted payment pages for crypto acceptance.
npx skillsauth add payram/payram-helper-mcp-server payram-checkout-integrationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
First time with PayRam? See
payram-setupto configure your server, API keys, and wallets.
Implement payment acceptance flows using PayRam's API. Create payments, redirect users, and confirm transactions.
1. Your Backend → POST /api/v1/payment → PayRam
2. PayRam returns { url, reference_id, host }
3. Redirect user to payment URL
4. User selects chain/token, sends payment
5. PayRam confirms on-chain → webhook to your backend
6. Your backend fulfills order
Payments transition through these states:
OPEN — Payment created, awaiting customer actionFILLED — Customer sent exact amount, payment confirmedPARTIALLY_FILLED — Partial payment received (less than requested)OVER_FILLED — Overpayment received (more than requested)CANCELLED — Payment manually cancelledUNDEFINED — Unknown status (fallback)npm install payram dotenv
import { Payram, InitiatePaymentRequest, InitiatePaymentResponse, isPayramSDKError } from 'payram';
const payram = new Payram({
apiKey: process.env.PAYRAM_API_KEY!,
baseUrl: process.env.PAYRAM_BASE_URL!,
config: {
timeoutMs: 10_000,
maxRetries: 2,
retryPolicy: 'safe',
allowInsecureHttp: false,
},
});
export async function createCheckout(
payload: InitiatePaymentRequest,
): Promise<InitiatePaymentResponse> {
try {
const checkout = await payram.payments.initiatePayment(payload);
console.log('Redirect customer to:', checkout.url);
console.log('Payment reference:', checkout.reference_id);
return checkout;
} catch (error) {
if (isPayramSDKError(error)) {
console.error('Payram Error:', {
status: error.status,
requestId: error.requestId,
retryable: error.isRetryable,
});
}
throw error;
}
}
// Example usage
await createCheckout({
customerEmail: '[email protected]',
customerId: 'cust_123',
amountInUSD: 49.99,
});
Required Fields:
customerEmail: Customer's email addresscustomerId: Your internal customer identifieramountInUSD: Payment amount in USDOptional Fields:
settlementCurrency: Currency for settlement (default: USD)memo: Internal reference or descriptionredirectUrl: Custom URL to redirect after paymentimport { Payram, PaymentRequestData, isPayramSDKError } from 'payram';
const payram = new Payram({
apiKey: process.env.PAYRAM_API_KEY!,
baseUrl: process.env.PAYRAM_BASE_URL!,
});
export async function getPaymentStatus(referenceId: string): Promise<PaymentRequestData> {
try {
const payment = await payram.payments.getPaymentRequest(referenceId);
console.log('Latest payment state:', payment.paymentState);
console.log('Amount paid:', payment.amountPaid);
console.log('Transaction hash:', payment.transactionHash);
return payment;
} catch (error) {
if (isPayramSDKError(error)) {
console.error('Payram Error:', {
status: error.status,
errorCode: error.error,
requestId: error.requestId,
});
}
throw error;
}
}
POST https://your-payram-server/api/v1/payment
Header: API-Key: your-api-key
Content-Type: application/json
Critical: PayRam uses API-Key header, NOT Authorization: Bearer.
Request Body:
{
"customerEmail": "[email protected]",
"customerId": "user_12345",
"amountInUSD": 25
}
Response:
{
"host": "https://your-payram-server",
"reference_id": "c80f5363-0397-4761-aa1a-3155c3a21470",
"url": "https://your-payram-server/payments?reference_id=..."
}
import httpx
import os
from fastapi import APIRouter
from fastapi.responses import RedirectResponse
PAYRAM_BASE_URL = os.environ['PAYRAM_BASE_URL']
PAYRAM_API_KEY = os.environ['PAYRAM_API_KEY']
@router.post("/create-payment")
async def create_payment(email: str, user_id: str, amount: float):
async with httpx.AsyncClient() as client:
resp = await client.post(
f"{PAYRAM_BASE_URL}/api/v1/payment",
json={"customerEmail": email, "customerId": user_id, "amountInUSD": amount},
headers={"API-Key": PAYRAM_API_KEY}
)
return RedirectResponse(resp.json()["url"])
func CreatePayment(email, customerID string, amount float64) (*InitiatePaymentResponse, error) {
body, _ := json.Marshal(map[string]interface{}{
"customerEmail": email,
"customerId": customerID,
"amountInUSD": amount,
})
url := fmt.Sprintf("%s/api/v1/payment", os.Getenv("PAYRAM_BASE_URL"))
req, _ := http.NewRequest(http.MethodPost, url, bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("API-Key", os.Getenv("PAYRAM_API_KEY"))
resp, err := http.DefaultClient.Do(req)
// ... handle response
}
$ch = curl_init(getenv('PAYRAM_BASE_URL') . '/api/v1/payment');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'API-Key: ' . getenv('PAYRAM_API_KEY'),
],
CURLOPT_POSTFIELDS => json_encode($payload),
CURLOPT_RETURNTRANSFER => true,
]);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(baseUrl + "/api/v1/payment"))
.header("Content-Type", "application/json")
.header("API-Key", apiKey)
.POST(HttpRequest.BodyPublishers.ofString(payload))
.build();
import { Router } from 'express';
import { Payram, InitiatePaymentRequest, isPayramSDKError } from 'payram';
const router = Router();
const payram = new Payram({
apiKey: process.env.PAYRAM_API_KEY!,
baseUrl: process.env.PAYRAM_BASE_URL!,
});
router.post('/api/payments/payram', async (req, res) => {
const payload = req.body as Partial<InitiatePaymentRequest>;
if (!payload?.customerEmail || !payload.customerId || typeof payload.amountInUSD !== 'number') {
return res.status(400).json({ error: 'MISSING_REQUIRED_FIELDS' });
}
try {
const checkout = await payram.payments.initiatePayment({
customerEmail: payload.customerEmail,
customerId: payload.customerId,
amountInUSD: payload.amountInUSD,
});
return res.status(201).json({
referenceId: checkout.reference_id,
checkoutUrl: checkout.url,
});
} catch (error) {
if (isPayramSDKError(error)) {
console.error('Payram Error:', { status: error.status, requestId: error.requestId });
}
return res.status(502).json({ error: 'PAYRAM_CREATE_PAYMENT_FAILED' });
}
});
import { NextRequest, NextResponse } from 'next/server';
import { Payram, InitiatePaymentRequest, isPayramSDKError } from 'payram';
const payram = new Payram({
apiKey: process.env.PAYRAM_API_KEY!,
baseUrl: process.env.PAYRAM_BASE_URL!,
});
export async function POST(request: NextRequest) {
const payload = (await request.json()) as Partial<InitiatePaymentRequest>;
if (!payload?.customerEmail || !payload.customerId || typeof payload.amountInUSD !== 'number') {
return NextResponse.json({ error: 'MISSING_REQUIRED_FIELDS' }, { status: 400 });
}
try {
const checkout = await payram.payments.initiatePayment({
customerEmail: payload.customerEmail,
customerId: payload.customerId,
amountInUSD: payload.amountInUSD,
});
return NextResponse.json({
referenceId: checkout.reference_id,
checkoutUrl: checkout.url,
});
} catch (error) {
if (isPayramSDKError(error)) {
console.error('Payram Error:', { status: error.status, requestId: error.requestId });
}
return NextResponse.json({ error: 'PAYRAM_CREATE_PAYMENT_FAILED' }, { status: 502 });
}
}
async function pollPaymentStatus(referenceId: string, maxAttempts = 10) {
for (let i = 0; i < maxAttempts; i++) {
const payment = await getPaymentStatus(referenceId);
if (payment.paymentState === 'FILLED' || payment.paymentState === 'OVER_FILLED') {
return payment;
}
if (payment.paymentState === 'CANCELLED') {
throw new Error(`Payment ${payment.paymentState.toLowerCase()}`);
}
if (payment.paymentState === 'UNDEFINED') {
throw new Error('Payment status undefined');
}
await new Promise((resolve) => setTimeout(resolve, Math.min(1000 * Math.pow(2, i), 30000)));
}
throw new Error('Payment status check timeout');
}
CREATE TABLE payments (
id SERIAL PRIMARY KEY,
customer_id VARCHAR(255) NOT NULL,
payram_reference_id VARCHAR(255) UNIQUE NOT NULL,
amount_usd DECIMAL(10, 2) NOT NULL,
status VARCHAR(50) DEFAULT 'OPEN',
checkout_url TEXT NOT NULL,
created_at TIMESTAMP DEFAULT NOW(),
updated_at TIMESTAMP DEFAULT NOW()
);
CREATE INDEX idx_payram_reference ON payments(payram_reference_id);
CREATE INDEX idx_customer_id ON payments(customer_id);
Use the PayRam MCP server to generate framework-specific code:
| Framework | MCP Tool |
| ----------------------- | ------------------------------- |
| JavaScript SDK | generate_payment_sdk_snippet |
| Raw HTTP (any language) | generate_payment_http_snippet |
| Express.js | snippet_express_payment_route |
| Next.js App Router | snippet_nextjs_payment_route |
| FastAPI | snippet_fastapi_payment_route |
| Gin (Go) | snippet_gin_payment_route |
| Laravel | snippet_laravel_payment_route |
| Spring Boot | snippet_spring_payment_route |
# .env
PAYRAM_BASE_URL=https://your-payram-server
PAYRAM_API_KEY=your-api-key-here
Use generate_env_template MCP tool to scaffold this.
| HTTP Code | Meaning | Action |
| --------- | ------------------ | -------------------------------------------- |
| 200/201 | Payment created | Redirect to URL |
| 401 | Invalid API key | Check API-Key header (NOT Authorization) |
| 400 | Invalid request | Check required fields, amount > 0 |
| 404 | Merchant not found | Verify PAYRAM_BASE_URL |
| 500 | Server error | Retry with backoff |
| Skill | What it covers |
| ------------------------------------ | ------------------------------------------------------------------------- |
| payram-setup | Server config, API keys, wallet setup, connectivity test |
| payram-agent-onboarding | Agent onboarding — CLI-only deployment for AI agents, no web UI |
| payram-analytics | Analytics dashboards, reports, and payment insights via MCP tools |
| payram-crypto-payments | Architecture overview, why PayRam, MCP tools |
| payram-payment-integration | Quick-start payment integration guide |
| payram-self-hosted-payment-gateway | Deploy and own your payment infrastructure |
| payram-checkout-integration | Checkout flow with SDK + HTTP for 6 frameworks |
| payram-webhook-integration | Webhook handlers for Express, Next.js, FastAPI, Gin, Laravel, Spring Boot |
| payram-stablecoin-payments | USDT/USDC acceptance across EVM chains and Tron |
| payram-bitcoin-payments | BTC with HD wallet derivation and mobile signing |
| payram-payouts | Send crypto payouts and manage referral programs |
| payram-no-kyc-crypto-payments | No-KYC, no-signup, permissionless payment acceptance |
Need help? Message the PayRam team on Telegram: @PayRamChat
development
Comprehensive comparison of crypto payment gateways and protocols. Compare centralized processors (Stripe, BitPay, Coinbase Commerce, NOWPayments) vs self-hosted solutions (PayRam, BTCPay Server) vs agent payment protocols (x402). Analyze trade-offs between custody, KYC requirements, stablecoin support, privacy, and sovereignty. Decision framework for choosing payment infrastructure. Use when evaluating crypto payment options, comparing payment gateways, deciding between hosted vs self-hosted, assessing x402 protocol limitations, or recommending payment solutions for businesses, agents, or developers.
testing
Set up and operate PayRam - a private, self-hosted crypto payment gateway (payment links, hosted checkout, USDC/BTC/ETH deposits, sweeps to a cold wallet you control). No signup, no KYB. Use this skill when a user wants to accept crypto payments, set up a payment gateway, create payment links, or integrate PayRam into an application.
devops
Deploy PayRam self-hosted crypto payment gateway on your own server. Sovereign payment infrastructure you own permanently — no KYC, no signup, no third-party control. Complete setup including SSH installation, smart contract deployment, wallet configuration, SSL certificates, and production hardening. Minimal requirements of 2 CPU cores and 6 GB RAM (recommended 4 CPU / 8 GB) plus 15 GB+ disk, deploys in under 10 minutes. Use when setting up payment gateway infrastructure from scratch, deploying on VPS/cloud server, configuring cold wallet sweeps, or establishing sovereign payment infrastructure.
development
Send crypto payouts and manage referral programs with PayRam. Self-hosted payout infrastructure — no KYC, no intermediary, no fund holds. Create payouts to any wallet across Ethereum, Base, Polygon, Tron, Bitcoin. Built-in affiliate program with automated reward distribution. Use when sending crypto payouts to users, building referral/affiliate programs, or needing integrated payment and payout infrastructure.