hivepay / client
Official PHP client for the HivePay payment gateway API
Requires
- php: >=8.2
- ext-curl: *
- ext-hash: *
- ext-json: *
Requires (Dev)
- phpstan/phpstan: ^2.0
- phpunit/phpunit: ^11.0
This package is not auto-updated.
Last update: 2026-05-24 09:34:50 UTC
README
Official PHP client for the HivePay payment gateway API. Accept Hive and HBD payments in your applications.
Using LLMs? Check out our skills: npx skills add hivepayme/agent-skills to enable AI agents to integrate HivePay into your applications with ease.
For AI assistants: Full documentation in a single file at docs.hivepay.me/llms-full.txt. Summary at docs.hivepay.me/llms.txt. OpenAPI spec at hivepay.me/openapi.json.
Features
- PHP 8.2+ with strict typing and readonly properties
- cURL-based HTTP client with timeout handling
- Built-in webhook verification using
hash_hmacwith timing-safe comparison - Custom error class with error codes for programmatic handling
- Generator-based pagination for memory-efficient iteration
- Zero external dependencies (uses native cURL, json, hash extensions)
Installation
composer require hivepay/client
Quick Start
use HivePay\HivePay; $hivepay = new HivePay(['apiKey' => 'sk_live_xxx']); // Create a payment $payment = $hivepay->payments->create([ 'amount' => '10500', // 10.500 HBD (precision 3) 'currency' => 'HBD', 'description' => 'Order #12345', ]); // Redirect user to checkout header('Location: ' . $payment['checkoutUrl']);
For more examples and detailed documentation, see the High-level documentation.
Having connectivity issues?
Visit Status Page to check for any ongoing incidents or maintenance that might be affecting connectivity.
API Reference
Creating a Client
use HivePay\HivePay; $hivepay = new HivePay([ 'endpoint' => 'https://hivepay.me', // optional, default 'apiKey' => 'sk_live_xxx', // required for most operations 'timeout' => 30, // optional, default 30s ]); // Create client without API key (for registration) $publicClient = new HivePay();
Payments
Create a Payment
$payment = $hivepay->payments->create([ 'amount' => '10500', // Amount in smallest unit (satoshis) 'currency' => 'HBD', // 'HIVE' or 'HBD' 'description' => 'Order #123', // Shown to customer ]); echo $payment['id']; // Payment ID echo $payment['checkoutUrl']; // URL to redirect customer
The full payment amount is transferred to your Hive account at settlement. HivePay does not deduct anything from individual transactions — fees are billed separately as a single monthly invoice (see Billing).
Get Payment Details
$payment = $hivepay->payments->get('payment_id'); echo $payment['status']; // 'pending', 'completed', 'cancelled', etc. echo $payment['amount']['formatted']; // '10.500 HBD' echo $payment['amount']['usdCents']; // USD equivalent in cents
Check Payment Status
$status = $hivepay->payments->getStatus('payment_id'); if ($status === 'completed') { // Handle successful payment }
Wait for Payment Completion
// Polls until payment reaches terminal status $status = $hivepay->payments->waitFor('payment_id', [ 'timeout' => 300, // 5 minutes (in seconds) 'interval' => 3, // Check every 3 seconds ]);
List Payments (Paginated)
// Get first page $result = $hivepay->payments->list(); print_r($result['data']); // Array of payments echo $result['pagination']['page']; // Current page: 1 echo $result['pagination']['total']; // Total items echo $result['pagination']['totalPages']; // Total pages // Get specific page with custom size $page3 = $hivepay->payments->list(['page' => 3, 'limit' => 50]);
Iterate Through All Payments
// Uses PHP Generators for memory-efficient iteration foreach ($hivepay->payments->iterate() as $payment) { echo $payment['id'] . ' ' . $payment['status'] . "\n"; } // With custom page size foreach ($hivepay->payments->iterate(['pageSize' => 50]) as $payment) { processPayment($payment); }
Merchants
Register a New Merchant
// No API key required for registration $publicClient = new HivePay(); $result = $publicClient->merchants->register([ 'name' => 'My Store', 'iconUrl' => 'https://example.com/logo.png', 'hiveAccount' => 'mystore', ]); // IMPORTANT: Store the API key securely! echo 'API Key: ' . $result['apiKey']; echo 'Merchant ID: ' . $result['merchant']['id']; // Create authenticated client with new API key $authClient = $publicClient->withApiKey($result['apiKey']);
Get Current Merchant
$merchant = $hivepay->merchants->getCurrent(); echo $merchant['name']; echo $merchant['webhookUrl'];
Update Merchant Settings
$updated = $hivepay->merchants->update('merchant_id', [ 'iconUrl' => 'https://example.com/new-logo.png', 'webhookUrl' => 'https://example.com/webhooks/hivepay', 'hiveAccount' => 'newaccount', ]);
x402 Protocol
HivePay operates an x402 facilitator that lets AI agents and automated clients pay for checkout sessions via the HTTP 402 protocol. The checkout URL returned by payments->create() works for both browsers and x402 clients — no additional setup needed.
See the x402 documentation for the full protocol details.
Toggle x402 Support
x402 is enabled by default for all merchants. Toggle it via the x402Enabled field:
// Disable x402 payments $hivepay->merchants->update('merchant_id', ['x402Enabled' => false]); // Re-enable x402 payments $hivepay->merchants->update('merchant_id', ['x402Enabled' => true]); // Check current status $merchant = $hivepay->merchants->getCurrent(); echo $merchant['x402Enabled'] ? 'enabled' : 'disabled';
Verify a Payment Payload
Validate an x402 payment against a session without broadcasting:
$result = $hivepay->payments->x402Verify('session_id', [ 'x402Version' => 1, 'scheme' => 'exact', 'network' => 'hive:mainnet', 'payload' => [ 'signedTransaction' => $tx, 'nonce' => 'unique-nonce', ], ]); if ($result['isValid']) { echo 'Valid payment from: ' . $result['payer']; } else { echo 'Invalid: ' . $result['invalidReason']; }
Settle a Payment
Verify, broadcast to the Hive blockchain, and mark the session as completed:
$result = $hivepay->payments->x402Settle('session_id', [ 'x402Version' => 1, 'scheme' => 'exact', 'network' => 'hive:mainnet', 'payload' => [ 'signedTransaction' => $tx, 'nonce' => 'unique-nonce', ], ]); if ($result['success']) { echo 'TX: ' . $result['txId'] . ' Payer: ' . $result['payer']; } else { echo 'Failed: ' . $result['errorReason']; }
Billing
HivePay charges merchants on a monthly cycle. Volume processed in a calendar month is billed as a single invoice using the configured fee tiers.
Get Your Billing Summary
$summary = $hivepay->billing->getMine(); // Running totals for the current month echo $summary['currentMonth']['totalVolumeCents']; // e.g. 12500 ($125) echo $summary['currentMonth']['transactionCount']; // e.g. 42 echo $summary['currentMonth']['projectedInvoiceCents']; // estimated month-end fee // Outstanding invoices include a hosted URL the merchant can pay at foreach ($summary['outstandingInvoices'] as $invoice) { echo $invoice['invoiceAmountCents']; // amount in USD cents echo $invoice['status']; // 'invoiced' | 'overdue' echo $invoice['invoicePaymentUrl']; // open or share to pay } // Paid invoice history echo $summary['totalPaidCents'];
Admin Operations
Admin endpoints require an API key with admin privileges.
List Merchants (Paginated)
$result = $hivepay->admin->listMerchants(); // With search query and custom page size $filtered = $hivepay->admin->listMerchants([ 'page' => 1, 'limit' => 50, 'query' => 'store', ]);
Iterate Through All Merchants
foreach ($hivepay->admin->iterateMerchants() as $merchant) { echo $merchant['id'] . ' ' . $merchant['name'] . "\n"; } // With search query foreach ($hivepay->admin->iterateMerchants(['query' => 'store', 'pageSize' => 50]) as $merchant) { echo $merchant['name'] . "\n"; }
Activate/Deactivate Merchant
$hivepay->admin->setActive('merchant_id', true); // Activate $hivepay->admin->setActive('merchant_id', false); // Deactivate
Billing Overview
$overview = $hivepay->billing->getOverview(); echo $overview['totals']['merchantsCount']; // total billable merchants echo $overview['totals']['merchantsBehindCount']; // merchants with overdue or 2+ unpaid invoices echo $overview['totals']['totalOutstandingCents']; // sum of unpaid invoices echo $overview['totals']['currentMonthVolumeCents']; // running volume across all merchants foreach ($overview['merchants'] as $row) { if ($row['isBehind']) { echo "{$row['merchantName']} owes " . ($row['outstandingAmountCents'] / 100) . " USD\n"; echo " oldest unpaid: {$row['oldestUnpaidPeriodStart']}\n"; } }
Inspect a Single Merchant's Billing
$detail = $hivepay->billing->getMerchantSummary('merchant_id'); // Same shape as billing->getMine(), but for any merchant.
List Billing Periods
// All overdue invoices across the platform $overdue = $hivepay->billing->listPeriods(['status' => 'overdue']); foreach ($overdue['data'] as $period) { echo $period['merchantName'] . ' ' . $period['invoiceAmountCents'] . ' ' . $period['invoicePaymentUrl'] . "\n"; } // Iterate foreach ($hivepay->billing->iteratePeriods(['status' => 'invoiced']) as $period) { echo $period['merchantName'] . ' ' . $period['invoicePaymentUrl'] . "\n"; }
Generate Invoices for a Month
Idempotent — runs that pick up a period that already has an invoice are skipped.
$result = $hivepay->billing->generateInvoices(['month' => 4, 'year' => 2026]); echo "Generated {$result['invoicesGenerated']} invoices, total " . ($result['totalBilledCents'] / 100) . " USD\n";
Manage Fee Tiers
// Read $tiers = $hivepay->billing->getTiers(); // Replace (must be contiguous, starting at 0; only the last tier may be open-ended) $hivepay->billing->setTiers([ ['minVolumeCents' => 0, 'maxVolumeCents' => 99999, 'percentFee' => 2.0], ['minVolumeCents' => 100000, 'maxVolumeCents' => null, 'percentFee' => 1.5], ]);
Error Handling
The client throws HivePayError for all API errors:
use HivePay\HivePay; use HivePay\HivePayError; try { $hivepay->payments->get('invalid-id'); } catch (HivePayError $e) { echo $e->errorCode; // 'NOT_FOUND_ERROR' echo $e->statusCode; // 404 echo $e->getMessage(); if ($e->isNotFound()) { // Handle not found } elseif ($e->isAuthError()) { // Handle authentication error } elseif ($e->isValidation()) { // Handle validation error } elseif ($e->isRateLimited()) { // Handle rate limit } }
Error Codes
| Code | Description |
|---|---|
NETWORK_ERROR |
Network request failed or timed out |
API_ERROR |
General API error |
AUTHENTICATION_ERROR |
Invalid or missing API key (401) |
FORBIDDEN_ERROR |
Insufficient permissions (403) |
NOT_FOUND_ERROR |
Resource not found (404) |
VALIDATION_ERROR |
Invalid request parameters (400) |
RATE_LIMIT_ERROR |
Too many requests (429) |
SERVER_ERROR |
Server error (5xx) |
Webhooks
HivePay sends webhooks for payment status changes. The client provides built-in verification using HMAC-SHA256 with timing-safe comparison.
use HivePay\HivePay; $hivepay = new HivePay([ 'webhookSecret' => 'whsec_xxx', // recommended // or: 'apiKey' => 'sk_live_xxx', ]); // In your webhook handler $payload = file_get_contents('php://input'); $signature = $_SERVER['HTTP_X_HIVEPAY_SIGNATURE'] ?? ''; $timestamp = $_SERVER['HTTP_X_HIVEPAY_TIMESTAMP'] ?? ''; $result = $hivepay->verifyWebhook([ 'payload' => $payload, 'signature' => $signature, 'timestamp' => $timestamp, 'maxAge' => 300000, // Optional: reject webhooks older than 5 minutes ]); if (!$result['valid']) { http_response_code(401); echo $result['error']; exit; } $event = $result['event']; if ($event['type'] === 'payment.status_changed') { $paymentId = $event['data']['paymentId']; $status = $event['data']['status']; if ($status === 'completed') { fulfillOrder($paymentId); } } http_response_code(200); echo 'OK';
Testing Webhooks
$hivepay = new HivePay(['apiKey' => 'sk_test_xxx']); $webhook = $hivepay->createTestWebhook([ 'type' => 'payment.status_changed', 'data' => ['id' => 'pay_xxx', 'merchantId' => 'merch_xxx', 'status' => 'completed'], ]); // Use in test request $ch = curl_init('http://localhost:8080/webhooks/hivepay'); curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_POSTFIELDS => $webhook['body'], CURLOPT_HTTPHEADER => [ 'Content-Type: application/json', 'X-HivePay-Signature: ' . $webhook['signature'], 'X-HivePay-Timestamp: ' . $webhook['timestamp'], ], CURLOPT_RETURNTRANSFER => true, ]); $response = curl_exec($ch); curl_close($ch);
Amount Formatting
HivePay charges merchants on a monthly billing cycle (see Billing) — nothing is deducted from individual payments. The full payment amount is transferred to the merchant's Hive account at settlement, so all you typically need is a helper to format raw satoshi values.
use HivePay\Fee; echo Fee::formatSatoshis('10500'); // "10.500" echo Fee::formatSatoshis('150'); // "0.150"
Requirements
- PHP 8.2 or later
- Extensions:
curl,json,hash(all commonly bundled)
License
See LICENSE.md for details.