Create Payment
Example
Request
URL
Headers:
Content-Type:application/jsonAccount: Your account UUID (available at: Project Accounts)Sign: Request signature
Go to API Certificates Settings and generate an "API certificate for payments". Save and unzip the archive:
password.txtprivate.pempublic.pem
We only store public.pem to verify signatures.
Wrap all POST data in JSON (in the same order) and sign it:
$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 signature = signer.sign(
{ key: privateKeyPem, passphrase: passphrase },
'base64'
);
import json
import base64
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
data_bytes = json.dumps(data).encode('utf-8')
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('utf-8')
import java.io.FileReader;
import java.nio.charset.StandardCharsets;
import java.security.Signature;
import java.util.Base64;
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;
ObjectMapper mapper = new ObjectMapper();
String dataStr = mapper.writeValueAsString(data);
char[] pass = new String(java.nio.file.Files.readAllBytes(
java.nio.file.Paths.get("password.txt")
)).toCharArray();
PEMParser parser = new PEMParser(new FileReader("private.pem"));
PEMEncryptedKeyPair ckp = (PEMEncryptedKeyPair) parser.readObject();
JcaPEMKeyConverter converter = new JcaPEMKeyConverter();
PrivateKey privateKey = converter.getKeyPair(
ckp.decryptKeyPair(
new JcePEMDecryptorProviderBuilder().build(pass)
)
).getPrivate();
Signature sig = Signature.getInstance("SHA1withRSA");
sig.initSign(privateKey);
sig.update(dataStr.getBytes(StandardCharsets.UTF_8));
String sign = Base64.getEncoder().encodeToString(sig.sign());
package main
import (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"io/ioutil"
)
func main() {
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)
}
Send the $sign value in the Sign header.
Required Fields
| Name | Type | Description |
|---|---|---|
amount * | decimal (11.2) | Amount |
order_id * | string (128) | Your unique ID |
service * | string (100) | Service |
desc | string (128) | Description |
lifetime | int | Lifetime in seconds (900–3600) |
customer_ip * | ip | Payer IP address |
customer_account | string (50) | Customer ID in your system |
customer_email | string (50) | Email address |
customer_first_name | string (50) | First name |
customer_last_name | string (50) | Last name |
customer_address | string (50) | Address |
customer_phone | string (12) | Phone number |
customer_post_code | int (12) | Postal code |
customer_state | string (50) | State |
customer_city | string (20) | City |
customer_browser_user_agent* | string (2000) | Browser user agent |
customer_birth_date | date (1992-08-10) | Customer's date of birth |
success_redirect_id | int | Redirect ID after success |
fail_redirect_id | int | Redirect ID after failure |
notification_endpoint_id | int | Notification ID |
success_redirect_url | string (max 255) | Redirect URL after success |
fail_redirect_url | string (max 255) | Redirect URL after failure |
notification_endpoint_url | string (max 255) | Callback URL for status notifications |
project_url | string | Project URL (for aggregators) |
Response
| Name | Description |
|---|---|
id | AliKassa payment ID |
uuid | AliKassa payment UUID |
url | Payment URL |
payment_status | Payment status |
Initial payment_status is always wait. Use API or notifications to track status.
Success Response (HTTP 200):
{
"url": "https://pay-merchant.alikassa.io/bd291fe1-5c19-4113-ae62-a2d3c4d01d20",
"payment_status": "wait",
"id": 100001524,
"uuid": "h12a5a34-7e21-3789-bf53-96fe96131601"
}
HTTP CODE 400 — Error while creating the payment.
It may be caused by validation failures, limit restrictions, anti-fraud checks, or other constraints.
Such payments are not created on our side and should be considered unsuccessful.
{
"message": "The given data was invalid.",
"errors": {
// ...
}
}
*Technical maintenance is in progress, payments are temporarily unavailable. Please contact support for details.*
{
"message": "Technical works."
}
*A transaction with this order_id already exists in your account. Always use a unique order_id.*
{
"message": "order_id exists"
}
*An invalid value was provided in the “service” field.*
{
"message": "Not exists service / No found service"
}
*Creating transactions in this project is not allowed. Please contact support for details.*
{
"message": "Project not allowed to accept payments"
}
*The submitted amount is below the minimum allowed for this service.*
{
"message": "Minimum amount " . $amount
}
*The submitted amount exceeds the maximum allowed for this service.*
{
"message": "Maximum amount " . $amount
}
500 Server Error — Unexpected server-side error.
An internal issue occurred while processing the request.
This HTTP code does not guarantee that the payment was not created.
If this error occurs, you must contact support and provide the request and response logs to clarify the cause and status.
{
"message": "Internal server error"
}
After receiving the URL, redirect the client to the payment link.
When creating, always wait, check the payment status via the API or wait for a notification!
Notifications
If you passed notification_endpoint_id, then you will receive a notification about the change in payment status
Example Code
Unzip the downloaded archive into the folder "path to script/cert/payment/"
function requestPayment(string $method, string $account, array $data)
{
$data = json_encode($data);
$privateKey = openssl_pkey_get_private(
file_get_contents(__DIR__ . '/cert/payment/private.pem'),
file_get_contents(__DIR__ . '/cert/payment/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);
}
$payment = requestPayment('v1/payment', '93d5df06-996c-48c3-9847-348d6b580b80', [
'order_id' => (string)time(),
'amount' => 500,
'customer_browser_user_agent' => 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0',
'customer_ip' => '18.191.80.10',
'success_redirect_id' => 1,
'fail_redirect_id' => 1,
'notification_endpoint_id' => 5,
'service' => 'payment_card_rub_hpp',
]);
var_dump($payment);
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/payment/private.pem', 'utf8');
const passphrase = readFileSync('cert/payment/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 payment = await requestPayment(
'v1/payment',
'93d5df06-996c-48c3-9847-348d6b580b80',
{
order_id: String(Date.now()),
amount: 500,
customer_browser_user_agent:
'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0',
customer_ip: '18.191.80.10',
success_redirect_id: 1,
fail_redirect_id: 1,
notification_endpoint_id: 5,
service: 'payment_card_rub_hpp',
}
);
console.log(payment);
})();
import json
import base64
from cryptography.hazmat.primitives import hashes, serialization
from cryptography.hazmat.primitives.asymmetric import padding
import requests
def request_payment(method: str, account: str, data: dict):
data_bytes = json.dumps(data).encode('utf-8')
with open('cert/payment/password.txt', 'rb') as f:
password = f.read().strip()
with open('cert/payment/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}', data=data_bytes, headers=headers, timeout=30)
return resp.json()
payment = request_payment('v1/payment', '93d5df06-996c-48c3-9847-348d6b580b80', {
'order_id': str(int(__import__('time').time())),
'amount': 500,
'customer_browser_user_agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:84.0) Gecko/20100101 Firefox/84.0',
'customer_ip': '18.191.80.10',
'success_redirect_id': 1,
'fail_redirect_id': 1,
'notification_endpoint_id': 5,
'service': 'payment_card_rub_hpp',
})
print(payment)
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 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;
import java.io.FileReader;
public class Example {
public static void main(String[] args) throws Exception {
ObjectMapper mapper = new ObjectMapper();
var data = Map.of(
"order_id", String.valueOf(System.currentTimeMillis()),
"amount", 500,
"customer_browser_user_agent", "Mozilla/5.0 ...",
"customer_ip", "18.191.80.10",
"success_redirect_id", 1,
"fail_redirect_id", 1,
"notification_endpoint_id", 5,
"service", "payment_card_rub_hpp"
);
String dataStr = mapper.writeValueAsString(data);
char[] pass = Files.readString(Paths.get("cert/payment/password.txt")).toCharArray();
PEMParser parser = new PEMParser(new FileReader("cert/payment/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/payment"))
.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 (
"crypto"
"crypto/rand"
"crypto/rsa"
"crypto/sha1"
"crypto/x509"
"encoding/base64"
"encoding/json"
"encoding/pem"
"io/ioutil"
"net/http"
"time"
"bytes"
"fmt"
)
func signData(data interface{}) (string, error) {
dataBytes, _ := json.Marshal(data)
pemBytes, _ := ioutil.ReadFile("cert/payment/private.pem")
passBytes, _ := ioutil.ReadFile("cert/payment/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), nil
}
func requestPayment(method, account string, data interface{}) (map[string]interface{}, error) {
sign, _ := signData(data)
dataBytes, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api-merchant.alikassa.io/"+method, bytes.NewReader(dataBytes))
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() {
payment, _ := requestPayment("v1/payment", "93d5df06-996c-48c3-9847-348d6b580b80", map[string]interface{}{
"order_id": time.Now().Unix(),
"amount": 500,
"customer_browser_user_agent": "Mozilla/5.0 ...",
"customer_ip": "18.191.80.10",
"success_redirect_id": 1,
"fail_redirect_id": 1,
"notification_endpoint_id": 5,
"service": "payment_card_rub_hpp",
})
fmt.Println(payment)
}