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 —invoicesnamespace
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:
- Use the Cardstream API directly for any operations not covered by the four spec methods.
- 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.