# Node.js SDK (/uk/online/integration/node_sdk)



`@tapayadot/checkout` є серверним TypeScript SDK для Tapaya Checkout. Цей довідник описує версію **0.3.0**.

| Параметр                 | Значення                                                                                       |
| ------------------------ | ---------------------------------------------------------------------------------------------- |
| **Пакет**                | `@tapayadot/checkout`                                                                          |
| **Версія**               | 0.3.0                                                                                          |
| **Середовище виконання** | Node.js 22.13.0 або новіша версія, ES-модулі, декларації TypeScript включено                   |
| **Браузерний скрипт**    | Tapaya.js 0.2.0, завантажується для [Embedded Checkout](/online/integration/embedded_checkout) |
| **Вихідний код**         | [tapayadot/checkout-node](https://github.com/tapayadot/checkout-node)                          |

<CodeBlockTabs defaultValue="npm" groupId="package-manager">
  <CodeBlockTabsList>
    <CodeBlockTabsTrigger value="npm">
      npm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="pnpm">
      pnpm
    </CodeBlockTabsTrigger>

    <CodeBlockTabsTrigger value="bun">
      Bun
    </CodeBlockTabsTrigger>
  </CodeBlockTabsList>

  <CodeBlockTab value="npm">
    ```sh
    npm install @tapayadot/checkout
    ```
  </CodeBlockTab>

  <CodeBlockTab value="pnpm">
    ```sh
    pnpm add @tapayadot/checkout
    ```
  </CodeBlockTab>

  <CodeBlockTab value="bun">
    ```sh
    bun add @tapayadot/checkout
    ```
  </CodeBlockTab>
</CodeBlockTabs>

```ts
import { Tapaya } from '@tapayadot/checkout';

const tapaya = new Tapaya();
```

Клієнт зчитує `TAPAYA_SECRET_KEY` із серверного середовища. Пакет також містить браузерний завантажувач і React-хук для [Embedded Checkout](/online/integration/embedded_checkout). Завантажувач отримує Tapaya.js **0.2.0** з `https://js.tapaya.com/checkout/0.2.0/checkout.js`; версія браузерного скрипта не залежить від версії цього пакета. Файли `.env` він не завантажує. Тримайте ключ і клієнт лише в серверному коді. [Посібник з Hosted Checkout](/online/integration/hosted_checkout) описує створення замовлення, переспрямування клієнта та перевірку платежу.

## Конфігурація [#configuration]

```ts
const tapaya = new Tapaya(apiKey, {
	environment: 'sandbox',
	timeoutMs: 30_000,
	maxRetries: 2,
})
```

| Параметр                   | Типове значення                                                                               | Опис                                                                                                                                                                                                                           |
| -------------------------- | --------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `apiKey` (перший аргумент) | `TAPAYA_SECRET_KEY`                                                                           | Checkout-ключ мерчанта або Secret key організації в режимі платформи.                                                                                                                                                          |
| `environment`              | `TAPAYA_ENVIRONMENT`, далі `production` для ключа `tapaya_live_` і `sandbox` в інших випадках | `sandbox` (`https://api.sandbox.tapaya.com`) або `production` (`https://api.tapaya.com`). Ключ робочого режиму поза робочим середовищем або тестовий ключ у робочому середовищі спричиняють виняток під час створення клієнта. |
| `baseUrl`                  | `TAPAYA_BASE_URL`, далі URL, вибраний через `environment`                                     | Перевизначає URL API для викликів Hosted і Embedded Checkout.                                                                                                                                                                  |
| `timeoutMs`                | `30000`                                                                                       | Тайм-аут для кожної спроби в мілісекундах.                                                                                                                                                                                     |
| `merchantToken`            | Немає                                                                                         | Токен мерчанта, що надсилається як `X-Tapaya-Merchant-Token`. Обов'язковий у режимі платформи.                                                                                                                                 |
| `maxRetries`               | `2`                                                                                           | Повторні спроби після мережевої помилки, тайм-ауту, HTTP 429, 502, 503 або 504 чи створення, яке ще триває.                                                                                                                    |
| `fetch`                    | Глобальний `fetch`                                                                            | Власна реалізація `fetch`, наприклад для додавання проксі чи інструментування.                                                                                                                                                 |

Щоб використовувати власний ендпоінт API, задайте на своєму сервері `TAPAYA_BASE_URL=https://api.example.com`.
Явно заданий `baseUrl` має пріоритет над `TAPAYA_BASE_URL`; обидва перевизначають вибір середовища.

Клієнт визначає API-ключ і URL API один раз, під час створення. Використовуйте ключ, що відповідає
вибраному середовищу. URL API, повернення та Hosted Checkout мають використовувати HTTPS, за винятком того, що HTTP дозволено для
`localhost`, `127.0.0.1` і `[::1]` поза `NODE_ENV=production`. SDK перевіряє поточне значення `NODE_ENV` щоразу,
коли валідує локальний HTTP URL.

`timeoutMs` має бути цілим числом від 1 до 2 147 483 647. `maxRetries` має бути невід'ємним безпечним цілим числом. Типова кількість повторних спроб дає до трьох спроб на виклик, кожна з власним тайм-аутом.

Кожен метод також приймає `signal`, `timeoutMs` і `maxRetries` для окремого запиту:

```ts
const current = await tapaya.checkout.sessions.get(sessionId, {
	signal: request.signal,
	timeoutMs: 5_000,
})
```

Коли сигнал перериває запит, метод одразу зупиняється без повторних спроб, а проміс відхиляється з причиною сигналу.

## Сесії Checkout [#checkout-sessions]

### Вибір мерчанта [#select-a-merchant]

У режимі мерчанта checkout-ключ мерчанта сам визначає свого мерчанта. Використовуйте `new Tapaya()` без `merchantToken`.

У режимі платформи один Secret key організації обслуговує багатьох мерчантів. Кожному запиту потрібен токен мерчанта; типового
мерчанта немає, і запит без токена завершується помилкою `TapayaAuthenticationError`. Скопіюйте токени з
таблиці мерчантів у [налаштуваннях Checkout](/online/integration/checkout_settings) і передавайте токен замовлення як під час
створення, так і під час отримання:

```ts
const tapaya = new Tapaya(process.env.TAPAYA_SECRET_KEY)
const session = await tapaya.checkout.sessions.create(params, {
	merchantToken: order.merchantToken,
	idempotencyKey: order.checkoutAttemptKey,
})
const current = await tapaya.checkout.sessions.get(session.id, {
	merchantToken: order.merchantToken,
})
```

Типове значення також можна задати через `new Tapaya(key, { merchantToken })`. Токен застосовується до викликів Hosted і Embedded
Checkout. Tapaya відхиляє токени, що не належать до організації ключа. З ключем мерчанта токен необов'язковий і має
вказувати на власного мерчанта цього ключа. Див. [автентифікацію Checkout](/online/integration/api_integration#authentication).

### Створення сесії [#create-a-session]

`tapaya.checkout.sessions.create(params, options?)` потребує `merchantOrderId`, `amount` і `currency`.
`merchantOrderId` є вашим референсом замовлення довжиною від 1 до 200 символів. Замовлення можна оплатити лише один раз; нова сесія для
неоплаченого замовлення замінює попередню. Див. [Один платіж на замовлення](/online/integration/api_integration#one-payment-per-order). `amount` є остаточною сумою,
включно з податком і доставкою, цілим числом від 1 до 2 147 483 647 мінімальних одиниць. `currency` є тризначним кодом ISO 4217.
Tapaya зберігає та повертає його у верхньому регістрі.

Необов'язкові поля:

| Поле                      | Опис                                                                                                                                                                                               |
| ------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `locale`                  | Мова сторінки Hosted Checkout, наприклад `en`. Типово `en`.                                                                                                                                        |
| `successUrl`, `cancelUrl` | URL повернення. Типово використовуються URL з ваших налаштувань Checkout.                                                                                                                          |
| `tax`, `shipping`         | Податок і доставка, включені в `amount`, у мінімальних одиницях.                                                                                                                                   |
| `taxRate`                 | Єдина ставка податку у відсоткових пунктах, наприклад `21`.                                                                                                                                        |
| `taxBreakdown`            | Податок за кожною ставкою, `[{ taxRate, tax }]`, для замовлень зі змішаними ставками. Використовуйте замість `taxRate`: типи відхиляють обидва поля разом.                                         |
| `items`                   | Товари, показані на сторінці Hosted Checkout: `reference`, `name`, `description`, `imageUrl`, `quantity` і `unitAmount`. Позиції слугують лише для відображення й не змінюють суму, що стягується. |
| `customer`                | Необов'язкові `email`, `billingAddress` і `shippingAddress`. Надсилайте лише ті дані, які ви збираєте.                                                                                             |

Перед надсиланням SDK перевіряє типи, обов'язкові поля, цілочисельні суми, формат валюти та максимальну довжину email
у 254 символи. URL повернення мають бути абсолютними HTTPS URL, з винятком для локального HTTP, описаним у розділі
[Конфігурація](#configuration). Tapaya валідує бізнес-правила, як-от формат email, обмеження адрес і коди
країн, і повідомляє про проблеми як `TapayaInvalidRequestError`. Правила полів,
суми податків і обмеження адрес клієнта див. у розділі [Сесії Checkout](/online/integration/api_integration#checkout-sessions).

### Отримання сесії [#get-a-session]

`tapaya.checkout.sessions.get(id, options?)` повертає поточний стан сесії. ID має бути непорожнім рядком довжиною не більше 200 символів; `.` і `..` недійсні. SDK кодує ID для URL.

Створення та отримання сесії Hosted Checkout повертають `HostedCheckoutSession`. Про методи вбудованої оплати `prepare()`, `verify()` і `configuration()` див. [Embedded Checkout](/online/integration/embedded_checkout).

Поля сесії Hosted Checkout:

| Поле                                         | Опис                                                                                                                |
| -------------------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `id`                                         | ID сесії, наприклад `cs_Y7u2d`.                                                                                     |
| `url`                                        | Сторінка оплати Hosted Checkout. Переспрямовуйте на неї без змін.                                                   |
| `merchantOrderId`, `amount`, `currency`      | Дані замовлення для порівняння зі збереженим замовленням.                                                           |
| `status`                                     | `open`, `completed` або `expired`. Сесії приймають нові платежі протягом 30 хвилин. Можуть з'явитися нові значення. |
| `paymentStatus`                              | `unpaid`, `successful`, `failed`, `cancelled` або `action_needed`. Можуть з'явитися нові значення.                  |
| `paymentReference`                           | Токен останньої спроби платежу або `null` до першої спроби.                                                         |
| `tax`, `shipping`, `taxRate`, `taxBreakdown` | Суми, надіслані під час створення сесії. Типово `0`, `0`, `null` і `[]`.                                            |
| `items`                                      | Позиції, надіслані під час створення сесії, або порожній масив.                                                     |
| `createdAt`, `expiresAt`, `completedAt`      | Позначки часу ISO 8601. `completedAt` має значення `null`, доки платіж не буде успішним.                            |

Обробляйте невідомі значення `status` і `paymentStatus`, наприклад вважаючи їх ще не оплаченими. Лише
`paymentStatus: 'successful'` доводить оплату.

Відхилена картка є результатом платежу, а не помилкою. Сесія залишається `open` з `paymentStatus: 'failed'`, і
клієнт може спробувати знову. Поки Tapaya підтверджує невизначений результат, сесія залишається `open` і `unpaid`.
Вебхуків поки немає; опитуйте `get()` із завдання звірки.

## Ідемпотентність і повторні спроби [#idempotency-and-retries]

Кожен запит на створення надсилає `Idempotency-Key`. Явно заданий ключ має бути непорожнім рядком із друкованих символів ASCII. Tapaya приймає щонайбільше 250 символів. Якщо ви не вкажете `idempotencyKey`, SDK генерує випадковий ключ для
кожного виклику. У межах цього виклику повторні спроби використовують той самий ключ, тому повторна спроба ніколи не створює другу сесію.

Щоб залишатися в безпеці між окремими викликами та перезапусками процесу, зберігайте ключ разом із замовленням і передавайте його щоразу, коли
створюєте сесію для цієї спроби, з тими самими параметрами. Tapaya повертає початкову сесію замість
створення нової. Використовуйте новий ключ лише для нової спроби оформлення замовлення, ніколи для повторення запиту з невизначеним результатом.

Повторне створення сесії Hosted Checkout повертає ту саму сесію з її поточними `status` і `paymentStatus`.
Викличте `tapaya.checkout.sessions.get(session.id)`, щоб ще раз перевірити статус перед виконанням замовлення.

Для того самого мерчанта повторні запити Hosted Checkout мають використовувати те саме тіло запиту та той самий режим облікових даних: checkout-ключ мерчанта
або Secret key організації. Зміна будь-чого з цього повертає HTTP 409 з кодом `API-0025`. Перемикання режиму облікових даних
спричиняє конфлікт навіть за ідентичного тіла, оскільки кожен режим використовує власні налаштування переспрямування.

SDK повторює обидва методи після мережевих помилок, тайм-аутів і HTTP 429, 502, 503 та 504. Він також повторює
створення, яке завершилося помилкою HTTP 409 `API-0024`. Повторні спроби надсилають той самий ключ і тіло, тому повертають початкову сесію. SDK
чекає між спробами з експоненційною затримкою та випадковим розкидом (jitter) і враховує `Retry-After` до 10 секунд. Коли Tapaya
просить чекати довше, SDK припиняє повторні спроби та викидає помилку для відповідного HTTP-статусу: `TapayaRateLimitError`
для 429, `TapayaServerError` для 502, 503 або 504 чи `TapayaConflictError` для 409. Лише `TapayaRateLimitError`
надає запитану затримку як `retryAfterMs`; інші HTTP-помилки зберігають заголовок `Retry-After` у `headers`.
Усі повторні спроби мають спільний ліміт `maxRetries`. Задайте `maxRetries: 0`, щоб вимкнути повторні спроби.

Ніколи не переходьте на новий ключ, щоб обійти невизначений результат. Початковий запит міг уже створити
сесію; з новим ключем і тим самим неоплаченим замовленням нова сесія її замінить.

## Помилки [#errors]

Класи помилок SDK розширюють `TapayaError`. Для перерваного запиту проміс відхиляється з причиною сигналу.

| Помилка                     | Коли                                                                                                                                                                                                 |
| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `TapayaError`               | Відсутній API-ключ або недійсна конфігурація клієнта; базовий клас помилок SDK.                                                                                                                      |
| `TapayaValidationError`     | Параметри не пройшли валідацію до надсилання запиту.                                                                                                                                                 |
| `TapayaAuthenticationError` | HTTP 401: ключ відсутній або недійсний, у режимі платформи відсутній токен мерчанта або токен не відповідає активному мерчанту.                                                                      |
| `TapayaInvalidRequestError` | HTTP 400 або 422: Tapaya відхилила параметри.                                                                                                                                                        |
| `TapayaPermissionError`     | HTTP 403.                                                                                                                                                                                            |
| `TapayaNotFoundError`       | HTTP 404: сесія не існує для цього мерчанта.                                                                                                                                                         |
| `TapayaConflictError`       | HTTP 409. `code` має значення `API-0025`, коли idempotency key уже використано з іншими параметрами. Створення сесії для замовлення, яке вже оплачено або платіж за яким триває, також повертає 409. |
| `TapayaRateLimitError`      | HTTP 429 після повторних спроб або одразу, коли `Retry-After` перевищує 10 секунд. `retryAfterMs` містить запитану затримку, якщо Tapaya її надсилає.                                                |
| `TapayaServerError`         | HTTP 5xx. Повторюються лише 502, 503 і 504, якщо повторні спроби не вимкнено і `Retry-After` не перевищує 10 секунд. Інші статуси 5xx одразу завершуються помилкою.                                  |
| `TapayaApiError`            | Базовий клас наведених вище HTTP-помилок і будь-якого іншого HTTP-статусу помилки.                                                                                                                   |
| `TapayaConnectionError`     | Запит не вдався або відповідь втрачено після повторних спроб. Початкова помилка міститься в `cause`.                                                                                                 |
| `TapayaTimeoutError`        | `TapayaConnectionError` для спроби, яка перевищила `timeoutMs`.                                                                                                                                      |
| `TapayaResponseError`       | Tapaya повернула відповідь, яку SDK не зміг прочитати.                                                                                                                                               |

HTTP-помилки містять `status`, `code` помилки Tapaya, `fieldErrors` (`{ field, message, code? }[]`),
`headers` відповіді та `requestId` із заголовка `X-Request-Id`, якщо він є. Наразі бекенд
не встановлює цей заголовок. У запитах до підтримки вказуйте ID сесії або референс замовлення та час запиту, а також
`requestId`, якщо він доступний. `TapayaResponseError` також містить `status`, `headers` і `requestId`.
`TapayaValidationError` також містить `fieldErrors`, де `field` містить шлях до параметра, наприклад `customer.email`.

```ts
import { TapayaConnectionError, TapayaError, TapayaValidationError } from '@tapayadot/checkout'

try {
	const session = await tapaya.checkout.sessions.create(params, { idempotencyKey })
	return Response.redirect(session.url, 303)
} catch (error) {
	if (error instanceof TapayaValidationError) {
		console.error(error.fieldErrors)
	} else if (error instanceof TapayaConnectionError) {
		// The outcome is unknown. Retry later with the same idempotency key.
	} else if (error instanceof TapayaError) {
		console.error(error.message)
	}
	throw error
}
```

## Експортовані типи [#exported-types]

Пакет експортує `TapayaEnvironment`, `TapayaOptions`, `RequestOptions`, `CreateSessionOptions`, `CreateCheckoutSessionParams`, `CheckoutSessions`, `CheckoutSession`, `CheckoutSessionStatus`, `CheckoutPaymentStatus`, `CheckoutItem`, `TaxBreakdownEntry`, `CheckoutCustomer`, `CheckoutContactAddress` і `TapayaFieldError`.

`VERSION` містить версію SDK. Типи імпортуються іменованим імпортом з `import type`:

```ts
import type { CheckoutSession, CreateCheckoutSessionParams } from '@tapayadot/checkout';
```

## Оновлення з 0.2.x [#upgrade-from-02x]

* Браузерний завантажувач завантажує Tapaya.js 0.2.0, який підтримує Apple Pay і Google Pay. Він відхиляє вже завантажений скрипт 0.1.x. Оновіть усі теги script, якими ви керуєте, на `https://js.tapaya.com/checkout/0.2.0/checkout.js`.
* `environment: 'production'` підтримує як платежі Hosted Checkout, так і вбудовані платежі. `configuration()` повертає `environment: 'production'` з ключами шлюзу робочого середовища.
* Без явно заданого середовища чи `TAPAYA_ENVIRONMENT` ключ `tapaya_live_` вибирає робоче середовище. Облікові дані, які не відповідають вибраному середовищу, спричиняють помилку під час створення клієнта. `baseUrl` і далі перевизначає URL API.
