Getting started

API for paying services and sending transfers on behalf of a partner (agent payments).

How it works

The full outgoing-payment flow from start to confirmation:

  1. You request the list of services and learn their required fields (requiredFields).
  2. You verify the recipient — Finik returns their name.
  3. You create a payment from your account with a unique transactionId.
  4. Finik debits the funds and sends the payment to the service provider.
  5. You receive a webhook with the final status (SUCCEEDED or FAILED) or check the status via GET /v2/payments/{paymentId}.
Finik Payments Gateway API — payment flow diagram

Introduction

This documentation will help you integrate the Finik Payments Gateway API into your application so that you can make payments on your own behalf: pay for mobile, internet, utilities and other services, and send transfers to Finik users — directly from your corporate account to hundreds of service providers in Kyrgyzstan.

The integration consists of the following steps:

  1. Generate an RSA key pair — private and public. They are needed to authorize your requests.
  2. Get an API key — send your public key to Finik representatives and receive an ApiKey to work with the API.
  3. Set up request signing — every request is signed with your private key.
  4. Get the list of services — request the catalog of available services and their required fields via POST /v2/services.
  5. Verify the recipient — before a payment, make sure the recipient exists via POST /v2/recipient.
  6. Create payments — send signed requests to POST /v2/payment and track the status.
  7. Handle the webhook — receive notifications about the final payment status and verify their signature.

Quick start

  1. Get your ApiKey from Finik representatives.
  2. Generate an RSA key pair:
terminal
openssl genrsa -out finik_private.pem 2048
openssl rsa -in finik_private.pem -pubout > finik_public.pem
  1. Send the public key (finik_public.pem) to Finik representatives. Keep the private key secret — whoever gets it can send requests on your behalf.
  2. Add a signing library:
    • Node.js — @mancho.devs/authorizer (NPM)
    • Python — mancho-devs/python-authorizer
    • Other languages — see the signing algorithm
  3. Make your first request in the beta environment — start with POST /v2/services.

Environments

EnvironmentBase URLFinik public key for verifying webhooks
Betahttps://beta.api.paymentsgateway.averspay.kgBeta public key (see the “Webhook and error codes” page)
Productionhttps://api.paymentsgateway.averspay.kgProd public key (see the “Webhook and error codes” page)

Authentication

Every request is signed with your private key. The signature is sent in HTTP headers:

HeaderTypeRequiredDescription
signatureStringRequiredRequest signature (Base64).
x-api-keyStringRequiredYour API key issued by Finik. Used in signature generation.
x-api-timestampStringRequiredCurrent time in milliseconds. Used in signature generation.

Building the string to sign

signature-data.txt
data  = lowercase(HTTP method) + "\n"         // "post" or "get"
data += URI path + "\n"                        // e.g. "/v2/payment"
data += headers + "\n"                         // see the rules below
data += query parameters + "\n"                // if there are no query params, DON'T add this "\n"
data += JSON of the request body               // keys sorted, see below

Rules for headers:

  1. Take Host and all headers that start with x-api-*.
  2. Sort by header name alphabetically.
  3. Join with & in the name:value format (names in lowercase):
canonical-headers.txt
host:api.paymentsgateway.averspay.kg&x-api-key:YOUR_KEY&x-api-timestamp:1719900000000

Rules for query parameters:

  1. Sort by parameter name alphabetically.
  2. Join with & in the URiEncode(name)=URiEncode(value) format.
  3. If a parameter has no value (e.g. ?acl) — use an empty string: acl=.

Rules for the request body:

The body is serialized to JSON with keys sorted alphabetically.

Signing

The assembled data string is signed with the SHA256withRSA algorithm using your private key, the result is encoded in Base64 and sent in the signature header.

Example in Java:

Signer.java
public String sign(String payload, String privatePath) {
  try {
    Signature signature = Signature.getInstance("SHA256withRSA");
    String privateKeyFile = new String(Files.readAllBytes(Paths.get(privatePath)));
    RSAKey rsaKey = (RSAKey) JWK.parseFromPEMEncodedObjects(privateKeyFile);
    PrivateKey privateKey = rsaKey.toPrivateKey();
    signature.initSign(privateKey);
    signature.update(payload.getBytes(StandardCharsets.UTF_8));
    return Base64.encodeBase64String(signature.sign());
  } catch (Exception e) {
    throw new AppException(e.getMessage());
  }
}

Ready-made libraries

LanguagePackage
Node.js@mancho.devs/authorizer (NPM)
Pythonmancho-devs/python-authorizer
OtherImplement the algorithm above. Libraries for other languages are planned.