hivepay/client

Official PHP client for the HivePay payment gateway API

Maintainers

Package info

github.com/hivepayme/client-php

Homepage

pkg:composer/hivepay/client

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-05-10 09:15 UTC

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_hmac with 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.

Links