React PriceBlocs JS [beta]
PriceBlocs makes it easy for developers to get started with in-app payments and billing through a set of functional components.
In just a few lines of code you'll be able to:
Show products and prices
Initiate checkouts
Enable billing managment
Everything you need to get started with in-app payments, with less server side code.
API Keys
Sign up for PriceBlocs and get your publishable API keys.
Development
Enable test mode within your PriceBlocs settings tab so that you can use Stripe test mode resources in local development.
Install
Add @priceblocs/react-priceblocs-js to your project
Our first set of components and hooks are compatible with React, examples of which you can see below.
The @priceblocs/react-priceblocs-js functional components are available via npm :
npm i --save @priceblocs/react-priceblocs-js
The quickest way to get started is with a single price:
Wrap any part of your app with an authenticated PriceBlocs component. To authenticate, pass your PriceBlocs api_key prop:
In Production: use your live publishable PriceBlocs api key and live Stripe price id (i.e. where livemode is true )
In Development: use your test publishable PriceBlocs api key and test Stripe price id (i.e.where livemode is false )
Attach the checkout function to any click handler
Pass any price id to the checkout call
import { PriceBlocs } from '@priceblocs/react-priceblocs-js'
export default ( ) => {
const isProd = process . env . NODE_ENV === 'production'
const apiKey = isProd ? 'PB_pk_live_*' : 'PB_pk_test_*'
const price = isProd ? 'price_123' : 'price_456'
return (
< PriceBlocs api_key = { apiKey } >
{ ( { loading, values, checkout } ) => {
if ( loading || ! values ) {
return null
}
return < button onClick = { ( ) => checkout ( price ) } > Buy Now</ button >
} }
</ PriceBlocs >
)
}
If you need to display product metadata to the user (e.g name and description) then you can pass one or more prices to the functional component and on initialization. The products associated with the prices will be fetched and the made available via the values object for use within your UI.
import { PriceBlocs } from '@priceblocs/react-priceblocs-js'
export default ( ) => {
const props =
process . env . NODE_ENV === 'production'
? {
api_key : 'PB_pk_live_*' ,
prices : [ 'price_123' ] ,
}
: {
api_key : 'PB_pk_test_*' ,
prices : [ 'price_456' ] ,
}
return (
< PriceBlocs { ...props } >
{ ( { loading, values, checkout } ) => {
if ( loading || ! values ) {
return null
}
/**
* 1. Destructure products from values
* 2. Use product attributes
*/
const { products } = values
const { name, prices } = products [ 0 ]
const { id } = prices [ 0 ]
return < button onClick = { ( ) => checkout ( id ) } > { `Buy ${ name } ` } </ button >
} }
</ PriceBlocs >
)
}
There are 3 steps to adding prices and checkout to your app:
Setup
Wrap any part of your app with an authenticated PriceBlocs component
Pass an api_key and a set of prices
Presentation
Access your fetched data via context hooks and use it to present product options to your customers
Checkout
Attach the checkout function to any of your price CTA actions to initiate a new checkout session
Import PriceBlocs and initialize it with both:
api_key: your PriceBlocs publishable API key
Use your PB_pk_live_* API key for live Stripe resources and checkout
Use your PB_pk_test_* API key for test Stripe resources and checkout
prices: set of prices you want to show to customers
You can also pass additional checkout configuration options like a customer id / email
Your PriceBlocs account can have both live and test API key sets
Each set of API keys has both a public and secret key
Only public (publishable) keys should be used for client side requests
Only livemode: true keys can initiate live Stripe checkout charges
Key name
Livemode
Audience
Publishable
PB_sk_live_*
true
Secret
No
PB_pk_live_*
true
Public
Yes
PB_sk_test_*
false
Secret
No
PB_pk_test_*
false
Public
Yes
Your connected Stripe account must have charges_enabled in order to initiate a checkout session
To achieve this, you will need to complete Stripe's business verification onboarding process
import { PriceBlocs } from '@priceblocs/react-priceblocs-js'
export default ( ) => {
const props =
process . env . NODE_ENV === 'production'
? {
api_key : 'PB_pk_live_*' ,
prices : [ 'price_123' ] ,
}
: {
api_key : 'PB_pk_test_*' ,
prices : [ 'price_456' ] ,
}
return (
< PriceBlocs { ...props } >
{ ( { loading, values } ) => {
if ( loading ) {
return < YourLoader />
} else if ( values && values . products && values . products . length > 0 ) {
return < YourPricingTable />
}
return null
} }
</ PriceBlocs >
)
}
Key
Required
Type
Description
Example
api_key
Yes
String
One of your PriceBlocs publishable API key
PB_pk_test_sRADszm...
prices
No
Array
Array of Stripe price ids to fetch
['price_123', 'price_456']
sessions
No
Array
Array of checkout inputs to generate session ids from
[ { line_items: [{price_id: 'price_123'}], ... } ]
success_url
No
String
Redirect location after a successful checkout
https://your-site.com/success
cancel_url
No
String
Redirect location if a user cancels their current checkout session
https://your-site.com/cancel
customer
No
String
Stripe customer id
cu_123
email
No
String
Email for your customer customer. If there is a matching customer within you Stripe account, we will use this to initiate the checkout session in the context of that customer
some.one@email.com
presentation
No
Object
Control the presentation of the response
{ order: 'desc' }
query
No
Object
Fetch associations or expand responses
{ customer: {expand: ['default_source'], associations: ['invoices'] }
values
No
Object
Values to initialize context with and prevent fetch on mount
{products: [...], ...}
config
No
Object
Initial configuration object for the lib internals. Control behavior like fetch on mount or customer change
{ fetch: { on_mount: true, on_customer_change: true }
An optional query object can be passed to fetch associated collections and expand responses
For example if you wanted to fetch all of a customers invoices, you could pass that parameter within the customer associations array like below.
To expand part of the customer response itself, you can pass parameters which align to Stripe's customer expand parameters. Read more here about expanding Stripe responses.
{
api_key : 'PB_pk_test_oYQN' ,
prices : [ 'price_123' , 'price_456' ] ,
customer : 'cus_123' ,
query : {
customer : {
expand : [
'default_source' ,
'invoice_settings.default_payment_method'
] ,
associations : [
'invoices' ,
'subscriptions' ,
'cards'
]
}
}
}
You can then access the associations and expanded properties on the related resource within the context values
For example, customer associations and expansions are then available on the customer object
const {
values : {
customer : { default_source, subscriptions, invoices, cards } ,
} ,
} = usePriceBlocsContext ( )
The sessions field allows you to compose checkout sessions using multiple Stripe resources
You can pass in one of more session inputs to generate a unique checkout id based on all of the values passed
The id returned in the response can then be passed in any checkout action call to initiate a new Stripe Checkout session
All of the values passed in the initial request will be used to initialize a new Checkout session
For example, a checkout session with multiple line_items and a discount will create a new Checkout session for those items with the disount applied
This way you can describe one or more checkout sessions from the client and then when you're ready, initiate a checkout session by just passing the checkout id
{
sessions : [
{
line_items : [
{
price : 'price_123' ,
} ,
] ,
discounts : [
{
coupon : 'cou_123' ,
} ,
] ,
} ,
]
}
The Session input aligns closely to that of the Stripe checkout api which you can see here
Key
Type
Description
line_items
Array
One or more prices to apply to this checkout session
success_url
string
url to be redirected to after a successful checkout session
cancel_url
string
url to be redirected to when a checkout session is canceled
payment_method_types
array
array of payment method types to use at checkout time
allow_promotion_codes
boolean
whether to allow promotion codes during checkout
discounts
array
Discounts to apply to the checkout. Max 1
billing_address_collection
Object
Whether to collect billing address info
shipping_address_collection
Object
Shipping adddress configuration. Set one or more allowed countries
shipping_worldwide
boolean
Whether shipping options are worldwide
shipping_options
array
Up to 5 shipping rate options to present at checkout time
submit_type
string
Type of copy to use within checkout session
consent_collection
object
Configuration for consent collection related to marketing
after_expiration
object
Configuration for post checkout session expiration
expires_at
number
Timestamp of when to expire the session
adjustable_quantity
object
Configuration object for adjustable quantity
tax_rates
array
Array of tax ids to apply to checkout session
dynamic_tax_rates
array
Array of dynamic tax ids to apply to checkout session
automatic_tax
object
Automatic tax configuration object
client_reference_id
string
Client reference id to attach to payment
tax_id_collection
object
Tax id collection configuration object
payment_intent_data
object
Payment intent confiration object which can control capture method.
trial_period_days
number
Number of days to apply to any line_item's with a recurring price type
trial_end
number
Timestamp of when the trial ends
metadata
object
Key value pair object to attach to the checkout and any resulting subscription / payment intent records
mode
string
What mode the session should be initialized in
Shared configuration (inheritence)
You can share session configuration options across multiple inputs by setting the field as a sibling to the sessions key.
For example, let's say you want to apply the same discount to all of the session inputs.
To do that you would set the discounts as a sibling to sessions like so
{
sessions : [
{
line_items : [
{
price : 'price_123' ,
} ,
] ,
} ,
{
line_items : [
{
price : 'price_999' ,
} ,
] ,
} ,
] ,
discounts : [
{
coupon : 'cou_123' ,
} ,
] ,
}
Overrides
However if you wanted override common configuration you would define a more specific configuration within the session input itself like below.
Here we are sharing discount cou_123 across the first two sessions but then overriding it withing the third session by setting coupon cou_abc
This ability to override works for every key within the configuration
The most specific configuration wins
{
sessions : [
{
line_items : [
{
price : 'price_123' ,
} ,
] ,
} ,
{
line_items : [
{
price : 'price_999' ,
} ,
] ,
} ,
{
line_items : [
{
price : 'price_456' ,
} ,
] ,
discounts : [
{
coupon : 'cou_abc' ,
} ,
] ,
} ,
] ,
discounts : [
{
coupon : 'cou_123' ,
} ,
] ,
}
You can configure how the default behavior of the lib internals with the configuration object
By default the component will fetch data from the PriceBlocs API on mount and when the customer reference changes
You can override that configuration by passing in a config object
{
fetch : {
on_mount : true ,
on_customer_change : true
}
}
You can then access the associations and expanded properties on the related resource within the context values
For example, customer associations and expansions are then available on the customer object
const {
values : {
customer : { default_source, subscriptions, invoices, cards } ,
} ,
} = usePriceBlocsContext ( )
Once initialized, you will be able to access your fetched data via the usePriceBlocsContext context hook
There are a variety of fields to help you:
present price options
update context values
initiate checkout and billing sessions
preview and confirm subscription updates
manage checkout cart and more
Key
Type
Description
values
Object
Core pricing resources like products and featureGroups etc.
refetch
Function
Function to refetch values from API using initial props
checkout
Function
Start a checkout session
billing
Function
Start a billing portal session for the provided customer
checkoutAdd
Function
Add a price to the form checkout items
checkoutRemove
Function
Remove a price from the form checkout items
previewInvoice
Function
Request a preview of the next invoice for the subscription
fetchUsage
Function
Fetch usage summary for a subscription line item
reportUsage
Function
Report usage summary for a subscription line item
updateSubscription
Function
Update a subscription with the a collection of updated subscription items
setFieldValue
Function
Update any of the context values
setValues
Function
Update all of the context values
ready
Boolean
True when Stripe has been initialized and consumer can initialize checkout sessions
loading
Boolean
True when fetching
isSubmitting
Boolean
True when submitting
stripe
Object
Stripe instance initialized and available for use in context
error
Error
Any errors in local state
setError
Error
Set error in local state
import {
usePriceBlocsContext ,
getActiveProductPrice ,
} from '@priceblocs/react-priceblocs-js'
const PricingTable = ( ) => {
const {
values : { products } ,
form : { currency, interval } ,
checkout,
} = usePriceBlocsContext ( )
return (
< div >
< ul >
{ products . map ( ( product , productIx ) => {
const price = getActiveProductPrice ( product , { currency, interval } )
return (
< li key = { product . id } >
< div >
< div > { product . name } </ div >
< div > { product . description } </ div >
</ div >
< button onClick = { ( ) => checkout ( { prices : [ price . id ] } ) } >
Buy Now
</ button >
</ li >
)
} ) }
</ ul >
</ div >
)
}
Use the refetch function to refetch values from the API
const { refetch } = usePriceBlocsContext ( )
// Single price
< button onClick = { ( ) => refetch ( ) } > Refetch < / b u t t o n >
Use the checkout function from context to start a checkout session
The simplest way is to call it with a single price id like so:
const { checkout } = usePriceBlocsContext ( )
// Single price
< button onClick = { ( ) => checkout ( price . id ) } > Buy Now < / b u t t o n >
checkout accepts a variety of arguments such as:
single price id
collection of price ids
encrypted session id
full Stripe Checkout session configuration
const { checkout } = usePriceBlocsContext ( )
/**
* Single price
*/
const price = 'price_123'
< button onClick = { ( ) => checkout ( price . id ) } > Buy Now < / b u t t o n >
/**
* Session id
* - session id fetched via PriceBlocs fetchData function
*/
const sessionId = 'cs_live_123'
< button onClick = { ( ) => checkout ( sessionId ) } > Buy Now < / b u t t o n >
/**
* Pass one or more prices to include multiple products within checkout
*/
const prices = [ 'price_123' , 'price_456' ]
< button onClick = { ( ) => checkout ( { prices } ) } > Buy Now < / b u t t o n >
/**
* Pass full session configuration object
*/
const session = {
line_items : [
{
price : 'price_123' ,
}
]
}
< button onClick = { ( ) => checkout ( session ) } > Buy Now < / b u t t o n >
Use the billing function from context to start a new Stripe billing portal session for one of your customers
A valid customer id is required to start a new session
By default, we will use the customer in context if you have initiated PriceBlocs with a valid customer
Otherwise you can pass a specific customer id parameter into the billing call
Your Stripe billing portal can be confiugred within Stripe here
const { billing } = usePriceBlocsContext ( )
// Use default customer if present
< button onClick = { billing} > Manage billing < / b u t t o n >
// Provide a customer to the billing call
< button onClick = { ( ) => billing ( { customer : 'cus_123' } ) } > Manage billing</ button >
Use the previewInvoice function from context to preview what an upcoming invoice for a subscription will look like based on the items passed in the request
To preview changes against a specific subscription, pass its id as well as a collection of items to preview
const previewData = await previewInvoice ( {
subscription : 'sub-123' ,
items : [
{
price : 'p_123' ,
} ,
] ,
} )
The preview response will include an itemized preview for the upcoming invoice and the raw invoice itself.
Key
Description
preview
Itemized invoice preview including confirmation payload
invoice
The raw Stripe invoice which is being previewed
The preview response includes lineItems, amountItems which describe the invoices details as well as a confirm object which can be passed in a subsequent updateSubscription request to update the associated subscription.
Key
Description
lineItems
A collection which describing the elements of the invoice
amountItems
A collection which describes the total amounts due / credited / paid etc.
confirm
A payload which can be passed in a subscription update request to apply the previewed changes
Use the updateSubscription function from context to update a customers subscription with the options passed.
const previewData = await updateSubscription ( {
id : 'sub-123' ,
items : [
{
id : "si_123" ,
deleted : true ,
clear_usage : true ,
} ,
{
id : "si_456" ,
price : "p_B_1"
} ,
{
price : "p_A_3"
}
]
proration_data : 12345678
} )
For convenience you can pick the confirm object from the invoicePreview response and use it when calling updateSubscription.
A proration_date timestamp is included in the preview response so that it too is available to be passed along in the request.
const response = await previewInvoice ( {
subscription : 'sub-123' ,
items : [
{
price : 'p_123' ,
} ,
] ,
} )
await updateSubscription ( response . preview . confirm )
Use the fetchUsage function from context to fetch all of the usage summaries for a subscription item
Each summary represents multiple usage records over a subscription billing period (e.g., 15 usage records in the month of September).
const previewData = await fetchUsage ( {
subscription_item : 'sub-item-123' ,
} )
The response will include a collection of summary records as well as some aggregate totals.
Key
Description
total_usage
Sum total of all the summary records
total_cost
Total usage multiplied by the cost per unit
unit_amount
Unit amount for the subscription item
unit_cost
Formatted cost amount for a unit amount value
data
Collection of usage summaries
Each usage summary record describes the amount of usage between the priod start and end date
Key
Description
id
Summary usage record id
invoice
Id of the invoice the summary belongs to
livemode
Whether its a live or test Stripe record
period
Timestamp info for the summary
subscription_item
Subscription item id the usage summary belongs to
total_usage
Sum count of the total usage for that period
Describes the timeframe for the usage summary
Key
Description
label
Formatted timestamp for the period
start
Unix timestamp for period start
end
Unix timestamp for period end
Use the reportUsage function from context to report usage for a particular subscription_item
e.g. this could be used for counting restricted API calls
You can specify additional fields like quantity, timestamp, and action
const previewData = await fetchUsage ( {
subscription_item : 'sub-item-123' ,
} )
Each additional field has default values if not specified
Key
Description
Default
quantity
Formatted timestamp for the period
1
timestamp
Unix timestamp usage recording
Now as unix timestamp
action
Usage action type, can be 'increment' or 'set'
increment
You can use the setValues function to replace the entire values object in context
This function is used internally on refetch
Avoid using this function unless necessary. Calling refetch is better for most use cases.
const {
setValues,
} = usePriceBlocsContext ( )
< button onClick = { ( ) => setValues ( { ...} ) } > Set all values < / b u t t o n >
You can use the setFieldValue function to update any of the state in context
This can be useful for updating values such as the interval or currency within the form state to assist with presentation logic
You can pass a dot path to target nested fields for updates
const {
setFieldValue,
} = usePriceBlocsContext ( )
< button onClick = { ( ) => setFieldValue ( 'form.interval' , 'month' ) } > Show monthly prices < / b u t t o n >
You can use the setError function to set the local error object
const {
setError,
} = usePriceBlocsContext ( )
< button onClick = { ( ) => setError ( new Error ( 'Custom error' ) ) } > Set error < / b u t t o n >
Key
Type
Description
PriceBlocs
HOC
Context container
usePriceBlocsContext
Function
Context hook
Key
Type
Description
getActiveProductPrice
Function
Get the product price based on the current form values for interval and currency
getProductFeatures
Function
Get all features for the provided product
getProductsFeaturesTable
Function
Generate a feature table representation for products in context
getGoodStandingSubscriptions
Function
Filter subscriptions in context to ones with either an active
trialing status
Key
Type
Description
Example
RECURRING_INTERVALS
Object
A mapping of the 4 recurring intervals
'month'
INTERVAL_LABELS_MAP
Object
A mapping of each interval to it's label
'monthly'
INTERVAL_SHORTHAND_MAP
Object
A mapping of each interval to it's shorthand
'mo'
Key
Type
Description
products
Array
An array of products
customer
Object
A Stripe customer
form
Object
Form state values like currencies and intervals to help with presentation
featureGroups
Array
An array of feature groups
This shape is closely aligned to the Stripe products API
Key
Description
name
Name of the product
description
Description of the product
prices
Array of Stripe prices
features
Array of features associated with the product
This shape is closely aligned to the Stripe prices API
Key
Description
id
Stripe price id
unit_amount
Unit amount for the price
currency
Stripe price id
product
Stripe product id which the price belongs to
formatted
Formatted price values
symbol
Currency symbol for this price
We format the unit_amount of each price so you don't have to.
This also includes formatting them for a variery of different intervals day | week | month | year
Each formatted interval is accessible under the intervals key
Key
Description
Example
unit_amount
Formatted version of the unit amount
12000 -> $120.00
intervals
Price formatted for different intervals [day, week, month, year]. e.g a yearly price presented as a per month cost
{ day: "$0.33", week: "$2.31", month: "$10.00", year: "$120.00"}
This shape is closely aligned to the Stripe customers API
This object will be extended with any additional expanded attributes or associations requested via the initial query props
Key
Present
Required
ation
id
always
ID of the Customer
email
always
Email of the Customer
invoices
conditionally
Array of this Customer's Stripe invoices
subscriptions
conditionally
Array of this Customer's Stripe subscriptions
cards
conditionally
Array of this Customer's Stripe cards
Key
Description
Example
interval
The default interval based on prices in config response
'month'
intervals
Set of intervals for prices in response
['month', 'year']
currency
The default currency based on prices in config response
'usd'
currencies
Set of intervals for prices in response
['usd','eur']
usage_types
Set of usage_types for prices in response
['licensed']
checkout
The checkout object which contains purchasable prices
{items: [{price: {id: 'price_123'}}]}
presentation
Presentation values for ationform
{interval: "month"}
Object which can be used to store checkout related options like items for purchase.
These items can be passed along in any checkout call
These items will also be used as the default collection of prices for an preview invoice request
Key
Description
items
Array of checkout items
Key
Required
Description
price
yes
Object with price id
quantity
no
Quantity of price
Key
Description
Example
interval
The interval presentation interval. For example 'month' will present all amounts in terms of per month pricing, so a $120 per year price will be presented as $10 per month
'month'
Key
Present
Description
Example
uuid
always
UUID for the feature group
847169d9-05bf-485f-8d01-637189e9c9a1
title
always
Title for the feature group
Analytics & Reports
features
conditionally
Array of Features included in the feature group
Key
Description
Example
uuid
UUID of the feature group
f0ecdee3-579f-4a9f-aeba-92ff9dbaa767
title
Report generator
Analytics & Reports
description
Generate monthly financial reports
Analytics & Reports
Key
Type
Description
Example
enabled
boolean
UUID of the feature group
true
value
string
Value for the config
Limit 100 runs a month
tooltip
string
Optional tooltip for feature
Custom scheduling allowed