Skip to main content

Checking payout status

Endpoint

POSThttps://api-merchant.alikassa.io/v1/payout/status📋

Headers

HeaderValue
Content-Typeapplication/json
AccountYour account uuid, you can find in Accounts
SignRequest signature

Certificate Setup

To generate API certificate for payouts, visit: https://merchant.alikassa.io/cabinet/form/setting-api-certs

Save the archive and unpack to get:

  • password.txt
  • private.pem
  • public.pem

We keep only public.pem for signature verification.

Signature Generation

Wrap all POST data in JSON (in the same order) and sign:

$data = json_encode($data);

$privateKey = openssl_pkey_get_private(
file_get_contents('private.pem'),
file_get_contents('password.txt')
);

if ($privateKey === false) {
throw new \Exception('Error cert.');
}

openssl_sign($data, $sign, $privateKey);
$sign = base64_encode($sign);
import { readFileSync } from 'fs';
import { createSign } from 'crypto';

const dataStr = JSON.stringify(data);
const privateKeyPem = readFileSync('private.pem', 'utf8');
const passphrase = readFileSync('password.txt', 'utf8').trim();
const signer = createSign('SHA1');
signer.update(dataStr);
signer.end();
const sign = signer.sign({ key: privateKeyPem, passphrase }, 'base64');
import json, base64
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding

data_bytes = json.dumps(data).encode()
with open('password.txt','rb') as f:
password = f.read().strip()
with open('private.pem','rb') as f:
private_key = serialization.load_pem_private_key(f.read(), password=password)
signature = private_key.sign(data_bytes, padding.PKCS1v15(), hashes.SHA1())
sign = base64.b64encode(signature).decode()
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Signature;
import java.util.Base64;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

byte[] dataBytes = new com.fasterxml.jackson.databind.ObjectMapper().writeValueAsBytes(data);
char[] pass = Files.readString(Paths.get("password.txt")).toCharArray();
PEMParser parser = new PEMParser(Files.newBufferedReader(Paths.get("private.pem")));
PEMEncryptedKeyPair ckp = (PEMEncryptedKeyPair) parser.readObject();
var privateKey = new JcaPEMKeyConverter()
.getKeyPair(ckp.decryptKeyPair(new JcePEMDecryptorProviderBuilder().build(pass)))
.getPrivate();
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign(privateKey);
sig.update(dataBytes);
String sign = Base64.getEncoder().encodeToString(sig.sign());
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"io/ioutil"
)

dataBytes, _ := json.Marshal(data)
pemBytes, _ := ioutil.ReadFile("private.pem")
passBytes, _ := ioutil.ReadFile("password.txt")
block, _ := pem.Decode(pemBytes)
der, _ := x509.DecryptPEMBlock(block, passBytes)
priv, _ := x509.ParsePKCS1PrivateKey(der)
hash := sha1.Sum(dataBytes)
sigBytes, _ := rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA1, hash[:])
sign := base64.StdEncoding.EncodeToString(sigBytes)

Pass the received $sign in the Sign header.

Request Parameters

NameTypeDescription
order_idstring (128)Your id specified during creation
idstring (128)AliKassa payment id
Note

You must pass order_id or id.

Response

NameDescription
order_idYour id specified during creation
idAliKassa payment id
payment_statusPayment status

wait — in the process of payment
paid — successfully paid (final status)
cancel — canceled (final status)
fail — error (final status)
card_maskCard mask when paying by card
card_brandCard brand (for example, VISA, MasterCard, MIR, etc.)
amountAmount
payment_amountPayment amount
is_partial_paymentIs the payment partial?
account_payment_amountAmount credited to the account
commission_amountCommission
service_codeService
error_messageError text/details in case of failed processing. Filled when payment_status = fail or cancel, absent for paid/wait.
RRNRRN
account_old_balanceBalance before making a request
account_new_balanceBalance after request processing

Response Example

*Successful Response (HTTP CODE 200)*

