Setting your app's billing model
Once your app has been developed and is ready to go live, it's time to think about its distribution. In this step, you must define who will be allowed to install your app, whether your app will be paid or not, and how much it will cost if so.
When preparing your app for distribution, you must first establish if your new app will be private or public on the VTEX IO platform.
- Private apps can only be installed by their
vendoraccount (i.e., the account responsible for the app's development and maintenance). - Public apps are available to all accounts of the VTEX IO ecosystem. These apps can be charged or not.
Setting the app as private
Take the following steps to make your app private:
- Open your project in any code editor of your preference.
- Open the
manifest.jsonfile and remove thebillingOptionsfield.
Without billingOptions, VTEX IO will understand that the app in question should not be made available to any account other than the one specified in the vendor field of the manifest.json file.
Setting the app as public
When making your app public available to the VTEX IO ecosystem, you must set up the billingOptions field in the app's manifest.json file. In this context, you first need to define whether or not your app will be charged. For more information, please refer to the billingOptions documentation.
You can contact the VTEX support team to get more information about the contracts and accounts that have installed your app.
Instructions
The first step in making an app public is defining whether the app will be charged or not. Consider the following according to your scenario:
Setting the app as free
-
Open your app in any code editor of your preference.
-
Open the
manifest.jsonfile. -
Add the
billingOptionsfield to your app'smanifest.jsonfile and set thetypeproperty asfree. -
Set up the
supportproperty to provide a support channel for the app users. -
Set up the
availableCountriesproperty to define in which countries the app will be available. If you want to make it available for all countries, use*._10"billingOptions": {_10"type": "free",_10"support": {_10"email": "support@com.br",_10"url": "https://support.com/hc/requests"_10},_10"availableCountries" : ["*"]_10}
Setting the app as charged
-
Open your app in any code editor of your preference.
-
Open the
manifest.jsonfile. -
Create the
billingOptionsfield in the app'smanifest.jsonfile and set thetypeproperty asbillable. -
Set up the
supportproperty to provide a support channel for the app users. -
Set up the
availableCountriesproperty to define in which countries the app will be available. If you want to make it available for all countries, use*._10"billingOptions": {_10"type": "billable",_10"support": {_10"email": "support@com.br",_10"url": "https://support.com/hc/requests"_10},_10"availableCountries" : ["*"]_10} -
Now, choose one of the following billing options and follow the procedures corresponding to your selection.
- Fixed subscription - Charges a fixed subscription price per month. This billing model only allows a single subscription plan to be created for the app.
- Fixed subscription + Variable rate - Charges a fixed subscription price plus a variable charge based on the app's usage. Apps with a variable rate are charged according to a metric value.
- Variable subscription + Variable rate - Charges a variable subscription price plus a variable rate based on the app's usage. Apps with a variable rate are charged according to a metric value.
-
Finally, if you opt for a variable-charge pricing strategy, take the steps presented in the Registering the metrics data section.
Fixed subscription
Establish a subscription plan for your app by setting up the plan property and its child properties:
id: Plan identifier.currency: Currency code following the ISO.price.subscription: Subscription price. This property is of typenumberand accepts values with or without cents. Examples:10(10 dollars),60.25(60 dollars and 25 cents),0.9(90 cents).
Example of an app with a fixed subscription price
_15 "billingOptions": {_15 "type": "billable",_15 "support": {_15 "email": "support@com.br",_15 "url": "https://support.com/hc/requests"_15 },_15 "availableCountries": ["*"],_15 "plans": [{_15 "id": "PlanBRL",_15 "currency": "BRL",_15 "price": {_15 "subscription": 100_15 }_15 }]_15 }
Fixed subscription + variable rate
- Establish a subscription plan for your app by setting up the
planproperty and its child properties:
id: Plan identifier.currency: Currency code following the ISO.price.subscription: Subscription price. This property is of typenumberand accepts values with or without cents. Examples:10(10 dollars),60.25(60 dollars and 25 cents),0.9(90 cents).price.metrics: An array specifying the metric's id and the ranges related to the app's usage and associated extra charge. Notice that you can set one or more metrics to calculate the variable rate.
Example of an app with a fixed subscription price plus a variable rate that considers only one metric
_32 "billingOptions": {_32 "type": "billable",_32 "support": {_32 "email": "support@com.br"_32 },_32 "availableCountries": ["*"],_32 "plans": [{_32 "id": "PlanUSD",_32 "currency": "USD",_32 "price": {_32 "subscription": 50,_32 "metrics": [{_32 "id": "smsSent",_32 "ranges": [{_32 "exclusiveFrom": 0,_32 "inclusiveTo": 2000,_32 "multiplier": 0.07_32 },_32 {_32 "exclusiveFrom": 2000,_32 "inclusiveTo": 4000,_32 "multiplier": 0.06_32 },_32 {_32 "exclusiveFrom": 4000,_32 "multiplier": 0.05_32 }_32 ]_32 }]_32 }_32 }]_32 }
From the previous example, we have:
- Each SMS costs
US$ 0.07(multiplier) when more than0(exclusiveFrom: 0) SMSs and less than or equal to2000(inclusiveTo: 2000) SMSs have already been sent. - Each SMS costs
US$ 0.06(multiplier) when more than2000(exclusiveFrom: 2000) and less than or equal to4000(inclusiveTo: 4000) SMSs have already been sent. - Each SMS costs
US$ 0.05(multiplier) when more than4000(exclusiveFrom: 4000) SMSs have already been sent.
Therefore, the extra variable rate would be charged as follows:
- For 1500 SMSs = US$ 105.00 (1500 x US$ 0.07 = US$ 105.00)
- For 3500 SMSs = US$ 210.00 (3500 x US$ 0.06 = US$ 210.00)
- For 7000 SMSs = US$ 350.00 (7000 x US$ 0.05 = US$ 350.00)
Example of an app with a fixed subscription price plus a variable rate that considers more than one metric
_38 "billingOptions": {_38 "type": "billable",_38 "support": {_38 "url": "https://support.com/hc/requests",_38 "email": "support@com.br",_38 "phone": "+5521988887777"_38 },_38 "availableCountries": ["USA", "GBR", "BRA", "ESP"],_38 "plans": [{_38 "id": "PlanUSD",_38 "currency": "USD",_38 "price": {_38 "subscription": 50,_38 "metrics": [{_38 "id": "myCredits",_38 "ranges": [{_38 "exclusiveFrom": 0,_38 "multiplier": 1,_38 "inclusiveTo": 100_38 },_38 {_38 "exclusiveFrom": 100,_38 "multiplier": 0.7_38 }],_38 "customUrl": "https://my.com/_v/metric/billing/info"_38 },_38 {_38 "id": "myCredit2",_38 "ranges": [{_38 "exclusiveFrom": 0,_38 "multiplier": 0.5_38 }],_38 "customUrl": "https://my.com/_v/metric/billing/info"_38 }_38 ]_38 }_38 }]_38 }
Variable subscription + variable rate
-
Establish a subscription plan for your app by setting up the
planproperty and its child properties:id: Plan identifier.currency: Currency code following the ISO.price.subscription: Subscription price. This property is of typenumberand accepts values with or without cents. Examples:10(10 dollars),60.25(60 dollars and 25 cents),0.9(90 cents).price.metrics: An array specifying the metric's ID and the ranges related to the app's usage and associated extra charge. Notice that you can set one or more metrics to calculate the variable rate.
-
Repeat the previous step to create a new subscription plan. This new plan will be a new object inside the
planarray.
Example of an app with a variable subscription and variable rate
_70 "billingOptions": {_70 "type": "billable",_70 "support": {_70 "url": "https://support.com/hc/requests",_70 "email": "support@com.br",_70 "phone": "+5521988887777"_70 },_70 "availableCountries": ["GBR", "BRA", "ESP"],_70 "plans": [{_70 "id": "PlanBRL",_70 "currency": "BRL",_70 "price": {_70 "subscription": 50,_70 "metrics": [{_70 "id": "myCredits",_70 "ranges": [{_70 "exclusiveFrom": 0,_70 "multiplier": 1,_70 "inclusiveTo": 100_70 },_70 {_70 "exclusiveFrom": 100,_70 "multiplier": 0.7_70 }_70 ],_70 "customUrl": "https://my.com/_v/metric/billing/info"_70 },_70 {_70 "id": "myCredit2",_70 "ranges": [{_70 "exclusiveFrom": 0,_70 "multiplier": 0.5_70 }],_70 "customUrl": "https://my.com/_v/metric/billing/info"_70 }_70 ]_70 }_70 },_70 {_70 "id": "PlanUSD",_70 "currency": "USD",_70 "price": {_70 "subscription": 50,_70 "metrics": [{_70 "id": "myCredits",_70 "ranges": [{_70 "exclusiveFrom": 0,_70 "multiplier": 1,_70 "inclusiveTo": 100_70 },_70 {_70 "exclusiveFrom": 100,_70 "multiplier": 0.7_70 }_70 ],_70 "customUrl": "https://my.com/_v/metric/billing/info"_70 },_70 {_70 "id": "myCredit2",_70 "ranges": [{_70 "exclusiveFrom": 0,_70 "multiplier": 0.5_70 }],_70 "customUrl": "https://my.com/_v/metric/billing/info"_70 }_70 ]_70 }_70 }_70 ]_70 }
Registering the metrics data (Only for apps with a variable pricing strategy)
If you opted for a variable-charge pricing strategy, you must ensure that your metrics are being tracked and updated over time. Otherwise, users won't be charged the right amount.
-
Create the
policiesfield in the app'smanifest.jsonfile and add thevtex.billing:save-metricsas its child. -
Make a POST request to
https://app.io.vtex.com/vtex.billing/v0/{account}/{workspace}/_v/billing-metricswith the following body:_10{_10"metric_id": "{metricId}",_10"value": "{metricAmount}"_10}Remember to remove the curly brackets from the endpoint and body replacing them with real values according to your own scenario.
account- VTEX account responsible for the app development and maintenance.Workspace- Workspace being used for the app development.metricId- ID of the metric specified in thebillingOptionsfield.metricAmount- Use of metrics for billing. For example: if your metric consists of charging for each SMS sent, themetricAmountshould be equal to 1.
-
Create a client for the
vtex.billingapp or complement it with thesaveBillingMetricmethod:_19import {AppClient, IOContext, InstanceOptions} from '@vtex/api'_19_19const routes = {_19billingMetrics: `/_v/billing-metrics`,_19}_19_19export class BillingApp extends AppClient {_19public constructor(ioContext: IOContext, opts?: InstanceOptions) {_19super('vtex.billing@0.x', ioContext, opts)_19}_19_19public saveBillingMetric = (billingMetric: {_19metric_id: string_19value: number_19}) =>_19this.http.post(routes.billingMetrics, billingMetric, {_19metric: 'save-billing-metric',_19})_19} -
Call the
saveBillingMetricmethod whenever you need to add a new quantity to the metric value:_13async function saveSMSBillingMetric(_13{clients: {billingApp}, vtex: {logger}}: ServiceContext<Clients>,_13res: SMSInfo,_13) {_13try {_13await billingApp.saveBillingMetric({_13metric_id: 'smsSent', // metric_id is defined in the app's billingOptions_13value: 1, // value is a whole/integer number that you want to register. This is accumulative._13})_13} catch (e) {_13// That was an error trying to save the metric value_13}_13}
Now, all the specified billing metrics will be tracked and updated by the saveBillingMetric method.
It's worth mentioning that each time the metric is recorded, the date for each register is saved as well. This allows the system to determine which metrics will be charged within a given date frame.