@@ -19,24 +19,21 @@
|
||||
#
|
||||
# ******************************************************************************
|
||||
|
||||
import logging
|
||||
import json
|
||||
import pprint
|
||||
|
||||
import requests
|
||||
import werkzeug
|
||||
from werkzeug import urls
|
||||
from werkzeug.exceptions import Forbidden
|
||||
|
||||
from odoo import _, http, SUPERUSER_ID
|
||||
from odoo import _, http
|
||||
from odoo.exceptions import ValidationError
|
||||
from odoo.http import request
|
||||
from odoo.tools import html_escape
|
||||
|
||||
import json
|
||||
from odoo.addons.payment.logging import get_payment_logger
|
||||
from ..models.libs.client import BTCPayClient
|
||||
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
_logger = get_payment_logger(__name__)
|
||||
|
||||
|
||||
class BTCPayController(http.Controller):
|
||||
@@ -44,11 +41,22 @@ class BTCPayController(http.Controller):
|
||||
_notify_url = '/payment/btcpay/ipn'
|
||||
_return_url = '/payment/btcpay/return'
|
||||
|
||||
@http.route(_checkout_url, type='http', auth='public', csrf=False, website=True)
|
||||
@http.route(_checkout_url, type='http', auth='public', csrf=False, website=True)
|
||||
def checkout(self, **data):
|
||||
|
||||
_logger.info("CHECKOUT: notification received from BTCPay with data:\n%s", pprint.pformat(data))
|
||||
tx_sudo = request.env['payment.transaction'].sudo()._get_tx_from_notification_data('btcpayserver', data)
|
||||
_logger.info("CHECKOUT: received data:\n%s", pprint.pformat(data))
|
||||
|
||||
# Look up the transaction by reference
|
||||
reference = data.get('reference')
|
||||
tx_sudo = request.env['payment.transaction'].sudo().search([
|
||||
('reference', '=', reference),
|
||||
('provider_code', '=', 'btcpayserver'),
|
||||
], limit=1)
|
||||
if not tx_sudo:
|
||||
raise ValidationError(
|
||||
_("BTCPay: No transaction found matching reference %s.", reference)
|
||||
)
|
||||
|
||||
provider = tx_sudo.provider_id
|
||||
notification_url = str(data.get('notify_url')).replace("http://", "https://")
|
||||
base_url = request.env['ir.config_parameter'].sudo().get_param('web.base.url')
|
||||
@@ -72,41 +80,47 @@ class BTCPayController(http.Controller):
|
||||
_logger.info('Invoice %s \n NOTIFY URL: %s', invoice, notification_url)
|
||||
return werkzeug.utils.redirect(invoice['url'])
|
||||
|
||||
@http.route(_notify_url, type='json', auth='public', csrf=False)
|
||||
@http.route(_notify_url, type='jsonrpc', auth='public', csrf=False)
|
||||
def btcpay_ipn(self, **post):
|
||||
""" BTCPay IPN. """
|
||||
_logger.info('BTCPAY IPN RECEIVED... ')
|
||||
_logger.info('BTCPAY IPN RECEIVED...')
|
||||
data = json.loads(request.httprequest.data)
|
||||
_logger.info("%s", pprint.pformat(data))
|
||||
try:
|
||||
notification_data = {"reference": data['data']['orderId'],
|
||||
"invoiceID": data['data']['id']}
|
||||
# Check the origin and integrity of the notification
|
||||
tx_sudo = request.env['payment.transaction'].sudo()._get_tx_from_notification_data('btcpayserver', notification_data)
|
||||
reference = data['data']['orderId']
|
||||
invoice_id = data['data']['id']
|
||||
|
||||
# Look up the transaction by reference
|
||||
tx_sudo = request.env['payment.transaction'].sudo().search([
|
||||
('reference', '=', reference),
|
||||
('provider_code', '=', 'btcpayserver'),
|
||||
], limit=1)
|
||||
if not tx_sudo:
|
||||
_logger.warning("No transaction found matching reference %s.", reference)
|
||||
return ''
|
||||
|
||||
provider = tx_sudo.provider_id
|
||||
client = BTCPayClient(host=provider.btcpay_location, pem=provider.btcpay_privateKey,
|
||||
tokens={provider.btcpay_facade: provider.btcpay_token})
|
||||
|
||||
fetched_invoice = client.get_invoice(notification_data['invoiceID'])
|
||||
_logger.info('fetched_invoice = %s',pprint.pformat(fetched_invoice))
|
||||
fetched_invoice = client.get_invoice(invoice_id)
|
||||
_logger.info('fetched_invoice = %s', pprint.pformat(fetched_invoice))
|
||||
|
||||
notification_data = {"reference": fetched_invoice['orderId'],
|
||||
"status": fetched_invoice['status'],
|
||||
"invoiceID": fetched_invoice['id'],
|
||||
"txid": fetched_invoice['url']}
|
||||
payment_data = {
|
||||
"reference": fetched_invoice['orderId'],
|
||||
"status": fetched_invoice['status'],
|
||||
"invoiceID": fetched_invoice['id'],
|
||||
"txid": fetched_invoice['url'],
|
||||
}
|
||||
|
||||
# Handle the notification data
|
||||
tx_sudo._handle_notification_data('btcpayserver', notification_data)
|
||||
except ValidationError: # Acknowledge the notification to avoid getting spammed
|
||||
# Use the new Odoo 19 _process() pipeline
|
||||
tx_sudo._process('btcpayserver', payment_data)
|
||||
except ValidationError:
|
||||
_logger.exception("Unable to handle the notification data; skipping to acknowledge")
|
||||
return ''
|
||||
|
||||
@http.route(_return_url, type='http', auth="public", methods=['GET'], crsf=False, save_session=False)
|
||||
@http.route(_return_url, type='http', auth="public", methods=['GET'], csrf=False, save_session=False)
|
||||
def btcpay_return_from_redirect(self, **data):
|
||||
""" BTCPay return
|
||||
|
||||
We could process and check the invoice status here but there is no need to as the status get's updated via
|
||||
IPN anyway, so just show the user the order confirmation / payment status page.
|
||||
"""
|
||||
""" BTCPay return """
|
||||
_logger.info("BTCPay: user returned to shop after payment")
|
||||
return request.redirect('/payment/status')
|
||||
return request.redirect('/payment/status')
|
||||
|
||||
Reference in New Issue
Block a user