Прескочи на садржај
AMIO
Мени

AMIO за програмере

Повежите касу, интернет продавницу или систем банке са AMIO. API даје исте резултате као рад у апликацији, са истим правилима, улогама и ревизорским трагом.

OpenAPI спецификација

Аутентификација

Администратор ваше организације прави API кључ у апликацији, у одељку За програмере. Кључ шаљете у заглављу Authorization: Bearer amio_live_... уз сваки захтев ка /api/public/v1. Кључ се приказује само једном и може се повући у сваком тренутку.

API је намењен серверима, не прегледачима: CORS није укључен, а кључ никада не стављајте у код који се извршава код купца.

curl https://www.getamio.com/api/public/v1/quotes \
  -H "Authorization: Bearer amio_live_..." \
  -H "Idempotency-Key: 6f1c2f9e-6d0b-4f7e-9a51-2c8f2f4b7a10" \
  -H "Content-Type: application/json" \
  -d '{"amount":{"amountMinor":"12990000","currency":"RSD"},
       "description":"Laptop","instalments":[6,12]}'

Улоге и права

Сваки кључ има једну улогу ваше организације, изабрану при прављењу, и сме само оно што сме та улога у апликацији. Кључ може бити и само за читање. Трговци: администратор, менаџер и запослени; партнери: администратор, одобравалац и аналитичар.

Кључ ради у име особе која га је направила и престаје да ради када та особа више није члан тима. Ограничење је 120 захтева у минути по кључу; преко тога добијате 429 и заглавље Retry-After.

Идемпотентност

Сваки POST и PUT захтев мора имати заглавље Idempotency-Key, на пример UUID. Поновљен захтев са истим кључем и истим телом враћа исти одговор (са заглављем Idempotent-Replayed), па се понуда или повраћај никада не направе двапут. Исти кључ са другачијим телом враћа 409 IDEMPOTENCY_CONFLICT. Кључеви се памте 24 сата.

Грешке и износи

Грешке увек имају исти облик: еррор.цоде, еррор.мессаге и еррор.correlationId, а исти идентификатор је и у заглављу X-Correlation-Id. Наведите га када се обраћате подршци. Измене користе верзије: пошаљите версион коју сте последњи пут добили; ако се у међувремену нешто променило, добијате 409 са разлогом VERSION_CONFLICT.

Износи су увек објекат { amountMinor, currency }, где је amountMinor цео број у најмањој јединици валуте, записан као текст, на пример "12990000" за 129.900,00 RSD.

{
  "error": {
    "code": "CONFLICT",
    "message": "VERSION_CONFLICT",
    "reason": "VERSION_CONFLICT",
    "correlationId": "c0a8..."
  }
}

Webhook обавештења

Администратор додаје адресу и бира догађаје. AMIO шаље POST са JSON телом { ид, type, createdAt, ливемоде, дата } када се статус промени. Одговорите статусом 2xx у року од 10 секунди; неуспеле испоруке понављамо са све дужим размацима, а последњи покушаји су видљиви у апликацији.

Свака порука има заглавље AMIO-Signature: т=<unix време>,в1=<hex HMAC-SHA256 над "т.тело">, потписано тајном адресе. Проверите потпис над сировим телом и одбаците старе поруке. Исти догађај може стићи више пута; користите ид да га обрадите једном.

  • Трговци: quote.created, quote.status_changed, application.status_changed, refund.status_changed
  • Партнери: application.status_changed, deferral.requested, deferral.decided
import { createHmac, timingSafeEqual } from "node:crypto";

// rawBody: the request body exactly as received (a string), before JSON.parse.
export function verifyAmioWebhook(rawBody, header, secret, toleranceSeconds = 300) {
  const parts = Object.fromEntries(
    String(header ?? "").split(",").map((part) => part.trim().split("=", 2)),
  );
  const timestamp = Number(parts.t);
  if (!parts.v1 || !Number.isInteger(timestamp)) return false;
  if (Math.abs(Date.now() / 1000 - timestamp) > toleranceSeconds) return false;
  const expected = createHmac("sha256", secret).update(`${timestamp}.${rawBody}`).digest();
  const given = Buffer.from(parts.v1, "hex");
  return given.length === expected.length && timingSafeEqual(given, expected);
}

// Express: app.post("/amio/webhooks", express.text({ type: "*/*" }), (req, res) => {
//   if (!verifyAmioWebhook(req.body, req.get("AMIO-Signature"), process.env.AMIO_WEBHOOK_SECRET))
//     return res.sendStatus(400);
//   const event = JSON.parse(req.body); // { id, type, createdAt, livemode, data }
//   res.sendStatus(200);
// });

Уграђени екрани

Екране за нову понуду и статус понуде можете приказати у свом порталу у iframe-у: /{locale}/embed/merchant/quotes/new и /{locale}/embed/merchant/quotes/{id}. Администратор прво додаје адресу портала; са свих других адреса прегледач блокира приказ (Content-Security-Policy: фраме-анцесторс).

Прегледачи не шаљу AMIO колачић пријаве у iframe на другом сајту, зато ваш сервер тражи једнократни токен: POST /api/public/v1/embed-tokens. Токен важи 5 минута и AMIO га при првом отварању мења за кратку сесију само за вашу фирму, са улогом кључа. Ако је портал на истом сајту као AMIO, ради и обична пријава (отворите је у искачућем прозору).

// On your server, with a merchant key:
const response = await fetch("https://www.getamio.com/api/public/v1/embed-tokens", {
  method: "POST",
  headers: {
    Authorization: "Bearer amio_live_...",
    "Idempotency-Key": crypto.randomUUID(),
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ locale: "sr-Latn-RS" }), // or { quoteId } for one quote's status
});
const { url } = await response.json();

// In your portal page (an origin registered under Developers):
// <iframe src="{url}" width="480" height="820" title="AMIO"></iframe>

Тест окружење

Кључеви који почињу са amio_test_ постоје само у тест окружењу и тамо раде са тест партнером. У продукцији се користе само amio_live_ кључеви. Понуде трговца који још није активан су увек означене као тест (моде SANDBOX, ливемоде фалсе у webhook порукама).

Повезивање банке

Банка повезује своје кредитне системе преко Генериц Банк Интегратион API-ја: једног верзионисаног HTTP уговора који банка имплементира, па свака банка користи исти адаптер. Покрива захтев, одлуку, понуде, прихватање, исплату, повраћаје, план отплате и одлагања.

Сваки захтев је потписан HMAC-SHA256 потписом са временском ознаком, захтеви који мењају стање носе Idempotency-Key, а нејасан одговор се пре свега другог проверава позивом за статус. Прихвата се само HTTPS.

Опционе могућности, као што су провера идентитета, повраћаји и одлагања, банка наводи у одговору на проверу доступности. Када банка не може да имплементира уговор, могућ је посебан адаптер уз иста правила.

Спецификација банкарског API-ја (OpenAPI)