All Docs
FeaturesCalmony PayUpdated March 15, 2026

v1.0.98: Restoring SDK Contract — Invoice Method Spec Drift

v1.0.98: Restoring SDK Contract — Invoice Method Spec Drift

Type: Spec drift correction
Affected component: Calmony Pay SDK Client — invoices namespace
Affected file: src/lib/calmony-pay/client.ts

What Happened

The Calmony Pay SDK Client Interface has a pinned specification that defines the exact public surface of the SDK. For invoice operations, the spec is unambiguous — four methods and four methods only:

invoices.create
invoices.retrieve
invoices.list
invoices.downloadPdf

In practice, the SDK had grown to expose eight invoice methods:

invoices.create        ✅ In spec
invoices.retrieve      ✅ In spec
invoices.list          ✅ In spec
invoices.downloadPdf   ✅ In spec
invoices.update        ❌ Not in spec
invoices.finalize      ❌ Not in spec
invoices.pay           ❌ Not in spec
invoices.voidInvoice   ❌ Not in spec

The four extra methods were not part of the agreed SDK Client Interface and represent a deviation from the pinned specification. invoices.update was the primary flagged deviation.

Why This Matters

The SDK Client Interface specification exists to guarantee a stable, predictable contract between Calmony Pay and the products built on top of it across the SaaS Factory. When methods exist outside the spec:

  • Consumers may depend on undocumented behaviour that could be removed or changed without a versioned guarantee.
  • The spec loses authority — if the implementation diverges silently, the spec can no longer be trusted as the source of truth.
  • Cross-product consistency breaks down — other Factory products integrating the SDK may call methods that won't exist in a spec-compliant build.

What Changed in v1.0.98

The invoices namespace in src/lib/calmony-pay/client.ts has been brought back into alignment with the pinned spec. The public SDK surface for invoices is now exactly:

// Create a new invoice
const invoice = await client.invoices.create({ customerId, items });

// Retrieve an existing invoice by ID
const invoice = await client.invoices.retrieve(invoiceId);

// List invoices with optional filters
const { data } = await client.invoices.list({ customerId, status });

// Download a PDF of a finalised invoice
const pdfBuffer = await client.invoices.downloadPdf(invoiceId);

No other invoice methods are exposed on the public client interface.

If You Were Using Out-of-Spec Methods

If your integration was calling invoices.update, invoices.finalize, invoices.pay, or invoices.voidInvoice directly, these are no longer available through the SDK client. You have two options:

  1. Use the Cardstream API directly for any operations not covered by the four spec methods.
  2. Raise a spec change request if you believe one of these methods should be formally added to the pinned SDK Client Interface — this keeps the process transparent and version-controlled.

The Four Supported Invoice Methods

invoices.create(params)

Creates a new invoice. Typically used before or alongside a payment intent for subscription or usage-based billing.

invoices.retrieve(invoiceId)

Fetches a single invoice by its ID. Returns full invoice detail including line items, status, and amounts.

invoices.list(params?)

Lists invoices with optional filtering (e.g. by customer, status, or date range). Returns a paginated response.

invoices.downloadPdf(invoiceId)

Generates and returns a PDF representation of the invoice, suitable for sending to customers or storing for accounting purposes.