vpn-btcpay-provisioner/app/handlers/payment_handler.py

144 lines
5.3 KiB
Python
Raw Normal View History

2024-12-13 09:57:12 +00:00
# app/handlers/payment_handler.py
import logging
import requests
import os
from flask import jsonify
import smtplib
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
from pathlib import Path
import traceback
from .webhook_handler import get_vault_values
logger = logging.getLogger(__name__)
class BTCPayHandler:
def __init__(self):
logger.info("Initializing BTCPayHandler")
try:
# Get configuration from Ansible vault
logger.debug("Retrieving vault values")
vault_values = get_vault_values()
self.base_url = vault_values['btcpay_base_url']
self.api_key = vault_values['btcpay_api_key']
self.store_id = vault_values['btcpay_store_id']
# Email configuration
self.smtp_config = vault_values.get('smtp_config', {})
logger.info(f"BTCPayHandler initialized with base URL: {self.base_url}")
except Exception as e:
logger.error(f"Failed to initialize BTCPayHandler: {str(e)}")
logger.error(traceback.format_exc())
raise
def create_invoice(self, amount_sats, duration_hours, email):
"""Create BTCPay invoice for VPN subscription"""
try:
logger.info(f"Creating invoice: {amount_sats} sats, {duration_hours}h for {email}")
headers = {
'Authorization': f'token {self.api_key}',
'Content-Type': 'application/json'
}
# Get app URL from environment or use a default
app_url = os.getenv('APP_BASE_URL', 'http://localhost:5000').rstrip('/')
logger.debug(f"Using app URL for redirect: {app_url}")
payload = {
'amount': amount_sats,
'currency': 'SATS',
'metadata': {
'duration_hours': duration_hours,
'email': email,
'orderId': f'vpn_sub_{duration_hours}h',
},
'checkout': {
'redirectURL': f'{app_url}/payment/success',
'redirectAutomatically': True
}
}
logger.debug(f"Sending request to BTCPay Server: {self.base_url}/api/v1/stores/{self.store_id}/invoices")
logger.debug(f"Request payload: {payload}")
response = requests.post(
f'{self.base_url}/api/v1/stores/{self.store_id}/invoices',
headers=headers,
json=payload
)
logger.debug(f"BTCPay response status: {response.status_code}")
logger.debug(f"BTCPay response content: {response.text}")
if response.status_code != 200:
logger.error(f"BTCPay invoice creation failed: {response.text}")
return None
invoice_data = response.json()
logger.info(f"Successfully created invoice {invoice_data.get('id')}")
return {
'invoice_id': invoice_data['id'],
'checkout_url': invoice_data['checkoutLink']
}
except Exception as e:
logger.error("Error creating BTCPay invoice:")
logger.error(traceback.format_exc())
return None
def send_confirmation_email(self, email, config_data):
"""Send VPN configuration details via email"""
try:
logger.info(f"Sending confirmation email to {email}")
if not self.smtp_config:
logger.warning("SMTP configuration not found in vault")
return False
msg = MIMEMultipart()
msg['From'] = self.smtp_config['sender_email']
msg['To'] = email
msg['Subject'] = "Your VPN Configuration"
body = f"""
Thank you for subscribing to our VPN service!
Please find your WireGuard configuration below:
{config_data}
Installation instructions:
1. Install WireGuard client for your platform from https://www.wireguard.com/install/
2. Save the above configuration to a file named 'wg0.conf'
3. Import the configuration file into your WireGuard client
Need help? Reply to this email for support.
"""
msg.attach(MIMEText(body, 'plain'))
logger.debug("Connecting to SMTP server")
with smtplib.SMTP(
self.smtp_config['server'],
self.smtp_config.get('port', 587)
) as server:
server.starttls()
server.login(
self.smtp_config['username'],
self.smtp_config['password']
)
server.send_message(msg)
logger.info("Confirmation email sent successfully")
return True
except Exception as e:
logger.error("Error sending confirmation email:")
logger.error(traceback.format_exc())
return False