Робота з підписанням

Структура JWS

Типовий JWS складається з трьох частин, розділених крапками (.):

{Base64Url(header)}.{Base64Url(payload)}.{Base64Url(signature)}

Де:

  • header — описує загальні мета данні

{
    "alg": "ES256",  // Алгоритм підписання 
    "kid": "uuid",  // Ідентифікатор публічного ключа (надається від співробітника банку)
    "ts" : "1763034308", // Дата та час у форматі timestamp
    "targetUrl" : "/ecom/jws/payments/create/purchase_v3" // URL на який надсилається запит
}
  • payload — дані, які потрібно передати (необхідні данні для коженого запиту, дивитись у документації Платіжні методи H2H).

  • signature — цифровий підпис, створений за допомогою приватного ключа відправника.

Приклад JWS:

eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.
eyJ1c2VySWQiOiIxMjMiLCJyb2xlIjoiYWRtaW4ifQ.
MEYCIQDmG...

Як виконується підписання

  1. Формується header (мета дані) payload (дані запиту).

  2. Обидві частини кодуються у формат Base64Url.

  3. Об’єднуються в одне повідомлення:

    signingInput = base64Url(header) + "." + base64Url(payload)
  4. Це повідомлення підписується приватним ключем (детальніше як отирмати ключ - Генерація ключів) за вказаним алгоритмом .

  5. Результат (signature) додається як третя частина JWS.

Приклад генерації JWS можна переглянути на сайті https://www.jwt.io/

Приклад коду для генерації підпису:

import { CompactSign, importPKCS8 } from 'jose';

// === Дані ===
const privateKeyPem = `
-----BEGIN EC PRIVATE KEY-----
MHcCAQEEIBOS+Xg3qgYSe5T4H2AoB0zWrhb0jNmcdW6o2bTXXWlQoAoGCCqGSM49
AwEHoUQDQgAEMO4qQsgPskZ4E1X6nHZU9yHnJrZ97K3QAjQ1oG1zgrht3mA4+lf5
aMqTIk1glXZpMT4pAzTURmmP2+prvQul3g==
-----END EC PRIVATE KEY-----
`;

const header = {
  alg: "ES256",
  kid: "9a3f6e6d-4f56-4b8b-99d3-24db19f54d8a",
  ts: Math.floor(Date.now() / 1000),
  targetUrl: "/ecom/jws/payments/create/purchase_v3"
};

// payload — це тіло запиту
const payload = {
  merchantId: "12345",
  amount: "1000.00",
  currency: "UAH",
  orderId: "ORD-2025-001"
};

// === Генерація JWS ===
const privateKey = await importPKCS8(privateKeyPem, 'ES256');
const encoder = new TextEncoder();

const encodedHeader = Buffer.from(JSON.stringify(header)).toString('base64url');
const encodedPayload = Buffer.from(JSON.stringify(payload)).toString('base64url');
const signingInput = `${encodedHeader}.${encodedPayload}`;

const sign = new CompactSign(encoder.encode(JSON.stringify(payload)))
  .setProtectedHeader(header);

const jws = await sign.sign(privateKey);

console.log("JWS:", jws);

Вимоги до JWS

1. Загальні вимоги до JWS :

  • Усі запити до API повинні бути підписані за допомогою JWS (JSON Web Signature).

  • Підпис формується відповідно до алгоритму, що відповідає типу ключа, переданого у параметрі kid.

  • При валідації JWS система перевіряє правильність header, payload та signature.

У разі порушення будь-якої з вимог запит відхиляється з помилкою.

2. Вимоги до частини header JWS :

ПІдтримувальні параметри header :

Поле
Опис
Тип
Обов'язкове
Приклад

alg

Алгоритм підпису, що відповідає типу ключа

string

так

ES256

kid

Ідентифікатор публічного ключа

string

так

28da60c2-d60f-404e-b4da-6b089fb29555

ts

Час генерації JWS

number (Unix timestamp, seconds)

так

1763034308

targetUrl

URL, для якого формується запит

string (URL)

так

/ecom/jws/payments/create/purchase_v3

2.1. Перевірка терміну дії токена (ts)

  • Поле ts повинно містити timestamp (у секундах).

  • JWS вважається дійсним протягом 60 секунд з моменту формування.

Умови помилки:

2.2. Перевірка targetUrl

Система перевіряє, що значення:

  • відповідає формату URL,

  • є дозволеним маршрутом API,

  • відповідає фактичному endpoint, куди надсилається запит. Приклад : Запит надійщо в на- {url}/ecom/jws/payments/create/purchase_v3 Фактичний - /ecom/jws/payments/create/purchase_v3

Умови помилки:

2.3. Перевірка алгоритму підпису (alg)

Значення alg повинно відповідати алгоритму пари ключів, що використовується для підпису ES256.

Умова помилки:

2.4. Перевірка існування ключа (kid)

  • kid повинен відповідати одному з активних ключів мерчанта.

Умова помилки:

3. Вимоги до JWS Payload

Payload JWS повинен містити тіло запиту (request body) у JSON, яке повністю відповідає вимогам конкретного endpoint’у.

Приклад: якщо запит виконується до /ecom/jws/payments/create/purchase_v3, то саме тіло цього запиту (Запит проведення PURCHASE Крок 1) включається у payload JWS.

3.1. Валідація структури тіла запиту

Payload повинен:

  • містити всі обов'язкові параметри, визначені для відповідного endpoint’у,

  • відповідати JSON схемі,

  • проходити внутрішню бізнес-валідацію.

Умова помилки:

3.2. Перевірка мерчанта (merchantId)

Усі операції повинні виконуватися від імені існуючого мерчанта.

Умова помилки:

Last updated