AliKassa API Documentation

website·Indexed 30 days ago

https://doc-merchant.alikassa.io/

Documentation for integrating with the AliKassa payment API. Includes guides for generating API certificates, managing account balances, creating payments and payouts, and implementing H2H payment workflows. Provides endpoint details and implementation examples in PHP, Node.js, Python, Java, and Go.

Tokens
25.8K
Snippets
88
Records
108
Agent score
49%

What's inside AliKassa

  1. Handle payment history API responses

    The API returns the following HTTP status codes:

    • 200 OK: Request successful. Returns a JSON object containing a data array of payments, links for pagination, and meta information about the total count and current page.
    • 400 Bad Request: The provided data was invalid.
    • 500 Internal Server Error: An unexpected server-side error occurred. Contact support with logs if this happens.
  2. AliKassa API Core Functionalities Overview

    The AliKassa API is organized into three primary functional areas:

    • API Basics: Covers fundamentals, certificate configuration, and signature verification for secure communication.
    • Payments: Provides endpoints to create payments, check payment status, retrieve payment lists, and handle Host-to-Host (H2H) payments.
    • Payouts: Provides endpoints to create payouts and monitor their status.
  3. H2H Payment Process Overview

    The H2H payment workflow consists of the following sequence of steps:

    1. Create a payment to obtain a uuid.
    2. Send payment details to the API endpoint.
    3. Redirect the client to the 3DS (Three-Domain Secure) authentication page.
    4. The payer is returned to the specified return_url after payment.
    5. Send a confirmation request to confirm the payment.
  4. Implement crypto wallet creation in Python

    This example demonstrates how to create a crypto wallet using Python. It uses the cryptography library to load a PEM private key and sign the payload using SHA1 and PKCS1v15 padding.
    import json
    import base64
    import requests
    from cryptography.hazmat.primitives import hashes, serialization
    from cryptography.hazmat.primitives.asymmetric import padding
    
    def create_crypto_wallet(method: str, account: str, data: dict):
        payload = json.dumps(data).encode('utf-8')
        password = open('cert/payment/password.txt','rb').read().strip()
        private_key = serialization.load_pem_private_key(
            open('cert/payment/private.pem','rb').read(),
            password=password
        )
        signature = private_key.sign(payload, 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=payload, headers=headers, timeout=30)
        return resp.json()
    
    crypto_wallet = create_crypto_wallet(
        'v1/account/crypto-wallet',
        '93d5df06-996c-48c3-9847-348d6b580b80',
        {'service': 'tron_usdt_hpp'}
    )
    print(crypto_wallet)
  5. Set up API certificates for payouts

    Payouts require a certificate for signature verification. Generate the certificate at https://merchant.alikassa.io/cabinet/form/setting-api-certs. The downloaded archive contains three essential files:

    • private.pem: The private key used for signing requests.
    • password.txt: The passphrase for the private key.
    • public.pem: The public key (kept by Alikassa for verification).
  6. Handle 3DS redirection for H2H payments

    After successfully sending payment details to the API, the response will contain a redirect object. You must redirect the payer to the provided url using the specified method (e.g., GET or POST) and include any provided params to complete the 3DS authentication.
  7. Sign AliKassa API requests using RSA

    AliKassa requires all POST data to be signed using a private key.

    1. Generate an 'API certificate for payments' in the API Certificates Settings.
    2. Download and unzip the archive containing private.pem and password.txt.
    3. Convert the request data to a JSON string.
    4. Sign the JSON string using the private key and the provided password (SHA1 with RSA).
    5. Base64-encode the resulting signature and place it in the Sign header.
    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',
    );
  8. Sign AliKassa API requests using RSA-SHA1

    To authenticate requests, you must sign the JSON-encoded request body using a private key generated from the 'API certificate for payments' in the AliKassa cabinet. The process involves:

    1. Converting the request data to a JSON string.
    2. Signing the string using the private.pem key and the passphrase from password.txt using the SHA1 algorithm.
    3. Base64-encoding the resulting signature for use in the Sign header.
    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');
  9. Implement account rate request in Go

    This Go implementation shows how to parse a passphrase-protected RSA private key, generate a SHA1 hash of the request body, sign it using PKCS#1 v1.5, and send the request to the AliKassa API.
    package main
    
    import (
    	"bytes"
    	"crypto"
    	"crypto/rand"
    	"crypto/rsa"
    	"crypto/sha1"
    	"crypto/tls"
    	"encoding/base64"
    	"encoding/json"
    	"fmt"
    	"io"
    	"net/http"
    	"os"
    	"time"
    	"golang.org/x/crypto/ssh"
    )
    
    func requestRate(method, account string, data any) (map[string]any, error) {
    	body, err := json.Marshal(data)
    	if err != nil { return nil, err }
    
    	pemBytes, err := os.ReadFile("cert/payout/private.pem")
    	if err != nil { return nil, fmt.Errorf("Error cert.") }
    	passBytes, err := os.ReadFile("cert/payout/password.txt")
    	if err != nil { return nil, fmt.Errorf("Error cert.") }
    	pass := bytes.TrimSpace(passBytes)
    
    	rawKey, err := ssh.ParseRawPrivateKeyWithPassphrase(pemBytes, pass)
    	if err != nil { return nil, fmt.Errorf("Error cert.") }
    
    	key, ok := rawKey.(*rsa.PrivateKey)
    	if !ok { return nil, fmt.Errorf("Error cert.") }
    
    	sum := sha1.Sum(body)
    	sig, err := rsa.SignPKCS1v15(rand.Reader, key, crypto.SHA1, sum[:])
    	if err != nil { return nil, err }
    	sign := base64.StdEncoding.EncodeToString(sig)
    
    	client := &http.Client{
    		Timeout: 30 * time.Second,
    		Transport: &http.Transport{
    			TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
    		},
    	}
    
    	req, err := http.NewRequest(http.MethodPost, "https://api-merchant.alikassa.io/"+method, bytes.NewReader(body))
    	if err != nil { return nil, err }
    	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")
    
    	resp, err := client.Do(req)
    	if err != nil { return nil, err }
    	defer resp.Body.Close()
    
    	b, err := io.ReadAll(resp.Body)
    	if err != nil { return nil, err }
    	if len(b) == 0 { return nil, nil }
    
    	var out map[string]any
    	if err := json.Unmarshal(b, &out); err != nil { return nil, err }
    	return out, nil
    }
    
    func main() {
    	rate, err := requestRate("v1/account/rate", "93d5df06-996c-48c3-9847-348d6b580b80", []any{})
    	if err != nil { panic(err) }
    	fmt.Println(rate)
    }
  10. Verify Alikassa notification signatures

    To ensure a notification is authentic, wrap all GET parameters into a JSON object in the specific order listed below and verify the signature using the public.pem certificate and the sign parameter (Base64 decoded). The verification uses the SHA1 algorithm.

    Required Parameter Order for JSON:

    1. type
    2. id (as integer)
    3. order_id
    4. payment_status
    5. amount
    6. payment_amount
    7. commission_amount
    8. is_partial_payment
    9. account
    10. service
    11. desc
    12. card_brand
    import http from 'http';
    import { createVerify } from 'crypto';
    import { readFileSync } from 'fs';
    
    http
      .createServer((req, res) => {
        const url = new URL(req.url || '', `http://${req.headers.host}`);
        const params = {
          type: url.searchParams.get('type'),
          id: Number(url.searchParams.get('id')),
          order_id: url.searchParams.get('order_id'),
          payment_status: url.searchParams.get('payment_status'),
          amount: url.searchParams.get('amount'),
          payment_amount: url.searchParams.get('payment_amount'),
          commission_amount: url.searchParams.get('commission_amount'),
          is_partial_payment: url.searchParams.get('is_partial_payment'),
          account: url.searchParams.get('account'),
          service: url.searchParams.get('service'),
          desc: url.searchParams.get('desc'),
          card_brand: url.searchParams.get('card_brand'),
        };
    
        const data = JSON.stringify(params);
        const signature = Buffer.from(url.searchParams.get('sign') || '', 'base64');
        const publicKey = readFileSync('./certs/notification/public.pem');
    
        const verifier = createVerify('SHA1');
        verifier.update(data);
        verifier.end();
    
        const verified = verifier.verify(publicKey, signature);
        if (!verified) {
          throw new Error('Invalid signature');
        }
    
        res.writeHead(200, { 'Content-Type': 'text/plain' });
        res.end('OK');
      })
      .listen(8080);
  11. Implement crypto wallet creation in Node.js

    This example demonstrates how to create a crypto wallet using Node.js. It includes reading the payment certificate (private.pem and password.txt), signing the JSON request body using SHA1, and sending the request via the https module.
    import { readFileSync } from 'fs';
    import { createSign } from 'crypto';
    import https from 'https';
    
    async function createCryptoWallet(method, account, data) {
      const body = JSON.stringify(data);
      const keyPem = readFileSync('cert/payment/private.pem', 'utf8');
      const passphrase = readFileSync('cert/payment/password.txt', 'utf8').trim();
      const signer = createSign('SHA1');
      signer.update(body);
      signer.end();
      const sign = signer.sign({ key: keyPem, 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 data = '';
          res.on('data', (chunk) => (data += chunk));
          res.on('end', () => resolve(JSON.parse(data)));
        });
        req.on('error', reject);
        req.write(body);
        req.end();
      });
    }
    
    (async () => {
      const cryptoWallet = await createCryptoWallet(
        'v1/account/crypto-wallet',
        '93d5df06-996c-48c3-9847-348d6b580b80',
        { service: 'tron_usdt_hpp' }
      );
      console.log(cryptoWallet);
    })();