@noa-eiland can you give us an update on the latest plans for improving this app ?
I have used the paid plans in a little unorthodox way. I donât provide a page that lists all of the plans (I have 7 plans at the moment including two trial plans).
I use repeaters to drill down all of the plans and display only a fraction of them on some pages. I use light boxes and the actual corvid âpaidPlans.purchasePlan()â to get all of the work done.
I also update my own âsubscriptionsâ database with relevant information about the purchased plan. Currently there is no effort to watch if the same user with the same user id purchases a plan twice, I have hooks in this now in that subscriptions database that prevent this and output a log message that a duplicate plan was attempted to be purchased.
I also have a subscriptions page setup using this same database so members can see their active subscriptions and press a button to cancel.
The last piece of the puzzle for me is letting the user cancel the subscription. I can set up an email delivery to myself when the user cancels using a button, but I would rather be able to call some type of back end code to get this done.
Also we need a way to alter payment information. How is WIX storing the credit card information of each user and the cron job or whatever that is auto charging them? Most of the other 3rd party apps out there are doing things like â14 day trial that leads into an automatic subscriptionâ but that is not possible with WIX paid plans.
@Cameron Osborne I am product manager responsible for the Paid Plans app. Itâs nice to hear that you like it and you do great things with our API. We are currently working on feature that allows to limit purchase once per customer. Also, I would love to talk more about your site if you could reach me out at antanasd at wix.com please?
@antanasd Hello, my site is still under construction but there are definitely use cases of the corvid backend code and web modules. I can share the name of the site with your privately, Iâm not sure how to do that though on these forums.
@antanasd My next task is to create an admin only page within the domain that I can create/remove/update items in my âsubscriptionsâ database. It would be WONDERFUL if somehow I can create a hook that:
Allows a user to go into his/her subscriptions list on a members page. I have already figured this out as mentioned above, by using a database that gives relevant information about existing user plans with a âstatusâ field as one of the elements by following this handy video here: https://www.youtube.com/watch?time_continue=667&v=E8W3nTazcNo
On the right side of each repeater item (repeater items occur in a column one at a time shown in the attached picture above) is a âCancelâ button. Once cancelled the âsubscriptionsâ database status is updated. Here is where things could get amazing if the wix developers are on board. I need a corvid function where I can âcancel a paid planâ. Currently the only way to do this is to manually do it in the âpurchased plansâ area of the dashboard. If I am on vacation or not available, that could get tricky. Right now I am about to set up an email push when a user attempts to cancel a subscription and the button changes from âCancelâ to âPending Cancellationâ. The button becomes disabled.
My job right now is to receive that cancellation request email from a user, then I can go into the subscriptions database and update the status field to âCancelledâ, and then go into the dashboard and manually cancel the plan.
@antanasd any updates on this? still no redirect?
@danerezsd @mikrokogebogen we are constantly improving the app. We just recently improved check out page and now it consists of summary box and check out component. Next up is free trial and ability to limit the purchase once per customer only. Also, we are working on ability that will allow to show active subscriptions to customers and manage them.
As for thank you page improvement and redirect, we will look into it after we are done with was I described above. Unfortunately, I canât provide exact timelines on those.
If you would want to learn more or tell me how redirect should work, please shoot me an email at antanasd (eta) wix.com and we could schedule a call.
@antanasd there is already an option for a free plan that you can use as a free trial. There is also a simple way of using corvid to check out what plan the current user has. Allowing a user to purchase a plan only once is nice but seems like a rare event ( users are not stupid enough to buy something twice for no reason ).
Redirect is supercritical for user flow. Only 1 in 3 users got our free trial and then found their way to our dashboard on their own. That should really be close to 100%.
@danerezsd letâs chat. I would love to learn about your case more. I will write a private message.
@danerezsd canât find your email. Can you ping me at antanasd (ata) wix.com. Thanks.
@antanasd Is there any update on this? How can a user cancel a plan on their own without me as an admin going into their account and doing it? How can a user modify payment information?
Has anyone found the solution to allow customers to ugrade/ cancel their plan by themselves? Maybe if someone can code this I can remunerate against some fee
Hi! I want to add my thoughts to the discussion on what can be achieved with the current API. Maybe it is usefull for someone here. I assume we are talking about Recurring plans, since thereâs no sense for a customer to cancel a one-time plan.
Cancel button
Canceling is discussed by wix here (probably youâve seen it):
- your customer has to do this manually (to go to his PayPal/CC and cancel the plan themselves)
- you have to do this manually (via the wix interface, I suggest you add a âRequest cancelâ button to your site if you do this so you get a notification when a customer wants to cancel)
- my solution I just thought of which is payment provider specific, in this case PayPal: to have the Cancel button trigger an API event to your merchant PayPal account which would cancel/suspend the recurring payment using the PayPal API .
Update button
I can sort of see how this can be hacked together with the little API they provide, but itâs quite tricky and it depends on having cancel functionality as well. It also depends on whether you want the new plan to take effect after the old plan ends, or immediately. The first case is simpler:
- Cancel the old plan
- Purchase/Order the new plan and activate it when the old plan ends (which can be done with the current API, I believe).
In you want the user to have access immediately, in the second case, you will have a scenario in which the user will have 2 active plans until the old plan expires. This brings many questions: if itâs an upgrade, does the customer only pay the difference between the two plans (perhaps in respect to how much time is left on the old plan)? Also, you need to make sure your site handles multiple plans (i.e.User.getPricingPlans( )
will return multiple plans now). Iâm not sure how other companies solve these design issues.
In any case, I think Wix doesnât allow you to directly update/cancel the plans right now because there are some complicated design issues. Automating this might be possible, but you have to think about whether it is worth it for how many customers you have.
Best,
Henk
@antanasd Hello i was hoping you could please help me. I simply want to separate the âpurchase nowâ buttons for my plans. Right now they have to appear together on the page -
is there a way to make them appear separate and have more control over layout?
@osbornecameron what you did sounds awesome. I would like to try to do the same for my website. I watched the video you shared but got stuck⌠Is there a way we can communicate with each other via email? Thanks
@osbornecameron We are working on My Plans feature that would allow to view and manage (cancel) orders for members in Members area. In the meantime, we have released Corvid API that allows to create a custom page that would show plans and cancel them.
You can read the documentation here https://www.wix.com/corvid/reference/wix-paid-plans.html#cancelOrder .
Way to allow site members to cancel their own orders:
- For the members to be able to cancel their orders first youâll need to be able to show them the orders so they could choose what to cancel. Way to have ordersâ data is to save it in your own DB dataset in corvid ( https://support.wix.com/en/article/creating-a-database-collection ) every time the member purchases a plan.
E.g. of the data that can be collected and saved on every purchase of the plan:
âplanNameâ: plan.name ,
âplanIdâ: plan._id,
âorderIdâ: purchaseResponse.orderId,
âmemberIdâ: user.id ,
âdateCreatedâ: Date().toString()
âplanâ is the plan to be purchased,
âpurchaseResponseâ is the response we get after calling .purchasePlan ( https://www.wix.com/corvid/reference/draft/wix-paid-plans.html#purchasePlan ) method because itâs return value is PurchaseResult ( https://www.wix.com/corvid/reference/draft/wix-paid-plans.html#PurchaseResult ) ,
âuserâ - currently logged in user https://www.wix.com/corvid/reference/draft/wix-users.html#currentUser .
Example of the code used on dynamic page of custom package picker where member can purchase a plan (notice a field called " canceled " - it is needed so you would be able to track if member canceled the order or not, it is obvious that on the purchase we need to set it to false ):
import paidPlans from âwix-paid-plansâ;
import wixData from âwix-dataâ;
import wixUsers from âwix-usersâ;
$w.onReady( function () {
$w(â#dynamicDatasetâ).onReady( () => {
const plan = $w(â#dynamicDatasetâ).getCurrentItem();
// purchase a plan
$w(â#button2â).onClick( (event) => {
const purchase = paidPlans.purchasePlan(plan._id).then(purchaseResponse => {
// get current member (who is purchasing the plan)
let user = wixUsers.currentUser;
// collect all the data you want to save to your collection
let toInsert = {
âplanNameâ: plan.name ,
âplanIdâ: plan._id,
âorderIdâ: purchaseResponse.orderId,
âmemberIdâ: user.id ,
âcanceledâ: false,
âdateCreatedâ: Date().toString()
};
// insert the data into âsubscriptionsâ collection that youâve created (how to https://support.wix.com/en/article/creating-a-database-collection )
wixData.insert(âsubscriptionâ, toInsert)
})
});
});
}); - Once you start saving membersâ orders data youâll have the necessary information to be able to allow them to cancel their orders. Cancellation can be done calling .cancelOrder method ( https://www.wix.com/corvid/reference/draft/wix-paid-plans.html#cancelOrder ) which takes orderId (which you are saving to your DB dataset (field " âorderIdâ: purchaseResponse.orderId " in the previous example)).
You can create members area page Subscriptions on your site where youâd show logged-in memberâs orders:
code example:
import wixPaidPlans from âwix-paid-plansâ;
import wixData from âwix-dataâ;
import wixUsers from âwix-usersâ;
import wixWindow from âwix-windowâ;
$w.onReady( function () {
// https://www.wix.com/corvid/reference/wix-users.html#currentUser
const user = wixUsers.currentUser;
// filter dataset so only currently logged-in userâs orders would be visible ( https://www.wix.com/corvid/reference/wix-dataset.Dataset.html#setFilter )
$w(â#dataset1â).setFilter( wixData.filter()
.eq(âmemberIdâ, user.id )
)
.then( () => {
$w(â#dataset1â).onReady( () => {
$w(â#button1â).onClick( (event) => {
const $item = $ w.at (event.context);
const subscription = $item(â#dataset1â).getCurrentItem();
const orderId = subscription.orderId;
// Cancel the specific order of the logged-in user - https://www.wix.com/corvid/reference/wix-paid-plans.html#cancelOrder
wixPaidPlans.cancelOrder(orderId)
.then( () => {
// Get details for updating status of existing subscription (âsubscriptionâ dataset youâve created before)
const toUpdate = {
â_idâ: subscription._id,
âplanNameâ: subscription.planName,
âplanIdâ: subscription.planId,
âorderIdâ: subscription.orderId,
âmemberIdâ: user.id ,
âdateCreatedâ: subscription.dateCreated,
âcanceledâ: true , // Set cancellation to true
âdateUpdatedâ: Date().toString()
};
// Update existing subscription in collection to show that the subscription is canceled
wixData.update(âsubscriptionâ, toUpdate);
// OPTIONAL - Let user know that cancellation succeeded by opening some lightbox
wixWindow.openLightbox(âplanCanceledâ)
})
// Do something in the case of error - e.g. open lightbox that says that cancellation failed
. catch ((err) => {
wixWindow.openLightbox(âcancelFailedâ);
});
})
})
} )
. catch ( (err) => {
// in the case $w(â#dataset1â).setFilter(âŚ) fails
console.log(err);
} );
})
Let me know if you will have questions at antanasd (eta) wix.com.
We are working on My Plans feature that would allow to view and manage (cancel) orders for members in Members area. In the meantime, we have released Corvid API that allows to create a custom page that would show plans and cancel them.
You can read the documentation here https://www.wix.com/corvid/reference/wix-paid-plans.html#cancelOrder .
Way to allow site members to cancel their own orders:
- For the members to be able to cancel their orders first youâll need to be able to show them the orders so they could choose what to cancel. Way to have ordersâ data is to save it in your own DB dataset in corvid ( https://support.wix.com/en/article/creating-a-database-collection ) every time the member purchases a plan.
E.g. of the data that can be collected and saved on every purchase of the plan:
âplanNameâ: plan.name ,
âplanIdâ: plan._id,
âorderIdâ: purchaseResponse.orderId,
âmemberIdâ: user.id ,
âdateCreatedâ: Date().toString()
âplanâ is the plan to be purchased,
âpurchaseResponseâ is the response we get after calling .purchasePlan ( https://www.wix.com/corvid/reference/draft/wix-paid-plans.html#purchasePlan ) method because itâs return value is PurchaseResult ( https://www.wix.com/corvid/reference/draft/wix-paid-plans.html#PurchaseResult ) ,
âuserâ - currently logged in user https://www.wix.com/corvid/reference/draft/wix-users.html#currentUser .
Example of the code used on dynamic page of custom package picker where member can purchase a plan (notice a field called " canceled " - it is needed so you would be able to track if member canceled the order or not, it is obvious that on the purchase we need to set it to false ):
import paidPlans from âwix-paid-plansâ;
import wixData from âwix-dataâ;
import wixUsers from âwix-usersâ;
$w.onReady( function () {
$w(â#dynamicDatasetâ).onReady( () => {
const plan = $w(â#dynamicDatasetâ).getCurrentItem();
// purchase a plan
$w(â#button2â).onClick( (event) => {
const purchase = paidPlans.purchasePlan(plan._id).then(purchaseResponse => {
// get current member (who is purchasing the plan)
let user = wixUsers.currentUser;
// collect all the data you want to save to your collection
let toInsert = {
âplanNameâ: plan.name ,
âplanIdâ: plan._id,
âorderIdâ: purchaseResponse.orderId,
âmemberIdâ: user.id ,
âcanceledâ: false,
âdateCreatedâ: Date().toString()
};
// insert the data into âsubscriptionsâ collection that youâve created (how to https://support.wix.com/en/article/creating-a-database-collection )
wixData.insert(âsubscriptionâ, toInsert)
})
});
});
}); - Once you start saving membersâ orders data youâll have the necessary information to be able to allow them to cancel their orders. Cancellation can be done calling .cancelOrder method ( https://www.wix.com/corvid/reference/draft/wix-paid-plans.html#cancelOrder ) which takes orderId (which you are saving to your DB dataset (field " âorderIdâ: purchaseResponse.orderId " in the previous example)).
You can create members area page Subscriptions on your site where youâd show logged-in memberâs orders:
code example:
import wixPaidPlans from âwix-paid-plansâ;
import wixData from âwix-dataâ;
import wixUsers from âwix-usersâ;
import wixWindow from âwix-windowâ;
$w.onReady( function () {
// https://www.wix.com/corvid/reference/wix-users.html#currentUser
const user = wixUsers.currentUser;
// filter dataset so only currently logged-in userâs orders would be visible ( https://www.wix.com/corvid/reference/wix-dataset.Dataset.html#setFilter )
$w(â#dataset1â).setFilter( wixData.filter()
.eq(âmemberIdâ, user.id )
)
.then( () => {
$w(â#dataset1â).onReady( () => {
$w(â#button1â).onClick( (event) => {
const $item = $ w.at (event.context);
const subscription = $item(â#dataset1â).getCurrentItem();
const orderId = subscription.orderId;
// Cancel the specific order of the logged-in user - https://www.wix.com/corvid/reference/wix-paid-plans.html#cancelOrder
wixPaidPlans.cancelOrder(orderId)
.then( () => {
// Get details for updating status of existing subscription (âsubscriptionâ dataset youâve created before)
const toUpdate = {
â_idâ: subscription._id,
âplanNameâ: subscription.planName,
âplanIdâ: subscription.planId,
âorderIdâ: subscription.orderId,
âmemberIdâ: user.id ,
âdateCreatedâ: subscription.dateCreated,
âcanceledâ: true , // Set cancellation to true
âdateUpdatedâ: Date().toString()
};
// Update existing subscription in collection to show that the subscription is canceled
wixData.update(âsubscriptionâ, toUpdate);
// OPTIONAL - Let user know that cancellation succeeded by opening some lightbox
wixWindow.openLightbox(âplanCanceledâ)
})
// Do something in the case of error - e.g. open lightbox that says that cancellation failed
. catch ((err) => {
wixWindow.openLightbox(âcancelFailedâ);
});
})
})
} )
. catch ( (err) => {
// in the case $w(â#dataset1â).setFilter(âŚ) fails
console.log(err);
} );
})
Let me know if you will have questions at antanasd (eta) wix.com.
We are working on My Plans feature that would allow to view and manage (cancel) orders for members in Members area. In the meantime, we have released Corvid API that allows to create a custom page that would show plans and cancel them.
You can read the documentation here https://www.wix.com/corvid/reference/wix-paid-plans.html#cancelOrder .
Way to allow site members to cancel their own orders:
- For the members to be able to cancel their orders first youâll need to be able to show them the orders so they could choose what to cancel. Way to have ordersâ data is to save it in your own DB dataset in corvid ( https://support.wix.com/en/article/creating-a-database-collection ) every time the member purchases a plan.
E.g. of the data that can be collected and saved on every purchase of the plan:
âplanNameâ: plan.name ,
âplanIdâ: plan._id,
âorderIdâ: purchaseResponse.orderId,
âmemberIdâ: user.id ,
âdateCreatedâ: Date().toString()
âplanâ is the plan to be purchased,
âpurchaseResponseâ is the response we get after calling .purchasePlan ( https://www.wix.com/corvid/reference/draft/wix-paid-plans.html#purchasePlan ) method because itâs return value is PurchaseResult ( https://www.wix.com/corvid/reference/draft/wix-paid-plans.html#PurchaseResult ) ,
âuserâ - currently logged in user https://www.wix.com/corvid/reference/draft/wix-users.html#currentUser .
Example of the code used on dynamic page of custom package picker where member can purchase a plan (notice a field called " canceled " - it is needed so you would be able to track if member canceled the order or not, it is obvious that on the purchase we need to set it to false ):
import paidPlans from âwix-paid-plansâ;
import wixData from âwix-dataâ;
import wixUsers from âwix-usersâ;
$w.onReady( function () {
$w(â#dynamicDatasetâ).onReady( () => {
const plan = $w(â#dynamicDatasetâ).getCurrentItem();
// purchase a plan
$w(â#button2â).onClick( (event) => {
const purchase = paidPlans.purchasePlan(plan._id).then(purchaseResponse => {
// get current member (who is purchasing the plan)
let user = wixUsers.currentUser;
// collect all the data you want to save to your collection
let toInsert = {
âplanNameâ: plan.name ,
âplanIdâ: plan._id,
âorderIdâ: purchaseResponse.orderId,
âmemberIdâ: user.id ,
âcanceledâ: false,
âdateCreatedâ: Date().toString()
};
// insert the data into âsubscriptionsâ collection that youâve created (how to https://support.wix.com/en/article/creating-a-database-collection )
wixData.insert(âsubscriptionâ, toInsert)
})
});
});
}); - Once you start saving membersâ orders data youâll have the necessary information to be able to allow them to cancel their orders. Cancellation can be done calling .cancelOrder method ( https://www.wix.com/corvid/reference/draft/wix-paid-plans.html#cancelOrder ) which takes orderId (which you are saving to your DB dataset (field " âorderIdâ: purchaseResponse.orderId " in the previous example)).
You can create members area page Subscriptions on your site where youâd show logged-in memberâs orders:
code example:
import wixPaidPlans from âwix-paid-plansâ;
import wixData from âwix-dataâ;
import wixUsers from âwix-usersâ;
import wixWindow from âwix-windowâ;
$w.onReady( function () {
// https://www.wix.com/corvid/reference/wix-users.html#currentUser
const user = wixUsers.currentUser;
// filter dataset so only currently logged-in userâs orders would be visible ( https://www.wix.com/corvid/reference/wix-dataset.Dataset.html#setFilter )
$w(â#dataset1â).setFilter( wixData.filter()
.eq(âmemberIdâ, user.id )
)
.then( () => {
$w(â#dataset1â).onReady( () => {
$w(â#button1â).onClick( (event) => {
const $item = $ w.at (event.context);
const subscription = $item(â#dataset1â).getCurrentItem();
const orderId = subscription.orderId;
// Cancel the specific order of the logged-in user - https://www.wix.com/corvid/reference/wix-paid-plans.html#cancelOrder
wixPaidPlans.cancelOrder(orderId)
.then( () => {
// Get details for updating status of existing subscription (âsubscriptionâ dataset youâve created before)
const toUpdate = {
â_idâ: subscription._id,
âplanNameâ: subscription.planName,
âplanIdâ: subscription.planId,
âorderIdâ: subscription.orderId,
âmemberIdâ: user.id ,
âdateCreatedâ: subscription.dateCreated,
âcanceledâ: true , // Set cancellation to true
âdateUpdatedâ: Date().toString()
};
// Update existing subscription in collection to show that the subscription is canceled
wixData.update(âsubscriptionâ, toUpdate);
// OPTIONAL - Let user know that cancellation succeeded by opening some lightbox
wixWindow.openLightbox(âplanCanceledâ)
})
// Do something in the case of error - e.g. open lightbox that says that cancellation failed
. catch ((err) => {
wixWindow.openLightbox(âcancelFailedâ);
});
})
})
} )
. catch ( (err) => {
// in the case $w(â#dataset1â).setFilter(âŚ) fails
console.log(err);
} );
})
Let me know if you will have questions at antanasd (eta) wix.com.
@antanasd Could to check for duplicates before actually invoking the paid plan interface:
function finishPlanPurchase(user, email, plan) {
let id = plan._id;
wixData.query("Subscriptions")
.contains("memberId", user.id)
.find()
.then(results => {
let exists = false ;
for ( var i = 0; i < results.items.length; i++) {
let sub = results.items[i];
matchedPlan = sub.memberId === user.id && sub.planId === id && sub.status.toUpperCase() === activeStatus.toUpperCase();
if (matchedPlan) {
exists = true ;
break ;
}
}
if (!exists) {
paidPlans.purchasePlan(id).then(purchase => {
if (purchase.wixPayStatus === âSuccessfulâ) {
wixWindow.lightbox.close({
âstatusâ: âSuccessfulâ,
âitemâ: plan
});
console.log("completed purchase")
} **else** {
wixWindow.lightbox.close({
âstatusâ: âPayment Unsuccessfulâ,
âitemâ: plan
});
}
})
} else {
wixWindow.lightbox.close({
âstatusâ: âDuplicateâ,
âitemâ: plan
});
}
}, rejected => {
wixWindow.lightbox.close({
âstatusâ: âRejectedâ
});
})
}
@antanasd So the cancelOrder(orderID) function requires an order id. Is this the same order ID from the purchasePlanEvent that is submitted to the backend? I intercept these events and dump them into a database by harvesting only a few key fields. That event has the following below.
Is the orderId the âorder.idâ field of the purchasePlanEvent, in this case the value âb8401bab-8e5d-4bf6-944b-b2d56698d4c9â below? I copied this directly from the purchasePlanEvent in the corvid manual: https://www.wix.com/corvid/reference/draft/wix-paid-plans-backend.Events.html#PlanPurchasedEvent
"order":{
* "paymentStatus":"PAID",
* "validUntil":"2019-09-12T05:43:53.246Z",
* "price":{
* "currency":"THB",
* "amount":0
* },
* "cancellationReason":"CANCELLATION_REASON_UNDEFINED",
* "validFrom":"2019-08-12T05:43:53.246Z",
* "planName":"valid 1 week",
* "wixPayOrderId":"",
* "recurring":false,
* "id":"b8401bab-8e5d-4bf6-944b-b2d56698d4c9",
* "dateCreated":"2019-08-12T05:43:53.246Z",
* "status":"ACTIVE",
* "roleId":"",
* "planDescription":"Platinum Plan",
* "memberId":"42d90dcb-b9ad-47be-9a36-488be3dec679",
* "orderType":"ONLINE",
* "planId":"a52f41cc-8129-4812-9e1c-fafa2807a25d",
* "validFor":{
* "forever":false,
* "period":{
* "amount":1,
* "unit":"MONTH"
* }
* }
* }