Skip to content

Angular — error handling

The Angular SDK never throws on HTTP errors. Every service call returns an RxJS Observable<PdirectHttpResponse<T>> whose isSuccess flag tells you whether to read data or apiResponseCode/message.

interface PdirectHttpResponse<T> {
data?: T;
message: string;
statusCode: number;
isSuccess: boolean;
apiResponseCode?: PdirectPayApiResponseCode; // LOK000..LOK009
timestamp: Date;
}
FieldNotes
dataParsed response body. Only populated when isSuccess.
messageLocalised, human-readable.
statusCodeHTTP status. 0 for connection-level failures.
isSuccesstrue for 2xx.
apiResponseCodeThe summary classification — see table below.
timestampWhen the SDK observed the response.

<pdirect-pay-checkout> calls (error)="..." with a PdirectPayOnError:

import {
PdirectPayOnError,
PdirectPayApiResponseCode,
} from "@mms/pdirect-pay";
onError(e: PdirectPayOnError) {
switch (e.errorCode) {
case PdirectPayApiResponseCode.LOK003: // auth failed
this.logoutAndRedirect();
break;
case PdirectPayApiResponseCode.LOK005: // insufficient funds
this.toast.error(e.message);
break;
case PdirectPayApiResponseCode.LOK008: // timeout
this.showRetryPrompt(e.message);
break;
default:
this.toast.error(e.message);
}
}

PdirectPayOnError fields:

FieldNotes
messageLocalised.
titleLocalised.
errorCodePdirectPayApiResponseCode?.
identifierOptional gateway identifier.
customerReference, systemReferenceEchoed.
amount, currencyEchoed.
successRedirectUrl, failRedirectUrlEchoed.
timestampDefaults to new Date().
this.payments.createPayment(body).subscribe((res) => {
if (res.isSuccess) {
const txn = res.data?.transactionId;
// happy path
return;
}
// failure path
console.warn(res.statusCode, res.apiResponseCode, res.message);
switch (res.apiResponseCode) {
case PdirectPayApiResponseCode.LOK006: // limit / rate
this.scheduleRetry(res);
break;
case PdirectPayApiResponseCode.LOK009: // service unavailable
this.scheduleRetry(res);
break;
default:
this.toast.error(res.message);
}
});

The service helper PdirectPayApiResponseCodeInfo:

import { PdirectPayApiResponseCodeInfo } from "@mms/pdirect-pay";
PdirectPayApiResponseCodeInfo.getMessage(PdirectPayApiResponseCode.LOK005);
// → "Insufficient funds"
PdirectPayApiResponseCodeInfo.isSuccess(PdirectPayApiResponseCode.LOK000);
// → true
PdirectPayApiResponseCodeInfo.fromString("LOK003");
// → PdirectPayApiResponseCode.LOK003

PdirectPayApiResponseCode collapses the gateway’s four-digit ranges into nine display buckets:

PdirectPayApiResponseCodeTypical gateway codes
LOK000 Success(no error)
LOK001 General error1401, 1403
LOK002 Invalid params11011110
LOK003 Auth failed10011005
LOK004 Method unavailable1205, 1206
LOK005 Insufficient funds1201, 1202
LOK006 Limit exceeded1207, 1301 (rate limit)
LOK007 Network error(client-side classification)
LOK008 Timeout1503
LOK009 Service unavailable1402, 1404

Need the underlying four-digit code? Inspect res.data (when present) — the gateway’s error_code is in the body envelope. See Errors for the envelope and the full code catalogue.

The SDK’s internal handleError maps:

HTTP statusapiResponseCode
200–299LOK000
400LOK002
401, 403LOK003
408LOK008
429LOK006
5xxLOK009
Connection errorLOK007

Invalid session token (LOK003, gateway 1001)

Section titled “Invalid session token (LOK003, gateway 1001)”

The token (the per-checkout session_token your backend minted) is wrong, expired, consumed, or revoked. Sessions are single-use: once /payments/submit succeeds, the session is CONSUMED and any further call on the same token returns 1001.

Fix: mint a fresh session via POST /internal/sessions/create from your merchant backend and pass the new token in. If the base URL is wrong (sandbox token on production), fix the isProduction flag and matching base URL first.

Session-binding drift (LOK002, gateway 1101 / 1102 / 1103)

Section titled “Session-binding drift (LOK002, gateway 1101 / 1102 / 1103)”

The body of /payments/collect carried an amount / currency / customer_reference value that doesn’t match what the session was minted with. This only happens to legacy callers that still send those three fields in the body; new integrations should leave the matching PdirectPaymentBody fields unset and let the SDK omit them.

Fix: either omit the three fields from PdirectPaymentBody, or mint a session whose bound values match what you’re about to send.

Validation failure (LOK002, gateway 11011110)

Section titled “Validation failure (LOK002, gateway 1101–1110)”

A required field is missing or malformed.

Fix: read res.data — the gateway’s envelope contains details: [{ field, message, code }] arrays for field-level errors.

Too many requests. Honour retry_after in the response body and back off.

Fix: exponential backoff. The Angular SDK does not auto-retry — implement it in your code.

Service unavailable (LOK009, gateway 1402)

Section titled “Service unavailable (LOK009, gateway 1402)”

Transient gateway issue. Retry with backoff.

The SDK does not log request bodies or response bodies — only status + URL. This was tightened in v1.2.x to remove a previous console-log-of-app-key issue. Your own application logging should respect the same boundary; never log the raw PdirectHttpResponse in production.