payram-checkout-integration

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.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "payram-checkout-integration" with this command: npx skills add payram/payram-helper-mcp-server/payram-payram-helper-mcp-server-payram-checkout-integration

PayRam Checkout Integration

First time with PayRam? See payram-setup to configure your server, API keys, and wallets.

Implement payment acceptance flows using PayRam's API. Create payments, redirect users, and confirm transactions.

Payment Flow Overview

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

Payment States

Payments transition through these states:

  • OPEN — Payment created, awaiting customer action
  • FILLED — Customer sent exact amount, payment confirmed
  • PARTIALLY_FILLED — Partial payment received (less than requested)
  • OVER_FILLED — Overpayment received (more than requested)
  • CANCELLED — Payment manually cancelled
  • UNDEFINED — Unknown status (fallback)

SDK Integration (Node.js/TypeScript)

Install SDK

npm install payram dotenv

Create Payment with SDK

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: 'customer@example.com',
  customerId: 'cust_123',
  amountInUSD: 49.99,
});

Required Fields:

  • customerEmail: Customer's email address
  • customerId: Your internal customer identifier
  • amountInUSD: Payment amount in USD

Optional Fields:

  • settlementCurrency: Currency for settlement (default: USD)
  • memo: Internal reference or description
  • redirectUrl: Custom URL to redirect after payment

Check Payment Status with SDK

import { 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;
  }
}

HTTP Integration (Python, Go, PHP, Java)

API Endpoint

POST https://your-payram-server:8080/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": "customer@example.com",
  "customerId": "user_12345",
  "amountInUSD": 25
}

Response:

{
  "host": "https://your-payram-server:8080",
  "reference_id": "c80f5363-0397-4761-aa1a-3155c3a21470",
  "url": "https://your-payram-server/payments?reference_id=..."
}

Python (FastAPI)

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"])

Go (Gin)

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
}

PHP (Laravel)

$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,
]);

Java (Spring Boot)

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();

Framework Route Examples

Express.js Route

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' });
  }
});

Next.js App Router

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 });
  }
}

Status Polling Pattern

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');
}

Database Schema

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);

MCP Server Code Generation

Use the PayRam MCP server to generate framework-specific code:

FrameworkMCP Tool
JavaScript SDKgenerate_payment_sdk_snippet
Raw HTTP (any language)generate_payment_http_snippet
Express.jssnippet_express_payment_route
Next.js App Routersnippet_nextjs_payment_route
FastAPIsnippet_fastapi_payment_route
Gin (Go)snippet_gin_payment_route
Laravelsnippet_laravel_payment_route
Spring Bootsnippet_spring_payment_route

Environment Configuration

# .env
PAYRAM_BASE_URL=https://your-payram-server:8080
PAYRAM_API_KEY=your-api-key-here

Use generate_env_template MCP tool to scaffold this.

Error Handling

HTTP CodeMeaningAction
200/201Payment createdRedirect to URL
401Invalid API keyCheck API-Key header (NOT Authorization)
400Invalid requestCheck required fields, amount > 0
404Merchant not foundVerify PAYRAM_BASE_URL
500Server errorRetry with backoff

All PayRam Skills

SkillWhat it covers
payram-setupServer config, API keys, wallet setup, connectivity test
payram-agent-onboardingAgent onboarding — CLI-only deployment for AI agents, no web UI
payram-analyticsAnalytics dashboards, reports, and payment insights via MCP tools
payram-crypto-paymentsArchitecture overview, why PayRam, MCP tools
payram-payment-integrationQuick-start payment integration guide
payram-self-hosted-payment-gatewayDeploy and own your payment infrastructure
payram-checkout-integrationCheckout flow with SDK + HTTP for 6 frameworks
payram-webhook-integrationWebhook handlers for Express, Next.js, FastAPI, Gin, Laravel, Spring Boot
payram-stablecoin-paymentsUSDT/USDC acceptance across EVM chains and Tron
payram-bitcoin-paymentsBTC with HD wallet derivation and mobile signing
payram-payoutsSend crypto payouts and manage referral programs
payram-no-kyc-crypto-paymentsNo-KYC, no-signup, permissionless payment acceptance

Support

Need help? Message the PayRam team on Telegram: @PayRamChat

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Web3

payram-crypto-payments

No summary provided by upstream source.

Repository SourceNeeds Review
Web3

payram-no-kyc-crypto-payments

No summary provided by upstream source.

Repository SourceNeeds Review
Web3

compare-crypto-payments

No summary provided by upstream source.

Repository SourceNeeds Review
General

payram-webhook-integration

No summary provided by upstream source.

Repository SourceNeeds Review