PHP Examples
Complete PHP example client for integrating with the Multihub API using cURL andhash('sha512', ...).
This is a reference implementation, not an official SDK package. It works with PHP 8.0+ and requires only the built-in cURL and JSON extensions.
Configuration
Store your credentials in environment variables or a.env file:
Copy
export MULTIHUB_APP_ID="1"
export MULTIHUB_SECRET_KEY="your_secret_key"
MultihubClient Class
A complete, reusable client class for all API operations:Copy
<?php
class MultihubClient
{
private string $appId;
private string $secretKey;
private string $baseUrl;
public function __construct(
?string $appId = null,
?string $secretKey = null,
string $baseUrl = 'https://api.123hub.pro/public/api/multihub/v1'
) {
$this->appId = $appId ?? getenv('MULTIHUB_APP_ID') ?: '';
$this->secretKey = $secretKey ?? getenv('MULTIHUB_SECRET_KEY') ?: '';
$this->baseUrl = $baseUrl;
if (!$this->appId || !$this->secretKey) {
throw new InvalidArgumentException('appId and secretKey are required');
}
}
/**
* Sign and send a request to the Multihub API.
*/
private function send(array $body): array
{
$bodyStr = json_encode($body, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$hash = hash('sha512', $bodyStr . $this->secretKey);
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $this->baseUrl,
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $bodyStr,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Content-Type: application/json',
'X-Data-Application-Id: ' . $this->appId,
'X-Data-Hash: ' . $hash,
],
]);
$response = curl_exec($ch);
$curlError = curl_error($ch);
curl_close($ch);
if ($curlError) {
throw new RuntimeException('cURL error: ' . $curlError);
}
$decoded = json_decode($response, true);
if ($decoded === null) {
throw new RuntimeException('Invalid JSON response');
}
return $decoded;
}
/**
* Health check / connectivity test.
*/
public function ping(): array
{
return $this->send(['method' => 'gateway.ping', 'params' => new \stdClass()]);
}
/**
* Create a deposit (pay-in) payment.
*/
public function createDeposit(
int $serviceId,
float $amount,
string $currency,
int $cId,
array $extra = []
): array {
return $this->send([
'method' => 'payment.in',
'service_id' => $serviceId,
'params' => [
'payment' => array_merge([
'identifiers' => ['c_id' => $cId],
'amount' => ['value' => $amount, 'currency' => $currency],
], $extra),
],
]);
}
/**
* Create a withdrawal (payout) payment.
*/
public function createWithdrawal(
int $serviceId,
float $amount,
string $currency,
int $cId,
array $receiver,
array $extra = []
): array {
return $this->send([
'method' => 'payment.out',
'service_id' => $serviceId,
'params' => [
'payment' => array_merge([
'identifiers' => ['c_id' => $cId],
'amount' => ['value' => $amount, 'currency' => $currency],
'receiver' => $receiver,
], $extra),
],
]);
}
/**
* Check payment status by identifiers.
*/
public function getStatus(?int $cId = null, ?int $hId = null): array
{
$identifiers = [];
if ($cId !== null) $identifiers['c_id'] = $cId;
if ($hId !== null) $identifiers['h_id'] = $hId;
return $this->send([
'method' => 'payment.status',
'params' => [
'payment' => ['identifiers' => $identifiers],
],
]);
}
/**
* Retrieve account balances.
*/
public function getBalance(): array
{
return $this->send(['method' => 'balance.get', 'params' => new \stdClass()]);
}
}
Usage Examples
Ping (Health Check)
Copy
<?php
require_once 'MultihubClient.php';
$client = new MultihubClient('1', 'your_secret_key');
$result = $client->ping();
if ($result['success']) {
echo "Gateway is up\n";
} else {
echo "Error: {$result['error']['code']} - {$result['error']['message']}\n";
}
Create a Deposit Payment
Copy
<?php
$client = new MultihubClient('1', 'your_secret_key');
$result = $client->createDeposit(
serviceId: 14701,
amount: 10000,
currency: 'INR',
cId: 12345,
extra: [
'description' => 'Order #12345',
'payer' => [
'email' => '[email protected]',
'person' => [
'first_name' => 'John',
'last_name' => 'Doe',
],
],
],
);
if ($result['success']) {
echo "Payment created successfully\n";
echo "Request ID: {$result['request_id']}\n";
} else {
echo "Error: {$result['error']['code']} - {$result['error']['message']}\n";
}
Create a Withdrawal (Payout)
Copy
<?php
$result = $client->createWithdrawal(
serviceId: 14701,
amount: 5000,
currency: 'INR',
cId: 67890,
receiver: [
'bank_account' => '1234567890',
'ifsc_code' => 'SBIN0001234',
'person' => [
'first_name' => 'Jane',
'last_name' => 'Doe',
],
],
extra: [
'description' => 'Payout #67890',
],
);
if ($result['success']) {
echo "Withdrawal created successfully\n";
} else {
echo "Error: {$result['error']['code']} - {$result['error']['message']}\n";
}
Check Payment Status
Copy
<?php
// Look up by client-side ID
$result = $client->getStatus(cId: 12345);
if ($result['success']) {
$status = $result['result']['payment']['status']['status'];
echo "Payment status: {$status}\n";
} else {
echo "Error: {$result['error']['code']} - {$result['error']['message']}\n";
}
// Look up by hub-side ID
$result = $client->getStatus(hId: 999001);
Get Balance
Copy
<?php
$result = $client->getBalance();
if ($result['success']) {
foreach ($result['result']['balances'] as $balance) {
echo "{$balance['currency']}: {$balance['available']}\n";
}
} else {
echo "Error: {$result['error']['code']} - {$result['error']['message']}\n";
}
Error Handling
Successful responses return HTTP 200, errors return HTTP 400. Always use thesuccess field to determine the outcome:
Copy
<?php
$result = $client->createDeposit(14701, 10000, 'INR', 12345);
if ($result['success']) {
// Operation succeeded
echo "Request ID: {$result['request_id']}\n";
echo "Processing time: {$result['processing_time']}s\n";
} else {
// Operation failed
$error = $result['error'];
echo "Error code: {$error['code']}\n";
echo "Error message: {$error['message']}\n";
switch ($error['code']) {
case 'INVALID_HASH':
echo "Authentication failed - check your secret key\n";
break;
case 'INVALID_PARAMS':
echo "Invalid parameters - check request body\n";
break;
case 'SERVICE_UNAVAILABLE':
echo "Service temporarily unavailable - retry later\n";
break;
default:
echo "Unhandled error code: {$error['code']}\n";
}
}
Handling Network Errors
Network-level errors can still occur independently of API responses:Copy
<?php
try {
$result = $client->ping();
if ($result['success']) {
echo "API is reachable\n";
} else {
echo "API error: {$result['error']['message']}\n";
}
} catch (RuntimeException $e) {
echo "Network error: {$e->getMessage()}\n";
} catch (InvalidArgumentException $e) {
echo "Configuration error: {$e->getMessage()}\n";
}
Laravel Integration
Copy
<?php
// app/Services/MultihubService.php
namespace App\Services;
class MultihubService
{
private string $appId;
private string $secretKey;
private string $baseUrl;
public function __construct()
{
$this->appId = config('services.multihub.app_id');
$this->secretKey = config('services.multihub.secret_key');
$this->baseUrl = config(
'services.multihub.base_url',
'https://api.123hub.pro/public/api/multihub/v1'
);
}
private function send(array $body): array
{
$bodyStr = json_encode($body, JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE);
$hash = hash('sha512', $bodyStr . $this->secretKey);
$response = \Illuminate\Support\Facades\Http::withHeaders([
'X-Data-Application-Id' => $this->appId,
'X-Data-Hash' => $hash,
])->post($this->baseUrl, $body);
return $response->json();
}
public function ping(): array
{
return $this->send(['method' => 'gateway.ping', 'params' => new \stdClass()]);
}
public function createDeposit(int $serviceId, float $amount, string $currency, int $cId, array $extra = []): array
{
return $this->send([
'method' => 'payment.in',
'service_id' => $serviceId,
'params' => [
'payment' => array_merge([
'identifiers' => ['c_id' => $cId],
'amount' => ['value' => $amount, 'currency' => $currency],
], $extra),
],
]);
}
public function getStatus(?int $cId = null, ?int $hId = null): array
{
$identifiers = [];
if ($cId !== null) $identifiers['c_id'] = $cId;
if ($hId !== null) $identifiers['h_id'] = $hId;
return $this->send([
'method' => 'payment.status',
'params' => ['payment' => ['identifiers' => $identifiers]],
]);
}
public function getBalance(): array
{
return $this->send(['method' => 'balance.get', 'params' => new \stdClass()]);
}
}
Copy
<?php
// config/services.php (add to existing config)
return [
// ...
'multihub' => [
'app_id' => env('MULTIHUB_APP_ID'),
'secret_key' => env('MULTIHUB_SECRET_KEY'),
'base_url' => env('MULTIHUB_BASE_URL', 'https://api.123hub.pro/public/api/multihub/v1'),
],
];
Complete Example
Copy
<?php
/**
* Multihub API Integration Example
*
* Demonstrates the complete flow: ping, check balance, create a deposit,
* and poll for status.
*/
require_once 'MultihubClient.php';
function main(): void
{
$appId = getenv('MULTIHUB_APP_ID') ?: '1';
$secretKey = getenv('MULTIHUB_SECRET_KEY') ?: 'your_secret_key';
$client = new MultihubClient($appId, $secretKey);
// 1. Ping the gateway
$pingResult = $client->ping();
if (!$pingResult['success']) {
echo "Gateway unreachable: {$pingResult['error']['message']}\n";
return;
}
echo "Gateway is up\n";
// 2. Check balance
$balanceResult = $client->getBalance();
if ($balanceResult['success']) {
foreach ($balanceResult['result']['balances'] as $b) {
echo " {$b['currency']}: {$b['available']}\n";
}
} else {
echo "Balance check failed: {$balanceResult['error']['message']}\n";
}
// 3. Create a deposit
$orderId = time();
$depositResult = $client->createDeposit(
serviceId: 14701,
amount: 10000,
currency: 'INR',
cId: $orderId,
extra: [
'description' => "Order #{$orderId}",
'payer' => [
'email' => '[email protected]',
'person' => ['first_name' => 'John', 'last_name' => 'Doe'],
],
],
);
if ($depositResult['success']) {
echo "Deposit created (request_id={$depositResult['request_id']})\n";
} else {
echo "Deposit failed: {$depositResult['error']['message']}\n";
return;
}
// 4. Poll for status
for ($i = 0; $i < 5; $i++) {
sleep(3);
$statusResult = $client->getStatus(cId: $orderId);
if ($statusResult['success']) {
$status = $statusResult['result']['payment']['status']['status'];
echo "Payment status: {$status}\n";
if (in_array($status, ['completed', 'failed', 'cancelled'])) {
break;
}
} else {
echo "Status check failed: {$statusResult['error']['message']}\n";
break;
}
}
}
main();
