Create a Payment
const crypto = require('crypto');
const https = require('https');
const API_KEY = 'pk_test_YOUR_PUBLIC_KEY';
const API_SECRET = 'sk_test_YOUR_SECRET_KEY';
const BASE_URL = 'https://test-merchant.ebioro.com';
function generateHeaders(method, path, body = '') {
const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = crypto
.createHmac('sha256', API_SECRET)
.update(path + timestamp + method + body)
.digest('hex');
return {
'Content-Type': 'application/json',
'X-Digest-Key': API_KEY,
'X-Digest-Timestamp': timestamp,
'X-Digest-Signature': signature,
};
}
async function createPayment() {
const path = '/payments';
const body = JSON.stringify({
amount: { currency: 'USD', value: 1500 },
description: 'Order #1234',
redirectUrl: 'https://yoursite.com/success',
webhookUrl: 'https://yoursite.com/webhook',
name: 'Your Store',
});
const headers = generateHeaders('POST', path, body);
const url = new URL(BASE_URL + path);
return new Promise((resolve, reject) => {
const req = https.request(
{ hostname: url.hostname, path: url.pathname, method: 'POST', headers },
(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();
});
}
createPayment().then((payment) => {
console.log('Payment ID:', payment.checkout_id);
console.log('Payment URL:', payment.hostedUrl);
});
import hmac
import hashlib
import json
import time
import requests
API_KEY = "pk_test_YOUR_PUBLIC_KEY"
API_SECRET = "sk_test_YOUR_SECRET_KEY"
BASE_URL = "https://test-merchant.ebioro.com"
def generate_headers(method, path, body=None):
data = json.dumps(body, separators=(',', ':')) if body else ""
timestamp = str(int(time.time()))
payload = path + timestamp + method + data
signature = hmac.new(
API_SECRET.encode(), payload.encode(), hashlib.sha256
).hexdigest()
return {
"Content-Type": "application/json",
"X-Digest-Key": API_KEY,
"X-Digest-Timestamp": timestamp,
"X-Digest-Signature": signature,
}
# Create a payment
payment_data = {
"amount": {"currency": "USD", "value": 1500},
"description": "Order #1234",
"redirectUrl": "https://yoursite.com/success",
"webhookUrl": "https://yoursite.com/webhook",
"name": "Your Store",
}
path = "/payments"
headers = generate_headers("POST", path, payment_data)
response = requests.post(
BASE_URL + path,
headers=headers,
json=payment_data,
)
payment = response.json()
print(f"Payment ID: {payment['checkout_id']}")
print(f"Payment URL: {payment['hostedUrl']}")
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URI;
import java.net.http.*;
import java.time.Instant;
public class CreatePayment {
static final String API_KEY = "pk_test_YOUR_PUBLIC_KEY";
static final String API_SECRET = "sk_test_YOUR_SECRET_KEY";
static final String BASE_URL = "https://test-merchant.ebioro.com";
static String generateSignature(String path, String timestamp,
String method, String body) throws Exception {
String payload = path + timestamp + method + body;
Mac mac = Mac.getInstance("HmacSHA256");
mac.init(new SecretKeySpec(API_SECRET.getBytes(), "HmacSHA256"));
byte[] hash = mac.doFinal(payload.getBytes());
StringBuilder hex = new StringBuilder();
for (byte b : hash) hex.append(String.format("%02x", b));
return hex.toString();
}
public static void main(String[] args) throws Exception {
String path = "/payments";
String body = "{\"amount\":{\"currency\":\"USD\",\"value\":1500},"
+ "\"description\":\"Order #1234\","
+ "\"redirectUrl\":\"https://yoursite.com/success\","
+ "\"webhookUrl\":\"https://yoursite.com/webhook\","
+ "\"name\":\"Your Store\"}";
String timestamp = String.valueOf(Instant.now().getEpochSecond());
String signature = generateSignature(path, timestamp, "POST", body);
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create(BASE_URL + path))
.header("Content-Type", "application/json")
.header("X-Digest-Key", API_KEY)
.header("X-Digest-Timestamp", timestamp)
.header("X-Digest-Signature", signature)
.POST(HttpRequest.BodyPublishers.ofString(body))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println("Status: " + response.statusCode());
System.out.println("Response: " + response.body());
}
}
<?php
$apiKey = 'pk_test_YOUR_PUBLIC_KEY';
$apiSecret = 'sk_test_YOUR_SECRET_KEY';
$baseUrl = 'https://test-merchant.ebioro.com';
function createPayment($baseUrl, $apiKey, $apiSecret) {
$path = '/payments';
$body = json_encode([
'amount' => ['currency' => 'USD', 'value' => 1500],
'description' => 'Order #1234',
'redirectUrl' => 'https://yoursite.com/success',
'webhookUrl' => 'https://yoursite.com/webhook',
'name' => 'Your Store',
]);
$timestamp = (string) time();
$payload = $path . $timestamp . 'POST' . $body;
$signature = hash_hmac('sha256', $payload, $apiSecret);
$ch = curl_init($baseUrl . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $body,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
"X-Digest-Key: $apiKey",
"X-Digest-Timestamp: $timestamp",
"X-Digest-Signature: $signature",
],
]);
$response = curl_exec($ch);
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return json_decode($response, true);
}
$payment = createPayment($baseUrl, $apiKey, $apiSecret);
echo "Payment ID: " . $payment['checkout_id'] . "\n";
echo "Payment URL: " . $payment['hostedUrl'] . "\n";
using System.Security.Cryptography;
using System.Text;
var apiKey = "pk_test_YOUR_PUBLIC_KEY";
var apiSecret = "sk_test_YOUR_SECRET_KEY";
var baseUrl = "https://test-merchant.ebioro.com";
string GenerateSignature(string path, string timestamp, string method, string body)
{
var payload = path + timestamp + method + body;
using var hmac = new HMACSHA256(Encoding.UTF8.GetBytes(apiSecret));
var hash = hmac.ComputeHash(Encoding.UTF8.GetBytes(payload));
return BitConverter.ToString(hash).Replace("-", "").ToLower();
}
var path = "/payments";
var body = """{"amount":{"currency":"USD","value":1500},"description":"Order #1234","redirectUrl":"https://yoursite.com/success","webhookUrl":"https://yoursite.com/webhook","name":"Your Store"}""";
var timestamp = DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString();
var signature = GenerateSignature(path, timestamp, "POST", body);
using var client = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Post, baseUrl + path);
request.Content = new StringContent(body, Encoding.UTF8, "application/json");
request.Headers.Add("X-Digest-Key", apiKey);
request.Headers.Add("X-Digest-Timestamp", timestamp);
request.Headers.Add("X-Digest-Signature", signature);
var response = await client.SendAsync(request);
var result = await response.Content.ReadAsStringAsync();
Console.WriteLine($"Status: {response.StatusCode}");
Console.WriteLine($"Response: {result}");
Get a Payment
const path = `/payments/${paymentId}`;
const headers = generateHeaders('GET', path);
https.get({ hostname: 'test-merchant.ebioro.com', path, headers }, (res) => {
let data = '';
res.on('data', (chunk) => (data += chunk));
res.on('end', () => console.log(JSON.parse(data)));
});
path = f"/payments/{payment_id}"
headers = generate_headers("GET", path)
response = requests.get(BASE_URL + path, headers=headers)
print(response.json())
function getPayment($baseUrl, $apiKey, $apiSecret, $paymentId) {
$path = "/payments/$paymentId";
$timestamp = (string) time();
$signature = hash_hmac('sha256', $path . $timestamp . 'GET', $apiSecret);
$ch = curl_init($baseUrl . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
"X-Digest-Key: $apiKey",
"X-Digest-Timestamp: $timestamp",
"X-Digest-Signature: $signature",
],
]);
return json_decode(curl_exec($ch), true);
}
Verify a Webhook
const crypto = require('crypto');
function verifyWebhook(body, signature, secretKey) {
const expected = crypto
.createHmac('sha256', secretKey)
.update(JSON.stringify(body))
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(expected),
Buffer.from(signature)
);
}
// Express.js example
app.post('/webhook', (req, res) => {
const signature = req.headers['x-webhook-auth'];
if (!verifyWebhook(req.body, signature, API_SECRET)) {
return res.status(401).send('Invalid signature');
}
const { type, status, id } = req.body.data;
console.log(`Payment ${id}: ${type} -> ${status}`);
res.status(200).send('OK');
});
import hmac
import hashlib
def verify_webhook(body, signature, secret_key):
expected = hmac.new(
secret_key.encode(),
json.dumps(body).encode(),
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(expected, signature)
# Flask example
@app.route('/webhook', methods=['POST'])
def webhook():
signature = request.headers.get('X-WEBHOOK-AUTH')
if not verify_webhook(request.json, signature, API_SECRET):
return 'Invalid signature', 401
data = request.json['data']
print(f"Payment {data['id']}: {data['type']} -> {data['status']}")
return 'OK', 200
function verifyWebhook($body, $signature, $secretKey) {
$expected = hash_hmac('sha256', json_encode($body), $secretKey);
return hash_equals($expected, $signature);
}
// Usage
$signature = $_SERVER['HTTP_X_WEBHOOK_AUTH'];
$body = json_decode(file_get_contents('php://input'), true);
if (!verifyWebhook($body, $signature, $apiSecret)) {
http_response_code(401);
exit('Invalid signature');
}
$data = $body['data'];
echo "Payment {$data['id']}: {$data['type']} -> {$data['status']}";
Full Client Libraries
Maintained client libraries — covering payments, payment links, invoices, refunds, balances, and webhook signature verification — are available in our test suite repository:merchant-api-test-suite
Python and Node.js clients verified live against the Ebioro API (last verified 2026-06-10), plus HMAC authentication references for Java, PHP, and C#.