Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.borga.is/llms.txt

Use this file to discover all available pages before exploring further.

Borga subscriptions let you bill customers on a repeating schedule without writing any scheduling logic yourself. You define a product catalogue once — products, then prices — attach them to a subscription for a customer, and Borga takes care of invoice generation, payment collection, and proration when plans change mid-cycle. This guide walks through every step from an empty catalogue to a running subscription.
1

Create a product

A product represents what you are selling — a plan, a service, or a bundle. Create one with a name and an optional description.
curl --request POST \
  --url https://api.borga.is/v1/products \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Pro Plan",
    "description": "Full access to all Pro features, unlimited projects, and priority support."
  }'
Save the product id — you will reference it when creating a price.
2

Create a price

A price defines how much to charge for the product and how often. Attach it to the product you just created and set the billing interval.
curl --request POST \
  --url https://api.borga.is/v1/prices \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID" \
  --header "Content-Type: application/json" \
  --data '{
    "product": "pro_01HXYZ",
    "currency": "ISK",
    "type": "recurring",
    "unit_amount": 4990,
    "recurring": {
      "interval": "month"
    }
  }'
The unit_amount is in whole ISK — 4990 charges 4,990 kr per month. Supported intervals are day, week, month, and year.
A product can have multiple prices — for example, a monthly price and an annual price at a discount. You can archive a price to stop new subscriptions from using it without affecting existing subscribers.
3

Create a customer

If you do not already have a customer in Borga, create one. A customer record links subscriptions, invoices, and saved payment methods to a single identity.
curl
curl --request POST \
  --url https://api.borga.is/v1/customers \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID" \
  --header "Content-Type: application/json" \
  --data '{
    "email": "subscriber@example.is",
    "name": "Anna Sigurðardóttir"
  }'
For charge_automatically subscriptions (the most common setup), the customer must have a default saved payment method before the first invoice is charged. You can collect and save a card using a payment session with save_payment_method: true, then set it as default with POST /v1/payment_methods/{id}/set_default.
4

Create a subscription

Create the subscription by specifying the customer and the price to bill. Pass trial_period_days to give new subscribers a free trial before the first charge.
curl --request POST \
  --url https://api.borga.is/v1/subscriptions \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID" \
  --header "Content-Type: application/json" \
  --data '{
    "customer": "cus_01HXYZ",
    "items": [
      { "price": "pri_01HXYZ", "quantity": 1 }
    ],
    "collection_method": "charge_automatically",
    "trial_period_days": 14
  }'
A subscription created with trial_period_days starts in trialing status. The first invoice is generated when the trial ends. Without a trial the subscription starts active and Borga attempts to charge the customer immediately.
5

Handle renewals

Borga manages the renewal cycle automatically. At the end of each billing period, Borga:
  1. Generates a new invoice for the upcoming period.
  2. Attempts to collect payment from the customer’s default payment method (for charge_automatically).
  3. Emits a subscription.renewed webhook event and an invoice.paid event on success.
You do not need to write any scheduling code. Listen to webhook events to update your application state when renewals succeed or fail — see Webhooks for setup details.
6

Cancel a subscription

Cancel a subscription at the end of the current billing period to let the customer keep access until they have paid for, or at the end of the period immediately on request.
curl --request POST \
  --url https://api.borga.is/v1/subscriptions/sub_01HXYZ/cancel \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID" \
  --header "Content-Type: application/json" \
  --data '{ "at_period_end": true }'
Setting at_period_end: true moves the subscription to canceling status — billing continues until the period ends, then the subscription moves to canceled. If the customer changes their mind before the period ends, call POST /v1/subscriptions/{id}/uncancel to reverse the cancellation.
7

Pause and resume

Pausing a subscription suspends invoicing without ending the subscription. No invoices are generated while the subscription is paused. Resume it to restart billing from the next scheduled cycle.
Pause
curl --request POST \
  --url https://api.borga.is/v1/subscriptions/sub_01HXYZ/pause \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID"
Resume
curl --request POST \
  --url https://api.borga.is/v1/subscriptions/sub_01HXYZ/resume \
  --header "Authorization: Bearer sk_test_YOUR_SECRET_KEY" \
  --header "X-Merchant-Id: mer_YOUR_MERCHANT_ID"
Pausing is useful for accommodating customer requests to temporarily freeze an account without losing the subscription history or configuration.

Subscription lifecycle

StatusMeaning
trialingWithin the trial period. No charges yet.
activeBilling normally.
past_dueLatest invoice is unpaid past its due date.
pausedBilling suspended. No invoices generated.
cancelingCancellation scheduled for end of current period.
canceledSubscription has ended. No further invoices.
When a customer upgrades to a higher-tier plan mid-cycle, use proration_behavior: "always_invoice" when updating the subscription item. Borga generates and immediately finalizes a prorated invoice for the difference rather than rolling it into the next cycle.

Usage-based billing

If you want to charge customers based on consumption rather than a fixed recurring amount, set up a metered price with a meter. See Usage billing for a full walkthrough.

Next steps

  • Usage billing — bill customers based on actual consumption using meters and events
  • Webhooks — receive subscription.created, subscription.canceled, and invoice.paid events
  • Accounting link — sync invoices to your accounting software automatically