@quickpay/node

Server-side Node.js SDK for creating checkout sessions, managing subscriptions, and handling webhooks.

Installation

Terminal
npm install @quickpay/node

Initialization

Initialize the SDK with your server key. Never expose this key in client-side code.

quickpay.ts
import { QuickPay } from '@quickpay/node';

const qp = new QuickPay('sk_live_your_server_key');

Security

Your server key (sk_live_...) grants full API access. Store it in environment variables and never commit it to source control.

Checkout Sessions

checkoutSessions.create()

Create a new checkout session. Returns a session object with an ID and client secret.

create-session.ts
const session = await qp.checkoutSessions.create({
  amount: 99.99,
  currency: 'USD',
  mode: 'embedded',        // 'embedded' | 'hosted'
  paymentType: 'oneTime',  // 'oneTime' | 'subscription'
  successUrl: 'https://yoursite.com/success?session_id={CHECKOUT_SESSION_ID}',
  cancelUrl: 'https://yoursite.com/cancel',
  customer: {
    email: '[email protected]',
    name: 'Jane Doe',
  },
  lineItems: [
    { name: 'Pro Plan', quantity: 1, unitAmount: 99.99 },
  ],
  metadata: {
    orderId: 'order_12345',
  },
});

// session.id — 'cs_live_abc123'
// session.clientSecret — 'cs_live_abc123_secret_xyz789'
// session.url — hosted checkout URL (only for mode: 'hosted')

{CHECKOUT_SESSION_ID} in successUrl or cancelUrl is replaced with the session id. To collect an invoice you already issued, pass invoiceId or invoiceReference instead of an amount and line items:

pay-invoice.ts
const session = await qp.checkoutSessions.create({
  invoiceReference: 'INV-7F3K2Q', // or invoiceId: 7731 — not both
  mode: 'hosted',
  paymentType: 'oneTime',
  successUrl: 'https://yoursite.com/paid?session_id={CHECKOUT_SESSION_ID}',
});
// Amount and currency come from the invoice. Calling this again while that
// session is still open returns the same session.

checkoutSessions.retrieve()

Retrieve an existing checkout session by its ID.

const session = await qp.checkoutSessions.retrieve('cs_live_abc123');

console.log(session.status);       // 'open' | 'complete' | 'expired'
console.log(session.paymentStatus); // 'unpaid' | 'paid' | 'no_payment_required'
console.log(session.amountTotal);   // 99.99

Subscriptions

List subscriptions

const subscriptions = await qp.subscriptions.list({
  customerId: 'cus_abc123',
  status: 'active', // 'active' | 'paused' | 'cancelled' | 'past_due'
  limit: 10,
});

for (const sub of subscriptions.data) {
  console.log(sub.id, sub.plan.name, sub.currentPeriodEnd);
}

Cancel a subscription

const cancelled = await qp.subscriptions.cancel('sub_abc123', {
  cancelAtPeriodEnd: true, // Let the subscription run until the end of the billing period
});

Pause a subscription

const paused = await qp.subscriptions.pause('sub_abc123', {
  resumeAt: '2025-02-01T00:00:00Z', // Optional: auto-resume date
});

Resume a subscription

const resumed = await qp.subscriptions.resume('sub_abc123');

Webhooks

webhooks.constructEvent()

Parse and verify an incoming webhook payload. Throws an error if the signature is invalid.

webhook-handler.ts
import express from 'express';
import { QuickPay } from '@quickpay/node';

const app = express();
const qp = new QuickPay('sk_live_your_server_key');

// Use raw body for signature verification
app.post('/webhooks/quickpay', express.raw({ type: 'application/json' }), (req, res) => {
  let event;

  try {
    event = qp.webhooks.constructEvent(
      req.body,                              // Raw request body
      req.headers['x-webhook-signature'],    // Signature header
      'whsec_your_webhook_secret'            // Your webhook signing secret
    );
  } catch (err) {
    console.error('Webhook signature verification failed:', err.message);
    return res.status(400).send('Invalid signature');
  }

  // Handle the event
  switch (event.type) {
    case 'checkout.session.completed':
      const session = event.data;
      // Fulfill the order
      break;
    case 'payment.succeeded':
      // Record the payment
      break;
    case 'subscription.renewed':
      // Extend access
      break;
    case 'payment.failed':
      // Notify the customer
      break;
  }

  res.json({ received: true });
});

webhooks.verifySignature()

Verify a webhook signature without parsing the payload. Returns a boolean.

const isValid = qp.webhooks.verifySignature(
  rawBody,
  signatureHeader,
  'whsec_your_webhook_secret'
);

if (!isValid) {
  throw new Error('Invalid webhook signature');
}

Tip

Always use the raw request body (not a parsed JSON object) for signature verification. If you're using Express, apply express.raw() middleware to your webhook route.

Error Handling

import { QuickPayError } from '@quickpay/node';

try {
  const session = await qp.checkoutSessions.create({ /* ... */ });
} catch (err) {
  if (err instanceof QuickPayError) {
    console.error(err.type);       // 'invalid_request' | 'authentication' | 'rate_limit'
    console.error(err.code);       // 'amount_too_small'
    console.error(err.message);    // Human-readable message
    console.error(err.statusCode); // HTTP status code
  }
}