Esempio n. 1
0
def create():
    if current_user.subscription:
        flash('You already have an active subscription.', 'info')
        return redirect(url_for('user.settings'))

    plan = request.args.get('plan')
    subscription_plan = Subscription.get_plan_by_id(plan)

    # Guard against an invalid or missing plan.
    if subscription_plan is None and request.method == 'GET':
        flash('Sorry, that plan did not exist.', 'error')
        return redirect(url_for('billing.pricing'))

    stripe_key = current_app.config.get('STRIPE_PUBLISHABLE_KEY')
    form = CreditCardForm(stripe_key=stripe_key, plan=plan)

    if form.validate_on_submit():
        subscription = Subscription()
        created = subscription.create(user=current_user,
                                      name=request.form.get('name'),
                                      plan=request.form.get('plan'),
                                      coupon=request.form.get('coupon_code'),
                                      token=request.form.get('stripe_token'))

        if created:
            flash('Awesome, thanks for subscribing!', 'success')
        else:
            flash('You must enable JavaScript for this request.', 'warning')

        return redirect(url_for('user.settings'))

    return render_template('billing/payment_method.html',
                           form=form,
                           plan=subscription_plan)
Esempio n. 2
0
    def bulk_delete(cls, ids):
        """
        Override the general bulk_delete method because we need to delete them
        one at a time while also deleting them on Stripe.

        :param ids: List of ids to be deleted
        :type ids: list
        :return: int
        """
        delete_count = 0

        for id in ids:
            user = User.query.get(id)

            if user is None:
                continue

            if user.payment_id is None:
                user.delete()
            else:
                subscription = Subscription()
                cancelled = subscription.cancel(user=user)

                # If successful, delete it locally.
                if cancelled:
                    user.delete()

            delete_count += 1

        return delete_count
Esempio n. 3
0
def update_payment_method():
    if not current_user.credit_card:
        flash('You do not have a payment method on file.', 'error')
        return redirect(url_for('user.settings'))

    active_plan = Subscription.get_plan_by_id(current_user.subscription.plan)

    card = current_user.credit_card
    stripe_key = current_app.config.get('STRIPE_PUBLISHABLE_KEY')
    form = CreditCardForm(stripe_key=stripe_key,
                          plan=active_plan,
                          name=current_user.name)

    if form.validate_on_submit():
        subscription = Subscription()
        updated = subscription.update_payment_method(
            user=current_user,
            credit_card=card,
            name=request.form.get('name'),
            token=request.form.get('stripe_token'))

        if updated:
            flash('Your payment method has been updated.', 'success')
        else:
            flash('You must enable JavaScript for this request.', 'warning')

        return redirect(url_for('user.settings'))

    return render_template('billing/payment_method.html',
                           form=form,
                           plan=active_plan,
                           card_last4=str(card.last4))
Esempio n. 4
0
    def test_no_coin_change_for_subscription_downgrade(self):
        """ Same coins for a subscription downgrade. """
        coins = 100

        current_plan = Subscription.get_plan_by_id('gold')
        new_plan = Subscription.get_plan_by_id('bronze')

        coins = add_subscription_coins(coins, current_plan, new_plan, None)

        assert coins == 100
Esempio n. 5
0
    def test_add_coins_to_subscription_upgrade(self):
        """ Add coins to a subscription upgrade. """
        coins = 100

        current_plan = Subscription.get_plan_by_id('bronze')
        new_plan = Subscription.get_plan_by_id('gold')

        coins = add_subscription_coins(coins, current_plan, new_plan, None)

        assert coins == 590
Esempio n. 6
0
    def test_no_coin_change_for_same_subscription(self):
        """ Same coins for the same subscription. """
        coins = 100

        current_plan = Subscription.get_plan_by_id('gold')
        new_plan = Subscription.get_plan_by_id('gold')

        may_29_2015 = datetime.datetime(2015, 5, 29, 0, 0, 0)
        may_29_2015 = pytz.utc.localize(may_29_2015)

        coins = add_subscription_coins(coins, current_plan, new_plan,
                                       may_29_2015)

        assert coins == 100
Esempio n. 7
0
def users_cancel_subscription():
    form = UserCancelSubscriptionForm()

    if form.validate_on_submit():
        user = User.query.get(request.form.get('id'))

        if user:
            subscription = Subscription()
            if subscription.cancel(user):
                flash(f'Subscripton has been cancelled for {user.name}', 'success')
            else:
                flash('No subscription was cancelle, something went wrong.', 'error')

    return redirect(url_for('admin.users'))
