Prices describe how much your products cost.
Once you have created a product, next you will need to create a price.
The price points to a specific product and will set how much that product costs, as well as important details like whether that product is paid for on a one-time or recurring (subscription) basis, and if pricing is tiered.
The price object
Let's take a look at a full price object:
{
"id": "price_d2e4fba4b9b44f39ada98f48ac6fab97",
"active": false,
"billingScheme": "tiered",
"created": "2021-01-01T00:00:00.000Z",
"currency": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"description": "This price encodes your billing scheme and can be attached to products.",
"lookupKey": "123e4567-e89b-12d3-a456-426614174000",
"meta": {
"uuid": "<your_uuid>"
},
"name": "Example Price",
"network": "sol",
"product": "product_94373caad0004e3e96c9e3b23d0c96c0",
"recurring": {
"type": "delegated",
"defaultLength": 5,
"interval": "month",
"intervalCount": 1,
"usageAggregation": "latest",
"usageType": "metered"
},
"taxBehavior": "inclusive",
"tiers": [
{
"flatAmount": "100",
"flatAmountDecimal": 10,
"unitAmount": "10",
"unitAmountDecimal": 1,
"upTo": 100
},
{
"flatAmount": "0",
"flatAmountDecimal": 20,
"unitAmount": "20",
"unitAmountDecimal": 2,
"upTo": "inf"
}
],
"tierType": "volume",
"type": "oneTime",
"unitAmountDecimal": 10,
"updated": "2021-01-01T00:00:00.000Z"
}
id: string Unique identifier for the object. Auto-generated by Sphere upon creation.
active: boolean Denotes whether your price is usable in new payment methods.
- Inactive
priceobjects passed as alineItemto a payment method will return an API error. - Pre-existing payment methods with a newly inactive price will continue to function. Recommended to update the payment method directly to make it inactive or remove specific line items.
billingScheme: enum Critical because it defines how the total cost of the price will be calculated.
-
perUnit: means that the cost of the price is defined by theunitAmountDecimalsfield.- For example,
"unitAmountDecimals" : 5means that the cost of this price is 5.
- For example,
-
tiered: means that the cost of the price is defined by the tranches within thetierfield.- See the
tierfield below for an example.
- See the
created: string datetime for when the price was created.
currency: string Defines the underlying token or money for the price.
- For crypto, it is the public key for the mint address (Solana) or token contract address (EVM).
- For fiat, it is one of
usd,euro, andgbp.
description: string Describes your price. Hidden from users. Max length (500).
lookupKey: string Used to retrieve prices quickly from a list of products. Useful if your products have many different prices. Unique. Max length (200).
meta: object Set of key-value pairs (JSON) for arbitrary usage. Used to save structured information about the object to reference elsewhere. Think of it as general purpose storage space.
name: string The name of your price. Hidden from users. Max length (500).
network: enum The underlying network of your subscription. Either a blockchain abbreviation or fiat.
- For cross-chain payments, this identifies the destination chain that your
pricewill live on. - Other than cross-chain, it is useful if your
currencyis an Ethereum token contract address and you would like to specify which EVM-compatible or equivalent blockchain it is native to.
product: string The id of the product that this price points to.
- This field is critical because it is what connects your price with a product.
- It is strongly recommended that you use this field upon creation of a price, although it is technically optional and you can always go back and update it.
recurring object Relevant if the type of your price is recurring (e.g., a subscription).
type:enumCritical. Defines whether the customer pays for the subscription by pre-funding an escrow account (escrowed), or approving automatic withdrawals from their wallet (delegated).escrowed:stringCustomers lock up funds dedicated to the subscription in an escrow account. Each billing period, funds will be withdrawn from that account.- Customers can withdraw at anytime through the subscription management portal. You can also use the withdraw escrow funds endpoint to serve the transaction on your own frontend.
- Similarly, customers may top-off their escrow account either through the subscription management portal or your own frontend via the add escrow funds endpoint.
- We suggest listening for the
subscription.escrowed.low_balanceandsubscription.escrowed.insufficientevents to appropriately notify your customers.
delegated:stringCustomers approve to have funds automatically drawn from their wallet at the end of each billing period. If there are insufficient funds, the subscription is voided.- Customers may revoke delegation in the subscription management portal. You can also use the revoke delegation endpoint to serve the transaction on your own frontend.
- Similarly, customers may approve for additional tokens to be delegated either through the subscription management portal or your own frontend via the extend delegation endpoint.
- We suggest listening for the
subscription.delegated.insufficientandsubscription.delegated.redelegatedevents to appropriately notify your customers.
defaultLength:numberDefines the default number of billing periods to approve token transfers for. Relevant if your subscription's billing scheme is escrowless (e.g.,delegated).- E.g., with
"defaultLength": 3and"interval": month, the customer will be prompted to approve the delegation of tokens equal to the amount of 3 months of billing upon subscribing.
- E.g., with
interval:numberDefines the frequency of each billing period, fromblock(for real-time streamed payments, coming soon),min,hr,day,week,monthtoyear.intervalCount:numberDefines the number of intervals between billing periods.- E.g., with
"interval": "day"andintervalCount: 2, the customer is billed every 2 days. - The maximum total amount of time between billing periods is 5 years.
- E.g., with
usageType:enumDefines whether your billing islicensedormetered.licensedmeans that your customers will be charged based upon the quantity they specify upon checkout, irrespective of usage. Oppositely,meteredmeans that your customer will get charged based upon their total usage.licensedcan get a little complicated, so let's break it down.- As we will explain in further detail in
paymentLinkandinvoice, payment methods requirelineItems.lineItemsare the connection between products and their payment methods. - A
lineItemhas three fields:- (1) The
idof thepriceobject, and therefore theproductobject that it points to, that will be included as an item for sale in the checkout. - (2)
quantity, anumberdefining the default amount of a givenproductbeing bought. - (3)
quantityMutable, abooleanfor if customers can adjust the defaultquantity.
- (1) The
- If
licensedis selected, then customers will be charged forpricexquantity.- If
quantityMutableis true, thenquantityis whatever the customer chooses.
- If
- As we will explain in further detail in
meteredmeans that your customer will be billed based on their usage.- This is calculated on your backend and passed to Sphere through the
usageRecordsobject, with the exact details for pricing, such as the underlying pricing model, being defined by fields such asusageAggregationandtierinside thepriceobject. - Check out Usage Records for more details. You will need to create
usageRecordobjects for each subscription customer periodically so we can appropriately bill them for their usage.
- This is calculated on your backend and passed to Sphere through the
usageAggregation:enumDefines how usage for metered billing is calculated.sum: The customer will be billed for the sum of their usage over the current billing period.latest: The customer will be billed for the latest reported usage, irrespective of billing period.max: The customer will be billed for the maximum of their usage over the current billing period.
taxBehavior: enum Identifies whether the price is inclusive or exclusive of taxes.
inclusive: Your price includes taxes.- E.g., a tax inclusive price of $10 could mean the "true" value of the product is $9, with a tax of $1.
exclusive: Your price does not include taxes.- E.g., a tax exclusive price of $10 means that the "true" value of the product is $10.
- Note: this field is primarily intended for your own accounting purposes. Sphere's billing engine will apply whatever
taxRateis defined to tax exclusive products during payment.
tier: object Defines details in your pricing model and makes it convenient to tier pricing.
- Note: this parameter requires
billingSchemeto be set totiered, otherwise it'll produce an error.
(Note: we suggest creating separate products if you want to offer a standard 3-tier product e.g., Bronze, Silver, Gold. Although it is technically possible to create this tiering through a single product using the tier field, it typically results in object overload and unexpected behavior, so is not recommended.)
Tiering can get complicated, so let's start with the basic example from above.
"tiers": [
{
"flatAmount": "100",
"flatAmountDecimal": 10,
"unitAmount": "10",
"unitAmountDecimal": 1,
"upTo": 100
},
{
"flatAmount": "0",
"flatAmountDecimal": 20,
"unitAmount": "20",
"unitAmountDecimal": 2,
"upTo": "inf",
},
],
In this example, we've defined two tiers. We can ignore the non-decimal sub-fields, as they contain the same information as the decimal sub-fields, but just presented as the raw default integer value of a token.
The algorithm for total billing will depend on the tier type.
tierType: enum Defines how usage costs are calculated across different tiers.
- Graduated billing sums up the cost of usage as you go up tiers.
- Whereas volume based billing will assume the most recent tier that was reached.
Let's suppose the customer is being billed for 110 units.
- If we're using
graduatedpricing, then the total will be: 10 + 1(100) + 2(10) = 130. - If we're using
volumebased pricing, then the total will be: 0 + 2(110) = 220.
Let's break this calculation down.
The first tier defines a flatAmountDecimal of 10, while the second tier defines a flatAmountDecimal of 0.
flatAmountDecimal: number The flat cost for usage in a given tier. Formatted to base-10.
- This means that usage within the first tier will trigger a flat cost of 10 tokens.
graduatedcalculates progressively by each tier. Hence, the first 100 units of usage triggers the 10 token cost set by tier 1. The next 10 units of usage triggers the 0 token cost set by tier 2. +10volumecalculates by most recent tier. Hence, it ignores the flat cost of 10 set by tier 1 because 110 units of usage gets us into tier 2, where the flat token cost is 0. +0
unitAmountDecimal: number The per-unit cost for each unit of usage in a given tier. Formatted to base-10.
The first tier also sets a unitAmountDecimal of 1, while the second tier sets a unitAmountDecimal of 2.
- This means each unit of usage in tier 1 costs 1 token, while each unit of usage in tier 2 costs 2 tokens.
graduatedcalculates progressively by each tier. So the first 100 units of usage costs 1 token each, whereas the last 10 units of usage cost 2 tokens each. 1(100) + 2(10) = +120.volumecalculates by most recent tier. So we ignore the cost of usage in tier 1, since 110 units of usage means that we're in tier 2. With each unit of usage costing 2 tokens each, 2(110) = +220.
You'll notice that for the last defined tier, upTo is set to inf.
upTo: number Defines the number of units of usage that the given tier goes up to.
- This is critical. Because your last defined tier covers the pricing for all potential usage indefinitely, if you don't set
upTotoinfin that final tier, the API will throw an error.
If you're still confused, check out the tier guide.
type: enum Critical because it defines whether the product you attach this price to is paid for on a one-time or on a recurring basis (subscription). Defaults to oneTime, but if set to recurring you will be able to define key variables such as the billing period (in the recurring field) and pricing model (in tier).
unitAmountDecimal: number Defines the default cost of your price, automatically converting the amount of raw token units for a given currency into base-10 (decimals).
- For example, SOL has a default unit amount of 10^e-9 and ETH is 10^e-18. Instead of passing in "1,000,000,000" to represent a cost of 1 SOL, you can just pass in "1".
updated: string datetime for when the price was last updated.