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
vendor
account (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:
Step by step
- Open your project in any code editor of your preference.
- Open the
manifest.json
file and remove thebillingOptions
field.
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.
Step by step
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.json
file. - Add the
billingOptions
field to your app'smanifest.json
file and set thetype
property asfree
. - Set up the
support
property to provide a support channel for the app users. - Set up the
availableCountries
property to define in which countries the app will be available. If you want to make it available for all countries, use*
.
"billingOptions": {
"type": "free",
"support": {
"email": "support@com.br",
"url": "https://support.com/hc/requests"
},
"availableCountries" : ["*"]
}
Setting the app as charged
- Open your app in any code editor of your preference.
- Open the
manifest.json
file. - Create the
billingOptions
field in the app'smanifest.json
file and set thetype
property asbillable
. - Set up the
support
property to provide a support channel for the app users. - Set up the
availableCountries
property to define in which countries the app will be available. If you want to make it available for all countries, use*
.
"billingOptions": {
"type": "billable",
"support": {
"email": "support@com.br",
"url": "https://support.com/hc/requests"
},
"availableCountries" : ["*"]
}
- 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.
Example of an app with a fixed subscription price
"billingOptions": {
"type": "billable",
"support": {
"email": "support@com.br",
"url": "https://support.com/hc/requests"
},
"availableCountries": ["*"],
"plans": [{
"id": "PlanBRL",
"currency": "BRL",
"price": {
"subscription": 100
}
}]
}
Fixed subscription + variable rate
- 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.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
"billingOptions": {
"type": "billable",
"support": {
"email": "support@com.br"
},
"availableCountries": ["*"],
"plans": [{
"id": "PlanUSD",
"currency": "USD",
"price": {
"subscription": 50,
"metrics": [{
"id": "smsSent",
"ranges": [{
"exclusiveFrom": 0,
"inclusiveTo": 2000,
"multiplier": 0.07
},
{
"exclusiveFrom": 2000,
"inclusiveTo": 4000,
"multiplier": 0.06
},
{
"exclusiveFrom": 4000,
"multiplier": 0.05
}
]
}]
}
}]
}
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$ 30.00 (1500 x US$ 0.07 = US$ 30.00)
- For 3500 SMSs = US$ 60.00 (3500 x US$ 0.06 = US$ 60.00)
- For 7000 SMSs = US$ 100.00 (7000 x US$ 0.05 = US$ 100.00)
Example of an app with a fixed subscription price plus a variable rate that considers more than one metric
"billingOptions": {
"type": "billable",
"support": {
"url": "https://support.com/hc/requests",
"email": "support@com.br",
"phone": "+5521988887777"
},
"availableCountries": ["USA", "GBR", "BRA", "ESP"],
"plans": [{
"id": "PlanUSD",
"currency": "USD",
"price": {
"subscription": 50,
"metrics": [{
"id": "myCredits",
"ranges": [{
"exclusiveFrom": 0,
"multiplier": 1,
"inclusiveTo": 100
},
{
"exclusiveFrom": 100,
"multiplier": 0.7
}],
"customUrl": "https://my.com/_v/metric/billing/info"
},
{
"id": "myCredit2",
"ranges": [{
"exclusiveFrom": 0,
"multiplier": 0.5
}],
"customUrl": "https://my.com/_v/metric/billing/info"
}
]
}
}]
}
Variable subscription + variable rate
- 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.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
plan
array.
Example of an app with a variable subscription and variable rate
"billingOptions": {
"type": "billable",
"support": {
"url": "https://support.com/hc/requests",
"email": "support@com.br",
"phone": "+5521988887777"
},
"availableCountries": ["GBR", "BRA", "ESP"],
"plans": [{
"id": "PlanBRL",
"currency": "BRL",
"price": {
"subscription": 50,
"metrics": [{
"id": "myCredits",
"ranges": [{
"exclusiveFrom": 0,
"multiplier": 1,
"inclusiveTo": 100
},
{
"exclusiveFrom": 100,
"multiplier": 0.7
}
],
"customUrl": "https://my.com/_v/metric/billing/info"
},
{
"id": "myCredit2",
"ranges": [{
"exclusiveFrom": 0,
"multiplier": 0.5
}],
"customUrl": "https://my.com/_v/metric/billing/info"
}
]
}
},
{
"id": "PlanUSD",
"currency": "USD",
"price": {
"subscription": 50,
"metrics": [{
"id": "myCredits",
"ranges": [{
"exclusiveFrom": 0,
"multiplier": 1,
"inclusiveTo": 100
},
{
"exclusiveFrom": 100,
"multiplier": 0.7
}
],
"customUrl": "https://my.com/_v/metric/billing/info"
},
{
"id": "myCredit2",
"ranges": [{
"exclusiveFrom": 0,
"multiplier": 0.5
}],
"customUrl": "https://my.com/_v/metric/billing/info"
}
]
}
}
]
}
}
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
policies
field in the app'smanifest.json
file and add thevtex.billing:save-metrics
as its child. - Make a POST request to
https://app.io.vtex.com/vtex.billing/v0/{account}/{workspace}/_v/billing-metrics
with the following body:
{
"metric_id": "{metricId}",
"value": "{metricAmount}"
}
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 thebillingOptions
field.metricAmount
- Use of metrics for billing. For example: if your metric consists of charging for each SMS sent, themetricAmount
should be equal to 1.
- Create a client for the
vtex.billing
app or complement it with thesaveBillingMetric
method:
import {AppClient, IOContext, InstanceOptions} from '@vtex/api'
const routes = {
billingMetrics: `/_v/billing-metrics`,
}
export class BillingApp extends AppClient {
public constructor(ioContext: IOContext, opts?: InstanceOptions) {
super('vtex.billing@0.x', ioContext, opts)
}
public saveBillingMetric = (billingMetric: {
metric_id: string
value: number
}) =>
this.http.post(routes.billingMetrics, billingMetric, {
metric: 'save-billing-metric',
})
}
- Call the
saveBillingMetric
method whenever you need to add a new quantity to the metric value:
async function saveSMSBillingMetric(
{clients: {billingApp}, vtex: {logger}}: ServiceContext<Clients>,
res: SMSInfo,
) {
try {
await billingApp.saveBillingMetric({
metric_id: 'smsSent', // metric_id is defined in the app's billingOptions
value: 1, // value is a whole/integer number that you want to register. This is accumulative.
})
} catch (e) {
// That was an error trying to save the metric value
}
}
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.