Resell Bitrefill Products

Standard integration pattern for B2B partners.

This guide describes the standard integration flow for B2B partners. Follow these steps to build a robust integration with Bitrefill.

Overview

A typical integration involves five steps:

flowchart LR
    A[Cache Products] --> B[Create Invoice]
    B --> C[Pay Invoice]
    C --> D[Receive Webhook]
    D --> E[Deliver to User]
  1. Cache the product catalog — Fetch and store products locally
  2. Create an invoice — When a user wants to purchase
  3. Pay the invoice — Via balance or crypto
  4. Receive webhook — Get notified when delivery completes
  5. Deliver to user — Provide the gift card code

Step 1: Cache the Product Catalog

Fetch the full product catalog and cache it locally. This avoids making product requests for every user interaction.

async function fetchAllProducts() {
  const products = [];
  let url = `${BASE_URL}/products?limit=50`;
  
  while (url) {
    const response = await fetch(url, { headers });
    const data = await response.json();
    products.push(...data.data);
    url = data.meta._next || null;
  }
  
  return products;
}

Refresh Frequency

Refresh your product cache regularly:

  • Minimum: Daily
  • Recommended: Every few hours
  • Best: Hourly or more frequently

Products can go out of stock or have issues. Stale data leads to failed orders.

Always check product availability before creating invoices. An out-of-stock product will return an error.

What to Cache

For each product, store:

FieldPurpose
idProduct identifier for invoices
nameDisplay name
packagesFixed denominations with package_id
rangeFlexible value range (min/max/step)
countryFilter by region
currencyProduct denomination currency
in_stockAvailability status

Step 2: Create an Invoice

When a user wants to purchase, create an invoice:

const response = await fetch(`${BASE_URL}/invoices`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    products: [{
      product_id: 'amazon-us',
      package_id: 'amazon-us<&>50',
      quantity: 1
    }],
    payment_method: 'balance',
    webhook_url: 'https://your-server.com/bitrefill-webhook',
    auto_pay: false
  })
});

Request Parameters

ParameterRequiredDescription
productsYesArray of products to purchase
products[].product_idYesProduct identifier
products[].package_idNo*Package ID for fixed denominations
products[].valueNo*Value for range-based products
products[].quantityNoNumber of units (default: 1)
products[].phone_numberNoRequired for phone top-ups
payment_methodNobalance or bitcoin (default: balance)
refund_addressNoRequired for crypto payments
webhook_urlNoURL for delivery notifications
auto_payNoPay immediately from balance (default: false)
emailNoEnd user email for notifications

*Either package_id or value is required.

Multiple Products

Include multiple products in one invoice. Each product becomes a separate order. Maximum 20 items per invoice.

Step 3: Pay the Invoice

Option A: Automatic Balance Payment

Set auto_pay: true when creating the invoice. The invoice is paid immediately if you have sufficient balance.

Option B: Manual Balance Payment

Create the invoice without auto_pay, then call the pay endpoint:

await fetch(`${BASE_URL}/invoices/${invoiceId}/pay`, {
  method: 'POST',
  headers,
  body: JSON.stringify({})
});

Option C: Crypto Payment

Create an invoice with a crypto payment method and refund_address. The response includes payment details (address, amount). Send the exact amount to the address.

Step 4: Handle Webhooks

When an invoice reaches its final state, Bitrefill POSTs to your webhook_url. See Webhooks for detailed implementation.

Alternative: Polling

If webhooks aren't suitable, poll for status until it's a final state (complete, denied, payment_error).

Step 5: Retrieve Order Details

Once the invoice is complete, get the redemption info:

const response = await fetch(`${BASE_URL}/orders/${orderId}`, { headers });
const { data: order } = await response.json();

console.log('Code:', order.redemption_info.code);
console.log('Instructions:', order.redemption_info.instructions);

Redemption Info Fields

FieldDescription
codeGift card code
linkRedemption URL
pinPIN if required
instructionsRedemption instructions
expiration_dateWhen the code expires

Not all fields are present for every product type.

Error Handling

Invoice Creation Errors

Error CodeDescriptionAction
not_foundProduct doesn't existRefresh product cache
out_of_stockProduct unavailableShow user, try later
invalid_paramBad parameter valueCheck request format
balance_too_lowInsufficient fundsAdd balance or use crypto
too_many_items>20 items in invoiceSplit into multiple invoices

Order Delivery Errors

Handle partial failures — some orders may succeed while others fail.

Complete Integration Checklist

  • Product catalog caching with regular refresh
  • Invoice creation with error handling
  • Payment flow (balance and/or crypto)
  • Webhook endpoint for delivery notifications
  • Order retrieval for redemption info
  • Error handling for all failure modes
  • Logging for debugging and auditing
  • Testing with test products