Select Products or Plans

The first part of a payment flow is for your users to select product(s) that they would like to purchase. This step (almost) always precedes the checkout and payment part of the flow.

Using Feathery, you can create custom form designs to allow the user to choose products and plans that they wish to purchase / subscribe to. These always correspond to Stripe products and prices, which live in your Stripe account and are configured directly in your Stripe account or from within your Feathery form.

At its core, your setup needs to save how much of each product your user is looking to purchase into hidden fields. This information is later tied to the purchase/checkout process.

Your product selector can use the Clear Product from Cart and Add Product to Cart actions. Any button or container may be configured to select one or more Stripe products for later purchase using multiple Add Product to Cart actions, each for a different product. Each Add Product to Cart action is configured with a Stripe product as well as a quantity of it to be purchased. The quantity can be configured to be derived from a Feathery field or as a fixed quantity value. Using a Feathery field allows for a dynamic quantity of the product to be chosen.

Selecting and Configuring Stripe Products

As always, you may use the Stripe dashboard at stripe.com to create and modify product and prices.

Feathery also supports the creation of Stripe products and prices directly at the point of configuring the Add Product to Cart and Clear Product from Cart actions on your Feathery form. Upon adding an action, clicking the Stripe product selector will pop the Stripe product selector dialog.

On this dialog, you may:

  • Select any existing product to be added to the cart by the action.

  • Edit an existing product and its price in Stripe.

  • Create a new product in Stripe.

Stripe and Feathery support both live and test modes, including live and test products. In order to make things a bit simpler for the form designer, we recommend that you create paired live and test products in Stripe with identical names. If you follow this practice, your Feathery form will automatically use the correct test or live product at runtime based on whether you are running a test or live form.

From this dialog you can create or update a product and its price. For example, use the Create Product button shown above to create a new product in Stripe. The dialog below is displayed.

Stripe and Feathery both support flat rate pricing for both one time and recurring subscription purchases. The product create/update screen in Feathery (shown above) support these types of products and pricing.

Stripe and Feathery both support more exotic pricing schemes such as tiered pricing, package pricing, etc. However, in order to configure this type of pricing, you will need to do it directly within the Stripe dashboard.

Also note that if you decide to follow our recommended best practice of managing paired live and test products in Stripe with identical names, our UI (above) supports the creation of a new product in both live and test. Just select "Both" on the Live/Test dropdown. Feathery will take care of creating it in both environments within Stripe. You can also do this manually at any point, just keep the names the same to take advantage of the Feathery runtime behavior.

Example 1: Plan selector using buttons

In this simple plan selector example, a series of three buttons allow the user to select a single plan. The button removes all products from the selected purchase using the Clear Product from Cart action (all). Following this action, it has an Add Product to Cart action to select the associated Stripe product with quantity of 1. This enforces the "single-select" behavior for a plan. This is partially illustrated below.

Also note that the plan names and prices can be dynamically derived from Stripe using the text source property on text and button elements. For example, the screen below show the text property set to the Stripe product name for the Starter Plan.

Using this text source property on buttons or text element, you can dynamically pull the following fields from the Stripe product catalog for each product:

  • name

  • price (raw and currency formatted)

  • currency code (e.g "usd")

  • subscription interval (one-time, daily, weekly, monthly, yearly)

  • mode - LIVE or TEST. Where the product is configured in Stripe.

  • cart quantity (for this product)

  • cart sub-total (for this product, raw and currency formatted)

  • cart grand total (for all products in the cart, raw and currency formatted)

Each button also immediately navigates to the next step for purchasing the selected plan.

The purchase step (illustrated below) provides a summary of the chosen plan's name and cost using text fields. The text fields use the text source property discussed above to dynamically pull the product name and price from stripe. Note in the screen below that there are lines for each of the three possible plans and that each has a show rule that dynamically shows the line based on what is in feathery.cart.

This step also has the credit card entry field since this form is designed as a Feathery form type of payment flow (not Stripe checkout). There is also "buy" button used to purchase the selected plan. The button is configured with a Checkout Cart click action (more about this in Payment). This action is used to actually purchase the previously selected products. This action triggers the payment and subscription creation for the selected product in Stripe and then the form navigates to the final confirmation step.

Example 2: Plan selector with number of licenses input

