Now with subscriptions.

master
Manager Bot 3 years ago
parent 9f56a6f1b1
commit 8348458870
  1. 3
      Web/lib/MJB/Web.pm
  2. 10
      Web/lib/MJB/Web/Controller/UserSettings.pm
  3. 71
      Web/script/stripe-backend
  4. 17
      Web/t/01_endpoints/06_user_settings/05_subscription.t
  5. 16
      Web/t/01_endpoints/06_user_settings/06_do_subscription.t
  6. 16
      Web/t/01_endpoints/06_user_settings/07_do_subscription_manage.t
  7. 8
      Web/templates/layouts/standard.html.ep
  8. 27
      Web/templates/user_settings/subscription.html.ep

@ -191,6 +191,9 @@ sub startup ($self) {
$auth->post( '/profile' )->to('UserSettings#do_profile' )->name('do_profile' );
$auth->get ( '/password' )->to('UserSettings#change_password' )->name('show_change_password' );
$auth->post( '/password' )->to('UserSettings#do_change_password' )->name('do_change_password' );
$auth->get ( '/subscription' )->to('UserSettings#subscription' )->name('show_subscription' );
$auth->post( '/subscription' )->to('UserSettings#do_subscription' )->name('do_subscription' );
$auth->post( '/manage' )->to('UserSettings#do_subscription_manage' )->name('do_subscription_manage' );
# Dashboard / Blog Management
$auth->get ( '/dashboard' )->to('Dashboard#index' )->name('show_dashboard' );

@ -111,10 +111,6 @@ sub do_change_password ( $c ) {
$c->redirect_to( $c->url_for( 'show_change_password' ) );
}
1;
__END__
sub subscription ($c) {
my $status = $c->param('status');
@ -131,7 +127,7 @@ sub subscription ($c) {
my $session_id = $c->param('session_id');
my $customer_id = $c->ua->get( $c->config->{stripe_backend} . '/stripe/session-to-customer?session_id=' . $session_id )->result->json->{customer_id};
my $customer_id = $c->ua->get( $c->config->{stripe}->{backend} . '/stripe/session-to-customer?session_id=' . $session_id )->result->json->{customer_id};
# Store the customer id along side the user in the DB.
if ( $customer_id ) {
@ -151,14 +147,14 @@ sub subscription ($c) {
# Send to stripe to signup for the subscription
sub do_subscription ($c) {
my $lookup_key = $c->param('lookup_key');
my $url = $c->ua->get( $c->config->{stripe_backend} . '/stripe/get-checkout-link?lookup_key=' . $lookup_key )->result->json->{url};
my $url = $c->ua->get( $c->config->{stripe}->{backend} . '/stripe/get-checkout-link?lookup_key=' . $lookup_key )->result->json->{url};
$c->redirect_to( $url );
}
# Send to stripe to manage the subscription
sub do_subscription_manage ($c) {
my $url = $c->ua->get( $c->config->{stripe_backend} . '/stripe/get-portal-link?customer_id=' . $c->stash->{person}->stripe_customer_id )->result->json->{url};
my $url = $c->ua->get( $c->config->{stripe}->{backend} . '/stripe/get-portal-link?customer_id=' . $c->stash->{person}->stripe_customer_id )->result->json->{url};
$c->redirect_to( $url );
}

@ -0,0 +1,71 @@
#! /usr/bin/env python3.6
"""
server.py
Stripe Sample.
Python 3.6 or newer required.
"""
import os
from flask import Flask, redirect, jsonify, json, request, current_app
import yaml
import stripe
with open('/etc/mjb.yml') as file:
config = yaml.safe_load(file)
# This is your test secret API key.
stripe.api_key = config.['stripe']['api_key']
app = Flask(__name__,
static_url_path='',
static_folder='public')
YOUR_DOMAIN = config['stripe']['return_domain']
@app.route('/stripe/get-checkout-link', methods=['GET'])
def create_checkout_session():
try:
checkout_session = stripe.checkout.Session.create(
line_items=[
{
'price': request.args.get('lookup_key'),
'quantity': 1,
},
],
mode='subscription',
success_url=YOUR_DOMAIN + '/subscription?status=success&session_id={CHECKOUT_SESSION_ID}',
cancel_url=YOUR_DOMAIN + '/subscription?status=error',
)
return jsonify({'status': 'success', 'url' : checkout_session.url })
except Exception as e:
return jsonify({'status': 'failure', 'error': e })
@app.route('/stripe/get-portal-link', methods=['GET'])
def customer_portal():
customer_id = request.args.get('customer_id')
# This is the URL to which the customer will be redirected after they are
# done managing their billing with the portal.
return_url = YOUR_DOMAIN + '/dashboard'
portalSession = stripe.billing_portal.Session.create(
customer=customer_id,
return_url=return_url,
)
return jsonify({'status': 'success', 'url' : portalSession.url })
@app.route('/stripe/session-to-customer', methods=['GET'])
def session_to_customer():
checkout_session_id = request.args.get('session_id')
checkout_session = stripe.checkout.Session.retrieve(checkout_session_id)
return jsonify({ 'customer_id' : checkout_session.customer })
if __name__ == '__main__':
app.run()

@ -0,0 +1,17 @@
#!/usr/bin/env perl
use MJB::Web::Test;
#==
# This test ensures that the subscription page works.
#
# 1. Create user and login.
# 2. Go to the subscription page
#==
my $t = Test::Mojo::MJB->new('MJB::Web');
my $blog_id = $t->create_user
->get_ok( '/subscription' )
->status_is( 200 );
done_testing;

@ -0,0 +1,16 @@
#!/usr/bin/env perl
use MJB::Web::Test;
#==
# Ensure the handler exists for do_subscription.
#
# Don't actually run it, since it depends on the stripe-backend, and
# that is outside of the scope of these tests.
#==
my $t = Test::Mojo::MJB->new('MJB::Web');
ok $t->app->routes->find( 'do_subscription' ), 'Have a route for do_subscription';
is $t->app->routes->find( 'do_subscription' )->methods->[0], 'POST', 'Is a post handler.';
done_testing();

@ -0,0 +1,16 @@
#!/usr/bin/env perl
use MJB::Web::Test;
#==
# Ensure the handler exists for do_subscription_manage.
#
# Don't actually run it, since it depends on the stripe-backend, and
# that is outside of the scope of these tests.
#==
my $t = Test::Mojo::MJB->new('MJB::Web');
ok $t->app->routes->find( 'do_subscription_manage' ), 'Have a route for do_subscription_manage';
is $t->app->routes->find( 'do_subscription_manage' )->methods->[0], 'POST', 'Is a post handler.';
done_testing();

@ -148,6 +148,14 @@
Change Password
</a>
</li>
% if ( $c->config->{stripe}->{enable} ) {
<li class="nav-item">
<a class="nav-link <%= $sb_active eq "subscription" ? "active" : "" %>" href="<%= $c->url_for( 'show_subscription' ) %>">
<span data-feather="credit-card"></span>
Subscription
</a>
</li>
% }
</ul>
% } else {
<h6 class="sidebar-heading d-flex justify-content-between align-items-center px-3 mt-4 mb-1 text-muted">

@ -0,0 +1,27 @@
% layout 'standard', title => 'Profile', sb_active => 'subscription';
%= include '_base/status_window';
<div class="row">
<div class="col">
% if ( $person->is_subscribed ) {
<h2 style="margin-top: 1.5em; margin-bottom: 1.5em" class="h2">Thank you for subscription!</h2>
<div class="col">
<form action="<%= $c->url_for( 'do_subscription_manage') %>" method="POST">
<button id="checkout-and-portal-button" class="btn btn-lg btn-primary" type="submit">Manage Subscription</button>
</form>
</div>
% } else {
<div class="col">
<h2 style="margin-top: 1.5em; margin-bottom: 1.5em" class="h2">You don't have a current subscription.</h2>
<form action="<%= $c->url_for( 'do_subscription') %>" method="POST">
<!-- Add a hidden field with the lookup_key of your Price -->
<input type="hidden" name="lookup_key" value="<%= $c->config->{stripe}->{lookup_key} %>" />
<button id="checkout-and-portal-button" class="btn btn-lg btn-primary" type="submit">Subscribe</button>
</form>
</div>
% }
</div>
</div>
Loading…
Cancel
Save