Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

garethdaine's avatar

Restrict Coupon to Specific Plan

Hi Folks,

I need to restrict coupon usage during registration both on the frontend and on the server based on the selected plan.

So when a user visits the following URL:

https://example.com/register?coupon=agency

I want to be able to not allow the user to select the other plans if that coupon is being used.

So, I have three plans:

  1. Individual - 40% Coupon
  2. Business - 50% Coupon
  3. Agency - 55% Coupon

As above, depending on the URL the customer goes to it will restrict plan selection based on the matching coupon code, or even remove the coupon code if another plan is selected.

Additionally, I would like it that based on the coupon passed, the appropriate plan would be selected.

There would also need to be some validation on the server side to check whether the coupon passed matches the plan selected.

Any advice would be most appreciated.

Thanks

0 likes
2 replies
garethdaine's avatar

OK, I have the frontend working by extending the resources/assets/js/spark-components/auth/register-stripe.js components selectAppropriateDefaultPlan() method.

var base = require('auth/register-stripe');

Vue.component('spark-register-stripe', {
    mixins: [base],

    methods: {
        selectAppropriateDefaultPlan() {
            if (this.monthlyPlans.length == 0 && this.yearlyPlans.length > 0) {
                this.showYearlyPlans();
            }
            
            var coupon = this.query.coupon;

            if (this.query.plan) {
                this.selectPlanByName(this.query.plan);
            } else if (this.query.invitation) {
                this.selectFreePlan();
            } else if (this.paidPlansForActiveInterval.length > 0) {
                if (typeof coupon !== 'undefined') {
                    this.selectPlanByName(this.toTitleCase(coupon));
                } else {
                    this.selectPlan(this.paidPlansForActiveInterval[0]);
                }
            } else {
                this.selectFreePlan();
            }
        },

        toTitleCase(str) {
            return str.replace(/\b\w+/g, function(s) {
                return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase();
            });
        }
    }
});

Now I just need to perform the validation server side.

garethdaine's avatar

OK, so now the user can only select a plan that matches the coupon code (both monthly and yearly plans):

var base = require('auth/register-stripe');

Vue.component('spark-register-stripe', {
    mixins: [base],

    methods: {
        /**
         * Select the appropriate default plan for registration.
         */
        selectAppropriateDefaultPlan() {
            if (this.monthlyPlans.length == 0 && this.yearlyPlans.length > 0) {
                this.showYearlyPlans();
            }

            if (this.query.plan) {
                this.selectPlanByName(this.query.plan);
            } else if (this.query.invitation) {
                this.selectFreePlan();
            } else if (this.paidPlansForActiveInterval.length > 0) {
                if (typeof this.query.coupon !== 'undefined') {
                    this.selectPlanByName(this.toTitleCase(this.query.coupon));
                } else {
                    this.selectPlan(this.paidPlansForActiveInterval[0]);
                }
            } else {
                this.selectFreePlan();
            }
        },


        /**
         * Select the given plan.
         */
        selectPlan(plan) {
            var planId = plan.id;

            if (typeof this.query.coupon !== 'undefined') {
                if (planId.indexOf(this.query.coupon) > -1) {
                    var allowedPlan = _.find(this.plans, plan => plan.id === planId);
                    
                    this.selectedPlan = allowedPlan;
                    this.registerForm.plan = allowedPlan.id;
                } else if (planId !== this.query.coupon) {
                    var allowedPlan = _.find(this.plans, plan => plan.id === this.query.coupon);

                    this.selectedPlan = allowedPlan;
                    this.registerForm.plan = allowedPlan.id;
                }
            } else {
                this.selectedPlan = plan;
                this.registerForm.plan = plan.id;
            }
        },

        toTitleCase(str) {
            return str.replace(/\b\w+/g, function(s) {
                return s.charAt(0).toUpperCase() + s.substr(1).toLowerCase();
            });
        }
    }
});

So, now just for the validation server side.

Please or to participate in this conversation.