> 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/c-.net.md).

# C# / .NET

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

Kasutage seda juhendit, kui olete läbinud [C# kiirjuhend](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/kiirstardid/c-.net.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)**. Üks [täielik näide](#complete-example) koondab sammud kokku.

## Samm 1 — Looge klient

Kõik algab `DefaultEgwClientFactory`, ladus tehas, mis koostab `EgwClienti`. Erinevalt Java ja PHP tehasetest ei tuleta .NET-tehas baas-URL-ist midagi — te seadistate baas-URL-i, tokeni lõpp-punkti ja (kaardi seansside puhul) JWK lõpp-punkti otseselt, suvalises järjekorras:

```csharp
using Egw.Sdk.Application;
using Egw.Sdk.Application.Bootstrap;

using EgwClient client = new DefaultEgwClientFactory()
    .ConnectingTo("https://sandbox.api.ecommerce.sebgroup.com")
    .TokenEndpoint("https://api.ecommerce.sebgroup.com/auth/realms/participants-seb/protocol/openid-connect/token")
    .AuthorizingAs(
        Environment.GetEnvironmentVariable("EGW_CLIENT_ID")!,
        Environment.GetEnvironmentVariable("EGW_CLIENT_SECRET")!)
    .EncryptingWith("https://checkout.ecommerce.sebgroup.com/api/keys/card-encryption.jwk")
    .CreateEgwClient();
```

`ConnectingTo(...)`, `TokenEndpoint(...)` ja `AuthorizingAs(...)` on nõutavad; mõne puudumine põhjustab nurjumise kell `CreateEgwClient()` koos `EgwBootstrapException`. `EncryptingWith(...)` on vajalik ainult kaardi kassaseansside jaoks ja `ListeningOn(uri)` lubab veebikonksu kuulaja, mida kasutatakse [Samm 5](#step-5--listen-for-webhooks).

Tehasekujundus hoiab kliendi infrastruktuuri asendatavana ilma teie rakenduskoodi muutmata: adapterid (HTTP-klient, serialiseerija, krüptija, logija) lahendatakse teenusepakkuja liideste kaudu (`IApiClientProvider`, `IEgwLoggerProvider`, …), mis leitakse koostete skannimise teel, seega asendate ühe, tarnides oma teenusepakkuja — tavapärane tee kohandatud puhverserverite, TLS-materjali või ajalõppude jaoks.

Looge klient käivitamisel üks kord ja taaskasutage seda — seda on turvaline jagada ning selle OAuthi token vahemällu salvestatakse ja värskendatakse automaatselt. `EgwClienti` on `IDisposable`; `Dispose()` peatab veebikonksu kuulaja, seega kui te selle lubasite, hoidke klienti aktiivsena seni, kuni soovite teateid vastu võtta.

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

Päringud ja vastused on andmeedastusobjektid (DTO-d) paketis `Egw.Sdk.Application.Dto`. Need on muutumatud — ainult loetavad omadused, avalik konstruktor puudub — ja neid koostatakse pesastatud `Builder` klass, millele pääseb ligi staatilise `NewBuilder()` meetodi kaudu. Üks nimetamiseripära, mida kohe teada: `amount` välja omadus ja setter on nimetatud `VarAmount` (JSON-väli võrgu kaudu on endiselt `amount`).

**Klassikaline ehitaja.** Setterid on nimetatud omaduse järgi ja tagastavad builderi; `Build()` loob DTO:

```csharp
using Egw.Sdk.Application.Dto;

Amount amount = Amount.NewBuilder()
    .VarAmount("100.00")
    .Currency("EUR")
    .Build();
```

**Pesastatud lambda-builder.** Iga omaduse puhul, mis ise on DTO, aktsepteerib builder ka `Func` üle pesastatud builderi — kirjeldage pesastatud objekt otse kohapeal, selle asemel et see eraldi üles ehitada. Lambda saab värske builderi ja peab selle tagastama:

```csharp
InitiateCitPaymentRequest request = InitiateCitPaymentRequest.NewBuilder()
    .Channel(CitPaymentChannel.BROWSER)
    .InstructedAmount(a => a.VarAmount("100.00").Currency("EUR"))
    .OrderNumber("ORD-1001")
    .ParticipantId(Environment.GetEnvironmentVariable("EGW_PARTICIPANT_ID")!)
    .ShopAgreementId(Environment.GetEnvironmentVariable("EGW_SHOP_AGREEMENT_ID")!)
    .ShopRedirectUrl("https://shop.example.com/return")
    .Build();
```

Mõlemad stiilid toodavad identsed objektid; lambda-kujund sobib kõige paremini pesastatud päringute puhul, klassikaline kujund aga siis, kui taaskasutate DTO-d päringute vahel. Skalaar- ja enum-omadustel on ainult klassikaline vorm.

**Üksikelementide lisajad.** Kogumiomadused saavad täiendava üksikmeetodi, mis lisab ühe elemendi, nii et saate üksusi tsüklis lisada ilma loendit ise haldamata:

```csharp
Basket basket = Basket.NewBuilder()
    .Item(BasketItemProduct.NewBuilder()
        .Name("Fishing rod")
        .Description("Carbon fiber rod, 2.7 m")
        .Price(a => a.VarAmount("100.00").Currency("EUR"))
        .Quantity(1)
        .Build())
    .SubtotalAmount(a => a.VarAmount("100.00").Currency("EUR"))
    .Build();
```

**Valideerimine.** .NET SDK ei kontrolli nõutavaid välju ehitamise ajal — erinevalt Javast, puuduv `OrderNumber` ilmneb serveripoolse HTTP 400-na, mitte kohaliku erindina.

## Samm 3 — Kutsuge API-t

`EgwClienti` rühmitab toimingud domeenipõhisteks pääsuriteks: `Payments()`, `Refunds()`, `Tokens()`, `Shops()`, kassaseansi rühmad `CardSessions()`, `BankSessions()`, `TokenSessions()`, `ClickToPaySessions()`, ja `Notifications()` veebikonksude jaoks. Kõik operatsioonid on asünkroonsed ja kannavad `Async` lõppu — sünkroonseid variante ei ole.

Iga operatsioon võtab argumendiks `Guid` päringu ID esimese argumendina. Looge iga kutse jaoks uus ID ja hoidke seda koos oma tellimuse kirjega — see on teie korrelatsioonivõti toe jaoks.

Päringukeha sisaldavad operatsioonid aktsepteerivad kas valmiskujul DTO-d või otse builder-lambdat:

```csharp
// Valmistatud DTO-ga:
InitiatePaymentResponse created =
    await client.Payments().InitiateCitPaymentAsync(Guid.NewGuid(), request);

// Või builder-lambdaga otse kohapeal:
CancelPaymentResponse cancelled = await client.Payments().CancelPaymentAsync(
    Guid.NewGuid(),
    created.PaymentId!,
    b => b.Reason(CancelReason.SUSPECTEDFRAUD));
```

Seisundi lugemine ja püüdmine pärast kassaprotsessi lõppu:

```csharp
PaymentInformationResponse info = await client.Payments()
    .GetPaymentInformationAsync(Guid.NewGuid(), created.PaymentId!, false);
Console.WriteLine($"Olek: {info.PaymentStatus}");

CapturePaymentResponse captured = await client.Payments().CapturePaymentAsync(
    Guid.NewGuid(),
    created.PaymentId!,
    b => b.InstructedAmount(a => a.VarAmount("100.00").Currency("EUR")));
```

Iga kõne taga hangib SDK OAuth 2.0 juurdepääsumärgi ja salvestab selle vahemällu, seab `X-Request-ID` päise, serialiseerib päringu ja deserialiseerib vastuse tüpiseeritud vastuse DTO-sse.

## Samm 4 — Käsitlege erindeid

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

```csharp
using Egw.Sdk.Core;
using Egw.Sdk.Application.Ports.ApiClient;

try
{
    InitiatePaymentResponse response =
        await client.Payments().InitiateCitPaymentAsync(Guid.NewGuid(), request);
}
catch (AuthenticationException e)
{
    // Tokeni hankimine või autoriseerimine ebaõnnestus — kontrollige volitusi ja tokeni lõpp-punkti.
}
catch (ConnectionException e)
{
    // Edastustõrge. SDK ei proovi kunagi uuesti: pärige makse olekut
    // GetPaymentInformationAsync(...) enne olekut muutva kutse uuesti saatmist.
}
catch (ECommException e)
{
    // API lükkas kõne tagasi (olekukood on sõnumis, nt
    // "Kliendi viga InitiateCitPayment ajal: 400") või vastus
    // ei saanud töödelda.
}
```

HTTP-veakoodid avalduvad baas-erindina `ECommException` koos olekukoodiga sõnumis; API veadetailid kirjutatakse SDK logisse, mitte ei lisata erindile ( `ApiException.StatusCode` ja `ResponseBody` pääsumeetodid on olemas, kuid selles versioonis neid ei täideta). Lubage logija ja korreleerige `X-Request-ID` — vt [API vigade lugemine](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/juhendid/vigade-kasitlemine.md#reading-api-errors). Kogu hierarhia (`SerializationException`, `EncryptionException`, `ApiServerException`, `EgwBootstrapException`, ja ülejäänud) on jaotises [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 `ListeningOn(...)`, seejärel registreerige töötleja:

```csharp
using EgwClient client = new DefaultEgwClientFactory()
    .ConnectingTo("https://sandbox.api.ecommerce.sebgroup.com")
    .TokenEndpoint("https://api.ecommerce.sebgroup.com/auth/realms/participants-seb/protocol/openid-connect/token")
    .AuthorizingAs(clientId, clientSecret)
    .ListeningOn("http://0.0.0.0:8080/egw/notifications")
    .CreateEgwClient();

client.Notifications().ReceiveNotifications(notification =>
{
    // Saabus teade: makse muutis olekut. Praeguses versioonis
    // teate kasulik sisu ei kuva veel ühtegi välja, seega käsitage kohaletoimetamist äratussignaalina
    // signaalina: pärige oma avatud maksed uuesti GetPaymentInformationAsync(...)
    // ning uuendage tellimusi API vastuse põhjal.
});
```

`ReceiveNotifications(...)` võtab argumendiks `Action<NotificationRequest>` ja tagastab kohe; kuulaja jätkab teavituste edastamist taustalõimedel, kuni klient vabastatakse. Kasuliku sisu pääsumeetodid (`tüüp`, `paymentId`, `makseolek`, nagu need edastusel saabuvad, lisatakse hilisemas versioonis — kuni siis on ülaltoodud äratussignaali muster töötav lahendus.

Käsitage teavitust alati käivitajana, mitte tõena: praegune versioon ei kontrolli sissetulevate veebikonksukõnede autentsust, seega kinnitage olek API kaudu enne tellimuse uuendamist. Edastusnõuded (sisseehitatud kuulaja kasutab tavalist HTTP-d — lõpetage TLS selle ees) on käsitletud [Turvamehhanismid](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/juhendid/turvamehhanismid.md#webhook-notifications). Kaks kasutusreeglit: seadistage `ListeningOn(...)` enne kutsumist `ReceiveNotifications(...)` (ilma selleta kutse ebaõnnestub `NullReferenceException` praeguses versioonis), ning registreerige iga kliendi kohta täpselt üks käsitleja — tühistamist ei ole. Kui teie käsitleja viskab erindi, vastab SDK HTTP 500-ga ja SDK ei saada teadet uuesti.

## Täielik näide

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

```csharp
using Egw.Sdk.Application;
using Egw.Sdk.Application.Bootstrap;
using Egw.Sdk.Application.Dto;
using Egw.Sdk.Core;

using EgwClient client = new DefaultEgwClientFactory()
    .ConnectingTo("https://sandbox.api.ecommerce.sebgroup.com")
    .TokenEndpoint("https://api.ecommerce.sebgroup.com/auth/realms/participants-seb/protocol/openid-connect/token")
    .AuthorizingAs(
        Environment.GetEnvironmentVariable("EGW_CLIENT_ID")!,
        Environment.GetEnvironmentVariable("EGW_CLIENT_SECRET")!)
    .ListeningOn("http://0.0.0.0:8080/egw/notifications")
    .CreateEgwClient();

try
{
    client.Notifications().ReceiveNotifications(_ =>
        Console.WriteLine("Teade vastu võetud — kontrollin avatud makseid uuesti.");

    InitiatePaymentResponse created = await client.Payments().InitiateCitPaymentAsync(
        Guid.NewGuid(),
        b => b.Channel(CitPaymentChannel.BROWSER)
              .InstructedAmount(a => a.VarAmount("100.00").Currency("EUR"))
              .OrderNumber("ORD-1001")
              .ParticipantId(Environment.GetEnvironmentVariable("EGW_PARTICIPANT_ID")!)
              .ShopAgreementId(Environment.GetEnvironmentVariable("EGW_SHOP_AGREEMENT_ID")!)
              .ShopRedirectUrl("https://shop.example.com/return")
              .Description("Õngeritv, 2,7 m"));

    Console.WriteLine($"Makse loodud: {created.PaymentId}");

    // ... ostja viib kassaprotsessi lõpule; te saate tulemuse teada
    // ülaltoodud teavituskäsitleja abil või pärides perioodiliselt GetPaymentInformationAsync(...).

    CapturePaymentResponse captured = await client.Payments().CapturePaymentAsync(
        Guid.NewGuid(),
        created.PaymentId!,
        b => b.InstructedAmount(a => a.VarAmount("100.00").Currency("EUR")));

    Console.WriteLine("Kinnitatud.");
}
catch (ECommException e)
{
    Console.Error.WriteLine($"Maksevoog ebaõnnestus: {e.Message}");
}
```

## 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üptimine, veebikonksu turvalisus.
* [C# kiirjuhend](/seb-docs-draft/seb-docs-public-et/integratsioon/api-kliendi-sdk/kiirstardid/c-.net.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/c-.net.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.