def event():
    if not request.json:
        return render_json(406, {'error': 'Mime-type is not application/json'})

    if request.json.get('id') is None:
        return render_json(406, {'error': 'Invalid Stripe event'})

    try:
        safe_event = PaymentEvent.retrieve(request.json.get('id'))
        parsed_event = Invoice.parse_from_event(safe_event)

        user = Invoice.prepare_and_save(parsed_event)

        if parsed_event.get('total') > 0:
            plan = Subscription.get_plan_by_id(user.subscription.plan)
            user.add_coins(plan)
    except InvalidRequestError as e:
        # We could not parse the event.
        return render_json(422, {'error': str(e)})
    except Exception as e:
        # Return a 200 because something is really wrong and we want Stripe to
        # stop trying to fulfill this webhook request.
        return render_json(200, {'error': str(e)})

    return render_json(200, {'success': True})
Esempio n. 9
0
def cancel():
    if not current_user.subscription:
        flash("You don't have an active subscription.", 'error')
        return redirect(url_for('user.settings'))

    form = CancelSubscriptionForm()

    if form.validate_on_submit():
        subscription = Subscription()
        cancelled = subscription.cancel(user=current_user)

        if cancelled:
            flash("Your subscription has been cancelled.", 'success')
            return redirect(url_for('user.settings'))

    return render_template('billing/cancel.html', form=form)
Esempio n. 10
0
def update():
    current_plan = current_user.subscription.plan
    active_plan = Subscription.get_plan_by_id(current_plan)
    new_plan = Subscription.get_new_plan(request.form.keys())

    plan = Subscription.get_plan_by_id(new_plan)

    # Guard against an invalid, missing or identical plan.
    is_same_plan = new_plan == active_plan['id']
    if ((new_plan is not None and plan is None) or is_same_plan) and \
            request.method == 'POST':
        return redirect(url_for('billing.update'))

    form = UpdateSubscriptionForm(coupon_code=current_user.subscription.coupon)

    if form.validate_on_submit():
        subscription = Subscription()
        updated = subscription.update(user=current_user,
                                      coupon=request.form.get('coupon_code'),
                                      plan=plan.get('id'))

        if updated:
            flash('Your subscription has been updated.', 'success')
            return redirect(url_for('user.settings'))

    return render_template('billing/pricing.html',
                           form=form,
                           plans=settings.STRIPE_PLANS,
                           active_plan=active_plan)
Esempio n. 11
0
def subscriptions(db):
    """
    Create subscription fixtures.

    :param db: Pytest fixture
    :return: SQLAlchemy database session
    """
    subscriber = User.find_by_identity('*****@*****.**')
    if subscriber:
        subscriber.delete()
    db.session.query(Subscription).delete()

    params = {
        'role': 'admin',
        'email': '*****@*****.**',
        'name': 'Subby',
        'password': '******',
        'payment_id': 'cus_000'
    }

    subscriber = User(**params)

    # The account needs to be commit before we can assign a subscription to it.
    db.session.add(subscriber)
    db.session.commit()

    # Create a subscription.
    params = {
        'user_id': subscriber.id,
        'plan': 'gold'
    }
    subscription = Subscription(**params)
    db.session.add(subscription)

    # Create a credit card.
    params = {
        'user_id': subscriber.id,
        'brand': 'Visa',
        'last4': '4242',
        'exp_date': datetime.date(2015, 6, 1)
    }
    credit_card = CreditCard(**params)
    db.session.add(credit_card)

    db.session.commit()

    return db
Esempio n. 12
0
def event():
    if not request.json:
        return render_json(406, {'error': 'Mime-type is not application/json'})

    if request.json.get('id') is None:
        return render_json(406, {'error': 'Invalid Stripe event'})

    try:
        safe_event = PaymentEvent.retrieve(request.json.get('id'))
        parsed_event = Invoice.parse_from_event(safe_event)
        user = Invoice.prepare_and_save(parsed_event)

        if parsed_event.get('total') > 0:
            plan = Subscription.get_plan_by_id(user.subscription.plan)
            user.add_coins(plan)
    except InvalidRequestError as e:
        
        return render_json(422, {'error': str(e)})
    except Exception as e:

        return render_json(200, {'error': str(e)})

    return render_json(200, {'success': True})
Esempio n. 13
0
    def test_subscribed_user_receives_more_coins(self, users):
        """ Subscribed user receives more coins. """
        user = User.find_by_identity('*****@*****.**')
        user.add_coins(Subscription.get_plan_by_id('bronze'))

        assert user.coins == 210