Интеграция

Ачкычтарды түзүү

Терминалда бул эки буйрукту иштетиңиз:

terminal
openssl genrsa -out finik_private.pem 2048
openssl rsa -in finik_private.pem -pubout > finik_public.pem
ФайлМаксаты
finik_private.pemАр бир сурамга ушул ачкыч менен кол коюңуз. Аны жашыруун сактаңыз, анткени ачкычты алган адам сиздин атыңыздан сурам жөнөтө алат.
finik_public.pemFinik сурамдарыңызды текшере алышы үчүн ачык ачкычты коопсуз канал аркылуу жөнөтүңүз.

Сурамдарга кол коюу

Ар бир суроо үчүн signature баш аты талап кылынат - RSA-SHA256, Base64-коддолгон, купуя ачкычыңыз менен түзүлгөн. Finik Node.js жана Python үчүн даяр пакеттерди камсыз кылат.

@mancho.devs/authorizer жана node-fetch орнотуп, андан кийин:

create-payment.ts
import { Signer, RequestData } from '@mancho.devs/authorizer';
import fetch from 'node-fetch'; // or axios

// Choose the environment you call:
const baseUrl = 'https://api.acquiring.averspay.kg';      // prod
// const baseUrl = 'https://beta.api.acquiring.averspay.kg'; // beta

// IMPORTANT: Host header must match the URL host exactly.
const host = new URL(baseUrl).host;

// Your credentials
const apiKey = process.env.FINIK_API_KEY!;           // from Finik
const privateKey = process.env.FINIK_PRIVATE_PEM!;   // contents of finik_private.pem
const timestamp = Date.now().toString();             // UNIX ms

// Create Payment body per spec
const body = {
  Amount: 100,
  CardType: 'FINIK_QR',
  PaymentId: '00000000-0000-0000-0000-000000000000',  // use a real UUID
  RedirectUrl: 'https://example.com/success',
  Data: {
    accountId: 'your-account-id',
    name_en: 'your-qr-name',
  },
};

// Build the canonical input for signing
const requestData: RequestData = {
  httpMethod: 'POST',
  path: '/v1/payment',                 // absolute path only (no query)
  headers: {
    Host: host,                        // must match baseUrl host
    'x-api-key': apiKey,               // included in signature
    'x-api-timestamp': timestamp,      // UNIX ms; same value used in signature
    // You may send other headers, but only `host` and `x-api-*` are included in the signature.
  },
  queryStringParameters: undefined,    // or { ... } if you have query; lib sorts & encodes
  body,                                // plain JS object; lib will canonicalize/JSON-stringify
};

// Produce Base64 RSA-SHA256 signature
const signature = await new Signer(requestData).sign(privateKey);

// Send the actual HTTP request
const url = `${baseUrl}${requestData.path}`;
const res = await fetch(url, {
  method: requestData.httpMethod,
  headers: {
    'content-type': 'application/json',
    'x-api-key': apiKey,
    'x-api-timestamp': timestamp,
    signature,                         // <- attach signature header
  },
  body: JSON.stringify(body),
  // If your API currently returns 302 (HTML) on S2S calls, prevent auto-follow:
  redirect: 'manual', // remove once API returns 201 JSON by default
});

if (res.status === 302) {
  // Read Location when you opt into redirects
  console.log('Redirect to:', res.headers.get('location'));
} else {
  console.error(res.status, await res.text());
}

Кол тамгага Host жана x-api- менен башталган баш аттар гана кирет. Кол тамгада жана сурамдын баш атында бир эле убакыт белгисин колдонуңуз.

Төлөм түзүү

POST кол коюлган өтүнүч:

API endpoints
POST https://api.acquiring.averspay.kg/v1/payment — Продакшен
POST https://beta.api.acquiring.averspay.kg/v1/payment — Бета

Баш аттар

Баш атСыпаттама
signatureСиз түзгөн кол тамга.
x-api-keyFinik берген API ачкычыңыз.
x-api-timestampUNIX миллисекунддарындагы учурдагы убакыт. Кол тамгада колдонулган мааниге барабар болушу керек.

Сурамдын денеси

