TypeScript SDK
GatewayPayClient targets the payment domain for checkout and machine
integrations; GatewayAdminClient targets the management domain for your own
organization's customers, subscriptions, catalog, reports and webhooks.
Server authentication
import { GatewayPayClient } from '@peakgateway/sdk'
const pay = new GatewayPayClient({
environment: 'staging',
clientId: process.env.GATEWAY_CLIENT_ID,
clientSecret: process.env.GATEWAY_CLIENT_SECRET,
})
Keep client secrets on your server. For a browser with an authorized user
session, supply a tokenProvider to GatewayAdminClient rather than embedding
machine credentials. Use Authentication for scopes and
Organizations and Locations
for tenant binding. Tokens do not grant access beyond their authorized scope.
Choose the right flow
- Hosted checkout keeps card entry on Gateway's
checkout surface; use the returned
checkoutUrl. - Elements card setup saves a payment method using the dedicated browser SDK, not a raw card payload in this SDK.
- Wallets use
pay.walletand the approved organization/route capability. - Gift cards and tax describe POS integration constraints.
- Webhook event operations explain replay versus a single delivery retry.
Durable checkout creation
pay.checkoutSessions.create(request, idempotencyKey) requires a nonblank key
of at most 64 characters. Persist the key, original location and request before
dispatch. After a lost response, use
pay.checkoutSessions.getByKey(idempotencyKey, locationId) with authenticated
server credentials to recover the existing session's current state.
The authenticated organization, location and key identify the durable create.
Gateway freezes the original request fingerprint: identical input replays the
session before mutable capability, policy or tax validation; changed input
under that identity returns HTTP 409. Replay never reprices or reopens a
terminal session. A lookup NotFoundError means no session was committed at
that read, not that a delayed original request cannot commit. Network,
authorization and contract errors do not establish absence. Any recovery retry
must preserve the original key and body; only a genuinely new business attempt
uses a new persisted identity.
Existing identities at cutover
The permanent identity guarantee covers newly durable creates and retained
legacy success entries adopted at cutover. A retained legacy success is
verified against its old sanitized request hash and the persisted session's
canonical owner, then adopts the original session ID. Adoption freezes the
current full typed request fingerprint for subsequent retries; it does not
prove the original full body, because the old hash excluded fields such as
expiresIn and scrubbed metadata. A legacy-equivalent first adoption returns
the unchanged original session; later changed fingerprints return HTTP 409.
Legacy in-progress entries fail closed rather than starting a new create.
Already-purged pre-cutover cache entries contain no retained key identity and cannot be reconstructed from the key alone. Operators must census and fence in-flight legacy attempts during rollout. Do not treat lookup absence for such an attempt as permission to create another payable session.
Errors and retries
Handle AuthenticationError, RateLimitError, NetworkError, ServerError,
ValidationError, and NotFoundError without logging credentials or raw
payment payloads. Transaction results are discriminated by kind; only an
explicit approved result is approval. A timeout or unknown outcome may have
committed remotely and needs reconciliation, not a new payment.
The transport has a whole-request readTimeoutMs deadline. Generic retry
settings are not a promise that every POST is safe to repeat: individual
non-idempotent operations disable retries. Preserve the original operation's
idempotency identity when the API permits a retry; never generate a new key to
investigate an unknown outcome. Use the installed SDK types and
API reference for request fields.
INTERNAL_STATE_ERROR is a server-side invariant failure (HTTP 500). The SDK
preserves its gatewayErrorCode on ServerError and does not retry it, including
text and blob requests. It does not establish that a payment was unexecuted;
look up or reconcile the outcome before considering a manual retry. Genuine
state conflicts remain HTTP 409.
Webhook verification
Verify the original raw request body with WebhookVerifier.verifyDelivery and
X-Gateway-Signature / X-Gateway-Timestamp before acting. Do not parse and
reserialize the body before verification. The returned delivery includes the
decoded event and optional correlation ID; retain safe IDs for support and
make receiver processing idempotent.
The event is a WebhookEvent: one <Name>Event member per Gateway event type
(payment.completed → PaymentCompletedEvent), discriminated on eventType,
or an UnknownWebhookEvent carrying the whole body in raw for an event type
newer than the SDK. Call isKnownWebhookEvent(event) before switching on
eventType; parseWebhookEvent types an already-verified parsed body.