createPlan( )
Creates a pricing plan.
Description
The createPlan()
function returns a Promise that resolves to a newly-created pricing plan after is has successfully been created.
The passed plan
object must contain a pricing model. A pricing model can be one of the following:
- A subscription: A subscription with recurring payment and how often the plan occurs. Subscriptions can have free trial days.
- A plan that does not renew: A single payment for a specific duration that doesn't renew.
- An unlimited plan: A single payment for an unlimited amount of time (until canceled).
Pricing plans created by this function are available to the site owner in the Pricing Plans section in the Dashboard.
This function requires elevated permissions to run. This function is not universal and runs only on the backend.
Syntax
function createPlan(plan: Plan): Promise<Plan>
createPlan Parameters
NAME
TYPE
DESCRIPTION
Information for the plan being created.
Returns
Fulfilled - The created plan.
Rejected - Error message.
Return Type:
NAME
TYPE
DESCRIPTION
Date plan was created.
Plan ID.
Date plan was last updated.
Whether the buyer can start the plan at a later date.
Default: false
.
Whether the plan is archived. Archived plans are not visible and can't be purchased anymore, but existing purchases remain in effect.
Whether the buyer is allowed to cancel their plan. If false
, calling the cancelOrder()
function returns an error.
Default: false
.
Plan description.
ID of the form associated with the plan at checkout.
Whether the plan has any orders (including pending and unpaid orders).
Number of times the same buyer can purchase the plan. Currently limited to support:
- Empty value or a value of
0
, meaning no limitation. - Value of
1
, meaning limited to one purchase per buyer.
Plan name.
List of text strings that promote what is included with this plan.
For example, "Plenty of parking" or "Free gift on your birthday".
Plan price, payment schedule, and expiration.
Whether the plan is marked as primary. If true
, the plan is highlighted on the site with a custom ribbon.
Default: false
.
Whether the plan is public (visible to site visitors and members).
URL-friendly version of plan name. Unique across all plans in the same site.
Any terms and conditions that apply to the plan. This information will be displayed during checkout.
Was this helpful?
1import { plans } from 'wix-pricing-plans.v2';23/* Sample plan value:4 * {5 * allowFutureStartDate: true,6 * buyerCanCancel: true,7 * description: 'Fun content for our younger users',8 * formId: 'ee62cefa-bdc2-4b5d-baab-6faeef83cecb',9 * maxPurchasesPerBuyer: 1,10 * name: 'Junior',11 * perks: {12 * values: [13 * 'Multiplayer',14 * 'Multiple devices',15 * 'No ads",16 * 'Unlimited access'17 * ]18 * },19 * pricing: {20 * price: {21 * currency: 'USD',22 * value: '10.00"23 * },24 * subscription: {25 * cycleCount: 12,26 * cycleDuration: {27 * count: 1,28 * unit: 'MONTH'29 * }30 * }31 * },32 * public: true,33 * termsAndConditions: 'No sharing access with others!'34 * }35 */3637export async function myCreatePlanFunction(plan) {38 try {39 const newPlan = await plans.createPlan(plan);4041 const planId = newPlan._id;42 const pricingObject = newPlan.pricing;43 const perks = newPlan.perks;4445 return newPlan;46 } catch (error) {47 console.error(error);48 // Handle the error49 }50}5152/* Promise resolves to:53 * {54 * "_createdDate": "2024-01-21T07:06:06.993Z",55 * "_id": "046371ff-7e5d-4bdb-a01d-a00ff462bed8",56 * "_updatedDate": "2024-01-21T07:06:06.993Z",57 * "allowFutureStartDate": true,58 * "archived": false,59 * "buyerCanCancel": true,60 * "description": "Fun content for our younger users",61 * "formId": "ee62cefa-bdc2-4b5d-baab-6faeef83cecb",62 * "hasOrders": false,63 * "maxPurchasesPerBuyer": 1,64 * "name": "Junior",65 * "perks": {66 * "values": [67 * "Multiplayer",68 * "Multiple devices",69 * "No ads",70 * "Unlimited access"71 * ]72 * },73 * "pricing": {74 * "price": {75 * "currency": "USD",76 * "value": "10.00"77 * },78 * "public": true,79 * "slug": "junior",80 * "subscription": {81 * "cycleCount": 12,82 * "cycleDuration": {83 * "count": 1,84 * "unit": "MONTH"85 * }86 * },87 * "termsAndConditions": "No sharing access with others!"88 * }89 * }90 */
1import { Permissions, webMethod } from 'wix-web-module';2import { plans } from 'wix-pricing-plans.v2';3import { elevate } from 'wix-auth';45/* Sample plan value:6 * {7 * allowFutureStartDate: true,8 * buyerCanCancel: true,9 * description: 'Fun content for our younger users',10 * formId: 'ee62cefa-bdc2-4b5d-baab-6faeef83cecb',11 * maxPurchasesPerBuyer: 1,12 * name: 'Junior',13 * perks: {14 * values: [15 * 'Multiplayer',16 * 'Multiple devices',17 * 'No ads",18 * 'Unlimited access'19 * ]20 * },21 * pricing: {22 * price: {23 * currency: 'USD',24 * value: '10.00"25 * },26 * subscription: {27 * cycleCount: 12,28 * cycleDuration: {29 * count: 1,30 * unit: 'MONTH'31 * }32 * }33 * },34 * public: true,35 * termsAndConditions: 'No sharing access with others!'36 * }37 */3839export const myCreatePlanFunction = webMethod(Permissions.Anyone, async (plan) => {40 try {41 const elevatedCreatePlan = elevate(plans.createPlan);42 const newPlan = await elevatedCreatePlan(plan);4344 const planId = newPlan._id;45 const pricingObject = newPlan.pricing;46 const perks = newPlan.perks;4748 return newPlan;49 } catch (error) {50 console.error(error);51 // Handle the error52 }53});5455/* Promise resolves to:56 * {57 * "_createdDate": "2024-01-21T07:06:06.993Z",58 * "_id": "046371ff-7e5d-4bdb-a01d-a00ff462bed8",59 * "_updatedDate": "2024-01-21T07:06:06.993Z",60 * "allowFutureStartDate": true,61 * "archived": false,62 * "buyerCanCancel": true,63 * "description": "Fun content for our younger users",64 * "formId": "ee62cefa-bdc2-4b5d-baab-6faeef83cecb",65 * "hasOrders": false,66 * "maxPurchasesPerBuyer": 1,67 * "name": "Junior",68 * "perks": {69 * "values": [70 * "Multiplayer",71 * "Multiple devices",72 * "No ads",73 * "Unlimited access"74 * ]75 * },76 * "pricing": {77 * "price": {78 * "currency": "USD",79 * "value": "10.00"80 * },81 * "public": true,82 * "slug": "junior",83 * "subscription": {84 * "cycleCount": 12,85 * "cycleDuration": {86 * "count": 1,87 * "unit": "MONTH"88 * }89 * },90 * "termsAndConditions": "No sharing access with others!"91 * }92 * }93 */94
1import { Permissions, webMethod } from 'wix-web-module';2import { plans } from 'wix-pricing-plans.v2';3import { elevate } from 'wix-auth';45/* Sample plan object:6 * {7 * name: 'Default',8 * pricing: {9 * singlePaymentUnlimited: true10 * }11 * }12 */1314export const myCreatePlanFunction = webMethod(Permissions.Anyone, async (plan) => {15 try {16 const elevatedCreatePlan = elevate(plans.createPlan);17 const newPlan = await elevatedCreatePlan(plan);1819 return newPlan;20 } catch (error) {21 console.error(error);22 // Handle the error23 }24});2526/* Promise resolves to:27 * {28 * "_createdDate": "2024-01-16T10:32:05.818Z",29 * "_id": "aa0d8e0e-99ad-4c95-ac48-4955e37956c5",30 * "_updatedDate": "2024-01-16T10:32:05.818Z",31 * "allowFutureStartDate": false,32 * "archived": false,33 * "buyerCanCancel": true,34 * "description": "",35 * "hasOrders": false,36 * "name": "Default",37 * "perks": {38 * "values": []39 * },40 * "pricing": {41 * "price": {42 * "currency": "EUR",43 * "value": "0"44 * },45 * "singlePaymentUnlimited": true46 * },47 * "primary": false,48 * "public": true,49 * "slug": "default"50 * }51 */
The populatePlansDropdown
function retrieves all plans and then populates them into the #plansDropdown
. The #plansDropdown
and #clonePlanBtn
are set to disabled
by default.
1/*************************************2 * Backend code - plan-functions.web.js *3 *************************************/45import { Permissions, webMethod } from 'wix-web-module';6import { plans } from 'wix-pricing-plans.v2';7import { elevate } from 'wix-auth';89const elevatedListPlans = elevate(plans.listPlans);10const elevatedGetPlan = elevate(plans.getPlan);11const elevatedCreatePlan = elevate(plans.createPlan);1213export const listPlans = webMethod(Permissions.Anyone, async () => {14 try {15 const response = await elevatedListPlans();16 const allPlans = response.plans;1718 return allPlans;19 } catch (error) {20 console.error(error);21 // Handle the error22 }23});2425export const getPlan = webMethod(Permissions.Anyone, async (planId) => {26 try {27 const selectedPlan = await elevatedGetPlan(planId);2829 return selectedPlan;30 } catch (error) {31 console.error(error);32 // Handle the error33 }34});3536export const createPlan = webMethod(Permissions.Anyone, async (plan) => {37 try {38 const newPlan = await elevatedCreatePlan(plan);3940 return newPlan;41 } catch (error) {42 console.error(error);43 // Handle the error44 }45});464748/*************49 * Page code *50 *************/5152import { listPlans, getPlan, createPlan } from 'backend/plan-functions.web';53$w.onReady(async function () {54 $w('#plansDropdown').disable();55 $w('#clonePlanBtn').disable();56 populatePlansDropdown();5758 let selectedPlan;5960 $w('#plansDropdown').onChange(async () => {61 const planId = $w('#plansDropdown').value;62 selectedPlan = await getPlan(planId);6364 // Set default value for the new plan name65 $w('#planName').value = `${selectedPlan.name}-duplicate`66 $w('#clonePlanBtn').enable();67 });6869 $w('#clonePlanBtn').onClick(async () => {70 const newPlan = selectedPlan;71 // Use inputs to set the new plan name and price72 newPlan.name = $w('#planName').value;73 newPlan.pricing.price.value = $w('#price').value;7475 await createPlan(newPlan);76 });77});7879async function populatePlansDropdown() {80 const plans = await listPlans();81 $w('#plansDropdown').options = plans.map((plan) => {82 return {83 label: plan.name,84 value: plan._id85 }86 });87 $w('#plansDropdown').enable();88}