Client Integration
Build apps and AI agents that can pay for HivePay checkout URLs automatically.
Overview
There are two ways to pay for HivePay x402-enabled checkout URLs:
- Automated — use
HiveX402Clientfor server-side apps and AI agents that hold a private key - Browser — use
buildPaymentTransaction()+ a wallet extension (Hive Keychain, HiveAuth) for browser-based apps
Automated Client (Server-side)
The HiveX402Client wraps the native fetch() API and transparently handles the 402 -> sign -> retry flow.
import { HiveX402Client } from '@hiveio/x402/client';
const client = new HiveX402Client({
account: 'alice',
activeKey: '5K...', // Hive active private key (WIF format)
maxPayment: 15.0 // Max HBD per request (default: 1.0)
});
// Pay for a HivePay checkout URL
const response = await client.fetch('https://hivepay.me/for/order-abc123');
const data = await response.json();
console.log(data.txId); // On-chain transaction ID
console.log(data.payer); // "alice"
console.log(data.sessionId); // HivePay session ID
Configuration
Protect Your Private Key
The activeKey has full transfer authority over your account. Only use this in secure server-side environments. Never expose it in client-side JavaScript.
HivePay x402 Transaction Structure
Unlike standard x402 (single transfer), HivePay x402 requires two transfer operations in the signed transaction — one for the merchant's net amount and one for HivePay's fee.
The 402 response includes the breakdown in the extra field:
{
"extra": {
"sessionId": "cmj7b2rg10004d2rimvum8kaz",
"feeAccount": "hivepay",
"feeAmount": "0.158 HBD",
"netAmount": "10.342 HBD"
}
}
The signed transaction must contain:
Browser Client
For browser-based apps, you cannot embed private keys. Instead, use the library's building blocks with an external wallet signer.
With Hive Keychain
import { parseRequirements } from '@hiveio/x402/client';
async function payForCheckout(checkoutUrl: string, account: string) {
// Step 1: Request the checkout URL, get 402 requirements
const initialResponse = await fetch(checkoutUrl);
if (initialResponse.status !== 402)
return initialResponse; // Not a 402 or already paid
// Step 2: Parse payment requirements from the response
const body = await initialResponse.json();
const requirements = body.accepts[0];
const { feeAccount, feeAmount, netAmount } = requirements.extra;
// Step 3: Build the two-operation transaction using Hive Keychain
const ops = [
['transfer', {
from: account,
to: requirements.payTo,
amount: netAmount,
memo: `pos-${requirements.extra.sessionId}`
}],
['transfer', {
from: account,
to: feeAccount,
amount: feeAmount,
memo: `Fee for ${requirements.extra.sessionId}`
}]
];
// Step 4: Sign with Hive Keychain
const signResult = await new Promise((resolve, reject) => {
window.hive_keychain.requestBroadcast(
account,
ops,
'Active',
(response) => {
if (response.success) resolve(response);
else reject(new Error(response.message));
}
);
});
// Payment is broadcast — HivePay detects it via block scanning
return signResult;
}
Note
When using Hive Keychain, the transaction is broadcast directly by the wallet extension. HivePay's block scanner will detect the transfers and mark the session as completed, just like a normal Hive checkout payment.
AI Agent Integration
x402 is designed for autonomous machine-to-machine payments. AI agents can use the automated client to complete HivePay payment sessions without human intervention.
import { HiveX402Client } from '@hiveio/x402/client';
// Create a client for your AI agent
const agent = new HiveX402Client({
account: 'my-ai-agent',
activeKey: process.env.HIVE_ACTIVE_KEY!,
maxPayment: 50.0 // Budget limit per request
});
// Example: An AI agent that pays for premium API access
async function purchaseApiAccess(merchantApiUrl: string) {
// Merchant creates a payment session
const session = await fetch(`${merchantApiUrl}/create-payment`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ plan: 'premium', duration: '1month' })
}).then(r => r.json());
// Agent pays via x402 using the checkout URL
const paymentResult = await agent.fetch(session.checkoutUrl);
const confirmation = await paymentResult.json();
console.log(`Paid ${confirmation.payer} -> tx: ${confirmation.txId}`);
return confirmation;
}
Budget Control
Use maxPayment to limit how much an agent can spend per request. If a resource costs more than the limit, the client throws an error instead of paying.
const client = new HiveX402Client({
account: 'my-agent',
activeKey: '5K...',
maxPayment: 1.0 // Only allow payments up to 1.000 HBD
});
// This will throw if the session charges more than 1.000 HBD
try {
await client.fetch('https://hivepay.me/for/expensive-item-xyz');
} catch (error) {
console.error('Payment exceeds budget:', error.message);
}
Programmatic Verify & Settle (SDK)
If you build your own x402 transaction signing and don't use HiveX402Client, you can call the HivePay verify and settle endpoints directly through the @hivepay/client SDK.
This is useful when you want full control over transaction construction, or when integrating x402 into an existing backend pipeline.
import { HivePay } from '@hivepay/client';
const hivepay = new HivePay({ apiKey: 'sk_live_xxx' });
// After constructing and signing the transaction yourself:
const payload = {
x402Version: 1 as const,
scheme: 'exact' as const,
network: 'hive:mainnet',
payload: {
signedTransaction: mySignedTx,
nonce: crypto.randomUUID()
}
};
// Optional: verify first (does NOT broadcast)
const check = await hivepay.payments.x402Verify('session_id', payload);
if (!check.isValid) {
throw new Error(check.invalidReason);
}
// Settle: verify + broadcast + mark session completed
const result = await hivepay.payments.x402Settle('session_id', payload);
if (result.success) {
console.log(`Paid! TX: ${result.txId}, Payer: ${result.payer}`);
}
use HivePay\HivePay;
$hivepay = new HivePay(['apiKey' => 'sk_live_xxx']);
$payload = [
'x402Version' => 1,
'scheme' => 'exact',
'network' => 'hive:mainnet',
'payload' => [
'signedTransaction' => $mySignedTx,
'nonce' => bin2hex(random_bytes(16)),
],
];
// Optional: verify first (does NOT broadcast)
$check = $hivepay->payments->x402Verify('session_id', $payload);
if (!$check['isValid']) {
throw new RuntimeException($check['invalidReason']);
}
// Settle: verify + broadcast + mark session completed
$result = $hivepay->payments->x402Settle('session_id', $payload);
if ($result['success']) {
echo "Paid! TX: {$result['txId']}, Payer: {$result['payer']}";
}
Error Handling
Common errors when making x402 payments:
External Resources
- x402 Protocol Specification — the open standard by Coinbase
- @hiveio/x402 on npm — the Hive implementation by Ecency
- hive-x402 on GitHub — source code and documentation
- Hive CAIP-2 Namespace — Hive's registration in the cross-chain standard