144 lines
5.3 KiB
Python
144 lines
5.3 KiB
Python
|
# 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
|