{
"payment_status": "paid",
"id": 100000536,
"order_id": "6422494",
"amount": "300.00",
"payment_amount": "300.00",
"is_partial_payment": false,
"account_payment_amount": "290",
"commission_amount": "10",
"service_code": "payment_card_rub",
"card_brand": "VISA",
"rrn": "11111111111",
"account_old_balance": "1290",
"account_new_balance": "1000"
}



*Failed response (HTTP CODE 200, with error)*

{
"payment_status": "fail",
"id": 100000537,
"order_id": "6422495",
"amount": "300.00",
"payment_amount": "0.00",
"is_partial_payment": false,
"account_payment_amount": "0",
"commission_amount": "0",
"service_code": "payment_card_rub",
"card_brand": "VISA",
"error_message": "Payment declined by issuer",
"rrn": null,
"account_old_balance": "1290",
"account_new_balance": "1290"
}

Error Response (HTTP 400):

*The payout with the specified ID/order_id was not found in the system. Please contact support and provide the request and response logs from the payment creation to investigate the issue. Do not assign a final status to this operation on your side until you receive guidance from support.*

{
"message": "Incorrect request. For information, contact support",
}

500 Server Error — Unexpected server-side error.
An internal error occurred while processing the request. In such a situation, the payment cannot be considered completed, cancelled, or unsuccessful on your side. The payout may be in one of the intermediate states, or it may have already been created, but is temporarily unavailable for verification. The payout status cannot be determined. If you receive such an error, you should contact support by attaching the request and response logs to clarify the reason and payment status.

{
"message": "Internal server error"
}

Example Implementation

Unpack the downloaded archive into the folder "path to script/cert/payout/"

function requestPayment(string $method, string $account, array $data)
{
$data = json_encode($data);

$privateKey = openssl_pkey_get_private(
file_get_contents(__DIR__ . '/cert/payout/private.pem'),
file_get_contents(__DIR__ . '/cert/payout/password.txt')
);

if ($privateKey === false) {
throw new \Exception('Error cert.');
}

openssl_sign($data, $sign, $privateKey);
$sign = base64_encode($sign);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api-merchant.alikassa.io/' . $method);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Content-Type: application/json',
'Account: ' . $account,
'Sign: ' . $sign,
]);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERAGENT, 'AliKassa2.0 API');
curl_setopt($ch, CURLOPT_TIMEOUT, 30);

$response = curl_exec($ch);

return json_decode($response, true);
}

$payout = requestPayment('v1/payout/status', '93d5df06-996c-48c3-9847-348d6b580b80', [
'id' => '100000536',
]);

var_dump($payout);
import { readFileSync } from 'fs';
import { createSign } from 'crypto';
import https from 'https';

async function requestPayment(method, account, data) {
const dataStr = JSON.stringify(data);
const privateKeyPem = readFileSync('cert/payout/private.pem', 'utf8');
const passphrase = readFileSync('cert/payout/password.txt', 'utf8').trim();

const signer = createSign('SHA1');
signer.update(dataStr);
signer.end();
const sign = signer.sign({ key: privateKeyPem, passphrase }, 'base64');

const options = {
hostname: 'api-merchant.alikassa.io',
path: `/${method}`,
method: 'POST',
headers: {
'Content-Type': 'application/json',
Account: account,
Sign: sign,
'User-Agent': 'AliKassa2.0 API',
},
timeout: 30000,
};

return new Promise((resolve, reject) => {
const req = https.request(options, (res) => {
let body = '';
res.on('data', (chunk) => (body += chunk));
res.on('end', () => resolve(JSON.parse(body)));
});
req.on('error', reject);
req.write(dataStr);
req.end();
});
}

(async () => {
const payout = await requestPayment(
'v1/payout/status',
'93d5df06-996c-48c3-9847-348d6b580b80',
{
id: '100000536',
}
);
console.log(payout);
})();
import json
import base64
import requests
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding

