Skip to content

TypeScript SDK ​

Use the FinCobra TypeScript SDK when you want a typed server-side client for the Checkout API.

The SDK covers the standard hosted checkout integration:

  • Create checkout sessions and invoices
  • Fetch invoice detail and payment status
  • Verify webhook signatures
  • Use exported TypeScript types for invoices, payment status, and webhook events

Install from GitHub until the package is published to npm:

bash
npm install github:dexstandard/fincobra-sdk

Source: dexstandard/fincobra-sdk

Client setup ​

Create the client on your server. Never expose the FinCobra API key or webhook signing secret in browser code.

ts
import { createFinCobraClient } from '@fincobra/sdk';

const fincobra = createFinCobraClient({
  apiKey: process.env.FINCOBRA_API_KEY,
});

The SDK defaults to https://fincobra.com.

Create checkout ​

checkoutSessions.create creates a hosted checkout invoice and returns paymentUrl.

ts
const session = await fincobra.checkoutSessions.create({
  amountUsd: 49.99,
  productName: 'Pro Plan - Monthly',
  merchantReference: 'order_123',
  customerEmail: '[email protected]',
  redirectUrl: 'https://example.com/account/billing',
  metadata: {
    orderId: 'order_123',
  },
});

return Response.redirect(session.paymentUrl);

Create invoice ​

ts
const invoice = await fincobra.invoices.create({
  amountUsd: 25,
  productName: 'One-time setup',
  customerEmail: '[email protected]',
});

Read payment status ​

ts
const payment = await fincobra.payments.get(
  'a1b2c3d4-1111-4222-8333-abcdefabcdef',
);

if (payment.status === 'confirmed') {
  // fulfill the order
}

You can also call fincobra.invoices.get(id) for full invoice detail or fincobra.invoices.getStatus(id) for the same status payload as payments.get(id).

Next.js example ​

ts
import { createFinCobraClient } from '@fincobra/sdk';
import { NextResponse } from 'next/server';

const fincobra = createFinCobraClient({
  apiKey: process.env.FINCOBRA_API_KEY,
});

export async function POST() {
  const invoice = await fincobra.checkoutSessions.create({
    amountUsd: 49.99,
    productName: 'Pro Plan - Monthly',
    merchantReference: 'order_123',
    customerEmail: '[email protected]',
    redirectUrl: 'https://example.com/account/billing',
    metadata: {
      orderId: 'order_123',
    },
  });

  return NextResponse.json({
    invoiceId: invoice.id,
    paymentUrl: invoice.paymentUrl,
  });
}

Express example ​

ts
import express from 'express';
import { createFinCobraClient } from '@fincobra/sdk';

const app = express();
app.use(express.json());

const fincobra = createFinCobraClient({
  apiKey: process.env.FINCOBRA_API_KEY,
});

app.post('/checkout', async (req, res, next) => {
  try {
    const invoice = await fincobra.invoices.create({
      amountUsd: Number(req.body.amountUsd),
      productName: String(req.body.productName),
      merchantReference: String(req.body.orderId),
      customerEmail:
        typeof req.body.customerEmail === 'string'
          ? req.body.customerEmail
          : undefined,
      metadata: {
        orderId: String(req.body.orderId),
      },
    });

    res.status(201).json({
      invoiceId: invoice.id,
      paymentUrl: invoice.paymentUrl,
    });
  } catch (err: unknown) {
    next(err);
  }
});

Webhook handler example ​

Configure this route with the raw request body. Verify the signature before processing the event, then fetch the latest invoice state before fulfilling an order.

ts
import express from 'express';
import { createFinCobraClient } from '@fincobra/sdk';

const app = express();
const fincobra = createFinCobraClient({
  apiKey: process.env.FINCOBRA_API_KEY,
});

app.post(
  '/webhooks/fincobra',
  express.raw({ type: 'application/json' }),
  async (req, res, next) => {
    try {
      const event = fincobra.webhooks.verifySignature({
        body: req.body,
        signature: req.header('X-Checkout-Signature'),
        secret: process.env.FINCOBRA_WEBHOOK_SECRET ?? '',
      });

      const invoice = await fincobra.invoices.get(event.invoice.id);
      if (
        invoice.status === 'confirmed' ||
        invoice.status === 'paid_out_of_band'
      ) {
        await markOrderPaid(invoice.merchantReference, invoice.id);
      }

      res.sendStatus(204);
    } catch (err: unknown) {
      next(err);
    }
  },
);

Error handling ​

All SDK errors extend FinCobraError. API responses with { "error": "message" } become FinCobraApiError with statusCode, responseBody, and a clear message.

ts
import { FinCobraApiError } from '@fincobra/sdk';

try {
  await fincobra.invoices.create({ amountUsd: 49.99 });
} catch (err: unknown) {
  if (err instanceof FinCobraApiError) {
    err.statusCode;
    err.message;
  }

  throw err;
}

For endpoint contracts and field definitions, see the API Reference.