control vor 3 Jahren
Ursprung
Commit
14547ad3e0

+ 6 - 12
app/__init__.py

@@ -6,9 +6,6 @@ from os import path
 # Talisman
 from flask_talisman import Talisman
 
-# Stripe
-import stripe
-
 db = SQLAlchemy()
 DB_NAME = "database.db"
 
@@ -49,16 +46,13 @@ def create_app():
         return User.query.get(int(id)) # by default get() looks for the primary key
 
     # Talisman
-    Talisman(app)
-
-    # Stripe
-    stripe_keys = {
-            "secret_key" : "sk_test_51KmKkAF0esudExGd5hSSlMUzVEyxK49zfmSlhhU0rHsVCQoSTkIyXalqLe1pUgDmpbLVU4huIuDeDzPOCXp2gFJB00n7X7PMf9",
-        "publishable_key" : "pk_test_51KmKkAF0esudExGdIscDaqn3Q4Sr5YJAu8X1yhjFerNe90HYgyjkk0tzakICpWyV8jE78m43ME2gSp2CXKg2L14I00wFIb0tQW"
+    csp = {
+        'default-src': [
+            '\'self\'',
+            '*.stripe.com'
+            ]
         }
-
-    stripe.api_key = stripe_keys['secret_key']
-
+    Talisman(app, content_security_policy=csp)
 
     return app
 

+ 64 - 5
app/dashboards.py

@@ -1,14 +1,15 @@
 from flask import Blueprint, render_template, request, flash, redirect, url_for
 from flask_login import login_required, current_user
 from werkzeug.security import generate_password_hash, check_password_hash
-from .models import User, Art, List, Bids
+from .models import User, Art, List, Bids, Wallet, Stripe
 from . import db
 
 from . import dispatch
 from app.lib import clean_file as cf, tools
 from app.lib import collector
+from app.lib import stripe
 
-from .forms import UPForm, PicForm, CAForm, BidForm
+from .forms import UPForm, PicForm, CAForm, BidForm, WalletForm
 
 dashboards = Blueprint('dashboards', __name__)
 
@@ -32,8 +33,14 @@ def market():
 def profile():
     form = UPForm()
     form2 = PicForm()
+    form3 = WalletForm()
     user_bid_hist = collector.user_bid_hist(current_user.id)
 
+    # Initializes wallet and fetches amount
+    dispatch.init_wallet(current_user.id)
+    wallet = Wallet.query.filter_by(user_id = current_user.id).first()
+    wallet_amount = float(wallet.amount/100)
+
     # This takes a post request button press
     # when user clicks on a photo
     if request.method == "POST":
@@ -48,9 +55,25 @@ def profile():
             flash('Auction page not available to items not for sale!', category='error')
 
 
+    # Wallet Top Up Form
+    if form3.validate_on_submit():
+        amount = form3.amount.data
+        raw_amount = int(amount*100) # converting to cents int for Stripe
+
+        if amount: # Send to stripe checkout
+            # render a checkout page for Stripe
+            # card handling
+            return render_template(
+                'checkout.html',
+                key = stripe.stripe_keys['publishable_key'],
+                user = current_user,
+                amount = amount,
+                ramount = raw_amount
+                )
+
+
     # Profile Picture Update Form
     if form2.validate_on_submit():
-        print('passsing')
         f =  form2.upload.data
         if cf.allowed_file(f.filename):
             designated_fn = cf.sanitize(f.filename)
@@ -85,7 +108,9 @@ def profile():
             my_creation = my_creation,
             form = form,
             form2 = form2,
-            ubh = user_bid_hist
+            form3 = form3,
+            ubh = user_bid_hist,
+            wallet_amount = wallet_amount
             )
 
 @dashboards.route('/create_art', methods=['GET', 'POST'])
@@ -97,7 +122,6 @@ def create():
 
    # check POST req
     if form.validate_on_submit():
-        print('this passes')
         new_art = form.upload.data
         art_name = form.art_name.data
         art_desc = form.art_desc.data
@@ -159,6 +183,14 @@ def detail():
     # New Bid
     if form.validate_on_submit():
         user_bid = form.price.data