def request_payment(method: str, account: str, data: dict):
data_bytes = json.dumps(data).encode('utf-8')
with open('cert/payout/password.txt', 'rb') as f:
password = f.read().strip()
with open('cert/payout/private.pem', 'rb') as f:
private_key = serialization.load_pem_private_key(f.read(), password=password)
signature = private_key.sign(data_bytes, padding.PKCS1v15(), hashes.SHA1())
sign = base64.b64encode(signature).decode('utf-8')

headers = {
'Content-Type': 'application/json',
'Account': account,
'Sign': sign,
'User-Agent': 'AliKassa2.0 API',
}
resp = requests.post(f'https://api-merchant.alikassa.io/{method}', json=data, headers=headers, timeout=30)
return resp.json()

payout = request_payment('v1/payout/status', '93d5df06-996c-48c3-9847-348d6b580b80', {
'id': '100000536',
})
print(payout)
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.Signature;
import java.util.Base64;
import java.util.Map;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.bouncycastle.openssl.PEMEncryptedKeyPair;
import org.bouncycastle.openssl.PEMParser;
import org.bouncycastle.openssl.jcajce.JcePEMDecryptorProviderBuilder;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;

public class Example {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
Map<String,String> data = Map.of("id", "100000536");
String dataStr = mapper.writeValueAsString(data);

char[] pass = Files.readString(Paths.get("cert/payout/password.txt")).toCharArray();
PEMParser parser = new PEMParser(Files.newBufferedReader(Paths.get("cert/payout/private.pem")));
PEMEncryptedKeyPair ckp = (PEMEncryptedKeyPair) parser.readObject();
var kp = new JcaPEMKeyConverter().getKeyPair(
ckp.decryptKeyPair(new JcePEMDecryptorProviderBuilder().build(pass))
);
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign(kp.getPrivate());
sig.update(dataStr.getBytes(StandardCharsets.UTF_8));
String sign = Base64.getEncoder().encodeToString(sig.sign());

HttpRequest request = HttpRequest.newBuilder()
.uri(java.net.URI.create("https://api-merchant.alikassa.io/v1/payout/status"))
.header("Content-Type", "application/json")
.header("Account", "93d5df06-996c-48c3-9847-348d6b580b80")
.header("Sign", sign)
.header("User-Agent", "AliKassa2.0 API")
.POST(HttpRequest.BodyPublishers.ofString(dataStr))
.build();
var client = HttpClient.newHttpClient();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(mapper.readValue(response.body(), Object.class));
}
}
package main

import (
"bytes"
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"io/ioutil"
"net/http"
"time"
"fmt"
)

func signData(data interface{}) string {
dataBytes, _ := json.Marshal(data)
pemBytes, _ := ioutil.ReadFile("cert/payout/private.pem")
passBytes, _ := ioutil.ReadFile("cert/payout/password.txt")
block, _ := pem.Decode(pemBytes)
der, _ := x509.DecryptPEMBlock(block, passBytes)
priv, _ := x509.ParsePKCS1PrivateKey(der)
hash := sha1.Sum(dataBytes)
sigBytes, _ := rsa.SignPKCS1v15(rand.Reader, priv, crypto.SHA1, hash[:])
return base64.StdEncoding.EncodeToString(sigBytes)
}

func requestPayment(method, account string, data interface{}) (map[string]interface{}, error) {
sign := signData(data)
body, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api-merchant.alikassa.io/"+method, bytes.NewReader(body))
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Account", account)
req.Header.Set("Sign", sign)
req.Header.Set("User-Agent", "AliKassa2.0 API")
client := &http.Client{Timeout: 30 * time.Second}
resp, _ := client.Do(req)
defer resp.Body.Close()
var result map[string]interface{}
json.NewDecoder(resp.Body).Decode(&result)
return result, nil
}

func main() {
payout, _ := requestPayment("v1/payout/status", "93d5df06-996c-48c3-9847-348d6b580b80", map[string]interface{}{
"id": "100000536",
})
fmt.Println(payout)
}