Guide: Product configuration in the subscription system (entitlements & credits)
Using the “Credit & Entitlement” architecture, we configure products in the backend so that they directly control our internal business logic (costs, credits, feature activations). The system supports seamless transitions between different tiers (upgrades and downgrades).
creditPrice (The ‘chameleon’ field for credits): This field controls credit transactions, but behaves differently depending on the payment method and subscription type:paidWithCredits = true): The value defines the pure cost. The amount is debited from the wallet (for one-off purchases or on a recurring basis for the automatic renewal of internal subscriptions).paidWithCredits = false): This value defines the credit equivalent of the real-money payment. The system distinguishes between different types:WALLET_TOP_UP .billingInterval (cycle): Optional. Specifies whether this is a subscription (e.g. „month“ or „year“).additionalProperties → subscriptionInfo (The core feature): A JSON object that defines what the entitlement (internal subscription) exactly unlocks for the user.
The subscriptionInfo directly controls the permissions (HostFeature) of the user.
type: The category bracket (e.g. „credit“, „licence“, „visualiser“). Per user and type , there is always a maximum of one active entitlement.level: The configuration level. Higher levels override lower levels of the same type (and vice versa in the case of downgrades).features: A key-value object for specific rights. The backend processes the values by type:true): Is adopted 1:1 as a flag (e.g. „panorama.model3ds“: true becomes panorama.model3ds = „true“).Integer): The backend combines the key and the number to form a new flag string (e.g. „host.licences.visualizer“: 3 becomes host.licences.visualizer3 = „true“).A typical product for new customers or for changing subscription levels (upgrades and downgrades).
creditPrice: 50 (Cost for wallet payments / equivalent value for Stripe payments for currency conversions and subsequent refunds)billingInterval: „month“subscriptionInfo:"subscriptionInfo": {
"type": "visualizer",
"level": 3,
"features": {
"host.licences.visualizer": 3,
"panorama.model3ds": true
}
}
What happens? The backend books the entitlement for type „visualizer“ and sets the HostFeatures host.licences.visualizer3 = „true“ as well as panorama.model3ds = „true“ . Old Visualizer keys from a previous level (e.g. visualizer2) are automatically cleared in the process.
Another level-based subscription with an annual billing cycle.
creditPrice: 150billingInterval: „year“subscriptionInfo:"subscriptionInfo": {
"type": "licence",
"level": 2,
"features": {
"host.licences.licence": 2
}
}
This product is designed to be paid for regularly via Stripe, with credits credited to the user’s wallet in return.
creditPrice: 100 (As it is a „credit“ type, this serves purely as a top-up value)billingInterval: „month“subscriptionInfo:"subscriptionInfo": {
"type": "credit",
"features": {}
}
What happens? The user pays real money via Stripe. The webhook recognises the type „credit“ and skips the direct chargeback. The creditPrice of 100 remains as WALLET_TOP_UP in the user’s wallet. Pro-rata refunds are automatically disabled for this type.