+
+        # first check if user has wallet balance
+        dbc_uwallet = Wallet.query.filter_by(user_id = current_user.id).first()
+        uwealth = float(dbc_uwallet.amount / 100)
+        if not uwealth >= float(user_bid):
+            flash('You don\'t have enough cash in your wallet!', category='error')
+            return redirect(url_for('dashboards.profile'))
+
         # checking if bid is at buyout price or more
         if user_bid and user_bid >= focus[8]:
             dispatch.enter_bid(user_bid, focus)
@@ -183,3 +215,30 @@ def detail():
             form = form,
             ibh = item_bid_hist
             )
+
+@dashboards.route('/charge', methods=['POST'])
+@login_required
+def charge():
+    # Stripe charge POST request method
+
+    # Amount in cents
+    dbc_stripe = Stripe.query.filter_by(user_id = current_user.id).order_by(Stripe.id.desc()).first()
+    raw_amount = dbc_stripe.raw_amount
+    amount = float(raw_amount/100)
+
+    customer = stripe.stripe.Customer.create(
+        email = 'customer@example.com',
+        source = request.form['stripeToken']
+    )
+
+    charge = stripe.stripe.Charge.create(
+        customer = customer.id,
+        amount = raw_amount,
+        currency = 'usd',
+        description = 'Flask Charge'
+    )
+
+    # db dispatch for wallet top up
+    dispatch.top_up(current_user.id, raw_amount)
+
+    return render_template('charge.html', amount = amount, user = current_user)

BIN
app/database.db


+ 39 - 3
app/dispatch.py

@@ -7,7 +7,7 @@ from datetime import datetime
 from flask import flash
 from flask_login import current_user
 
-from .models import Hashchain, Art, List, TX , User, Bids, List
+from .models import Hashchain, Art, List, TX , User, Bids, List, Wallet, Stripe
 from . import db
 
 from app.lib import clean_file as cf
@@ -153,6 +153,10 @@ def tx_exchange(filehash, source_id, price, dest_id=None):
 
     db.session.commit()
 
+    # transaction action on wallets
+    tx_wallet(dest_id, source_id, price)
+
+
 def clean_bid_table(filehash):
     # cleans Bid table when Artwork is bought
     old_bids = Bids.query.filter_by(filehash = filehash).all()
@@ -189,7 +193,6 @@ def check_auction_end():
         # if close_date and min bid reached
         ddt = datetime.utcnow().strftime("%Y-%m-%d")
         if listing.timeout == ddt and listing.cur_bid > listing.min_price:
-            print(f'DEBUG: scheduler >>> EXCHANGING!!') ##
             # transaction for the last bid made
             # get buyer id from Bids table using filehash
             buyer_bid = Bids.query.filter_by(filehash = listing.filehash).order_by(desc(Bids.id)).first()
@@ -198,6 +201,39 @@ def check_auction_end():
             clean_bid_table(listing.filehash)
         # if close_date and min bid not reached (no one made a qualifying bid)
         elif listing.timeout == ddt and not listing.cur_bid > listing.min_price:
-            print(f'DEBUG: scheduler >>> DE-LISTING!!') ##
             # remove from List table
             List.query.filter_by(filehash = filehash).delete()
+
+def init_wallet(user_id):
+    user_wallet = Wallet.query.filter_by(user_id = user_id).first()
+    if not user_wallet:
+        dbc_ntable = Wallet(
+            user_id = user_id,
+            amount = 0
+            )
+        db.session.add(dbc_ntable)
+        db.session.commit()
+
+def top_up(user_id, raw_amount):
+    # add to Stripe top up transaction table
+    dbc_ntable = Stripe(
+        user_id = user_id,
+        raw_amount = raw_amount,
+        )
+    db.session.add(dbc_ntable)
+    # Append to user Wallet amount
+    dbc_wallet = Wallet.query.filter_by(user_id = user_id).first()
+    dbc_wallet.amount += raw_amount # converted to dollars float in db
+
+    db.session.commit()
+
+def tx_wallet(src_id, dest_id, tx_amount):
+    # user paying
+    dbc_src = Wallet.query.filter_by(user_id = src_id).first()
+    # user receiving
+    dbc_dest = Wallet.query.filter_by(user_id = dest_id).first()
+    tx_amount = int(tx_amount*100) # converting to cents int
+    dbc_src.amount -= tx_amount
+    dbc_dest.amount += tx_amount
+    db.session.commit()
+    

