Regional and Market Pricing
Combine currency pricing, reusable country Markets, and selectable price variants.
Commet supports two complementary pricing layers:
| Layer | Use it for |
|---|---|
| Currency Pricing | Derive or fix a plan price, included balance, and feature overage values in one presentment currency |
| Market Pricing | Assign explicit prices and currencies to reusable, non-overlapping groups of billing countries |
Existing Currency Pricing remains canonical. Add Markets only when country segmentation or selectable variants require it.
Currency Pricing
Configure a currency from the plan's Regional Prices section. An exchange rate can keep values synchronized with USD, while any field can be stored as a manual override.
import { Commet } from "@commet/node";const commet = new Commet({ apiKey: "ck_xxx" });const planRegionalPricingResult = await commet.plans.setRegionalPricing({ id: "pln_xxx", currency: "usd", exchangeRate: 1,});from commet import Commetcommet = Commet("ck_xxx")plan_regional_pricing_result = commet.plans.set_regional_pricing( "pln_xxx", currency="usd", exchange_rate=1,)client, err := commet.New("ck_xxx")if err != nil { log.Fatal(err)}ctx := context.Background()planRegionalPricingResult, err := client.Plans.SetRegionalPricing(ctx, "pln_xxx", &commet.SetPlanRegionalPricingParams{ Currency: "usd", ExchangeRate: 1,})if err != nil { log.Fatal(err)}import co.commet.Commet;import co.commet.params.SetPlanRegionalPricingParams;var commet = Commet.builder().apiKey("ck_xxx").build();var planRegionalPricingResult = commet.plans().setRegionalPricing( "pln_xxx", SetPlanRegionalPricingParams.builder("usd", 1.0).build());use Commet\Commet;$commet = new Commet('ck_xxx');$planRegionalPricingResult = $commet->plans->setRegionalPricing( id: 'pln_xxx', currency: 'usd', exchangeRate: 1,);The subscription currency becomes fixed after the first successful payment.
Markets
A Market is a reusable country group. Countries may belong to only one active group, but the price for each Market chooses its own presentment currency.
Market methods live under commet.pricing because pricing is their SDK and API namespace. Creating a Market does not require a plan or price; prices reference the group later.
const latamFive = await commet.pricing.createMarketGroup({
name: 'Paraguay and Bolivia',
countryCodes: ['PY', 'BO'],
})
const asiaEight = await commet.pricing.createMarketGroup({
name: 'China and India',
countryCodes: ['CN', 'IN'],
})
const unitedStates = await commet.pricing.createMarketGroup({
name: 'United States',
countryCodes: ['US'],
})
const argentina = await commet.pricing.createMarketGroup({
name: 'Argentina',
countryCodes: ['AR'],
})Base price with country groups
The base amount is the fallback for every country without a Market override.
const basePrice = await commet.plans.addPrice({
id: 'pln_pro',
billingInterval: 'monthly',
price: 1000,
isDefault: true,
marketPrices: [
{ marketGroupId: latamFive.id, currency: 'usd', price: 500 },
{ marketGroupId: asiaEight.id, currency: 'usd', price: 800 },
{ marketGroupId: unitedStates.id, currency: 'usd', price: 900 },
{ marketGroupId: argentina.id, currency: 'ars', price: 1200000 },
],
})This resolves to US$5 in Paraguay and Bolivia, US$8 in China and India, US$9 in the United States, ARS 12,000 in Argentina, and US$10 everywhere else.
Selectable variants
A variant inherits the base price everywhere and overrides only the Markets it declares. This makes it possible to offer several commercial options that differ only in Argentina without duplicating the rest of the world.
const argentinaLaunch = await commet.plans.addPrice({
id: 'pln_pro',
billingInterval: 'monthly',
inheritsFromPriceId: basePrice.id,
metadata: { name: 'Argentina launch' },
marketPrices: [
{ marketGroupId: argentina.id, currency: 'ars', price: 800000 },
],
})
const argentinaGrowth = await commet.plans.addPrice({
id: 'pln_pro',
billingInterval: 'monthly',
inheritsFromPriceId: basePrice.id,
metadata: { name: 'Argentina growth' },
marketPrices: [
{ marketGroupId: argentina.id, currency: 'ars', price: 1600000 },
],
})Pass priceId only when the customer selects a variant:
await commet.subscriptions.create({
customerId: 'user_123',
planCode: 'pro',
priceId: argentinaLaunch.id,
})Omitting priceId keeps normal default-price resolution.
Renewal and archival
- A subscription stores the selected price ID and renews from that row's current catalog value.
- Updating the selected price changes future renewals.
- Archiving hides a price from new reads and selection, while existing subscriptions continue using it.
- Dependent variants must be archived before their base price.
- Commet does not silently move an existing subscription to another price or Market.
Offer terms have a separate boundary: accepted Offer phases are immutable even though the selected catalog price remains editable.
Related
How is this guide?