Products API
Manage a reusable catalog of products and prices, then charge them from a payment session — a Stripe-style split.
A product has one or more prices (e.g. one per currency). To charge a customer, pass a price's priceId (or a lineItems array) to payments.create(). Products and prices are archived, never deleted, so historical payments always resolve to what was charged.
Create a Product
Optionally create prices together with the product.
const product = await hivepay.products.create({
name: 'Pro Plan',
description: 'Full access to all premium features',
prices: [
{ amount: '50000', currency: 'HBD' }, // 50.000 HBD
{ amount: '120000', currency: 'HIVE' } // 120.000 HIVE
]
});
console.log(product.id); // 'prod_xxx'
console.log(product.prices[0].id); // 'price_xxx'
$product = $hivepay->products->create([
'name' => 'Pro Plan',
'description' => 'Full access to all premium features',
'prices' => [
['amount' => '50000', 'currency' => 'HBD'],
['amount' => '120000', 'currency' => 'HIVE'],
],
]);
curl -X POST https://hivepay.me/api/public/products/create \
-H "X-API-Key: sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Pro Plan",
"prices": [{ "amount": "50000", "currency": "HBD" }]
}'
Parameters
Add a Price
A product can carry multiple prices — for example one per currency.
const price = await hivepay.products.createPrice('prod_xxx', {
amount: '9900',
currency: 'HBD'
});
$price = $hivepay->products->createPrice('prod_xxx', [
'amount' => '9900',
'currency' => 'HBD',
]);
curl -X POST https://hivepay.me/api/public/products/prod_xxx/prices/create \
-H "X-API-Key: sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{ "amount": "9900", "currency": "HBD" }'
List & Get Products
Listings return active products only by default. Ad-hoc products (created automatically for one-time payments) are never listed.
const { data, pagination } = await hivepay.products.list();
const all = await hivepay.products.list({ includeArchived: true });
const one = await hivepay.products.get('prod_xxx');
// Iterate through every product
for await (const product of hivepay.products) {
console.log(product.name, product.prices.length);
}
$result = $hivepay->products->list();
$all = $hivepay->products->list(['includeArchived' => true]);
$one = $hivepay->products->get('prod_xxx');
foreach ($hivepay->products->iterate() as $product) {
echo $product['name'] . "\n";
}
curl "https://hivepay.me/api/public/products/list?includeArchived=true" \
-H "X-API-Key: sk_live_xxx"
Update & Archive
Update a product's mutable fields, or archive products/prices to hide them from listings without breaking past payments.
await hivepay.products.update('prod_xxx', { name: 'Pro Plan (2026)' });
await hivepay.products.archive('prod_xxx'); // active = false
await hivepay.products.archivePrice('prod_xxx', 'price_xxx');
$hivepay->products->update('prod_xxx', ['name' => 'Pro Plan (2026)']);
$hivepay->products->archive('prod_xxx');
$hivepay->products->archivePrice('prod_xxx', 'price_xxx');
# Archive a product
curl -X POST https://hivepay.me/api/public/products/prod_xxx \
-H "X-API-Key: sk_live_xxx" -H "Content-Type: application/json" \
-d '{ "active": false }'
Charge a Product
Charge a price from a payment session. See Creating Payments for the full flow.
// Single price with an optional quantity
const payment = await hivepay.payments.create({ priceId: 'price_xxx', quantity: 2 });
// Multiple line items — all prices must share the same currency
const cart = await hivepay.payments.create({
lineItems: [
{ priceId: 'price_plan' },
{ priceId: 'price_addon', quantity: 3 }
]
});
// Redirect the customer to checkout
window.location.href = payment.checkoutUrl;
$payment = $hivepay->payments->create(['priceId' => 'price_xxx', 'quantity' => 2]);
$cart = $hivepay->payments->create([
'lineItems' => [
['priceId' => 'price_plan'],
['priceId' => 'price_addon', 'quantity' => 3],
],
]);
header('Location: ' . $payment['checkoutUrl']);
The session stores a snapshot of the total amount, currency, and description, so the payment is unaffected if the underlying product or price is later edited or archived.
Next Steps