Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.swiftpay.finance/llms.txt

Use this file to discover all available pages before exploring further.

The Hosted Checkout integration redirects users to a SwiftPay-hosted payment page (pay.swiftpay.finance/{invoice_id}). This is the simplest integration method — no frontend UI needed, and full mobile support.

When to Use

  • Minimal frontend work — No custom checkout UI required
  • Mobile-first experiences — Full-screen checkout on any device
  • High conversion — Optimized payment experience
  • Link-based payments — Generate payment links for email, SMS, QR codes
  • Marketplace — Each seller has their own checkout page

How It Works

  1. Create invoice on your backend using the API Client
  2. Generate checkout URLhttps://pay.swiftpay.finance/{invoice_id}
  3. Redirect user — Button, link, QR code, or email
  4. User completes payment — Checkout page handles chain/token selection
  5. Confirmation redirect — User returns to your app

Implementation

Step 1: Create Invoice

Create an invoice on your backend (Node.js example):
import { SwiftPay } from '@swiftpayfi/api-client';

const client = new SwiftPay({
  secretKey: process.env.SWIFTPAY_SECRET_KEY,
});

const { invoice } = await client.invoices.create({
  amount: '100.00',
  token: 'USDC',
  network: 'ethereum',
  recipients: { evm: '0xYourWallet...' },
  externalRef: 'order_12345',
  metadata: {
    userId: 'user_456',
    productId: 'product_789',
  },
});

// Generate checkout URL
const checkoutUrl = `https://pay.swiftpay.finance/${invoice.id}`;

Step 2: Redirect User

Present a button or link to redirect the user:
<a href="https://pay.swiftpay.finance/inv_xxxxxxxxxxxxx" class="btn btn-primary">
  Pay with Stablecoin
</a>
Or in JavaScript:
function openCheckout(invoiceId) {
  window.location.href = `https://pay.swiftpay.finance/${invoiceId}`;
}

Step 3: Handle Callback

Configure a callback URL when creating the invoice to redirect users back after payment:
// Backend (Node.js)
const { invoice } = await client.invoices.create({
  amount: '100.00',
  token: 'USDC',
  network: 'ethereum',
  recipients: { evm: '0xYourWallet...' },
  externalRef: 'order_12345',
  metadata: {
    callbackUrl: 'https://myapp.com/order-confirmation?ref=order_12345',
  },
});

Step 4: Verify Payment

Your backend should verify payment completion via:
  1. Webhooks — SwiftPay notifies your server when payment completes
  2. Polling — Query /invoices/{id}/transactions to check status
  3. Callback redirect — User redirects back with payment confirmed
// Verify payment via API
const invoice = await client.invoices.get(invoiceId);

if (invoice.status === 'paid' || invoice.status === 'completed') {
  // Payment confirmed — fulfill order
  await fulfillOrder(invoice.metadata.externalRef);
}

Session Management

For additional control, use Hosted Checkout Sessions:
// Create a checkout session (optional, for session tracking)
const session = await client.invoices.create({
  amount: '100.00',
  token: 'USDC',
  network: 'ethereum',
  recipients: { evm: '0xYourWallet...' },
  metadata: {
    sessionId: 'session_abc123',
    userId: 'user_456',
  },
});

// Track session in your database
await db.sessions.create({
  sessionId: 'session_abc123',
  invoiceId: session.invoice.id,
  userId: 'user_456',
  status: 'pending',
});

// After user completes payment, update session
await db.sessions.update(invoiceId, { status: 'completed' });

QR Code Payments

Generate a QR code linking to the hosted checkout:
import QRCode from 'qrcode';

async function generatePaymentQR(invoiceId) {
  const checkoutUrl = `https://pay.swiftpay.finance/${invoiceId}`;
  const qrCode = await QRCode.toDataURL(checkoutUrl);
  
  // Display QR code
  document.getElementById('qr').src = qrCode;
}
Use cases:
  • In-store payments — Display QR at register
  • Invoice emails — Include QR in payment invoices
  • Social sharing — Share payment link with QR
  • Print marketing — Physical payment cards/flyers

Email/SMS Payments

Send payment links via email or SMS:
import nodemailer from 'nodemailer';

const transporter = nodemailer.createTransport({/* ... */});

const { invoice } = await client.invoices.create({
  amount: '50.00',
  token: 'USDC',
  network: 'ethereum',
  recipients: { evm: '0xYourWallet...' },
});

await transporter.sendMail({
  to: customer.email,
  subject: 'Payment Required',
  html: `
    <p>Please complete your payment:</p>
    <a href="https://pay.swiftpay.finance/${invoice.id}">
      Click here to pay
    </a>
  `,
});

Marketplace Pattern

Each invoice has its own hosted checkout, making it ideal for marketplaces:
// Multiple sellers, one invoice per seller
const invoice1 = await client.invoices.create({
  amount: '100.00',
  recipients: { evm: seller1.walletAddress },
  metadata: { sellerId: seller1.id },
});

const invoice2 = await client.invoices.create({
  amount: '50.00',
  recipients: { evm: seller2.walletAddress },
  metadata: { sellerId: seller2.id },
});

// Each seller has their own checkout link
const checkoutUrl1 = `https://pay.swiftpay.finance/${invoice1.id}`;
const checkoutUrl2 = `https://pay.swiftpay.finance/${invoice2.id}`;

Best Practices

Customization

While the hosted checkout page is fixed, you can customize the pre-checkout experience with metadata like order items, customer info, etc.

Order Tracking

Store the invoice ID with your order records to correlate payments with orders.

Error Handling

Use webhooks to detect failed payments and retry logic. Some users may close the page without completing payment.

Analytics

Track checkout abandonment by comparing invoices created vs. payments completed.

Webhook Verification

Handle payment notifications securely:
import crypto from 'crypto';

app.post('/webhooks/swiftpay', (req, res) => {
  const signature = req.headers['x-swiftpay-signature'];
  const body = JSON.stringify(req.body);
  
  // Verify signature
  const computed = crypto
    .createHmac('sha256', process.env.WEBHOOK_SECRET)
    .update(body)
    .digest('hex');
  
  if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(computed))) {
    return res.status(401).send('Unauthorized');
  }
  
  // Handle payment
  if (req.body.event === 'invoice.payment.completed') {
    const invoiceId = req.body.data.invoice.id;
    fulfillOrder(invoiceId);
  }
  
  res.json({ ok: true });
});

Comparison

See Integration Options for a comparison of Hosted Checkout vs. other integration methods.