Fixing the Cardstream Direct API type Field Mismatch
Fixing the Cardstream Direct API type Field Mismatch
Release: v1.0.83
Overview
This post documents a spec drift issue discovered in Calmony Pay's Cardstream integration, where a misassigned type field caused all Direct API requests — including card charges and tokenisation — to be silently routed to the wrong Cardstream integration path.
Background: Cardstream's type Field
Cardstream's gateway uses a type parameter to determine which integration flow handles a request:
type=1— Hosted Integration: the customer is redirected to a Cardstream-hosted payment page.type=2— Direct API: a server-to-server call where card data is submitted directly to/direct/without a browser redirect.
Calmony Pay is built on the Direct API path. All charges and card tokenisation are intended to be server-to-server calls, which means every request must carry type=2.
The Contradiction
Two files in the Cardstream integration held conflicting definitions of the type field:
types.ts (correct)
/**
* Integration type.
* 1 = hosted, 2 = direct
*/
type?: string;
The type definition had the right mapping documented in its JSDoc comment.
client.ts (incorrect)
// type=1 = direct (server-to-server)
if (!fields.type) fields.type = "1";
The request() method defaulted type to "1" and labelled this as the Direct (server-to-server) path — directly contradicting both the types.ts JSDoc and the Cardstream specification.
Because this default was applied to every outbound request that didn't explicitly set type, all charge and tokenisation calls were sent with type=1, routing them to the Hosted integration path rather than /direct/.
The Fix
The default in client.ts has been corrected to "2":
// type=2 = direct (server-to-server), type=1 = hosted
if (!fields.type) fields.type = "2";
This aligns client.ts with both the types.ts documentation and the Cardstream Payment Gateway Integration specification, ensuring that all server-to-server requests reach the /direct/ endpoint as intended.
Affected Files
| File | Change |
|---|---|
src/lib/calmony-pay/cardstream/client.ts | Default type corrected from "1" to "2" |
src/lib/calmony-pay/cardstream/types.ts | No code change — JSDoc retained as the authoritative reference |
Who Is Affected
All deployments running v1.0.82 or earlier were affected. Because the incorrect default applied to every request that did not explicitly override the type field, this included all standard charge and tokenisation flows. Upgrading to v1.0.83 resolves the routing issue.
Lessons Learned
This bug arose from a comment in client.ts that inverted the meaning of type=1 relative to the upstream specification and the project's own types.ts. Where an integration's field values are non-obvious, the upstream vendor specification should be treated as the single source of truth — inline comments that redefine vendor semantics create ambiguity that can persist undetected.