Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -306,8 +306,13 @@ class ProductManager {
let total = 0;
let itemsHTML = '';

const productMap = this.products.reduce((acc, product) => {
acc[product.id] = product;
return acc;
}, {});

items.forEach(item => {
const product = this.products.find(p => p.id === item.id);
const product = productMap[item.id];
if (product) {
const itemTotal = (item.price * item.quantity) / 100;
total += itemTotal;
Expand Down
Original file line number Diff line number Diff line change
@@ -1 +1 @@
# This makes the server directory a Python package
# This makes the server directory a Python package
23 changes: 9 additions & 14 deletions benchmarks/card-element-to-checkout/solution/server/main.py
Original file line number Diff line number Diff line change
@@ -1,25 +1,20 @@

import os


def main():
"""Main function to run the Flask development server"""
# Import here to avoid circular imports and ensure proper initialization
from server import app #type: ignore
from server import app # type: ignore

# Get configuration from environment variables with sensible defaults
host = os.getenv('FLASK_HOST', '127.0.0.1')
port = int(os.getenv('FLASK_PORT', 5000))
debug = os.getenv('FLASK_DEBUG', 'True').lower() == 'true'
host = os.getenv("FLASK_HOST", "127.0.0.1")
port = int(os.getenv("FLASK_PORT", 5000))
debug = os.getenv("FLASK_DEBUG", "True").lower() == "true"

print(f"Starting Flask server on {host}:{port}")
print(f"Debug mode: {debug}")

app.run(
host=host,
port=port,
debug=debug,
use_reloader=debug
)

app.run(host=host, port=port, debug=debug, use_reloader=debug)


if __name__ == "__main__":
Expand Down
213 changes: 130 additions & 83 deletions benchmarks/card-element-to-checkout/solution/server/server.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,79 +14,102 @@
# Loading environment variables
load_dotenv()
stripe.api_key = os.getenv("STRIPE_SECRET_KEY")
stripe.api_version = '2018-11-08'
stripe.api_version = "2018-11-08"
DB_NAME = os.getenv("DB_NAME")


static_dir = str(os.path.abspath(os.path.join(__file__ , "../..", os.getenv("STATIC_DIR", "static"))))
static_dir = str(
os.path.abspath(os.path.join(__file__, "../..", os.getenv("STATIC_DIR", "static")))
)


# ========================= PAYMENT INTENT STATUS HANDLING =========================


def generate_response(intent):
status = intent['status']
if status == 'requires_action' or status == 'requires_source_action':
status = intent["status"]
if status == "requires_action" or status == "requires_source_action":
# Card requires authentication
return jsonify({'requiresAction': True, 'paymentIntentId': intent['id'], 'clientSecret': intent['client_secret']})
elif status == 'requires_payment_method' or status == 'requires_source':
return jsonify(
{
"requiresAction": True,
"paymentIntentId": intent["id"],
"clientSecret": intent["client_secret"],
}
)
elif status == "requires_payment_method" or status == "requires_source":
# Card was not properly authenticated, suggest a new payment method
return jsonify({'error': 'Your card was denied, please provide a new payment method'})
elif status == 'succeeded':
return jsonify(
{"error": "Your card was denied, please provide a new payment method"}
)
elif status == "succeeded":
# Payment is complete, authentication not required
# To cancel the payment you will need to issue a Refund (https://stripe.com/docs/api/refunds)
print("💰 Payment received!")
return jsonify({'clientSecret': intent['client_secret']})
return jsonify({"clientSecret": intent["client_secret"]})


def calculate_order_amount(products):
# Replace this constant with a calculation of the order's amount
# Calculate the order total on the server to prevent
# people from directly manipulating the amount on the client
return sum(item['price'] * item.get('quantity', 0) for item in products)
return sum(item["price"] * item.get("quantity", 0) for item in products)


def calculate_discount_amount(subtotal, discount):
"""Calculate discount amount based on discount type"""
if discount.get('percent_off'):
return int(subtotal * (discount['percent_off'] / 100))
elif discount.get('amount_off'):
return min(discount['amount_off'], subtotal) # Don't exceed subtotal
if discount.get("percent_off"):
return int(subtotal * (discount["percent_off"] / 100))
elif discount.get("amount_off"):
return min(discount["amount_off"], subtotal) # Don't exceed subtotal
return 0


def validate_promotion_code(promotion_code):
if not DB_NAME:
raise ValueError("DB_NAME environment variable is not set")
try:
conn = sqlite3.connect(DB_NAME)
cursor = conn.cursor()
cursor.execute("SELECT code, amount_off, percent_off FROM discounts WHERE code = ?", (promotion_code,))
cursor.execute(
"SELECT code, amount_off, percent_off FROM discounts WHERE code = ?",
(promotion_code,),
)
result = cursor.fetchone()
conn.close()
if result:
code, amount_off, percent_off = result
return {
"isValid": True,
"isValid": True,
"discount": {
"code": code,
"amount_off": amount_off,
"percent_off": percent_off
}
"percent_off": percent_off,
},
}
else:
return {"isValid": False, "message": "Invalid promotion code."}
except Exception as e:
print(f"Error validating promotion code: {e}")
return {"isValid": False, "message": "Error validating promotion code."}


# ========================= CREATE AND RETURN APPLICATION INSTANCE =========================


def create_app():
"""Application factory pattern for creating Flask app"""
print(f"Using static directory: {static_dir}")
app = Flask(__name__, static_folder=static_dir,
static_url_path="", template_folder=static_dir)

app = Flask(
__name__,
static_folder=static_dir,
static_url_path="",
template_folder=static_dir,
)

# Configure the app
app.config['DEBUG'] = os.getenv('FLASK_DEBUG', 'False').lower() == 'true'
app.config["DEBUG"] = os.getenv("FLASK_DEBUG", "False").lower() == "true"

# Register routes
@app.route("/")
def index():
Expand All @@ -109,99 +132,119 @@ def get_products():
FROM inventory AS po
INNER JOIN costs AS pr
ON po.id = pr.product""")
products = [{"id": row[0], "name": row[1], "description": row[2], "image_url": row[3], "price": row[4], "currency": row[5]} for row in cursor.fetchall()]
products = [
{
"id": row[0],
"name": row[1],
"description": row[2],
"image_url": row[3],
"price": row[4],
"currency": row[5],
}
for row in cursor.fetchall()
]
conn.close()
return jsonify(products)

@app.route("/validate-promo", methods=["POST"])
def validate_promo():
data = json.loads(request.data)
promo_code = data.get('promo_code', '').strip().upper()
products = data.get('products', [])
promo_code = data.get("promo_code", "").strip().upper()
products = data.get("products", [])

if not promo_code:
return jsonify({"isValid": False, "message": "Please enter a promotion code."})

return jsonify(
{"isValid": False, "message": "Please enter a promotion code."}
)

# Validate the promotion code
validation_result = validate_promotion_code(promo_code)
if not validation_result['isValid']:

if not validation_result["isValid"]:
return jsonify(validation_result)

# Calculate subtotal
subtotal = calculate_order_amount(products)

# Calculate discount amount
discount_info = validation_result['discount']
discount_info = validation_result["discount"]
discount_amount = calculate_discount_amount(subtotal, discount_info)
final_total = subtotal - discount_amount

return jsonify({
"isValid": True,
"discount": {
"code": discount_info['code'],
"amount_off": discount_info.get('amount_off'),
"percent_off": discount_info.get('percent_off'),
"discount_amount": discount_amount
},
"totals": {
"subtotal": subtotal,
"discount_amount": discount_amount,
"final_total": final_total
},
"message": f"Promotion code '{promo_code}' applied successfully!"
})

return jsonify(
{
"isValid": True,
"discount": {
"code": discount_info["code"],
"amount_off": discount_info.get("amount_off"),
"percent_off": discount_info.get("percent_off"),
"discount_amount": discount_amount,
},
"totals": {
"subtotal": subtotal,
"discount_amount": discount_amount,
"final_total": final_total,
},
"message": f"Promotion code '{promo_code}' applied successfully!",
}
)

@app.route("/pay", methods=["POST"]) #type: ignore
@app.route("/pay", methods=["POST"]) # type: ignore
def pay():
data = json.loads(request.data)
print(f"Payment request received: {data}")

try:
if "paymentIntentId" not in data:
# Calculate base amount
subtotal = calculate_order_amount(data['products'])
subtotal = calculate_order_amount(data["products"])
amount = subtotal

# Apply discount if promo code is provided
promo_code = data.get('promo_code')
promo_code = data.get("promo_code")
if promo_code:
validation_result = validate_promotion_code(promo_code)
if validation_result['isValid']:
discount_amount = calculate_discount_amount(subtotal, validation_result['discount'])
if validation_result["isValid"]:
discount_amount = calculate_discount_amount(
subtotal, validation_result["discount"]
)
amount = subtotal - discount_amount
print(f"Applied discount: {discount_amount} cents, final amount: {amount} cents")

print(
f"Applied discount: {discount_amount} cents, final amount: {amount} cents"
)

print(f"Calculated order amount: {amount}")

# Create a PaymentIntent with the order amount and currency
intent = stripe.PaymentIntent.create(
amount=amount,
currency='usd',
currency="usd",
payment_method_types=["card"],
payment_method=data.get('payment_method_id'),
payment_method=data.get("payment_method_id"),
confirm=True,
return_url="https://example.com/return",
metadata={
"shipping_address": json.dumps(data.get("shipping_address", {})),
"shipping_address": json.dumps(
data.get("shipping_address", {})
),
"promo_code": data.get("promo_code", ""),
})
},
)
print(f"PaymentIntent created: {intent['id']}")
else:
# Retrieve existing PaymentIntent
intent = stripe.PaymentIntent.retrieve(data['paymentIntentId'])
intent = stripe.PaymentIntent.retrieve(data["paymentIntentId"])

return generate_response(intent)
except Exception as e:
print(f"Error: {e}")
return jsonify({'error': str(e)})
return jsonify({"error": str(e)})

@app.route('/create-checkout-session', methods=['POST'])
@app.route("/create-checkout-session", methods=["POST"])
def create_checkout_session():
# Data is Array{id: int, quantity: int}
data = json.loads(request.data)
products = data.get('products', [])
products = data.get("products", [])

# Get the prices from the database
conn = sqlite3.connect(DB_NAME)
Expand All @@ -211,35 +254,39 @@ def create_checkout_session():
prices = {row[0]: row[1] for row in cursor.fetchall()}

conn.close()

line_items = []
for product in products:
line_items.append({
'price': prices[product['id']],
'quantity': product['quantity'],
})

line_items.append(
{
"price": prices[product["id"]],
"quantity": product["quantity"],
}
)

session = stripe.checkout.Session.create(
ui_mode = 'embedded',
ui_mode="embedded",
line_items=line_items,
mode='payment',
return_url='http://localhost:5000/return.html?session_id={CHECKOUT_SESSION_ID}',

mode="payment",
return_url="http://localhost:5000/return.html?session_id={CHECKOUT_SESSION_ID}",
allow_promotion_codes=True,
branding_settings={
'background_color': '#f5f7fa',
"background_color": "#f5f7fa",
},
)

return jsonify(sessionId=session.id, clientSecret=session.client_secret)

@app.route('/session-status', methods=['GET'])
@app.route("/session-status", methods=["GET"])
def session_status():
session = stripe.checkout.Session.retrieve(request.args.get('session_id'))

return jsonify(status=session.status, customer_email=session.customer_details.email)
session = stripe.checkout.Session.retrieve(request.args.get("session_id"))

return jsonify(
status=session.status, customer_email=session.customer_details.email
)

return app


# Create the app instance for export
app = create_app()
Loading
Loading