This example is similar to the first example but additionally allows the user to select a quantity of licenses to purchase when a plan is selected. Each selector now has a licenses number input field as shown below. Like above, each button also removes all product selections using the Clear Product from Cart action and uses the Add Product to Cart action to add the Stripe product to the selections. Note that the select action uses the "starter-licenses" field value for the quantity to add. This again enforces the "single-select" behavior for a plan. This is partially illustrated below.

Similar to the previous example, names and prices are dynamically derived from Stripe using the text source property on text and button elements.

The purchase step is similar to the example above, but does include a more complete representation of the "cart" including the cart grand total. The text fields used to build the cart representation use the text source property discussed above to dynamically pull the product name, price, cart quantity and cart (product line item) subtotal from stripe. Note in the screen below that there are lines for each of the three possible plans and that each has a show rule that dynamically shows the line based on what is in feathery.cart.

Example 3: Plan selector using container clicks (no buttons)

This example is similar to example 1 but instead uses a click on the container to select the plan. The container click removes all product selections using the Clear Product from Cart action and uses the Add Product to Cart action to add the Stripe product to the selections with a fixed quantity of 1. This enforces the "single-select" behavior for a plan just as in example 1. This is illustrated below.

The Next button simply navigates to the purchase step. The purchase step is the same as in example 1. Note below that the Next button does have a validation rule to ensure a plan is selected before advancing.

The purchase step is similar to a previous example above and dynamically shows the selected product and cost depending on the feathery.cart selections.

Cart Selection Total

Feathery automatically calculates the total of the purchase based on what has been added to the cart and the prices of those products that you have configured in Stripe. This monetary value is stored in a special hidden field named: feathery.cart.total. If you wish to display this value on your form you may use a text that contains {{feathery.cart.total}} in it. You may also use the text source property discussed above on a text element and choose "Cart Grand Total".

Logic Rule Cart Access

Feathery forms make the payment/shopping cart and the items it contains available within advanced logic rules via the feathery.cart global object. The cart object is a sub-property of the feathery object that is available as a global in all logic rules. The feathery global is documented in the Context API

Cart PropertyTypeDescription

total

number

The cart monetary total. Read-only.

total_formatted

string

The cart monetary total locale formatted as a currency value. Read-only.

items

{[product_id: string]: {id: string; name:string;price: number; price_formatted: string; quantity: number; subtotal: number; subtotal_formatted: string;}}

Items that have been added to the cart for purchase. This is an object hash of cart item objects keyed by product IDs. Read-only.

addProductToCart

(productId: string, quantity: number, replace = true) => {[productId: string]: number}

Adds a product to the cart of the given quantity. The quantity is either added to any existing quantity already in the cart or if replace is passed as true, then the passed quantity is set as the new cart quantity of the product. Returns the updated cart product quantities.

removeProductFromCart

(productId: string) => {[productId: string]: number}

Removes a product from the cart. Returns the updated cart product quantities.

Logic Rule Stripe Purchasable Products

Feathery forms make the Stripe purchasable products available within advanced logic rules via the feathery.products global object. The products object is a sub-property of the feathery object that is available as a global in all logic rules. The feathery global is documented in the Context API. All properties are READ ONLY.

Product PropertyTypeDescription

id

string

The Stripe product ID.

name

string

Product name.

description

string

Product description, if any.

active

boolean

False if the product is archived in Stripe. Only active products are selectable to be purchased.

price

number

The product price.

price_formatted

string

The product price locale formatted as a currency value.

currency

string

The price currency 3-letter code (ISO 4217).

subscription_interval

string

One-Time, Dayly (Daily), Weekly, Monthly, Yearly

mode

string

Where configured in Stripe: 'live' or 'test'.

cart_quantity

number

The quantity of this product in the cart.

cart_subtotal

number

The cart monetary total for this product. Price X quantity.

cart_subtotal_formatted

string

The cart monetary total for this product locale formatted as a currency value.

pricing_type

string

The type of pricing: flat-rate, per x units (where x is the number of units), tiered - volume, tiered - graduated.

addToCart

(quantity: number, replace = true) => {[productId: string]: number}

Adds this product to the cart of the given quantity. The quantity is either added to any existing quantity already in the cart or if replace is passed as true, then the passed quantity is set as the new cart quantity of the product. Returns the updated cart product quantities.

removeFromCart

() => {[productId: string]: number}

Removes this product from the cart. Returns the updated cart product quantities.

Also...

Note that Feathery is designed to allow you maximum flexibility in your design. It is also possible to design a flow in which the user product choice and payment/checkout initiation are triggered by a single click and therefore not separate steps. There are many possible design approaches.

Last updated