async getPaymentLink({tier, cadence, offer, member, metadata, successUrl, cancelUrl, email}) {
        let coupon = null;
        let trialDays = null;
        if (offer) {
            if (!tier.id.equals(offer.tier.id)) {
                throw new BadRequestError({
                    message: 'This Offer is not valid for the Tier'
                });
            }
            if (offer.type === 'trial') {
                trialDays = offer.amount;
            } else {
                coupon = await this.getCouponForOffer(offer.id);
            }
        }

        let customer = null;
        if (member) {
            customer = await this.getCustomerForMember(member);
        }

        const price = await this.getPriceForTierCadence(tier, cadence);

        const data = {
            metadata,
            successUrl: successUrl,
            cancelUrl: cancelUrl,
            trialDays: trialDays ?? tier.trialDays,
            coupon: coupon?.id
        };

        // If we already have a coupon, we don't want to give trial days over it
        if (data.coupon) {
            delete data.trialDays;
        }

        if (!customer && email) {
            data.customerEmail = email;
        }

        const session = await this.stripeAPIService.createCheckoutSession(price.id, customer, data);

        return session.url;
    }
@param {object} params
@param {import('../../../tiers/Tier')} params.tier
@param {Tier.Cadence} params.cadence
@param {Offer} [params.offer]
@param {Member} [params.member]
@param {Object.<string, any>} [params.metadata]
@param {string} params.successUrl
@param {string} params.cancelUrl
@param {string} [params.email]

@returns {Promise<URL>}