CIBPay API Integration Guide
This documentation provides code examples for integrating with the CIBPay sandbox API across multiple programming languages. CIBPay offers a comprehensive payment processing solution with support for various payment methods and currencies.
Base Configuration
- Base URL: `https://api-preprod.cibpay.co`
- Authentication: Basic Auth (username/password)
- Content-Type: `application/json`
Base Configuration
Before integrating with CIBPay API, you need to configure your base settings and credentials.
Required Configuration
- Base URL: `https://api-preprod.cibpay.co` (Sandbox) / `https://api.cibpay.co` (Production)
- Authentication: Basic Auth with username and password
- Content-Type: `application/json` for all requests
- Character Encoding: UTF-8
Authentication Setup
CIBPay API uses Basic Authentication. Developers must use the `username` and `password` provided in their merchant account. These credentials should be encoded in Base64 format and included in the `Authorization` header with every request.
import requests
import base64
import json
# Configuration
BASE_URL = "https://api-preprod.cibpay.co"
USERNAME = "your_username"
PASSWORD = "your_password"
# Create auth header
auth_string = f"{USERNAME}:{PASSWORD}"
auth_bytes = auth_string.encode('ascii')
auth_b64 = base64.b64encode(auth_bytes).decode('ascii')
headers = {
'Authorization': f'Basic {auth_b64}',
'Content-Type': 'application/json'
}
const BASE_URL = "https://api-preprod.cibpay.co";
const USERNAME = "your_username";
const PASSWORD = "your_password";
const authString = btoa(`${USERNAME}:${PASSWORD}`);
const headers = {
'Authorization': `Basic ${authString}`,
'Content-Type': 'application/json'
};
const axios = require('axios');
const BASE_URL = "https://api-preprod.cibpay.co";
const USERNAME = "your_username";
const PASSWORD = "your_password";
const authString = Buffer.from(`${USERNAME}:${PASSWORD}`).toString('base64');
const headers = {
'Authorization': `Basic ${authString}`,
'Content-Type': 'application/json'
};
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.net.URI;
import java.util.Base64;
public class CIBPayClient {
private static final String BASE_URL = "https://api-preprod.cibpay.co";
private static final String USERNAME = "your_username";
private static final String PASSWORD = "your_password";
private String getAuthHeader() {
String auth = USERNAME + ":" + PASSWORD;
return "Basic " + Base64.getEncoder().encodeToString(auth.getBytes());
}
private HttpClient client = HttpClient.newHttpClient();
}
package main
import (
"bytes"
"encoding/base64"
"encoding/json"
"net/http"
)
const (
BaseURL = "https://api-preprod.cibpay.co"
Username = "your_username"
Password = "your_password"
)
func getAuthHeader() string {
auth := Username + ":" + Password
return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth))
}
import 'dart:convert';
import 'package:http/http.dart' as http;
class CIBPayClient {
static const String baseUrl = "https://api-preprod.cibpay.co";
static const String username = "your_username";
static const String password = "your_password";
static String get authHeader {
String auth = '$username:$password';
String encoded = base64Encode(utf8.encode(auth));
return 'Basic $encoded';
}
static Map get headers => {
'Authorization': authHeader,
'Content-Type': 'application/json',
};
}
<?php
class CIBPayClient {
private const BASE_URL = "https://api-preprod.cibpay.co";
private const USERNAME = "your_username";
private const PASSWORD = "your_password";
private function getAuthHeader() {
$auth = self::USERNAME . ':' . self::PASSWORD;
return 'Basic ' . base64_encode($auth);
}
private function getHeaders() {
return [
'Authorization: ' . $this->getAuthHeader(),
'Content-Type: application/json'
];
}
}
?>
using System;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using Newtonsoft.Json;
public class CIBPayClient
{
private const string BaseUrl = "https://api-preprod.cibpay.co";
private const string Username = "your_username";
private const string Password = "your_password";
private readonly HttpClient _httpClient;
public CIBPayClient()
{
_httpClient = new HttpClient();
var authString = Convert.ToBase64String(Encoding.ASCII.GetBytes($"{Username}:{Password}"));
_httpClient.DefaultRequestHeaders.Authorization =
new System.Net.Http.Headers.AuthenticationHeaderValue("Basic", authString);
}
}
API Endpoints
Test API connectivity and verify your authentication credentials.
def ping():
response = requests.get(f"{BASE_URL}/ping", headers=headers)
response.raise_for_status()
return response.json()
async function ping() {
const response = await fetch(`${BASE_URL}/ping`, {
method: 'GET',
headers: headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async function ping() {
try {
const response = await axios.get(`${BASE_URL}/ping`, { headers });
return response.data;
} catch (error) {
console.error('Error:', error.response.data);
throw error;
}
}
public String ping() throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/ping"))
.header("Authorization", getAuthHeader())
.GET()
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("Ping failed with status: " + response.statusCode());
}
return response.body();
}
func ping() ([]byte, error) {
req, err := http.NewRequest("GET", BaseURL+"/ping", nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", getAuthHeader())
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("ping failed with status: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
}
Future
public function ping() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . '/ping');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code != 200) {
throw new Exception("Ping failed with status: " . $http_code);
}
return json_decode($response, true);
}
public async Task PingAsync()
{
var response = await _httpClient.GetAsync($"{BaseUrl}/ping");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Response Examples
{
"status": "ok"
}
{
"error": {
"code": "AUTHENTICATION_ERROR",
"message": "Invalid credentials"
}
}
Get exchange rates for a specific date.
def get_exchange_rates(date="2025-07-03", rate_table=None):
params = {"date": date}
if rate_table:
params["rate_table"] = rate_table
response = requests.get(f"{BASE_URL}/exchange_rates/",
headers=headers, params=params)
return response.json()
async function getExchangeRates(date = "2025-07-03", rateTable = null) {
const url = new URL(`${BASE_URL}/exchange_rates/`);
url.searchParams.append('date', date);
if (rateTable) {
url.searchParams.append('rate_table', rateTable);
}
const response = await fetch(url.toString(), {
method: 'GET',
headers: headers
});
return await response.json();
}
async function getExchangeRates(date = "2025-07-03", rateTable = null) {
const params = { date };
if (rateTable) params.rate_table = rateTable;
try {
const response = await axios.get(`${BASE_URL}/exchange_rates/`, {
headers,
params
});
return response.data;
} catch (error) {
console.error('Error:', error.response.data);
throw error;
}
}
public String getExchangeRates(String date) throws IOException, InterruptedException {
URI uri = new URI(BASE_URL + "/exchange_rates/?date=" + date);
HttpRequest request = HttpRequest.newBuilder()
.uri(uri)
.header("Authorization", getAuthHeader())
.GET()
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
return response.body();
}
func getExchangeRates(date string) ([]byte, error) {
req, err := http.NewRequest("GET", BaseURL+"/exchange_rates/?date="+date, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", getAuthHeader())
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
return ioutil.ReadAll(resp.Body)
}
Future
public function getExchangeRates($date) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . '/exchange_rates/?date=' . $date);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
public async Task GetExchangeRatesAsync(string date)
{
var response = await _httpClient.GetAsync($"{BaseUrl}/exchange_rates/?date={date}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Response Examples
{
"rates": [
{
"currency_from": "AZN",
"currency_to": "EUR",
"buy": 1.70,
"sell": 1.75
},
{
"currency_from": "AZN",
"currency_to": "USD",
"buy": 1.70,
"sell": 1.70
}
]
}
Create a new order with automatic charge processing. `auto_charge` is set to `true`.
def create_order_charge(amount=3.33, currency="AZN", merchant_order_id="PKgn75jB"):
order_data = {
"amount": amount,
"currency": currency,
"extra_fields": {
"invoice_id": "001",
"oneclick": {
"customer_id": "99455555555",
"prechecked": 0
}
},
"merchant_order_id": merchant_order_id,
"options": {
"auto_charge": True,
"expiration_timeout": "15m",
"force3d": 1,
"language": "az",
"return_url": "https://yourdomain.az",
"country": "AZE",
"recurring": 1
},
"custom_fields": {
"region_code": 10,
"home_phone_country_code": "994",
"home_phone_subscriber": "129998877",
"mobile_phone_country_code": "055",
"mobile_phone_subscriber": "5554433",
"work_phone_country_code": "010",
"work_phone_subscriber": "2223344"
},
"client": {
"email": "email@yourdomain.az",
"city": "Baku",
"country": "AZE",
"address": "1, Azerbaijan ave.",
"zip": "1000"
}
}
response = requests.post(f"{BASE_URL}/orders/create",
headers=headers, json=order_data)
response.raise_for_status()
return response.json()
async function createOrderCharge(amount = 3.33, currency = "AZN", merchantOrderId = "PKgn75jB") {
const orderData = {
amount: amount,
currency: currency,
extra_fields: {
invoice_id: "001",
oneclick: {
customer_id: "99455555555",
prechecked: 0
}
},
merchant_order_id: merchantOrderId,
options: {
auto_charge: true,
expiration_timeout: "15m",
force3d: 1,
language: "az",
return_url: "https://yourdomain.az",
country: "AZE",
recurring: 1
},
custom_fields: {
region_code: 10,
home_phone_country_code: "994",
home_phone_subscriber: "129998877",
mobile_phone_country_code: "055",
mobile_phone_subscriber: "5554433",
work_phone_country_code: "010",
work_phone_subscriber: "2223344"
},
client: {
email: "email@yourdomain.az",
city: "Baku",
country: "AZE",
address: "1, Azerbaijan ave.",
zip: "1000"
}
};
const response = await fetch(`${BASE_URL}/orders/create`, {
method: 'POST',
headers: headers,
body: JSON.stringify(orderData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async function createOrderCharge(amount = 3.33, currency = "AZN", merchantOrderId = "PKgn75jB") {
const orderData = {
amount: amount,
currency: currency,
extra_fields: {
invoice_id: "001",
oneclick: {
customer_id: "99455555555",
prechecked: 0
}
},
merchant_order_id: merchantOrderId,
options: {
auto_charge: true,
expiration_timeout: "15m",
force3d: 1,
language: "az",
return_url: "https://yourdomain.az",
country: "AZE",
recurring: 1
},
custom_fields: {
region_code: 10,
home_phone_country_code: "994",
home_phone_subscriber: "129998877",
mobile_phone_country_code: "055",
mobile_phone_subscriber: "5554433",
work_phone_country_code: "010",
work_phone_subscriber: "2223344"
},
client: {
email: "email@yourdomain.az",
city: "Baku",
country: "AZE",
address: "1, Azerbaijan ave.",
zip: "1000"
}
};
try {
const response = await axios.post(`${BASE_URL}/orders/create`, orderData, { headers });
return response.data;
} catch (error) {
console.error('Error:', error.response.data);
throw error;
}
}
public String createOrderCharge() throws IOException, InterruptedException {
String orderData = "{"
+ "\"amount\": 3.33,"
+ "\"currency\": \"AZN\","
+ "\"extra_fields\": {"
+ " \"invoice_id\": \"001\","
+ " \"oneclick\": {"
+ " \"customer_id\": \"99455555555\","
+ " \"prechecked\": 0"
+ " }"
+ "},"
+ "\"merchant_order_id\": \"PKgn75jB\","
+ "\"options\": {"
+ " \"auto_charge\": true,"
+ " \"expiration_timeout\": \"15m\","
+ " \"force3d\": 1,"
+ " \"language\": \"az\","
+ " \"return_url\": \"https://yourdomain.az\","
+ " \"country\": \"AZE\","
+ " \"recurring\": 1"
+ "},"
+ "\"custom_fields\": {"
+ " \"region_code\": 10,"
+ " \"home_phone_country_code\": \"994\","
+ " \"home_phone_subscriber\": \"129998877\","
+ " \"mobile_phone_country_code\": \"055\","
+ " \"mobile_phone_subscriber\": \"5554433\","
+ " \"work_phone_country_code\": \"010\","
+ " \"work_phone_subscriber\": \"2223344\""
+ "},"
+ "\"client\": {"
+ " \"email\": \"email@yourdomain.az\","
+ " \"city\": \"Baku\","
+ " \"country\": \"AZE\","
+ " \"address\": \"1, Azerbaijan ave.\","
+ " \"zip\": \"1000\""
+ "}"
+ "}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/orders/create"))
.header("Authorization", getAuthHeader())
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(orderData))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("API call failed with status: " + response.statusCode() + " and body: " + response.body());
}
return response.body();
}
func createOrderCharge() ([]byte, error) {
orderData := map[string]interface{}{
"amount": 3.33,
"currency": "AZN",
"extra_fields": map[string]interface{}{
"invoice_id": "001",
"oneclick": map[string]interface{}{
"customer_id": "99455555555",
"prechecked": 0,
},
},
"merchant_order_id": "PKgn75jB",
"options": map[string]interface{}{
"auto_charge": true,
"expiration_timeout": "15m",
"force3d": 1,
"language": "az",
"return_url": "https://yourdomain.az",
"country": "AZE",
"recurring": 1,
},
"custom_fields": map[string]interface{}{
"region_code": 10,
"home_phone_country_code": "994",
"home_phone_subscriber": "129998877",
"mobile_phone_country_code": "055",
"mobile_phone_subscriber": "5554433",
"work_phone_country_code": "010",
"work_phone_subscriber": "2223344",
},
"client": map[string]interface{}{
"email": "email@yourdomain.az",
"city": "Baku",
"country": "AZE",
"address": "1, Azerbaijan ave.",
"zip": "1000",
},
}
jsonData, err := json.Marshal(orderData)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", BaseURL+"/orders/create", bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Authorization", getAuthHeader())
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("create order failed with status: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
}
Future
public function createOrderCharge() {
$data = [
"amount" => 3.33,
"currency" => "AZN",
"extra_fields" => [
"invoice_id" => "001",
"oneclick" => [
"customer_id" => "99455555555",
"prechecked" => 0
]
],
"merchant_order_id" => "PKgn75jB",
"options" => [
"auto_charge" => true,
"expiration_timeout" => "15m",
"force3d" => 1,
"language" => "az",
"return_url" => "https://yourdomain.az",
"country" => "AZE",
"recurring" => 1
],
"custom_fields" => [
"region_code" => 10,
"home_phone_country_code" => "994",
"home_phone_subscriber" => "129998877",
"mobile_phone_country_code" => "055",
"mobile_phone_subscriber" => "5554433",
"work_phone_country_code" => "010",
"work_phone_subscriber" => "2223344"
],
"client" => [
"email" => "email@yourdomain.az",
"city" => "Baku",
"country" => "AZE",
"address" => "1, Azerbaijan ave.",
"zip" => "1000"
]
];
$data_string = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . '/orders/create');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code != 200) {
throw new Exception("Create order failed with status: " . $http_code . " and body: " . $response);
}
return json_decode($response, true);
}
public async Task CreateOrderChargeAsync(decimal amount = 3.33m, string currency = "AZN", string merchantOrderId = "PKgn75jB")
{
var orderData = new
{
amount = amount,
currency = currency,
extra_fields = new
{
invoice_id = "001",
oneclick = new
{
customer_id = "99455555555",
prechecked = 0
}
},
merchant_order_id = merchantOrderId,
options = new
{
auto_charge = true,
expiration_timeout = "15m",
force3d = 1,
language = "az",
return_url = "https://yourdomain.az",
country = "AZE",
recurring = 1
},
custom_fields = new
{
region_code = 10,
home_phone_country_code = "994",
home_phone_subscriber = "129998877",
mobile_phone_country_code = "055",
mobile_phone_subscriber = "5554433",
work_phone_country_code = "010",
work_phone_subscriber = "2223344"
},
client = new
{
email = "email@yourdomain.az",
city = "Baku",
country = "AZE",
address = "1, Azerbaijan ave.",
zip = "1000"
}
};
var content = new StringContent(JsonConvert.SerializeObject(orderData), Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"{BaseUrl}/orders/create", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Response Examples
{
"orders": [
{
"id": "94611545647300120",
"status": "CREATED",
"created": "2025-08-02T12:52:28.000Z",
"expiration_date": "2025-08-02T13:07:28.000Z",
"checkout_url": "https://checkout-preprod.cibpay.co/pay/94611545647300120"
}
],
"result_code": 0
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Validation failed",
"details": {
"amount": [
"Amount must be greater than zero."
]
}
}
}
Charge a previously authorized order. The amount should be a string representing a decimal value, e.g., `"11.00"`.
def charge_order(order_id, amount=11.00):
charge_data = {"amount": str(amount)}
response = requests.put(f"{BASE_URL}/orders/{order_id}/charge",
headers=headers, json=charge_data)
response.raise_for_status()
return response.json()
async function chargeOrder(orderId, amount = 11.00) {
const chargeData = {
amount: amount.toString()
};
const response = await fetch(`${BASE_URL}/orders/${orderId}/charge`, {
method: 'PUT',
headers: headers,
body: JSON.stringify(chargeData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async function chargeOrder(orderId, amount = 11.00) {
const chargeData = { amount: amount.toString() };
try {
const response = await axios.put(`${BASE_URL}/orders/${orderId}/charge`, chargeData, { headers });
return response.data;
} catch (error) {
console.error('Error:', error.response.data);
throw error;
}
}
public String chargeOrder(String orderId, double amount) throws IOException, InterruptedException {
String chargeData = "{\"amount\":\"" + String.format("%.2f", amount) + "\"}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/orders/" + orderId + "/charge"))
.header("Authorization", getAuthHeader())
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(chargeData))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("Charge failed with status: " + response.statusCode() + " and body: " + response.body());
}
return response.body();
}
func chargeOrder(orderID string, amount float64) ([]byte, error) {
chargeData := map[string]string{"amount": fmt.Sprintf("%.2f", amount)}
jsonData, err := json.Marshal(chargeData)
if err != nil {
return nil, err
}
req, err := http.NewRequest("PUT", BaseURL+"/orders/"+orderID+"/charge", bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Authorization", getAuthHeader())
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("charge order failed with status: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
}
Future
public function chargeOrder($orderId, $amount) {
$data = json_encode(['amount' => (string)$amount]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . '/orders/' . $orderId . '/charge');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code != 200) {
throw new Exception("Charge order failed with status: " . $http_code . " and body: " . $response);
}
return json_decode($response, true);
}
public async Task ChargeOrderAsync(string orderId, decimal amount)
{
var chargeData = new { amount = amount.ToString("0.00") };
var content = new StringContent(JsonConvert.SerializeObject(chargeData), Encoding.UTF8, "application/json");
var response = await _httpClient.PutAsync($"{BaseUrl}/orders/{orderId}/charge", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Response Examples
{
"status": "CHARGED",
"transactions": [
{
"id": "94611545647300120-1",
"status": "SUCCESS",
"amount": 11.00
}
]
}
{
"error": {
"code": "INVALID_STATE",
"message": "Order is not in a valid state to be charged (e.g., already charged or canceled)."
}
}
Rebill an existing order using previously saved payment details.
def rebill_order(order_id):
rebill_data = {
"amount": 33.00,
"currency": "AZN",
"order_id": "123456789",
"location": {
"ip": "82.194.26.42"
},
"merchant_order_id": "PKgn75jB",
"options": {
"auto_charge": False,
"force3d": 0,
"expiration_timeout": "5m",
"language": "az",
"return_url": "https://google.com",
"terminal": "millikart_test",
"trace_id": "MCC8454300719",
"segment": "987654321",
"recurring": 1
},
"custom_fields": {
"region_code": 10,
"home_phone_country_code": "123",
"home_phone_subscriber": "123123123",
"mobile_phone_country_code": "345",
"mobile_phone_subscriber": "34535345345",
"work_phone_country_code": "567",
"work_phone_subscriber": "1565757567556"
},
"client": {
"email": "test@gmail.com",
"city": "City",
"country": "AZE",
"address": "Address",
"zip": "123456"
}
}
headers_with_request_id = {**headers, 'X-Request-Id': 'PKgn75jB11'}
response = requests.post(f"{BASE_URL}/orders/{order_id}/rebill",
headers=headers_with_request_id, json=rebill_data)
response.raise_for_status()
return response.json()
async function rebillOrder(orderId) {
const rebillData = {
amount: 33.00,
currency: "AZN",
order_id: "123456789",
location: {
ip: "82.194.26.42"
},
merchant_order_id: "PKgn75jB",
options: {
auto_charge: false,
force3d: 0,
expiration_timeout: "5m",
language: "az",
return_url: "https://google.com",
terminal: "millikart_test",
trace_id: "MCC8454300719",
segment: "987654321",
recurring: 1
},
custom_fields: {
region_code: 10,
home_phone_country_code: "123",
home_phone_subscriber: "123123123",
mobile_phone_country_code: "345",
mobile_phone_subscriber: "34535345345",
work_phone_country_code: "567",
work_phone_subscriber: "1565757567556"
},
client: {
email: "test@gmail.com",
city: "City",
country: "AZE",
address: "Address",
zip: "123456"
}
};
const headersWithRequestId = { ...headers, 'X-Request-Id': 'PKgn75jB11' };
const response = await fetch(`${BASE_URL}/orders/${orderId}/rebill`, {
method: 'POST',
headers: headersWithRequestId,
body: JSON.stringify(rebillData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async function rebillOrder(orderId) {
const rebillData = {
amount: 33.00,
currency: "AZN",
order_id: "123456789",
location: {
ip: "82.194.26.42"
},
merchant_order_id: "PKgn75jB",
options: {
auto_charge: false,
force3d: 0,
expiration_timeout: "5m",
language: "az",
return_url: "https://google.com",
terminal: "millikart_test",
trace_id: "MCC8454300719",
segment: "987654321",
recurring: 1
},
custom_fields: {
region_code: 10,
home_phone_country_code: "123",
home_phone_subscriber: "123123123",
mobile_phone_country_code: "345",
mobile_phone_subscriber: "34535345345",
work_phone_country_code: "567",
work_phone_subscriber: "1565757567556"
},
client: {
email: "test@gmail.com",
city: "City",
country: "AZE",
address: "Address",
zip: "123456"
}
};
const headersWithRequestId = { ...headers, 'X-Request-Id': 'PKgn75jB11' };
try {
const response = await axios.post(`${BASE_URL}/orders/${orderId}/rebill`, rebillData, { headers: headersWithRequestId });
return response.data;
} catch (error) {
console.error('Error:', error.response.data);
throw error;
}
}
public String rebillOrder(String orderId) throws IOException, InterruptedException {
String rebillData = "{"
+ "\"amount\": 33.00,"
+ "\"currency\": \"AZN\","
+ "\"order_id\": \"123456789\","
+ "\"location\": {"
+ " \"ip\": \"82.194.26.42\""
+ "},"
+ "\"merchant_order_id\": \"PKgn75jB\","
+ "\"options\": {"
+ " \"auto_charge\": false,"
+ " \"force3d\": 0,"
+ " \"expiration_timeout\": \"5m\","
+ " \"language\": \"az\","
+ " \"return_url\": \"https://google.com\","
+ " \"terminal\": \"millikart_test\","
+ " \"trace_id\": \"MCC8454300719\","
+ " \"segment\": \"987654321\","
+ " \"recurring\": 1"
+ "},"
+ "\"custom_fields\": {"
+ " \"region_code\": 10,"
+ " \"home_phone_country_code\": \"123\","
+ " \"home_phone_subscriber\": \"123123123\","
+ " \"mobile_phone_country_code\": \"345\","
+ " \"mobile_phone_subscriber\": \"34535345345\","
+ " \"work_phone_country_code\": \"567\","
+ " \"work_phone_subscriber\": \"1565757567556\""
+ "},"
+ "\"client\": {"
+ " \"email\": \"test@gmail.com\","
+ " \"city\": \"City\","
+ " \"country\": \"AZE\","
+ " \"address\": \"Address\","
+ " \"zip\": \"123456\""
+ "}"
+ "}";
Map requestHeaders = new HashMap<>(getHeaders());
requestHeaders.put("X-Request-Id", "PKgn75jB11");
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/orders/" + orderId + "/rebill"))
.headers(requestHeaders.entrySet().stream().flatMap(e -> Stream.of(e.getKey(), e.getValue())).toArray(String[]::new))
.POST(HttpRequest.BodyPublishers.ofString(rebillData))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("Rebill failed with status: " + response.statusCode() + " and body: " + response.body());
}
return response.body();
}
func rebillOrder(orderID string) ([]byte, error) {
rebillData := map[string]interface{}{
"amount": 33.00,
"currency": "AZN",
"order_id": "123456789",
"location": map[string]string{"ip": "82.194.26.42"},
"merchant_order_id": "PKgn75jB",
"options": map[string]interface{}{
"auto_charge": false,
"force3d": 0,
"expiration_timeout": "5m",
"language": "az",
"return_url": "https://google.com",
"terminal": "millikart_test",
"trace_id": "MCC8454300719",
"segment": "987654321",
"recurring": 1,
},
"custom_fields": map[string]string{
"region_code": "10",
"home_phone_country_code": "123",
"home_phone_subscriber": "123123123",
"mobile_phone_country_code": "345",
"mobile_phone_subscriber": "34535345345",
"work_phone_country_code": "567",
"work_phone_subscriber": "1565757567556",
},
"client": map[string]string{
"email": "test@gmail.com",
"city": "City",
"country": "AZE",
"address": "Address",
"zip": "123456",
},
}
jsonData, err := json.Marshal(rebillData)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", BaseURL+"/orders/"+orderID+"/rebill", bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Authorization", getAuthHeader())
req.Header.Set("Content-Type", "application/json")
req.Header.Set("X-Request-Id", "PKgn75jB11")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("rebill failed with status: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
}
Future
public function rebillOrder($orderId) {
$data = [
"amount" => 33.00,
"currency" => "AZN",
"order_id" => "123456789",
"location" => [
"ip" => "82.194.26.42"
],
"merchant_order_id" => "PKgn75jB",
"options" => [
"auto_charge" => false,
"force3d" => 0,
"expiration_timeout" => "5m",
"language" => "az",
"return_url" => "https://google.com",
"terminal" => "millikart_test",
"trace_id" => "MCC8454300719",
"segment" => "987654321",
"recurring" => 1
],
"custom_fields" => [
"region_code" => 10,
"home_phone_country_code" => "123",
"home_phone_subscriber" => "123123123",
"mobile_phone_country_code" => "345",
"mobile_phone_subscriber" => "34535345345",
"work_phone_country_code" => "567",
"work_phone_subscriber" => "1565757567556"
],
"client" => [
"email" => "test@gmail.com",
"city" => "City",
"country" => "AZE",
"address" => "Address",
"zip" => "123456"
]
];
$data_string = json_encode($data);
$headersWithRequestId = $this->getHeaders();
$headersWithRequestId[] = 'X-Request-Id: PKgn75jB11';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . '/orders/' . $orderId . '/rebill');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headersWithRequestId);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code != 200) {
throw new Exception("Rebill failed with status: " . $http_code . " and body: " . $response);
}
return json_decode($response, true);
}
public async Task RebillOrderAsync(string orderId)
{
var rebillData = new
{
amount = 33.00m,
currency = "AZN",
order_id = "123456789",
location = new { ip = "82.194.26.42" },
merchant_order_id = "PKgn75jB",
options = new
{
auto_charge = false,
force3d = 0,
expiration_timeout = "5m",
language = "az",
return_url = "https://google.com",
terminal = "millikart_test",
trace_id = "MCC8454300719",
segment = "987654321",
recurring = 1
},
custom_fields = new
{
region_code = 10,
home_phone_country_code = "123",
home_phone_subscriber = "123123123",
mobile_phone_country_code = "345",
mobile_phone_subscriber = "34535345345",
work_phone_country_code = "567",
work_phone_subscriber = "1565757567556"
},
client = new
{
email = "test@gmail.com",
city = "City",
country = "AZE",
address = "Address",
zip = "123456"
}
};
var content = new StringContent(JsonConvert.SerializeObject(rebillData), Encoding.UTF8, "application/json");
_httpClient.DefaultRequestHeaders.Add("X-Request-Id", "PKgn75jB11");
var response = await _httpClient.PostAsync($"{BaseUrl}/orders/{orderId}/rebill", content);
response.EnsureSuccessStatusCode();
_httpClient.DefaultRequestHeaders.Remove("X-Request-Id"); // Clean up header after use
return await response.Content.ReadAsStringAsync();
}
Response Examples
{
"orders": [
{
"id": "94611545647300120",
"status": "CREATED",
"created": "2025-08-02T12:52:28.000Z",
"expiration_date": "2025-08-02T13:07:28.000Z",
"checkout_url": "https://checkout-preprod.cibpay.co/pay/94611545647300120"
}
],
"result_code": 0
}
Retrieve order details by ID.
def get_order(order_id):
response = requests.get(f"{BASE_URL}/orders/{order_id}", headers=headers)
response.raise_for_status()
return response.json()
async function getOrder(orderId) {
const response = await fetch(`${BASE_URL}/orders/${orderId}`, {
method: 'GET',
headers: headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async function getOrder(orderId) {
try {
const response = await axios.get(`${BASE_URL}/orders/${orderId}`, { headers });
return response.data;
} catch (error) {
console.error('Error:', error.response.data);
throw error;
}
}
public String getOrder(String orderId) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/orders/" + orderId))
.header("Authorization", getAuthHeader())
.GET()
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("Get order failed with status: " + response.statusCode() + " and body: " + response.body());
}
return response.body();
}
func getOrder(orderID string) ([]byte, error) {
req, err := http.NewRequest("GET", BaseURL+"/orders/"+orderID, nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", getAuthHeader())
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("get order failed with status: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
}
Future
public function getOrder($orderId) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . '/orders/' . $orderId);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code != 200) {
throw new Exception("Get order failed with status: " . $http_code . " and body: " . $response);
}
return json_decode($response, true);
}
public async Task GetOrderAsync(string orderId)
{
var response = await _httpClient.GetAsync($"{BaseUrl}/orders/{orderId}");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Response Examples
{
"id": "94611545647300120",
"status": "CHARGED",
"amount": 11.00,
"currency": "AZN",
"created": "2025-08-02T12:52:28.000Z",
"transactions": [
{
"id": "94611545647300120-1",
"status": "SUCCESS",
"amount": 11.00
}
]
}
{
"error": {
"code": "NOT_FOUND",
"message": "Order not found"
}
}
Retrieve all orders.
def get_all_orders():
response = requests.get(f"{BASE_URL}/orders", headers=headers)
response.raise_for_status()
return response.json()
async function getAllOrders() {
const response = await fetch(`${BASE_URL}/orders`, {
method: 'GET',
headers: headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async function getAllOrders() {
try {
const response = await axios.get(`${BASE_URL}/orders`, { headers });
return response.data;
} catch (error) {
console.error('Error:', error.response.data);
throw error;
}
}
public String getAllOrders() throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/orders"))
.header("Authorization", getAuthHeader())
.GET()
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("Get all orders failed with status: " + response.statusCode() + " and body: " + response.body());
}
return response.body();
}
func getAllOrders() ([]byte, error) {
req, err := http.NewRequest("GET", BaseURL+"/orders", nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", getAuthHeader())
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("get all orders failed with status: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
}
Future
public function getAllOrders() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . '/orders');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code != 200) {
throw new Exception("Get all orders failed with status: " . $http_code . " and body: " . $response);
}
return json_decode($response, true);
}
public async Task GetAllOrdersAsync()
{
var response = await _httpClient.GetAsync($"{BaseUrl}/orders");
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Response Examples
{
"orders": [
{
"id": "94611545647300120",
"status": "CHARGED",
"amount": 11.00,
"currency": "AZN",
"created": "2025-08-02T12:52:28.000Z"
},
{
"id": "94611545647300121",
"status": "AUTHORIZED",
"amount": 33.33,
"currency": "AZN",
"created": "2025-08-02T12:55:00.000Z"
}
]
}
Cancel an existing order.
def cancel_order(order_id):
response = requests.put(f"{BASE_URL}/orders/{order_id}/cancel", headers=headers)
response.raise_for_status()
return response.json()
async function cancelOrder(orderId) {
const response = await fetch(`${BASE_URL}/orders/${orderId}/cancel`, {
method: 'PUT',
headers: headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async function cancelOrder(orderId) {
try {
const response = await axios.put(`${BASE_URL}/orders/${orderId}/cancel`, null, { headers });
return response.data;
} catch (error) {
console.error('Error:', error.response.data);
throw error;
}
}
public String cancelOrder(String orderId) throws IOException, InterruptedException {
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/orders/" + orderId + "/cancel"))
.header("Authorization", getAuthHeader())
.PUT(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("Cancel order failed with status: " + response.statusCode() + " and body: " + response.body());
}
return response.body();
}
func cancelOrder(orderID string) ([]byte, error) {
req, err := http.NewRequest("PUT", BaseURL+"/orders/"+orderID+"/cancel", nil)
if err != nil {
return nil, err
}
req.Header.Set("Authorization", getAuthHeader())
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("cancel order failed with status: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
}
Future
public function cancelOrder($orderId) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . '/orders/' . $orderId . '/cancel');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code != 200) {
throw new Exception("Cancel order failed with status: " . $http_code . " and body: " . $response);
}
return json_decode($response, true);
}
public async Task CancelOrderAsync(string orderId)
{
var response = await _httpClient.PutAsync($"{BaseUrl}/orders/{orderId}/cancel", null);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Response Examples
{
"status": "CANCELED"
}
{
"error": {
"code": "INVALID_STATE",
"message": "Order is not in a valid state to be canceled (e.g., already charged)."
}
}
Process a refund for an order. The amount should be a string representing a decimal value, e.g., `"1.00"`.
def refund_order(order_id, amount=1.00):
refund_data = {"amount": str(amount)}
response = requests.put(f"{BASE_URL}/orders/{order_id}/refund",
headers=headers, json=refund_data)
response.raise_for_status()
return response.json()
async function refundOrder(orderId, amount = 1.00) {
const refundData = { amount: amount.toString() };
const response = await fetch(`${BASE_URL}/orders/${orderId}/refund`, {
method: 'PUT',
headers: headers,
body: JSON.stringify(refundData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async function refundOrder(orderId, amount = 1.00) {
const refundData = { amount: amount.toString() };
try {
const response = await axios.put(`${BASE_URL}/orders/${orderId}/refund`, refundData, { headers });
return response.data;
} catch (error) {
console.error('Error:', error.response.data);
throw error;
}
}
public String refundOrder(String orderId, double amount) throws IOException, InterruptedException {
String refundData = "{\"amount\":\"" + String.format("%.2f", amount) + "\"}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/orders/" + orderId + "/refund"))
.header("Authorization", getAuthHeader())
.header("Content-Type", "application/json")
.PUT(HttpRequest.BodyPublishers.ofString(refundData))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("Refund failed with status: " + response.statusCode() + " and body: " + response.body());
}
return response.body();
}
func refundOrder(orderID string, amount float64) ([]byte, error) {
refundData := map[string]string{"amount": fmt.Sprintf("%.2f", amount)}
jsonData, err := json.Marshal(refundData)
if err != nil {
return nil, err
}
req, err := http.NewRequest("PUT", BaseURL+"/orders/"+orderID+"/refund", bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Authorization", getAuthHeader())
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("refund failed with status: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
}
Future
public function refundOrder($orderId, $amount = 1.00) {
$data = json_encode(['amount' => (string)$amount]);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . '/orders/' . $orderId . '/refund');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code != 200) {
throw new Exception("Refund failed with status: " . $http_code . " and body: " . $response);
}
return json_decode($response, true);
}
public async Task RefundOrderAsync(string orderId, decimal amount = 1.00m)
{
var refundData = new { amount = amount.ToString("0.00") };
var content = new StringContent(JsonConvert.SerializeObject(refundData), Encoding.UTF8, "application/json");
var response = await _httpClient.PutAsync($"{BaseUrl}/orders/{orderId}/refund", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Response Examples
{
"status": "REFUNDED"
}
{
"error": {
"code": "INVALID_STATE",
"message": "Order is not in a valid state to be refunded."
}
}
Send money to a card. The amount should be a string representing a decimal value, e.g., `"77.00"`.
def create_payout(amount=77.00, pan="4169741330151778", description="Test Payment", client_info):
payout_data = {
"amount": str(amount),
"currency": "AZN",
"pan": pan,
"description": description,
"client": client_info,
"options": {
"terminal": "kapital"
}
}
response = requests.post(f"{BASE_URL}/orders/credit",
headers=headers, json=payout_data)
response.raise_for_status()
return response.json()
async function createPayout(amount = 77.00, pan = "4169741330151778", description = "Test Payment", clientInfo) {
const payoutData = {
amount: amount.toString(),
currency: "AZN",
pan: pan,
description: description,
client: clientInfo,
options: {
terminal: "kapital"
}
};
const response = await fetch(`${BASE_URL}/orders/credit`, {
method: 'POST',
headers: headers,
body: JSON.stringify(payoutData)
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
return await response.json();
}
async function createPayout(amount, pan, description, clientInfo) {
const payoutData = {
amount: amount.toString(),
currency: "AZN",
pan: pan,
description: description,
client: clientInfo,
options: {
terminal: "kapital"
}
};
try {
const response = await axios.post(`${BASE_URL}/orders/credit`, payoutData, { headers });
return response.data;
} catch (error) {
console.error('Error:', error.response.data);
throw error;
}
}
public String createPayout(double amount, String pan, String description, String clientInfoJson) throws IOException, InterruptedException {
String payoutData = "{"
+ "\"amount\": \"" + String.format("%.2f", amount) + "\","
+ "\"currency\": \"AZN\","
+ "\"pan\": \"" + pan + "\","
+ "\"description\": \"" + description + "\","
+ "\"client\": " + clientInfoJson + ","
+ "\"options\": {"
+ " \"terminal\": \"kapital\""
+ "}"
+ "}";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + "/orders/credit"))
.header("Authorization", getAuthHeader())
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofString(payoutData))
.build();
HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());
if (response.statusCode() != 200) {
throw new RuntimeException("Payout failed with status: " + response.statusCode() + " and body: " + response.body());
}
return response.body();
}
func createPayout(amount float64, pan, description string, clientInfo map[string]interface{}) ([]byte, error) {
payoutData := map[string]interface{}{
"amount": fmt.Sprintf("%.2f", amount),
"currency": "AZN",
"pan": pan,
"description": description,
"client": clientInfo,
"options": map[string]string{"terminal": "kapital"},
}
jsonData, err := json.Marshal(payoutData)
if err != nil {
return nil, err
}
req, err := http.NewRequest("POST", BaseURL+"/orders/credit", bytes.NewBuffer(jsonData))
if err != nil {
return nil, err
}
req.Header.Set("Authorization", getAuthHeader())
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
defer resp.Body.Close()
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("payout failed with status: %s", resp.Status)
}
return ioutil.ReadAll(resp.Body)
}
Future
public function createPayout($amount, $pan, $description, $clientInfo) {
$data = [
"amount" => (string)$amount,
"currency" => "AZN",
"pan" => $pan,
"description" => $description,
"client" => $clientInfo,
"options" => [
"terminal" => "kapital"
]
];
$data_string = json_encode($data);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, self::BASE_URL . '/orders/credit');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);
curl_setopt($ch, CURLOPT_HTTPHEADER, $this->getHeaders());
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($http_code != 200) {
throw new Exception("Payout failed with status: " . $http_code . " and body: " . $response);
}
return json_decode($response, true);
}
public async Task CreatePayoutAsync(decimal amount, string pan, string description, object clientInfo)
{
var payoutData = new
{
amount = amount.ToString("0.00"),
currency = "AZN",
pan = pan,
description = description,
client = clientInfo,
options = new { terminal = "kapital" }
};
var content = new StringContent(JsonConvert.SerializeObject(payoutData), Encoding.UTF8, "application/json");
var response = await _httpClient.PostAsync($"{BaseUrl}/orders/credit", content);
response.EnsureSuccessStatusCode();
return await response.Content.ReadAsStringAsync();
}
Response Examples
{
"status": "SUCCESS",
"order_id": "94611545647300120"
}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid PAN or amount."
}
}
Error Handling
Proper error handling is crucial for production applications. Here are examples of how to handle API errors gracefully.
def safe_api_call(func, *args, **kwargs):
try:
response = func(*args, **kwargs)
if response.status_code >= 400:
print(f"API Error: {response.status_code} - {response.text}")
return None
return response.json()
except requests.exceptions.RequestException as e:
print(f"Request failed: {e}")
return None
async function safeApiCall(apiFunction, ...args) {
try {
const response = await apiFunction(...args);
return response;
} catch (error) {
console.error('API call failed:', error);
if (error.response) {
console.error('Response data:', error.response.data);
console.error('Response status:', error.response.status);
}
throw error;
}
}
async function safeApiCall(apiFunction, ...args) {
try {
const result = await apiFunction(...args);
return result;
} catch (error) {
console.error('API call failed:', error.response ? error.response.data : error.message);
throw error;
}
}
public String safeApiCall(Callable apiCall) {
try {
return apiCall.call();
} catch (IOException | InterruptedException e) {
System.err.println("API call failed: " + e.getMessage());
return null;
} catch (RuntimeException e) {
System.err.println("API call failed: " + e.getMessage());
return null;
}
}
public async Task SafeApiCallAsync(Func> apiCall)
{
try
{
var jsonResponse = await apiCall();
return JsonConvert.DeserializeObject(jsonResponse);
}
catch (HttpRequestException e)
{
Console.WriteLine($"Request failed: {e.Message}");
return default(T);
}
}
Environment Variables
For production use, always store your credentials as environment variables to keep them secure.
Python (.env file)
CIBPAY_USERNAME=your_username
CIBPAY_PASSWORD=your_password
CIBPAY_BASE_URL=https://api-preprod.cibpay.co
Node.js
require('dotenv').config();
const USERNAME = process.env.CIBPAY_USERNAME;
const PASSWORD = process.env.CIBPAY_PASSWORD;
const BASE_URL = process.env.CIBPAY_BASE_URL;
Testing
Always test your integration in the sandbox environment before going live. The checkout URL format for sandbox is: `https://checkout-preprod.cibpay.co/pay/{order_id}`.
Testing Checklist
- ✓ Test authentication with valid credentials
- ✓ Test order creation with various amounts
- ✓ Test payment processing flow
- ✓ Test error scenarios (invalid credentials, network issues)
- ✓ Test refund functionality
- ✓ Verify webhook notifications (if applicable)
CIBPay API