Billy billy Beta Docs

Quickstart

From zero to a paid bill.

1. Get an API key

Sign in to the partner dashboard at https://billy.finfactory.dev/partners and issue a key under Developer → API keys. The key is shown once — Billy stores only a hash and can't recover it later.

A sandbox environment with test keys is on the roadmap — reach out if you'd like early access. Today, every payment you post is real.

2. Set your environment

export KEY=billy_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
export BILLY=https://bills.finfactory.dev/api/v1

3. Check your float

Billy pays billers out of a balance you fund in advance. Confirm you have one before anything else — spendable is what a payment can draw on.

curl -H "Authorization: Bearer $KEY" "$BILLY/wallet"
{
  "data": {
    "currency": "PHP",
    "available": "10000.00",
    "held": "0.00",
    "total": "10000.00",
    "credit_limit": "0.00",
    "spendable": "10000.00"
  }
}

Empty? See Your float for how to top up.

4. Find a biller

The id in each result is the biller's opaque public_id (a ULID) — use it for detail, quote, and payment calls.

curl -H "Authorization: Bearer $KEY" "$BILLY/billers?search=pldt"

5. Read the biller's fields

The detail response includes the field schema, the current fee, and policies — everything you need to build the payment form.

curl -H "Authorization: Bearer $KEY" "$BILLY/billers/01KTQCYWKEW9ZX0BS1CTHFYR8B"
{
  "data": {
    "name": "PLDT",
    "fields": [
      {
        "position": 1,
        "name": "10 Digit Account Number",
        "format": "numeric",
        "width": 10,
        "required": true,
        "validation_regex": "^[0-9]{10}$"
      }
    ]
  }
}
Note the position. You send fields back keyed as field_1, field_2… by position — not by name. This catches almost everyone once.

6. Quote a payment

Send an amount; get back Billy's fee and the total the customer pays. The quote runs the same calculation the payment does, so it can't disagree with what you're charged.

curl -H "Authorization: Bearer $KEY" \
  -d '{"amount": 1500}' \
  "$BILLY/billers/01KTQCYWKEW9ZX0BS1CTHFYR8B/quote"
{
  "data": {
    "amount": "1500.00",
    "convenience_fee": "20.00",
    "platform_fee": "25.00",
    "gateway_fee": "0.00",
    "customer_total": "1545.00",
    "currency": "PHP"
  }
}

Add "funding_source": "collect" to quote a Billy-collects payment. Collect adds a gateway_fee — the payment gateway's charge, surcharged to the payer — so its customer_total is higher than the same bill on wallet. Wallet payments always have gateway_fee of 0.00.

7. Pay the bill

Post the payment with an idempotency key so a retry can never pay twice.

curl -H "Authorization: Bearer $KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"amount": 1500, "fields": {"field_1": "1234567890"}}' \
  "$BILLY/billers/01KTQCYWKEW9ZX0BS1CTHFYR8B/payments"
{
  "data": {
    "id": "01kxjehb1aa3ztdy315q0ffbdh",
    "status": "processing",
    "customer_total": "1545.00",
    "reference": null
  }
}

processing means the money is reserved and Billy is posting the bill. It is not yet paid.

8. Find out how it went

Read it back:

curl -H "Authorization: Bearer $KEY" "$BILLY/payments/01kxjehb1aa3ztdy315q0ffbdh"
{
  "data": {
    "id": "01kxjehb1aa3ztdy315q0ffbdh",
    "status": "succeeded",
    "reference": "ECPAY-X8MGLSTUPS"
  }
}

succeeded with a reference — the bill is paid and that's your receipt. In production, don't poll for this: add a webhook and let Billy tell you.

Next steps

  • Your float — balances, holds, top-ups, and the 402 you'll eventually hit.
  • Making a payment — the full flow, including letting Billy collect from your end-user.
  • Webhooks — get the outcome pushed to you, and verify it's really Billy.
  • Errors & idempotency — retry safely.
  • API reference — every endpoint, parameter, and schema.