Интеграция
Ачкычтарды түзүү
Терминалда бул эки буйрукту иштетиңиз:
terminal
openssl genrsa -out finik_private.pem 2048
openssl rsa -in finik_private.pem -pubout > finik_public.pem| Файл | Максаты |
|---|---|
finik_private.pem | Ар бир сурамга ушул ачкыч менен кол коюңуз. Аны жашыруун сактаңыз, анткени ачкычты алган адам сиздин атыңыздан сурам жөнөтө алат. |
finik_public.pem | Finik сурамдарыңызды текшере алышы үчүн ачык ачкычты коопсуз канал аркылуу жөнөтүңүз. |
Сурамдарга кол коюу
Ар бир суроо үчүн 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-key | Finik берге н API ачкычыңыз. |
x-api-timestamp | UNIX миллисекунддарындагы учурдагы убакыт. Кол тамгада колдонулган мааниге барабар болушу керек. |
Сурамдын денеси
| Талаа | Түрү | Милдеттүү | Сыпаттама |
|---|---|---|---|
Amount | Number | Милдеттүү эмес | Төлөмдүн белгиленген суммасы. Көрсөтүлбөсө, кардар каалаган сумманы төлөй алат. |
CardType | String | Милдеттүү | Ар дайым FINIK_QR. |
PaymentId | String | Милдеттүү | Кайталанган төлөмдөрдү болтурбоочу уникалдуу төлөм ID. |
RedirectUrl | String | Милдеттүү | Ийгиликтүү төлөмдөн кийин кардар багыттала турган дарек. |
Data | Object | Милдеттүү | Төлөмдүн чоо-жайы. Төмөндө караңыз. |
Data object
| Талаа | Түрү | Милдеттүү | Сыпаттама |
|---|---|---|---|
accountId | String | Милдеттүү | Каражат түшө турган Finik эсебиңиздин IDси. |
name_en | String | Милдеттүү | Кардарга көрсөтүлө турган QR коддун аталышы. |
webhookUrl | String | Милдеттүү | Төлөмдүн статусу тууралуу билдирүүлөр үчүн сервериңиздин endpoint дареги. |
description | String | Милдеттүү эмес | Төлөм барагындагы сыпаттама. |
startDate | Number | Милдеттүү эмес | QR коддун жарактуулук мөөнөтүнүн башталышы (UNIX мс). |
endDate | Number | Милдеттүү эмес | QR коддун жарактуулук мөөнөтүнүн аягы (UNIX мс). |
additionalData | Array | Милдеттүү эмес | Эгер value талаасы берилбесе, кардар төлөм ыкмалары көрсөтүлгөнгө чейин форманы толтурат. Талаалардын максималдуу саны — 20. |
additionalData items
| Талаа | Түрү | Милдеттүү | Сыпаттама |
|---|---|---|---|
fieldId | String | Милдеттүү | Webhook payload ичиндеги талаанын ачкычы. |
name | String | Милдеттүү | Төлөм барагындагы талаанын аталышы. |
isHidden | Boolean | Милдеттүү эмес | Төлөм барагындагы талааны жашыруу. |
value | String | Милдеттүү эмес | Алдын ала толтурулган маани. |
Сурамдын 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>- Багыттоолорду өчүрүү менен бэкендден POST /v1/payment чалыңыз.
Locationокуңуз - бул төлөм барагыңыздын URL дареги.- Бул URL даректи кардарга жөнөтүү - браузерди ага багыттаңыз же веб-көрүнүштө ачуу үчүн SPA/мобилдик тиркемеңизге кайтарыңыз.
- Кардар төлөмдү аяктайт жана сиздин
RedirectUrl'ге багытталат. - Финик вебхук жөнөтөт акыркы статусу менен - аны чындыктын булагы деп эсептеңиз.
Автоматтык багыттоону өчүрүп, 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 орното алат.