Skip to main content

CardPointe Integration

1. Overview

The Fiserv CardPointe integration has three independent vendor HTTP boundaries:

  • libs/cardpointe-client implements the CardPointe Gateway API and is consumed by the (FISERV, CARDPOINTE) processing adapter.
  • libs/cardpointe-client/.../cardsecure implements CardSecure tokenization as a separate, no-Authorization vendor client used internally by processing.
  • libs/bolt-client and services/card-present implement the Bolt Integrated Terminal API and its Gateway/SDK facade.

These boundaries do not share authentication merely because they share a vendor. The exact activation, certification, and hardware gates are maintained in the root cardpointe-transit-feature-parity.md ledger and the activation runbook.

CoPilot is not part of this public integration surface. libs/copilot-client is a standalone low-level vendor library with no service workflow, controller, persistence, Terraform credential, Gateway OpenAPI path, generated SDK member, or portal UI.

2. Vendor endpoints and authentication

BoundaryHost/pathAuthentication
CardPointe Gateway APISandbox https://fts-uat.cardconnect.com/cardconnect/rest; production https://fts.cardconnect.com/cardconnect/restHTTP Basic from the selected credential profile's username and password; requests carry the profile MID where the vendor operation requires merchid
CardSecureDerived /cardsecure/api/v1 host, or an explicit merchant tokenizer hostNo Authorization header. It shares host and timeout configuration with the Gateway client, not Gateway Basic credentials
Bolt Integrated TerminalSandbox https://bolt-uat.cardpointe.com/api/Every request sends the Terraform-managed BOLT_AUTH_KEY value in Authorization; session-scoped operations additionally send X-CardConnect-SessionKey

BOLT_AUTH_KEY is an integrator secret, not a merchant credential or a UI/request input. Terraform owns the CMEK-protected bolt-auth-key Secret Manager container, card-present accessor grant, and Cloud Run reference to version latest; operators add secret versions out of band. Never print or copy its value into a credential profile, support form, log, request body, or documentation.

CardSecure echo checks reachability only. Gateway credential validation is the documented Basic-auth PUT / request with exactly {"merchid":"<MID>"}; only HTTP 401/403 means invalid credentials. Other status and transport failures propagate instead of being treated as a successful or failed credential proof.

3. Gateway credentials, merchant inquiry, and profiles

CardPointeProcessorCredentials, stored in encrypted typed credential_payload, contains:

data class CardPointeProcessorCredentials(
val merchid: String,
val username: String,
val password: String,
val environment: CardPointeConfig.Environment? = null,
val baseUrl: String? = null,
)

merchid, username, and password are required. baseUrl overrides environment; otherwise the configured environment selects the Gateway host. The adapter factory caches one client/adapter per credential profile, so Basic credentials and merchant routing remain profile-scoped.

CardPointeClient.inquireMerchant(merchid) issues Basic-authenticated GET /inquireMerchant/{merchid} and preserves the vendor's configuration codes as nullable strings. It is deliberately low-level only: there is no Gateway controller or generated SDK operation for direct merchant inquiry.

For a recurring/MIT authorization with valid stored profile metadata, processing sends:

  • profile=<profileid> so CardPointe selects the profile's default account;
  • no account, expiry, or cvv2;
  • the existing recurring stored-credential indicators.

That branch does not detokenize the canonical token before authorization. If profile metadata is absent or invalid, processing retains the existing canonical-token and expiry fallback and omits profile. Expiry sync-back remains best-effort after approval.

CardPointe ACH provider mapping

The public virtual-terminal ACH identity and routing invariant are documented under Management Service. Once that generic route has selected the CardPointe adapter, the provider wire fields are mapped as follows:

Gateway canonical valueCardPointe wire fieldMapping
cardData.cardNumber (DDA/account)accountPass the DDA/account value as the provider account
achAccountType=CHECKING or SAVINGSaccttypeMap to the provider's ECHK or ESAV value
achRoutingNumberbankabaPass the nine-digit ABA routing value
achDescriptionachDescriptionPass the optional description
achEntryCodeachEntryCodePass the optional CCD, PPD, TEL, or WEB code

Provider-shaped values, when needed for diagnostics, must remain placeholders such as <dda>, <routing-number>, and <ECHK-or-ESAV>; never put live bank values in documentation. See the official Fiserv CardPointe Gateway guide for the provider's current ACH field definitions and response behavior.

4. CardSecure and canonical tokenization

The supported direct methods are PAN tokenize, ACH tokenize, encrypted-input tokenize, device/wallet tokenize, and echo. Each sends JSON and deliberately omits Authorization. The two collection track-data tokenization examples remain excluded because the Gateway has no server-side track source.

CardSecure tokens stay behind the canonical vault boundary: public callers use canonical av_tok_… references, not raw provider tokens. Direct CardSecure methods are not exposed through GatewayPayClient, public/internal Gateway OpenAPI, management/processing controllers, or the portal.

5. Bolt card-present flow

Bolt is a cloud-connected attended-terminal rail. The Android/TypeScript/Kotlin Gateway clients call card-present service endpoints; applications never receive BOLT_AUTH_KEY or the Bolt session key.

Provisioning and sessions

  1. Bind the physical HSN to a location. The Gateway resolves the effective CARD_PRESENT credential profile and its CardPointe MID.
  2. Bind verification alone connects with force=true to reclaim a stale vendor session, then disconnects before inserting the binding.
  3. Ordinary payment and device operations connect without force and disconnect in finally.
  4. Vendor terminal reconciliation requires both credentialProfileId and a real online seed hsn. The Gateway opens a normal session to that HSN, calls vendor listTerminals, and never guesses a bound terminal or reuses a cached session key.

Vendor listTerminals and terminalDetails send a merchant-only JSON body while carrying X-CardConnect-SessionKey.

Corrected operation inputs

OperationGateway/SDK inputs
Manual authExisting amount/payment fields plus optional includeCVV
Read cardhsn, amountMinor, optional includeSignature, optional confirmAmount
Read manualhsn, amountMinor, optional includeSignature, optional includeExpirationDate, optional beep
Tip prompthsn, prompt, amountMinor, non-empty numeric tipPercentPresets
Vendor terminal listcredentialProfileId, required seed hsn, optional authorized merchantId

The low-level Terminal JSON encodes audited Boolean flags and delays as strings. Tip presets remain JSON numbers. Current official endpoint versions win over stale collection examples: read-card/read-manual remain /v4, and tip remains /v2.

Terminal/cardholder operations are not automatically retried. Treat UNKNOWN or an indeterminate HTTP 503 as a possibly completed payment: verify through the terminal, CardPointe reporting, or the Gateway transaction list; reverse if necessary; never blindly resubmit.

The compile-backed Android walkthrough is Android Semi-Integrated (Bolt).

6. Audited low-level boundaries

The five audited collections contain 120 request items. Card Account Updater's three-request client surface remains unchanged: PUT /v2/updater, GET /v2/updater, and DELETE /v2/updater. Product activation remains disabled pending authoritative Fiserv schemas and outcome codes.

The CoPilot collection contains 62 examples but 61 unique method/path operations: one token request plus 60 authenticated resource operations. libs/copilot-client implements those contracts as a JSON-preserving, no-auto-replay low-level client. It is not a public or internal Gateway API and is not exposed through GatewayPayClient.