> For the complete documentation index, see [llms.txt](https://docs.ecommerce.seb.ee/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.ecommerce.seb.ee/seb-docs-draft/seb-docs-public-lv/integracija/api-klienta-sdk/sdk-izmantosana/node.js-typescript.md).

# Node.js / TypeScript

Izveidojiet Node.js maksājumu integrācijas ar klientiem, pieprasījuma DTO, API izsaukumiem, kļūdu apstrādi un webhook.

Izmantojiet šo ceļvedi, ja esat pabeidzis [Node.js ātrā sākšana](/seb-docs-draft/seb-docs-public-lv/integracija/api-klienta-sdk/atrie-sakumi/node.js-typescript.md) un vēlaties izveidot pilnu integrāciju: izveidot klientu, sastādīt pieprasījuma objektus, izsaukt API, apstrādāt kļūmes un apstrādāt **Webhook (saukts arī par atpakaļizsaukuma paziņojumiem)**. Pilns [piemērs](#complete-example) saliek soļus kopā.

## 1. solis — izveidojiet klientu

Viss sākas ar `DefaultEgwClientFactory`. Atšķirībā no plūstošajām Java un PHP fabrikām, Node.js fabrika pieņem vienu konfigurācijas objektu un neko neatvasina no bāzes URL — jums skaidri jānorāda bāzes URL, tokena galapunkts un JWK galapunkts:

```ts
import { DefaultEgwClientFactory } from "@tieto/egw-sdk";

const client = new DefaultEgwClientFactory().create({
  baseUri: new URL("https://sandbox.api.ecommerce.sebgroup.com"),
  authentication: {
    tokenEndpoint: new URL("https://api.ecommerce.sebgroup.com/auth/realms/participants-seb/protocol/openid-connect/token"),
    clientId: process.env.EGW_CLIENT_ID!,
    clientSecret: process.env.EGW_CLIENT_SECRET!,
  },
  jwkUri: new URL("https://checkout.ecommerce.sebgroup.com/api/keys/card-encryption.jwk"),
});
```

Fabrikas importēšana automātiski reģistrē noklusējuma adapterus (HTTP klients, serializētājs, šifrētājs, klusais žurnalētājs), tāpēc iepriekš redzamais fragments ir pilnīgs. Lai nomainītu adapteri — parasti tas vajadzīgs noildēm, starpniekserveriem vai žurnalēšanai — izsauciet `registerProvider({...})` *pirms* `create()`; fabrika reģistrētos nodrošinātājus uzņem momentuzņēmumā izveides brīdī. Piekļuve `registerProvider` šobrīd prasa dziļo importu.

Izveidojiet klientu vienu reizi startēšanas laikā un izmantojiet to atkārtoti — OAuth tokens tiek kešots un automātiski atjaunots. Node.js SDK nav klausītāja, ko atbrīvot ([5. solis](#step-5--process-webhooks)); `dispose()` eksistē simetrijas dēļ, bet pašreizējā būvē nav ko apturēt.

## 2. solis — sastādiet pieprasījuma DTO

Pieprasījumi un atbildes ir datu pārsūtīšanas objekti (DTO): nemainīgas klases ar `readonly` īpašībām, kuras nolasa tieši (`response.paymentId`). Katram pieprasījuma DTO ir atbilstoša būvētāja klase, kas pieejama gan kā nosaukts exports (`AmountBuilder`) gan kā statisks aizstājvārds DTO (`new Amount.Builder()`).

**Klasiskais būvētājs.** Iestatītāji ir camelCase, nosaukti pēc īpašības un atgriež būvētāju; `build()` izveido DTO:

```ts
import { Amount } from "@tieto/egw-sdk";

const amount = new Amount.Builder()
  .amount("100.00")
  .currency("EUR")
  .build();
```

**Ligzdots lambda būvētājs.** Katram īpašumam, kas pats ir DTO, būvētājs piedāvā `<property>Builder(...)` variantu, kas pieņem funkciju pār ligzdoto būvētāju — aprakstiet ligzdoto objektu tieši vietā, nevis būvējiet to atsevišķi. Funkcija saņem svaigu būvētāju un tam tas arī jāatgriež:

```ts
import { CitPaymentChannel, InitiateCitPaymentRequest } from "@tieto/egw-sdk";

const request = new InitiateCitPaymentRequest.Builder()
  .channel(CitPaymentChannel.Browser)
  .instructedAmountBuilder((a) => a.amount("100.00").currency("EUR"))
  .orderNumber("ORD-1001")
  .participantId(process.env.EGW_PARTICIPANT_ID!)
  .shopAgreementId(process.env.EGW_SHOP_AGREEMENT_ID!)
  .shopRedirectUrl("https://shop.example.com/return")
  .build();
```

**Viendabīgu vienumu pievienotāji.** Masīva īpašībām ir papildu `<property>Item(...)` metode, kas pievieno vienu elementu, tāpēc varat pievienot vienumus ciklā, pašam nevadot masīvu:

```ts
import { Basket } from "@tieto/egw-sdk";

const basket = new Basket.Builder()
  .itemsItem(rodItem)
  .itemsItem(reelItem)
  .subtotalAmountBuilder((a) => a.amount("100.00").currency("EUR"))
  .build();
```

**Validācija.** Node.js SDK būvēšanas laikā nepārbauda obligātos laukus — atšķirībā no Java, būvētājs mierīgi izveido objektu ar nedefinētiem obligātajiem laukiem, un kļūda parādās kā HTTP 400 no servera puses.

## 3. solis — izsauciet API

Darbības ir sagrupētas pēc domēna un pieejamas caur piekļuves metodēm klientā: `client.payments()`, `client.refunds()`, `client.tokens()`, `client.shop()`, un checkout sesiju grupas `client.cardSessions()`, `client.bankSessions()`, `client.tokenSessions()`, `client.clickToPaySessions()`.

```ts
import { randomUUID } from "node:crypto";

const payments = client.payments();
```

Visas darbības ir `async` un kā pirmo argumentu pieņem pieprasījuma ID virkni. Ģenerējiet to katram izsaukumam un saglabājiet kopā ar savu pasūtījuma ierakstu — tas ir jūsu korelācijas rīks atbalstam.

Darbībām ar pieprasījuma ķermeni ir divas formas: `<operation>(...)` kas pieņem gatavu DTO, un `<operation>WithBuilder(...)` kas pieņem funkciju pār pieprasījuma būvētāju:

```ts
// Ar sagatavotu DTO:
const created = await payments.initiateCitPayment(randomUUID(), request);

// Vai ar būvētāja funkciju tieši vietā (CancelReason enum ietekmē
// atvērtās enum serializācijas kļūda, tāpat kā visi enum pa vadu):
const cancelled = await payments.cancelPaymentWithBuilder(
  randomUUID(),
  created.paymentId!,
  (b) => b.reason(CancelReason.SuspectedFraud)
);
```

Stāvokļa nolasīšana un maksājuma ieturēšana pēc norēķinu pabeigšanas:

```ts
const info = await payments.getPaymentInformation(randomUUID(), created.paymentId!);
console.log("Statuss:", info.paymentStatus);

const captured = await payments.capturePaymentWithBuilder(
  randomUUID(),
  created.paymentId!,
  (b) => b.instructedAmountBuilder((a) => a.amount("100.00").currency("EUR"))
);
```

Aiz katra izsaukuma SDK iegūst un kešo OAuth 2.0 piekļuves tokenu, iestata `X-Request-ID` galveni, serializē pieprasījumu un deserializē atbildi tipizētā atbildes DTO.

## 4. solis — Apstrādājiet kļūdas

Visas SDK kļūmes manto `ECommException`, kas paplašina `Error` un iestata `name` uz konkrētās klases nosaukumu — `"AuthenticationException"`, `"ConnectionException"`, un tā tālāk — ar pamatkļūdu sadaļā `cause`. Izņēmumu klases šajā būvē nav eksportētas no pakotnes saknes, tāpēc atzarojiet pēc `name` nevis pēc `instanceof`:

```ts
try {
  const created = await payments.initiateCitPayment(randomUUID(), request);
} catch (e) {
  if (e instanceof Error) {
    switch (e.name) {
      case "AuthenticationException":
        // Tokena izgūšana neizdevās — pārbaudiet akreditācijas datus un tokena galapunktu.
        break;
      case "ConnectionException":
        // Transporta kļūme. SDK nekad nemēģina atkārtoti: pārbaudiet maksājuma stāvokli
        // ar getPaymentInformation() pirms atkārtotas ar stāvokli saistītas izsaukuma nosūtīšanas.
        break;
      default:
        // ECommException: API noraidīja izsaukumu (statusa kods ir
        // ziņojumā, piem. "Klienta kļūda initiateCitPayment laikā: 400") vai
        // atbildi nevarēja apstrādāt.
        break;
    }
  }
}
```

API kļūdu detaļas šajā būvē nav pievienotas kļūdai — iespējojiet žurnalētāju ar `registerProvider` un korelējiet pēc `X-Request-ID`; skatiet [API kļūdu lasīšana](/seb-docs-draft/seb-docs-public-lv/integracija/api-klienta-sdk/celvezi/kludu-apstrade.md#reading-api-errors). Pilnā hierarhija ir [Kļūdu apstrāde](/seb-docs-draft/seb-docs-public-lv/integracija/api-klienta-sdk/celvezi/kludu-apstrade.md).

## 5. solis — Apstrādājiet Webhook paziņojumus

Platforma paziņo par maksājuma stāvokļa izmaiņām, nosūtot POST uz jūsu piedāvātu galapunktu. Atšķirībā no Java, PHP un C# SDK, Node.js SDK nesāk klausītāju — HTTP galapunktu palaižat paši (vai atkārtoti izmantojat savu esošo Express/Fastify lietotni) un izmantojat `parseWebhook()` lai deserializētu ielādi:

```ts
import { createServer } from "node:http";

interface PaymentNotification {
  type: string;
  paymentId: string;
  paymentStatus: string;
}

const notifications = client.notifications();

createServer((req, res) => {
  const chunks: Buffer[] = [];
  req.on("data", (c) => chunks.push(c));
  req.on("end", async () => {
    res.writeHead(200).end(); // vispirms apstipriniet, dariet darbu pēc tam

    const n = notifications.parseWebhook<PaymentNotification>(Buffer.concat(chunks));
    if (n.type === "PAYMENT") {
      const info = await payments.getPaymentInformation(randomUUID(), n.paymentId);
      // Atjauniniet pasūtījumu, pamatojoties uz info.paymentStatus — nevis tikai uz paziņojumu.
    }
  });
}).listen(8080);
```

`parseWebhook<T>()` ir vispārīgs — jūs definējat ielādes formu, kā ar `PaymentNotification` iepriekš. Paziņojuma ielādes līgums (kanoniskais lauku saraksts un notikumu tipi): **\[TBC — saite]**

Vienmēr uztveriet paziņojumu kā trigeri, nevis kā patiesību: pašreizējā būvē netiek pārbaudīta ienākošo webhook izsaukumu autentiskums, tāpēc pirms pasūtījuma atjaunināšanas atkārtoti pieprasiet maksājuma stāvokli caur API. Nodrošiniet galapunktu zem TLS. Abi punkti ir apskatīti [Drošības mehānika](/seb-docs-draft/seb-docs-public-lv/integracija/api-klienta-sdk/celvezi/drosibas-mehanismi.md#webhook-notifications).

## Pilns piemērs

Minimāla end-to-end plūsma — izveidojiet klientu, publicējiet webhook galapunktu, iniciējiet maksājumu un iekasējiet to, tiklīdz norēķināšanās ir pabeigta:

```ts
import { DefaultEgwClientFactory, CitPaymentChannel } from "@tieto/egw-sdk";
import { createServer } from "node:http";
import { randomUUID } from "node:crypto";

const client = new DefaultEgwClientFactory().create({
  baseUri: new URL("https://sandbox.api.ecommerce.sebgroup.com"),
  authentication: {
    tokenEndpoint: new URL("https://api.ecommerce.sebgroup.com/auth/realms/participants-seb/protocol/openid-connect/token"),
    clientId: process.env.EGW_CLIENT_ID!,
    clientSecret: process.env.EGW_CLIENT_SECRET!,
  },
  jwkUri: new URL("https://checkout.ecommerce.sebgroup.com/api/keys/card-encryption.jwk"),
});

const payments = client.payments();
const notifications = client.notifications();

createServer((req, res) => {
  const chunks: Buffer[] = [];
  req.on("data", (c) => chunks.push(c));
  req.on("end", () => {
    res.writeHead(200).end();
    const n = notifications.parseWebhook<{ paymentId: string; paymentStatus: string }>(
      Buffer.concat(chunks)
    );
    console.log(`Maksājums ${n.paymentId} → ${n.paymentStatus}`);
  });
}).listen(8080);

try {
  const created = await payments.initiateCitPaymentWithBuilder(randomUUID(), (b) =>
    b.channel(CitPaymentChannel.Browser) // ietekmē atvērtā enum kļūda
     .instructedAmountBuilder((a) => a.amount("100.00").currency("EUR"))
     .orderNumber("ORD-1001")
     .participantId(process.env.EGW_PARTICIPANT_ID!)
     .shopAgreementId(process.env.EGW_SHOP_AGREEMENT_ID!)
     .shopRedirectUrl("https://shop.example.com/return")
     .description("Makšķeres kāts, 2,7 m")
  );
  console.log("Maksājums izveidots:", created.paymentId);

  // ... pircējs pabeidz norēķinus; rezultātu uzzināsiet, izmantojot
  // webhook galapunkts iepriekš vai aptaujājot getPaymentInformation().

  const captured = await payments.capturePaymentWithBuilder(
    randomUUID(),
    created.paymentId!,
    (b) => b.instructedAmountBuilder((a) => a.amount("100.00").currency("EUR"))
  );
  console.log("Iekasēts.");
} catch (e) {
  console.error("Maksājuma plūsma neizdevās:", e instanceof Error ? e.message : e);
}
```

## Nākamie soļi

* [Kļūdu apstrāde](/seb-docs-draft/seb-docs-public-lv/integracija/api-klienta-sdk/celvezi/kludu-apstrade.md) — pilnu izņēmumu hierarhiju un atkārtotas mēģināšanas norādes.
* [Drošības mehānika](/seb-docs-draft/seb-docs-public-lv/integracija/api-klienta-sdk/celvezi/drosibas-mehanismi.md) — karšu šifrēšanu un webhook drošību.
* [Node.js ātrā sākšana](/seb-docs-draft/seb-docs-public-lv/integracija/api-klienta-sdk/atrie-sakumi/node.js-typescript.md) — instalēšanu, akreditācijas datus un zināmos ierobežojumus.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.ecommerce.seb.ee/seb-docs-draft/seb-docs-public-lv/integracija/api-klienta-sdk/sdk-izmantosana/node.js-typescript.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
