Files
Autoparts-DB/pos/blueprints/bnpl_bp.py
consultoria-as 2cfe4b3913 feat(api): add BNPL, ERP, WhatsApp Cloud, Supplier Portal stubs
- bnpl_bp.py: APLAZO/Kueski/Clip application workflow (mock)
- erp_bp.py: Aspel/CONTPAQi/SAP/Odoo sync jobs (mock)
- whatsapp_cloud_bp.py: Meta Cloud API webhook, messages, templates
- supplier_portal_bp.py: demand by zone/branch and top-parts analytics
- app.py: register all new blueprints
2026-04-29 06:31:03 +00:00

91 lines
3.0 KiB
Python

"""BNPL Blueprint — Buy Now Pay Later integrations (stub architecture).
Providers: APLAZO, Kueski, Clip (configured per tenant).
All endpoints are stubs with mock responses until real credentials are provided.
"""
from flask import Blueprint, request, jsonify, g
from functools import wraps
import uuid
from datetime import datetime, timedelta
bnpl_bp = Blueprint('bnpl', __name__, url_prefix='/pos/api/bnpl')
# ─── Auth helper ───
from middleware import require_auth
# ─── Mock store ───
_mock_applications = {}
@bnpl_bp.route('/providers', methods=['GET'])
@require_auth()
def list_providers():
"""List configured BNPL providers."""
return jsonify({
'providers': [
{'id': 'ap lazo', 'name': 'APLAZO', 'enabled': False, 'config_needed': ['api_key', 'merchant_id']},
{'id': 'kueski', 'name': 'Kueski Pay', 'enabled': False, 'config_needed': ['api_key', 'secret']},
{'id': 'clip', 'name': 'Clip Pagos', 'enabled': False, 'config_needed': ['api_key']},
]
})
@bnpl_bp.route('/applications', methods=['POST'])
@require_auth()
def create_application():
"""Create a BNPL application for a sale."""
data = request.get_json() or {}
sale_id = data.get('sale_id')
amount = data.get('amount')
provider = data.get('provider', 'ap lazo')
customer = data.get('customer', {})
if not sale_id or amount is None:
return jsonify({'error': 'sale_id and amount are required'}), 400
app_id = str(uuid.uuid4())
_mock_applications[app_id] = {
'id': app_id,
'sale_id': sale_id,
'provider': provider,
'amount': float(amount),
'status': 'pending',
'customer': customer,
'created_at': datetime.utcnow().isoformat(),
'expires_at': (datetime.utcnow() + timedelta(hours=24)).isoformat(),
'approval_url': f'/pos/api/bnpl/applications/{app_id}/approve',
'webhook_url': f'/pos/api/bnpl/webhook/{provider}',
}
return jsonify(_mock_applications[app_id]), 201
@bnpl_bp.route('/applications/<app_id>', methods=['GET'])
@require_auth()
def get_application(app_id):
"""Get BNPL application status."""
app = _mock_applications.get(app_id)
if not app:
return jsonify({'error': 'Application not found'}), 404
return jsonify(app)
@bnpl_bp.route('/applications/<app_id>/approve', methods=['POST'])
@require_auth()
def approve_application(app_id):
"""Mock approve an application (admin/override)."""
app = _mock_applications.get(app_id)
if not app:
return jsonify({'error': 'Application not found'}), 404
app['status'] = 'approved'
app['approved_at'] = datetime.utcnow().isoformat()
return jsonify(app)
@bnpl_bp.route('/webhook/<provider>', methods=['POST'])
def webhook(provider):
"""Receive webhooks from BNPL providers."""
data = request.get_json() or {}
# In production, verify signature per provider
return jsonify({'received': True, 'provider': provider, 'payload': data}), 200