ТалааТүрүМилдеттүүСыпаттама
AmountNumberМилдеттүү эмесТөлөмдүн белгиленген суммасы. Көрсөтүлбөсө, кардар каалаган сумманы төлөй алат.
CardTypeStringМилдеттүүАр дайым FINIK_QR.
PaymentIdStringМилдеттүүКайталанган төлөмдөрдү болтурбоочу уникалдуу төлөм ID.
RedirectUrlStringМилдеттүүИйгиликтүү төлөмдөн кийин кардар багыттала турган дарек.
DataObjectМилдеттүүТөлөмдүн чоо-жайы. Төмөндө караңыз.

Data object

ТалааТүрүМилдеттүүСыпаттама
accountIdStringМилдеттүүКаражат түшө турган Finik эсебиңиздин IDси.
name_enStringМилдеттүүКардарга көрсөтүлө турган QR коддун аталышы.
webhookUrlStringМилдеттүүТөлөмдүн статусу тууралуу билдирүүлөр үчүн сервериңиздин endpoint дареги.
descriptionStringМилдеттүү эмесТөлөм барагындагы сыпаттама.
startDateNumberМилдеттүү эмесQR коддун жарактуулук мөөнөтүнүн башталышы (UNIX мс).
endDateNumberМилдеттүү эмесQR коддун жарактуулук мөөнөтүнүн аягы (UNIX мс).
additionalDataArrayМилдеттүү эмесЭгер value талаасы берилбесе, кардар төлөм ыкмалары көрсөтүлгөнгө чейин форманы толтурат. Талаалардын максималдуу саны — 20.

additionalData items

ТалааТүрүМилдеттүүСыпаттама
fieldIdStringМилдеттүүWebhook payload ичиндеги талаанын ачкычы.
nameStringМилдеттүүТөлөм барагындагы талаанын аталышы.
isHiddenBooleanМилдеттүү эмесТөлөм барагындагы талааны жашыруу.
valueStringМилдеттүү эмесАлдын ала толтурулган маани.

Сурамдын body мисалы

POST /v1/payment — body
{
  "Amount": 100,
  "CardType": "FINIK_QR",
  "PaymentId": "a3f1c2e4-7b9d-4e2a-8c1f-3d0e9b2a5f6c",
  "RedirectUrl": "https://example.com/success",
  "Data": {
    "accountId": "your-account-id",
    "name_en": "your-qr-name",
    "webhookUrl": "https://merchant.example.com/webhooks/finik",
    "description": "your-qr-description",
    "startDate": 1737369000000,
    "endDate": 1737455400000
  }
}

Жоопту иштетүү

Төлөм ийгиликтүү түзүлгөндө, төлөм барагынын URL дареги Location баш атында берилген 302 багыттоо кайтарылат:

response
HTTP/1.1 302 Found
Location: https://qr.finik/<payment-path>
  1. Багыттоолорду өчүрүү менен бэкендден POST /v1/payment чалыңыз.
  2. Location окуңуз - бул төлөм барагыңыздын URL дареги.
  3. Бул URL даректи кардарга жөнөтүү - браузерди ага багыттаңыз же веб-көрүнүштө ачуу үчүн SPA/мобилдик тиркемеңизге кайтарыңыз.
  4. Кардар төлөмдү аяктайт жана сиздин RedirectUrl'ге багытталат.
  5. Финик вебхук жөнөтөт акыркы статусу менен - ​​аны чындыктын булагы деп эсептеңиз.

Автоматтык багыттоону өчүрүп, Location баш атын окуңуз

fetch.js
const res = await fetch("https://api.acquiring.averspay.kg/v1/payment", {
  method: "POST",
  headers: { "content-type": "application/json", "x-api-key": apiKey, "x-api-timestamp": ts, signature },
  body: JSON.stringify(body),
  redirect: "manual", // don't auto-follow
});

if (res.status === 302) {
  const paymentUrl = res.headers.get("location"); // send this to the browser
}

Бэкенд браузерди багыттай алат (302 Location: <paymentUrl>) же SPA колдонмоңузга JSON кайтарып, window.location = paymentUrl орното алат.