Skip to main content

Media Publishing Billing

How to implement paper + digital news products under a single contract with bundle discounts using Billerang.

Business Model

OfferProductsMonthly Price
Paper OnlyPaper newspaper$29.00
Digital OnlyDigital access$14.00
BundlePaper + Digital$35.00 (save $8)
Pay-Per-ArticleDigital articles5 free/month + $1.99/article

Key requirements:

  • Same products reused across offers with different pricing
  • Bundle discount via offer-scoped price plan matrices
  • Mid-contract amendment (drop/add products)
  • Counter-based free article allowance

Catalog Structure

Step-by-Step Implementation

1. Create Charges

Paper subscription charge:

POST /api/rest/v2/chargeTemplate/RC_PAPER
{
"chargeType": "RECURRING",
"description": "Paper newspaper subscription",
"calendar": "MONTHLY",
"subscriptionProrata": true,
"terminationProrata": true,
"applyInAdvance": true,
"invoiceSubCategoryCode": "ISC_PAPER_SUB",
"taxClassCode": "TAX_PRESS",
"pricing": {
"mode": "FLAT",
"baseCurrency": "USD",
"price": 29.00,
"autoPublish": true
}
}

Digital access charge:

POST /api/rest/v2/chargeTemplate/RC_DIGITAL
{
"chargeType": "RECURRING",
"description": "Digital news access",
"calendar": "MONTHLY",
"subscriptionProrata": true,
"terminationProrata": true,
"applyInAdvance": true,
"invoiceSubCategoryCode": "ISC_DIGITAL_SUB",
"taxClassCode": "TAX_DIGITAL",
"pricing": {
"mode": "FLAT",
"baseCurrency": "USD",
"price": 14.00,
"autoPublish": true
}
}

Article usage charge (with counter):

# Counter for free articles
POST /api/rest/catalog/counterTemplate/createOrUpdate
{
"code": "CTR_FREE_ARTICLES",
"description": "5 free articles per month",
"counterType": "USAGE",
"ceiling": 5,
"calendar": "MONTHLY",
"counterLevel": "UA"
}

# Usage charge for articles
POST /api/rest/v2/chargeTemplate/UC_ARTICLE_READ
{
"chargeType": "USAGE",
"description": "Per-article read charge (after free tier)",
"invoiceSubCategoryCode": "ISC_PAY_PER_USE",
"taxClassCode": "TAX_DIGITAL",
"filterExpression": "#{edr.parameter1 == 'ARTICLE_READ'}",
"pricing": {
"mode": "PER_UNIT",
"baseCurrency": "USD",
"price": 1.99,
"autoPublish": true
}
}

2. Create Products

POST /api/rest/catalog/products
{ "code": "PAPER_NEWS", "description": "Daily paper newspaper delivery" }
POST /api/rest/catalog/products/PAPER_NEWS/addCharges
{ "productCharges": [{ "chargeTemplateCode": "RC_PAPER" }] }

POST /api/rest/catalog/products
{ "code": "DIGITAL_NEWS", "description": "Unlimited digital news access" }
POST /api/rest/catalog/products/DIGITAL_NEWS/addCharges
{ "productCharges": [{ "chargeTemplateCode": "RC_DIGITAL" }] }

POST /api/rest/catalog/products
{ "code": "ARTICLE_ACCESS", "description": "Pay-per-article access" }
POST /api/rest/catalog/products/ARTICLE_ACCESS/addCharges
{ "productCharges": [{ "chargeTemplateCode": "UC_ARTICLE_READ", "counterTemplateCode": "CTR_FREE_ARTICLES" }] }

3. Create Offers with Bundle Pricing

Standalone offers (use default charge pricing):

POST /api/rest/catalog/offerTemplate/createOrUpdate
{
"code": "MEDIA_PAPER_ONLY",
"description": "Paper newspaper only",
"offerProductTemplates": [{ "productTemplate": { "code": "PAPER_NEWS" }, "mandatory": true }]
}

POST /api/rest/catalog/offerTemplate/createOrUpdate
{
"code": "MEDIA_DIGITAL_ONLY",
"description": "Digital access only",
"offerProductTemplates": [{ "productTemplate": { "code": "DIGITAL_NEWS" }, "mandatory": true }]
}

Bundle offer (with offer-scoped PPM overrides):

POST /api/rest/catalog/offerTemplate/createOrUpdate
{
"code": "MEDIA_BUNDLE",
"description": "Paper + Digital bundle ($35/mo, save $8)",
"offerProductTemplates": [
{ "productTemplate": { "code": "PAPER_NEWS" }, "mandatory": true },
{ "productTemplate": { "code": "DIGITAL_NEWS" }, "mandatory": true }
]
}

Now create offer-scoped PPMs to override the standalone prices:

# Bundle price for paper: $25 instead of $29
POST /api/rest/catalog/pricePlanMatrix/createOrUpdate
{
"code": "PP_PAPER_BUNDLE",
"description": "Paper price in bundle",
"eventCode": "RC_PAPER",
"offerTemplateCode": "MEDIA_BUNDLE",
"priority": 1,
"pricePlanMatrixVersions": [{
"status": "PUBLISHED",
"price": 25.00
}]
}

# Bundle price for digital: $10 instead of $14
POST /api/rest/catalog/pricePlanMatrix/createOrUpdate
{
"code": "PP_DIGITAL_BUNDLE",
"description": "Digital price in bundle",
"eventCode": "RC_DIGITAL",
"offerTemplateCode": "MEDIA_BUNDLE",
"priority": 1,
"pricePlanMatrixVersions": [{
"status": "PUBLISHED",
"price": 10.00
}]
}

How bundle pricing works:

  • Each PricePlanMatrix has an offerTemplateCode field
  • During rating, the engine selects the PPM that matches both the charge code AND the offer
  • Bundle PPMs have higher priority than the default (standalone) PPMs
  • Same product, same charge, different price depending on the offer

Pay-per-article offer:

POST /api/rest/catalog/offerTemplate/createOrUpdate
{
"code": "MEDIA_PAY_PER_ARTICLE",
"description": "Pay per article (5 free/month)",
"offerProductTemplates": [{ "productTemplate": { "code": "ARTICLE_ACCESS" }, "mandatory": true }]
}

Mid-Contract Amendment: Drop Digital

When a bundle subscriber wants to drop digital access mid-cycle:

POST /api/rest/orderManagement/commercialOrders
{
"code": "ORD_AMEND_001",
"billingAccountCode": "BA_SUBSCRIBER",
"orderDate": "2026-03-15T00:00:00Z",
"orderItems": [{
"action": "MODIFY",
"subscriptionCode": "SUB_BUNDLE_001",
"productsToTerminate": [{ "productCode": "DIGITAL_NEWS" }],
"terminationDate": "2026-03-15T00:00:00Z"
}]
}

Invoice result (March):

Paper (full month, bundle price):    $25.00
Digital (Mar 1-15, bundle price): $5.00 (prorated $10)
Digital Credit (Mar 15-31): -$5.00 (prorated credit)

Note: From April, Paper falls back to standalone pricing ($29/mo)
since only one product remains in the subscription.

Pay-Per-Article Flow

Key Billerang Features Used

FeaturePurpose
Offer-scoped PPMBundle discount without changing the product/charge
Product reuseSame PAPER_NEWS/DIGITAL_NEWS across standalone and bundle
ProrationFair billing on mid-cycle amendments
Counter template5 free articles per month
Usage chargePer-article billing after free tier
AMEND orderMid-contract product add/remove
PPM priorityBundle PPM overrides standalone PPM