+ 4 - 0
app/forms.py

@@ -47,3 +47,7 @@ class BidForm(FlaskForm):
 class MFAForm(FlaskForm):
     otp = StringField(validators=[DataRequired()])
     submit = SubmitField('Authenticate')
+
+class WalletForm(FlaskForm):
+    amount = FloatField(validators=[DataRequired()])
+    submit = SubmitField('Top Up')

+ 9 - 0
app/lib/stripe.py

@@ -0,0 +1,9 @@
+# Stripe
+import stripe
+
+stripe_keys = {
+    "secret_key" : "sk_test_51KmKkAF0esudExGd5hSSlMUzVEyxK49zfmSlhhU0rHsVCQoSTkIyXalqLe1pUgDmpbLVU4huIuDeDzPOCXp2gFJB00n7X7PMf9",
+    "publishable_key" : "pk_test_51KmKkAF0esudExGdIscDaqn3Q4Sr5YJAu8X1yhjFerNe90HYgyjkk0tzakICpWyV8jE78m43ME2gSp2CXKg2L14I00wFIb0tQW"
+    }
+
+stripe.api_key = stripe_keys['secret_key']

+ 9 - 1
app/models.py

@@ -53,6 +53,14 @@ class Bids(db.Model):
     bid_date = db.Column(db.DateTime(timezone=True), default=func.now()) 
 
 class Wallet(db.Model):
+    id = db.Column(db.Integer, primary_key=True)
+    user_id = db.Column(db.Integer, unique=True)
+    amount = db.Column(db.Integer) # in cents
+
+class Stripe(db.Model):
+    # This table is for keeping track of top-up
+    # transactions
     id = db.Column(db.Integer, primary_key=True)
     user_id = db.Column(db.Integer)
-    amount = db.Column(db.Float)
+    raw_amount = db.Column(db.Integer) # in cents (multiply by 100)
+    tx_date = db.Column(db.DateTime(timezone=True), default=func.now()) 

BIN
app/static/incoming/JI5I0xuTc4tKHQ19.jpeg


BIN
app/static/incoming/VwpVttZR5uZDm7BS.jpg


BIN
app/static/incoming/qdZMSHlBpx9PtNFX.jpeg


BIN
app/static/repository/aX8P2sE4J27J8KPm.jpeg


+ 7 - 0
app/templates/charge.html

@@ -0,0 +1,7 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+<h2>Thanks, you topped-up $ {{ amount }}!</h2>
+
+{% endblock %}

+ 23 - 0
app/templates/checkout.html

@@ -0,0 +1,23 @@
+{% extends "base.html" %}
+
+{% block content %}
+
+<form action="/charge" method="post">
+    <article>
+    <label>
+        <span>Amount is $ {{ amount }}</span>
+    </label>
+    </article>
+
+    
+    <!-- Stripe Pay Button -->
+    <!-- Sends payment token POST Req -->
+    <script src="https://checkout.stripe.com/checkout.js" class="stripe-button"
+          data-key="{{ key }}"
+          data-description="artFi Exchange Deposit"
+          data-amount="{{ raw_amount }}"
+          data-locale="auto">
+    </script>
+</form>
+
+{% endblock %}

+ 4 - 3
app/templates/profile.html

@@ -84,16 +84,17 @@
                             <div class="tab-pane fade" id="Wallet" role="tabpanel" aria-labelledby="Wallet-tab">.
                                 <div class="row row-cols-3">
                                     <form method="POST">
+                                        {{ form3.hidden_tag() }}
                                         <div class="row">
                                             <div class="col-sm-3">
-                                                <h6 class="mb-0 change_password_location"><label for="add_money">Add Money</label></h6><br>
+                                                <h6 class="mb-0 change_password_location"><label for="add_money">$ {{ wallet_amount }}</label></h6><br>
                                             </div>
                                             <div class="col-sm-9 text-secondary">
-                                                Input
+                                                {{ form3.amount(placeholder="Input Amount to Top Up") }}
                                             </div>
                                             <div class="row">
                                                 <div class="col-sm-12">
-                                                    {{ form.submit(class="btn btn-grey update_password-form-btn") }}
+                                                    {{ form3.submit() }}
                                                 </div>
                                             </div>
                                         </div>