ForhoppPay Connect — Subscription Add-Ons (Items)
Feature Reference: FR-4.1 | Service:
SubscriptionItemService| Controller:ConnectSubscriptionItemController
1. Overview
Subscription add-ons allow merchants to attach additional line items (prices) to an existing subscription mid-cycle. Each item can have its own quantity and generates prorated charges or credits when added or removed. At the next billing cycle, the consolidated invoice includes all active items plus any pending prorations.
2. Endpoints
| Method | Path | Description |
|---|---|---|
POST |
/api/v1/connect/subscriptions/{subId}/items |
Add an item |
GET |
/api/v1/connect/subscriptions/{subId}/items |
List items |
PATCH |
/api/v1/connect/subscriptions/{subId}/items/{itemId} |
Update quantity |
DELETE |
/api/v1/connect/subscriptions/{subId}/items/{itemId} |
Remove item |
All endpoints require API key authentication.
3. Add Item
3.1 Request
POST /api/v1/connect/subscriptions/sub_xxx/items
Authorization: Bearer sk_live_xxx
Content-Type: application/json
{
"priceId": "price_addon123",
"quantity": 2,
"prorationBehavior": "defer_to_next_cycle",
"metadata": { "feature": "extra_storage" }
}
3.2 Parameters
| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
priceId |
string | Yes | — | Price ID for the add-on |
quantity |
integer | No | 1 | Number of units (min 1) |
prorationBehavior |
string | No | defer_to_next_cycle |
How to handle mid-cycle cost |
metadata |
object | No | — | Arbitrary key-value pairs |
3.3 Proration Behaviors
| Behavior | Description |
|---|---|
defer_to_next_cycle |
Proration calculated but charged on next invoice (default) |
charge_immediately |
Create and charge a proration invoice now |
none |
No proration, item starts at next cycle |
3.4 Response
{
"id": "si_item_xxx",
"subscriptionId": "sub_xxx",
"priceId": "price_addon123",
"quantity": 2,
"status": "active",
"prorationBehavior": "defer_to_next_cycle",
"prorationAmountCents": 1500,
"isBaseItem": false,
"addedAt": "2026-06-25T12:00:00",
"removedAt": null,
"metadata": { "feature": "extra_storage" }
}
4. Update Item Quantity
PATCH /api/v1/connect/subscriptions/sub_xxx/items/si_item_xxx
Authorization: Bearer sk_live_xxx
Content-Type: application/json
{ "quantity": 5 }
Changes in quantity generate a proration (difference between old and new cost for the remaining period).
5. Remove Item
DELETE /api/v1/connect/subscriptions/sub_xxx/items/si_item_xxx?immediate=false
Authorization: Bearer sk_live_xxx
| Parameter | Default | Description |
|---|---|---|
immediate |
false |
If true, remove now with credit proration. If false, remove at period end. |
6. Proration Calculation
When an item is added mid-cycle:
days_remaining = period_end - now
days_total = period_end - period_start
item_cost = price × quantity
proration = (item_cost × days_remaining) / days_total
For removals, a credit proration is generated with the same formula.
7. Consolidated Invoicing
At billing time, the SubscriptionBillingService builds a consolidated invoice:
- Sum all active items:
base_item + addon1 + addon2 + ... - Add pending prorations (deferred charges from mid-cycle adds)
- Subtract pending credits (deferred credits from mid-cycle removals)
- Apply tax
- Charge total
Invoice line items include:
subscription— base subscription chargeaddon— add-on item chargespast_due_proration— deferred proration chargescredit— deferred proration credits
8. Base Item
Every subscription has a base item created automatically at subscription creation time (with is_base_item = true). This represents the original price the customer subscribed to. It cannot be removed.
9. Webhook Events
| Event | When |
|---|---|
subscription_item.created |
Item added |
subscription_item.updated |
Quantity changed |
subscription_item.deleted |
Item removed |
10. Database Tables
forhopppay.subscription_items— active items per subscriptionforhopppay.pending_prorations— deferred proration charges/creditsforhopppay.subscription_invoice_line_items— breakdown per invoice
11. Correctness Properties
| # | Property | Validates |
|---|---|---|
| 45 | Proration proportional to days remaining in cycle | FR-4.1.1 |
| 46 | Removal at period end generates no proration | FR-4.1.2 |
| 47 | Consolidated invoice = sum(items) + prorations - credits | FR-4.1.3 |
| 48 | Base item cannot be removed | FR-4.1.4 |
Last Updated: June 2026
