> 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-lt/integracija/api-kliento-sdk/naudojant-sdk/java.md).

# Java

Kurti Java mokėjimo integracijas naudojant klientus, užklausų DTO, API kvietimus, klaidų valdymą ir webhook'us.

Naudokite šį gidą, jei jau baigėte [Java greitasis paleidimas](/seb-docs-draft/seb-docs-public-lt/integracija/api-kliento-sdk/greitos-pradzios/java.md) ir norite sukurti pilną integraciją: sukurti klientą, sudaryti užklausos objektus, kviesti API, apdoroti nesėkmes ir gauti **Webhook'ą (dar vadinamą atgalinio iškvietimo pranešimais)**. Kiekvienas žingsnis remiasi ankstesniu. A [pilnas pavyzdys](#complete-example) sujungia juos į vieną.

## 1 žingsnis — Sukurkite klientą

Viskas prasideda nuo `DefaultEgwClientFactory`, sklandaus stiliaus gamyklos, kuri sukuria `EgwClient` iš jūsų ryšio nustatymų. Kiekvienas metodas grąžina gamyklą, todėl konfigūraciją jungiate grandine ir užbaigiate naudodami `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();
```

Gamyklos šablonas egzistuoja tam, kad kliento infrastruktūrą būtų galima pakeisti nekeičiant jūsų programos kodo: `connectingWith(ApiClient)` keičia HTTP klientą (proxy, TLS, laiko limitus), `loggingWith(EgwLogger)` įjungia diagnostiką ir `listeningAt(URI)` įjungia Webhook klausyklą, naudojamą [5 žingsnyje](#step-5--listen-for-webhooks). Konfigūruokite ir kurkite vienoje gijoje — gamykla nėra saugi naudoti keliomis gijomis — tačiau gautas `EgwClient` yra nekintamas ir saugus dalytis visoje jūsų programoje. Sukurkite jį vieną kartą paleidimo metu ir naudokite pakartotinai; jo OAuth prieigos rakto talpykla yra saugi gijoms ir atsinaujina automatiškai.

Gamykla iš bazinio URL nustato OAuth rakto gavimo galinį tašką ir kortelės šifravimo JWK galinį tašką. Jei jūsų diegimas kurį nors iš jų teikia iš kito serverio, perrašykite tik tą vieną naudodami `.tokenEndpoint(URI)` arba `.jwkEndpoint(URI)` bet kurioje grandinės vietoje — tas, kurio nenustatysite, vis tiek bus nustatytas automatiškai.

`EgwClient` yra `AutoCloseable`. `close()` sustabdo „webhook“ klausyklę; jei ją įjungėte, laikykite klientą atidarytą tol, kol norite gauti pranešimus, ir rinkitės try-with-resources arba išjungimo kablį, kad klausyklė būtų tvarkingai atlaisvinta.

## 2 žingsnis — Sudarykite užklausos DTO

Užklausos ir atsakymai yra paprasti duomenų perdavimo objektai (DTO) adresu `...sdk.application.dto`: `InitiateCitPaymentRequest`, `Suma`, `Basket`, ir t. t. Atsakymai pateikia standartinius getterius (`response.getPaymentId()`). Užklausos sudaromos naudojant konstruktorius-kompozitorius (builderius), o jie palaiko tris papildančius modelius.

**Klasikinis kūrimo modelis.** Kiekvienas DTO turi statinį `builder()` metodu; seteriai pavadinti pagal lauką ir grąžina builderį, ir `build()` sukuria DTO:

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

**Įdėtasis lambda kūrėjas.** Kiekvienai savybei, kuri pati yra DTO, kūrėjas taip pat priima `UnaryOperator` virš įdėtinio builderio. Vietoje to, kad kurtumėte `Suma` atskirai, aprašykite jį vietoje — lambda gauna naują įdėtinį builderį ir turi jį grąžinti:

```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();
```

Abu stiliai sukuria identiškus objektus; lambda forma geriausiai tinka giliai įdėtoms užklausoms, o klasikinė forma — kai DTO naudojate pakartotinai skirtingose užklausose. Skaliarinės ir enum savybės (`orderNumber`, `channel`) turi tik klasikinę formą.

**Vieno elemento pridėjimo metodai.** Sąrašo savybės gauna papildomą `<property>Item(...)` metodą, kuris prideda vieną elementą, todėl galite pridėti elementus cikle patys nevaldydami sąrašo:

```java
Basket basket = Basket.builder()
        .itemsItem(BasketItemProduct.builder()
                .name("Meškerė")
                .description("Anglies pluošto meškerė, 2,7 m")
                .price(Amount.builder().amount("100.00").currency("EUR").build())
                .quantity(1)
                .build())
        .subtotalAmount(a -> a.amount("100.00").currency("EUR"))
        .build();
```

Elementų pridėjimo metodai priima visiškai sukurtą elementą — polimorfiniams sąrašams, pvz., krepšelio elementams, pasirinkite konkretų tipą (`BasketItemProduct`, `BasketItemShipping`, `BasketItemDiscount`, `BasketItemTax`).

**Validacija.** `build()` patikrina privalomus laukus ir išmeta `InvalidRequestException` nedelsdamas — trūkstamas `orderNumber` nepraeina jūsų kode kūrimo metu, o ne tampa HTTP 400 atsakymo ciklu. Dėl to užklausas visada turėtumėte kurti per builderius: DTO taip pat turi viešus konstruktorius be argumentų ir seterius, tačiau šis kelias visiškai praleidžia patikrą.

## 3 žingsnis — Kviesti API

`EgwClient` sugrupuoja operacijas į srities prieigos metodus: `payments()`, `refunds()`, `tokens()`, `shops()`, taip pat „checkout-session“ grupės `cardSessions()`, `bankSessions()`, `tokenSessions()`, `clickToPaySessions()`, ir `notifications()` webhook'ams. Kiekvienas prieigos metodas grąžina lengvą API objektą — kvieskite jį vietoje, o ne kaupkite talpykloje.

Kiekviena operacija, kuri priima užklausos kūną, priima arba jau sukurtą DTO, arba tiesiogiai builderio lambda, todėl trumpiems kvietimams nereikia atskiro užklausos kintamojo:

```java
// Su paruoštu DTO:
InitiatePaymentResponse created = client.payments().initiateCitPayment(request);

// Arba su lambda kūrėju vietoje:
CancelPaymentResponse cancelled = client.payments().cancelPayment(
        created.getPaymentId(),
        b -> b.reason(CancelReason.SUSPECTED_FRAUD));
```

Operacijos be kūno priima paprastus argumentus:

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

Įprastas lėšų nuskaičiavimo procesas po to, kai pirkėjas užbaigia atsiskaitymą:

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

Ir grąžinimas, kuris turi atskirą prieigos metodą, nes tai atskiras išteklius su savo ID:

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

Už kiekvieno kvietimo SDK gauna ir kaupia OAuth 2.0 prieigos raktą, nustato unikalų `X-Request-ID` antraštės lauką, serializuoja užklausą ir deserializuoja atsakymą į tipizuotą atsakymo DTO. Įjunkite registravimą naudodami `loggingWith(...)` ir įrašykite `X-Request-ID` kad susietumėte nesėkmingus kvietimus su pagalba — žr. [Klaidų tvarkymas](/seb-docs-draft/seb-docs-public-lt/integracija/api-kliento-sdk/gaires/klaidu-valdymas.md#reading-api-errors).

## 4 žingsnis — Apdorokite išimtis

Visos SDK nesėkmės yra netikrintos išimtys, paveldinčios `ECommException`. Pirmiausia gaudykite konkrečius tipus, su kuriais galite veikti, o kaip apsaugos tinklą naudokite: `ECommException` kaip apsaugos tinklą:

```java
try {
    InitiatePaymentResponse response = client.payments().initiateCitPayment(request);
} catch (InvalidRequestException e) {
    // Kūrimo metu trūko privalomo lauko — pataisykite užklausą kode.
} catch (AuthenticationException e) {
    // Prieigos rakto gavimas arba autorizacija nepavyko — patikrinkite prisijungimo duomenis ir prieigos rakto galinį tašką.
} catch (ConnectionException e) {
    // Perkėlimo klaida (DNS, ryšys atmestas, tinklo klaida).
} catch (ECommException e) {
    // API atmetė kvietimą arba atsakymo nepavyko apdoroti.
}
```

Ką praktiškai reiškia kiekvienas catch blokas:

* `InvalidRequestException` — išmetama `build()` prieš bet kokį tinklo srautą. Tai kodo klaida, o ne vykdymo metu atsirandanti būsena; nėra ką bandyti pakartotinai.
* `AuthenticationException` — nepavyko gauti OAuth prieigos rakto. Patikrinkite kliento ID ir slaptąjį kodą „Merchant Portal“.
* `ConnectionException` — užklausa galėjo pasiekti platformą arba ne. SDK niekada nekartoja užklausos; po ryšio klaidos būseną keičiantį kvietimą patikrinkite mokėjimo būseną naudodami `getPaymentInformation(...)` prieš siųsdami iš naujo. Žr. [Kartojimai, idempotentiškumas, laiko limitai](/seb-docs-draft/seb-docs-public-lt/integracija/api-kliento-sdk/gaires/klaidu-valdymas.md#retries-idempotency-timeouts).
* `ECommException` (bazinis tipas) — HTTP klaidos būsena arba netinkamas naudoti atsakymas. Būsenos kodas rodomas išimties pranešime (pvz., `Kliento klaida atliekant initiateCitPayment: 404`); atsakymo klaidos detalės įrašomos į SDK žurnalą, o ne pridedamos prie išimties, todėl laikykite įjungtą žurnalą, kad galėtumėte diagnozuoti šias klaidas — žr. [API klaidų nuskaitymas](/seb-docs-draft/seb-docs-public-lt/integracija/api-kliento-sdk/gaires/klaidu-valdymas.md#reading-api-errors).

Paskutinio catch nesusiaurinkite iki `ApiException`: HTTP klaidų būsenos pasirodo kaip bazinės `ECommException`, ir `AuthenticationException`/`ConnectionException` yra tos pačios hierarchijos kaip `ApiException`, o ne potemės. Visa hierarchija, įskaitant `SerializationException`, `EncryptionException`, `ApiServerException` ir `EgwBootstrapException`, pateikta [Klaidų tvarkymas](/seb-docs-draft/seb-docs-public-lt/integracija/api-kliento-sdk/gaires/klaidu-valdymas.md).

## 5 žingsnis — Klausykitės webhook'ų

Platforma jus informuoja apie mokėjimo būsenos pokyčius siųsdama POST į jūsų pateiktą galinį tašką. SDK gali paleisti tą galinį tašką už jus: įjunkite klausyklą kliento kūrimo metu su `listeningAt(...)`, tada užregistruokite tvarkyklę per `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);
        // Užsakymą atnaujinkite pagal info.getPaymentStatus() — ne pagal patį pranešimą.
    }
});
```

`receiveNotifications(...)` priima `Consumer<NotificationRequest>` ir grąžina iškart; klausyklė toliau perduoda pranešimus fono gijoje, kol `client.close()`. Pranešime yra `tipas`, `paymentId` ir `paymentStatus` kaip eilutės.

Visada vertinkite pranešimą kaip paleidiklį, o ne kaip tiesą: dabartinė versija netikrina įeinančių webhook iškvietimų autentiškumo, todėl prieš atnaujindami užsakymą iš naujo užklauskite mokėjimo būseną per API. Tai ir perdavimo reikalavimai (įmontuota klausyklė naudoja paprastą HTTP — TLS nutraukite prieš ją) aptariama [Saugumo mechanizmuose](/seb-docs-draft/seb-docs-public-lt/integracija/api-kliento-sdk/gaires/saugumo-mechanizmai.md#webhook-notifications).

Du naudojimo principai padeda išlaikyti klausyklę sveiką: sukonfigūruokite `listeningAt(...)` prieš kviesdami `receiveNotifications(...)` (be to kvietimas dabartiniame leidime nepavyks su `NullPointerException` dabartinėje versijoje), ir užregistruokite lygiai vieną tvarkyklę kiekvienam klientui — išregistravimo nėra, o kviesti `receiveNotifications(...)` du kartus tame pačiame kliente nepalaikoma. Jei jūsų tvarkyklė išmeta išimtį, SDK platformai atsako HTTP 500, o SDK pranešimo neperduoda pakartotinai, todėl tvarkykles laikykite mažas ir greitai patvirtinančias gavimą.

## Pilnas pavyzdys

Minimalus visos eigos pavyzdys — sukurkite klientą, klausykitės pranešimų, inicijuokite mokėjimą ir užfiksuokite jį, kai atsiskaitymas baigiasi:

```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("Payment " + 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("Meškerė, 2,7 m"));

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

            // ... pirkėjas užbaigia atsiskaitymą; rezultatą sužinote per
            // aukščiau pateikta pranešimų tvarkyklė arba periodiškai užklausiant getPaymentInformation(...).

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

            System.out.println("Captured, status: " + captured.getPaymentStatus());

        } catch (ECommException e) {
            System.err.println("Payment flow failed: " + e.getMessage());
        }
    }
}
```

## Kiti žingsniai

* [Klaidų tvarkymas](/seb-docs-draft/seb-docs-public-lt/integracija/api-kliento-sdk/gaires/klaidu-valdymas.md) — visa išimčių hierarchija ir rekomendacijos dėl pakartotinio bandymo.
* [Saugumo mechanizmuose](/seb-docs-draft/seb-docs-public-lt/integracija/api-kliento-sdk/gaires/saugumo-mechanizmai.md) — kortelių šifravimas kortelių atsiskaitymo sesijoms, webhook saugumas.
* [Java greitasis paleidimas](/seb-docs-draft/seb-docs-public-lt/integracija/api-kliento-sdk/greitos-pradzios/java.md) — diegimas, prisijungimo duomenys, žinomi apribojimai.


---

# 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-lt/integracija/api-kliento-sdk/naudojant-sdk/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.
