> 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-et/integratsioon/api-kliendi-sdk/sdk-kasutamine/java.md).

# Java

Looge Java makseintegratsioone klientide, päringu DTO-de, API-kõnede, veakäsitluse ja webhookidega.

Kasutage seda juhendit, kui olete läbinud [Java kiirjuhend](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/kiirstardid/java.md) ja soovite luua täieliku integratsiooni: looge klient, koostage päringuobjektid, kutsuge API-t, käsitlege tõrkeid ja saage **Veebikonksu (nimetatakse ka tagasikutse teavitusteks)**. Iga samm tugineb eelmisele. A [täielik näide](#complete-example) viib need kokku.

## Samm 1 — Looge klient

Kõik algab `DefaultEgwClientFactory`, ladus tehas, mis koostab `EgwClienti` teie ühenduse seadistustest. Iga meetod tagastab tehase, nii et saate seadistust aheldada ja lõpetada käsuga `createEgwClient()`:

```java
import com.tieto.banking.egw.merchantapi.sdk.application.EgwClient;
import com.tieto.banking.egw.merchantapi.sdk.application.bootstrap.DefaultEgwClientFactory;
import java.net.URI;

EgwClient client = new DefaultEgwClientFactory()
        .connectingTo(URI.create("https://sandbox.api.ecommerce.sebgroup.com"))
        .authorizingAs(System.getenv("EGW_CLIENT_ID"), System.getenv("EGW_CLIENT_SECRET"))
        .createEgwClient();
```

Tehasekujundusmuster on olemas selleks, et kliendi infrastruktuur jääks asendatavaks ilma teie rakenduse koodi muutmata: `connectingWith(ApiClient)` asendab HTTP-kliendi (proksi, TLS, ajapiirangud), `loggingWith(EgwLogger)` lisab diagnostika ja `listeningAt(URI)` lubab veebikonksu kuulaja, mida kasutatakse [Samm 5](#step-5--listen-for-webhooks). Konfigureerige ja ehitage see ühes lõimes — tehas ei ole lõimturvaline — kuid saadud `EgwClienti` on muutumatu ja seda on turvaline kogu rakenduses jagada. Looge see korra rakenduse käivitamisel ja kasutage uuesti; selle OAuthi tokeni vahemälu on lõimturvaline ja uuendab end automaatselt.

Tehas tuletab OAuthi tokeni lõpp-punkti ja kaardi krüpteerimise JWK lõpp-punkti baas-URL-ist. Kui teie juurutus serveerib kumbagi teisest hostist, kirjutage üle ainult see üks käsuga `.tokenEndpoint(URI)` või `.jwkEndpoint(URI)` ükskõik kus ahelas — see, mille jätate määramata, tuletatakse ikka.

`EgwClienti` on `AutoCloseable`. `close()` peatab veebikonksu kuulaja; kui olete selle lubanud, hoidke klienti avatuna nii kaua, kui soovite teavitusi vastu võtta, ning eelistage try-with-resources-i või sulgemiskonksu, et kuulaja vabastataks korrektselt.

## Samm 2 — Koostage päringu DTO-d

Päringud ja vastused on lihtsad andmeedastusobjektid (DTO-d) paketis `...sdk.application.dto`: `InitiateCitPaymentRequest`, `Summa`, `Basket`, ja nii edasi. Vastused pakuvad standardseid gettereid (`response.getPaymentId()`). Päringud koostatakse koostajate abil ning koostajad toetavad kolme täiendavat mustrit.

**Klassikaline ehitaja.** Igal DTO-l on staatiline `builder()` meetod; seadistajad on nimetatud välja järgi ja tagastavad koostaja ning `build()` loob DTO:

```java
Amount amount = Amount.builder()
        .amount("100.00")
        .currency("EUR")
        .build();
```

**Pesastatud lambda-builder.** Iga omaduse puhul, mis ise on DTO, aktsepteerib builder ka `UnaryOperator` pesastatud koostaja peal. Selle asemel, et ehitada `Summa` eraldi, kirjeldage seda kohapeal — lambda saab värske pesastatud koostaja ja peab selle tagastama:

```java
InitiateCitPaymentRequest request = InitiateCitPaymentRequest.builder()
        .channel(CitPaymentChannel.BROWSER)
        .instructedAmount(a -> a.amount("100.00").currency("EUR"))
        .orderNumber("ORD-1001")
        .participantId(System.getenv("EGW_PARTICIPANT_ID"))
        .shopAgreementId(System.getenv("EGW_SHOP_AGREEMENT_ID"))
        .shopRedirectUrl("https://shop.example.com/return")
        .build();
```

Mõlemad variandid loovad identsed objektid; lambda-kuju sobib paremini sügavalt pesastatud päringute jaoks, klassikaline kuju aga siis, kui kasutate sama DTO-d päringutes uuesti. Skalaar- ja enum-omadustel (`tellimuse number`, `channel`) on ainult klassikaline kuju.

**Üksikelementide lisajad.** Loendiomadustele lisandub täiendav `<property>Item(...)` meetod, mis lisab ühe elemendi, nii et saate elemente tsüklis lisada ilma loendit ise haldamata:

```java
Basket basket = Basket.builder()
        .itemsItem(BasketItemProduct.builder()
                .name("Fishing rod")
                .description("Carbon fiber rod, 2.7 m")
                .price(Amount.builder().amount("100.00").currency("EUR").build())
                .quantity(1)
                .build())
        .subtotalAmount(a -> a.amount("100.00").currency("EUR"))
        .build();
```

Elemendilisajad võtavad täielikult loodud elemendi — polümorfsete loendite, nagu ostukorvi elemendid, puhul valige konkreetne tüüp (`BasketItemProduct`, `BasketItemShipping`, `BasketItemDiscount`, `BasketItemTax`).

**Valideerimine.** `build()` kontrollib kohustuslikke välju ja viskab `InvalidRequestException` kohe — puuduolev `tellimuse number` kukub teie koodis koostamise ajal läbi, mitte HTTP 400 ringreisina. Seetõttu peaksite päringud alati koostajate kaudu looma: DTO-del on küll ka avalikud parameetriteta konstruktorid ja seadistajad, kuid see tee jätab valideerimise täielikult vahele.

## Samm 3 — Kutsuge API-t

`EgwClienti` rühmitab toimingud domeenipõhisteks pääsuriteks: `payments()`, `refunds()`, `tokens()`, `shops()`, ning lisaks ka checkout-sessioni grupid `cardSessions()`, `bankSessions()`, `tokenSessions()`, `clickToPaySessions()`, ja `notifications()` veebikonksude jaoks. Iga ligipääsumeetod tagastab kergekaalulise API-objekti — kutsuge seda otse, selle asemel et seda vahemällu salvestada.

Iga operatsioon, mis võtab päringukeha, aktsepteerib kas valmis DTO-d või otse koostaja lambda’t, nii et lühikeste väljakutsete jaoks pole vaja eraldi päringu muutujat:

```java
// Valmistatud DTO-ga:
InitiatePaymentResponse created = client.payments().initiateCitPayment(request);

// Või builder-lambdaga otse kohapeal:
CancelPaymentResponse cancelled = client.payments().cancelPayment(
        created.getPaymentId(),
        b -> b.reason(CancelReason.SUSPECTED_FRAUD));
```

Ilma kehana operatsioonid võtavad tavalisi argumente:

```java
PaymentInformationResponse info =
        client.payments().getPaymentInformation(created.getPaymentId(), null);
System.out.println("Staatus: " + info.getPaymentStatus());
```

Tüüpiline capture-vool pärast seda, kui ostja on kassas ostu lõpetanud:

```java
CapturePaymentResponse captured = client.payments().capturePayment(
        created.getPaymentId(),
        b -> b.instructedAmount(a -> a.amount("100.00").currency("EUR")));
```

Ja tagasimakse, mis asub omaette ligipääsujuures, sest see on eraldi ressurss oma ID-ga:

```java
RefundPaymentResponse refund = client.refunds().refundPayment(b -> b
        .paymentId(created.getPaymentId())
        .instructedAmount(a -> a.amount("100.00").currency("EUR")));
```

Iga kutsungi taga hangib SDK OAuth 2.0 juurdepääsutokeni ja salvestab selle vahemällu, seab unikaalse `X-Request-ID` päise, serialiseerib päringu ja deserialiseerib vastuse tüpiseeritud vastuse DTO-ks. Lubage logija kaudu `loggingWith(...)` ja salvestage `X-Request-ID` selleks, et seostada ebaõnnestunud kutsed toega — vt [Vigade käsitlemine](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/juhendid/vigade-kasitlemine.md#reading-api-errors).

## Samm 4 — Käsitlege erindeid

Kõik SDK tõrked on kontrollimata erandid, mis pärinevad klassist `ECommException`. Püüdke kõigepealt kinni konkreetsed tüübid, millega saate midagi ette võtta, ja `ECommException` kasutage turvavõrguna:

```java
try {
    InitiatePaymentResponse response = client.payments().initiateCitPayment(request);
} catch (InvalidRequestException e) {
    // Kohustuslik väli puudus koostamise ajal — parandage päring koodis.
} catch (AuthenticationException e) {
    // Tokeni hankimine või autoriseerimine ebaõnnestus — kontrollige volitusi ja tokeni lõpp-punkti.
} catch (ConnectionException e) {
    // Edastusviga (DNS, ühendusest keeldumine, võrgutõrge).
} catch (ECommException e) {
    // API lükkas kutsungi tagasi või vastust ei õnnestunud töödelda.
}
```

Mida iga catch-plokk praktikas tähendab:

* `InvalidRequestException` — viskab `build()` enne igasugust võrguliiklust. Koodiviga, mitte käitusaja seisund; uuesti proovimiseks pole midagi.
* `AuthenticationException` — OAuthi tokenit ei õnnestunud hankida. Kontrollige Merchant Portalis kliendi ID-d ja saladust.
* `ConnectionException` — päring võis platvormini jõuda, aga ei pruukinud jõuda. SDK ei proovi ühtegi päringut uuesti; pärast ühenduse tõrget olekut muutval kutsungil küsige makse olekut käsuga `getPaymentInformation(...)` enne uuesti saatmist. Vt [Uuesti proovimised, idempotentsus, ajapiirangud](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/juhendid/vigade-kasitlemine.md#retries-idempotency-timeouts).
* `ECommException` (baastüüp) — HTTP-vea staatus või kasutuskõlbmatu vastus. Staatusekood on erandi sõnumis (näiteks `Klientviga initiateCitPayment ajal: 404`); vastuse veaandmed kirjutatakse SDK logijasse, mitte ei lisata erandile, seega hoidke diagnostikaks logija sees — vt [API vigade lugemine](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/juhendid/vigade-kasitlemine.md#reading-api-errors).

Ärge kitsendage oma viimast catch’i klassile `ApiException`: HTTP-vea staatused ilmuvad baasi `ECommException`, ja `AuthenticationException`/`ConnectionException` on klassi `ApiException`õdesed-vennad, mitte alamklassid. Täielik hierarhia, sealhulgas `SerializationException`, `EncryptionException`, `ApiServerException` ja `EgwBootstrapException`, on olemas [Vigade käsitlemine](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/juhendid/vigade-kasitlemine.md).

## Samm 5 — Kuulake veebikonksusid

Platvorm teavitab teid makse oleku muutustest, tehes POST-päringu lõpp-punkti, mille te avalikustate. SDK saab seda lõpp-punkti teie eest käitada: lubage kuulaja kliendi loomisel käsuga `listeningAt(...)`, seejärel registreerige käsitleja kaudu `notifications()`:

```java
EgwClient client = new DefaultEgwClientFactory()
        .connectingTo(URI.create("https://sandbox.api.ecommerce.sebgroup.com"))
        .authorizingAs(System.getenv("EGW_CLIENT_ID"), System.getenv("EGW_CLIENT_SECRET"))
        .listeningAt(URI.create("http://0.0.0.0:8080/egw/notifications"))
        .createEgwClient();

client.notifications().receiveNotifications(notification -> {
    if ("PAYMENT".equals(notification.getType())) {
        PaymentInformationResponse info =
                client.payments().getPaymentInformation(notification.getPaymentId(), null);
        // Uuendage tellimust info.getPaymentStatus()-i põhjal — mitte ainult teate põhjal.
    }
});
```

`receiveNotifications(...)` võtab `Consumer<NotificationRequest>` ja naaseb kohe; kuulaja edastab teateid taustalõimes seni, kuni `client.close()`. Teade kannab `tüüp`, `paymentId` ja `makseolek` stringidena.

Käsitlege teadet alati vallandajana, mitte tõena: praegune versioon ei kontrolli sissetulevate veebikonksukutsete autentsust, seega küsige enne tellimuse uuendamist makse olek API kaudu uuesti. Seda ja transpordinõudeid (sisseehitatud kuulaja kasutab tavalist HTTP-d — lõpetage TLS selle ees) käsitletakse [Turvamehhanismid](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/juhendid/turvamehhanismid.md#webhook-notifications).

Kaks kasutusreeglit hoiavad kuulaja tervena: seadistage `listeningAt(...)` enne kutsumist `receiveNotifications(...)` (ilma selleta kutse ebaõnnestub `NullPointerException` praeguses versioonis), ja registreerige iga kliendi kohta täpselt üks käsitleja — eemaldamist ei ole ning kutsumine `receiveNotifications(...)` sama kliendi puhul kaks korda ei ole toetatud. Kui teie käsitleja viskab vea, vastab SDK platvormile HTTP 500-ga ja SDK ei edasta teadet uuesti, seega hoidke käsitlejad väikesed ja kiirelt kinnitatavad.

## Täielik näide

Minimaalne algusest lõpuni voog — looge klient, kuulake teateid, algatage makse ja võtke see kinni, kui kassaprotsess lõpeb:

```java
import com.tieto.banking.egw.merchantapi.sdk.application.EgwClient;
import com.tieto.banking.egw.merchantapi.sdk.application.bootstrap.DefaultEgwClientFactory;
import com.tieto.banking.egw.merchantapi.sdk.application.dto.*;
import com.tieto.banking.egw.merchantapi.sdk.core.ECommException;
import java.net.URI;

public class EgwIntegration {
    public static void main(String[] args) {
        try (EgwClient client = new DefaultEgwClientFactory()
                .connectingTo(URI.create("https://sandbox.api.ecommerce.sebgroup.com"))
                .authorizingAs(System.getenv("EGW_CLIENT_ID"), System.getenv("EGW_CLIENT_SECRET"))
                .listeningAt(URI.create("http://0.0.0.0:8080/egw/notifications"))
                .createEgwClient()) {

            client.notifications().receiveNotifications(n ->
                    System.out.println("Makse " + n.getPaymentId() + " → " + n.getPaymentStatus()));

            InitiatePaymentResponse created = client.payments().initiateCitPayment(b -> b
                    .channel(CitPaymentChannel.BROWSER)
                    .instructedAmount(a -> a.amount("100.00").currency("EUR"))
                    .orderNumber("ORD-1001")
                    .participantId(System.getenv("EGW_PARTICIPANT_ID"))
                    .shopAgreementId(System.getenv("EGW_SHOP_AGREEMENT_ID"))
                    .shopRedirectUrl("https://shop.example.com/return")
                    .description("Fishing rod, 2.7 m"));

            System.out.println("Makse loodud: " + created.getPaymentId());

            // ... ostja viib kassaprotsessi lõpule; te saate tulemuse teada
            // ülaltoodud teate käsitleja või getPaymentInformation(...)-i pärimise kaudu.

            CapturePaymentResponse captured = client.payments().capturePayment(
                    created.getPaymentId(),
                    b -> b.instructedAmount(a -> a.amount("100.00").currency("EUR")));

            System.out.println("Kinnitatud, staatus: " + captured.getPaymentStatus());

        } catch (ECommException e) {
            System.err.println("Maksevoog ebaõnnestus: " + e.getMessage());
        }
    }
}
```

## Järgmised sammud

* [Vigade käsitlemine](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/juhendid/vigade-kasitlemine.md) — kogu erindite hierarhia ja korduskatsete juhised.
* [Turvamehhanismid](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/juhendid/turvamehhanismid.md) — kaardikrüpteerimine kaardikassasessioonide jaoks, veebikonksu turve.
* [Java kiirjuhend](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/kiirstardid/java.md) — paigaldus, mandaadid, teadaolevad piirangud.


---

# 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-et/integratsioon/api-kliendi-sdk/sdk-kasutamine/java.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.
