~sircmpwn/meta.sr.ht

ca12e884a29bd30f25447250617e59d9830f74a3 — Drew DeVault 16 days ago 7cb96da 0.53.23
billing: run billing after period update

This addresses a confusing edge case where the user would not be billed
until later, when the cronjob runs.
3 files changed, 26 insertions(+), 3 deletions(-)

M metasrht/blueprints/billing.py
M metasrht/templates/billing.html
M scss/main.scss
M metasrht/blueprints/billing.py => metasrht/blueprints/billing.py +4 -1
@@ 87,6 87,7 @@ def billing_chperiod_POST():
    term = valid.require("term")
    audit_log("billing", "Payment term changed")
    current_user.payment_interval = PaymentInterval(term)
    success, details = charge_user(current_user)
    db.session.commit()
    freshen_user()
    deliver_profile_update(current_user)


@@ 121,13 122,15 @@ def new_payment_POST():
                    email=current_user.email,
                    card=token)
            current_user.stripe_customer = customer.id
            current_user.payment_due = datetime.utcnow() + timedelta(seconds=-1)
            current_user.payment_due = datetime.utcnow() + timedelta(minutes=-5)
        except stripe.error.CardError as e:
            details = e.json_body["error"]["message"]
            return render_template("new-payment.html",
                    amount=current_user.payment_cents, error=details)
    else:
        new_customer = False
        if current_user.user_type != UserType.active_paying:
            current_user.payment_due = datetime.utcnow() + timedelta(minutes=-5)
        try:
            customer = stripe.Customer.retrieve(current_user.stripe_customer)
            source = customer.sources.create(source=token)

M metasrht/templates/billing.html => metasrht/templates/billing.html +18 -2
@@ 9,26 9,35 @@
    {% if message %}
    <div class="alert alert-info">{{message}}</div>
    {% endif %}

    {% if current_user.user_type == UserType.active_non_paying %}

    <div class="alert alert-info">
      You are currently using an <strong>unpaid</strong>
      {{cfg("sr.ht", "site-name")}} account. Some site features may be
      unavailable to your account.
    </div>

    {% elif current_user.user_type == UserType.active_free %}

    <div class="alert alert-info">
      Your account is <strong>exempt</strong> from billing. All features are
      available to you free of charge. You may choose to set up billing
      if you wish to support the site.
    </div>

    {% elif current_user.user_type == UserType.active_paying %}

    {% if current_user.payment_cents == 0 %}

    <div class="alert alert-warning">
      Your paid service has been cancelled. At the end of your current term,
      {{current_user.payment_due | date}}, your account will be downgraded to a
      non-paying account.
    </div>

    {% else %}

    <div class="alert alert-success">
      {% if invoices %}
      Your account is <strong>paid</strong> and up-to-date, and your last


@@ 47,17 56,24 @@
        else current_user.payment_cents*10/100)}}.
      {% endif %}
    </div>

    {% endif %}

    {% elif current_user.user_type == UserType.active_delinquent %}

    <div class="alert alert-danger">
      <strong>Notice</strong>: Your payment is past due. Please check that your
      payment information is correct or your service may be reduced.
      payment information is correct or your service may be impacted.
    </div>

    {% elif current_user.user_type == UserType.admin %}

    <div class="alert alert-info">
      Admins are exempt from billing.
    </div>

    {% endif %}

    <div style="margin-bottom: 1rem">
      <div class="progress">
        <div class="progress-bar"


@@ 201,7 217,7 @@
    <h3>Invoices</h3>
    <div class="event-list">
      {% for invoice in invoices %}
      <div class="event">
      <div class="event invoice">
        <h4>
          <small class="text-success" style="margin-left: 0">
            {{icon('check')}}

M scss/main.scss => scss/main.scss +4 -0
@@ 105,3 105,7 @@ input[type="date"], input[type="number"] {
#card-element {
  background: white !important;
}

.invoice h4 {
  margin-top: 0;
}