89 lines
3.6 KiB
Python
89 lines
3.6 KiB
Python
import logging
|
|
import requests
|
|
import json
|
|
from odoo import http
|
|
|
|
_logger = logging.getLogger(__name__)
|
|
|
|
|
|
class PaydunyaController(http.Controller):
|
|
@http.route('/payment/paydunya/return', type='http', auth='public', methods=['GET'], csrf=False)
|
|
def paydunya_return(self, **kwargs):
|
|
"""Handle return from PayDunya after payment attempt."""
|
|
token = kwargs.get('token') or http.request.params.get('token')
|
|
if not token:
|
|
return http.request.redirect('/')
|
|
|
|
provider = http.request.env['payment.provider'].sudo().search([('code', '=', 'paydunya')], limit=1)
|
|
if not provider:
|
|
_logger.warning('PayDunya return called but no provider found')
|
|
return http.request.redirect('/')
|
|
|
|
# Build check URL using the confirm endpoint
|
|
base = provider._get_paydunya_api_base()
|
|
confirm_url = base + '/checkout-invoice/confirm/{}'.format(token)
|
|
|
|
headers = {
|
|
'Content-Type': 'application/json',
|
|
'PAYDUNYA-MASTER-KEY': provider.paydunya_master_key or '',
|
|
'PAYDUNYA-PRIVATE-KEY': provider.paydunya_private_key or '',
|
|
'PAYDUNYA-TOKEN': provider.paydunya_token or ''
|
|
}
|
|
|
|
try:
|
|
# GET request to verify status
|
|
resp = requests.get(confirm_url, headers=headers, timeout=15)
|
|
data = resp.json()
|
|
_logger.info('PayDunya confirm response: %s', data)
|
|
except Exception as e:
|
|
_logger.exception('Error verifying PayDunya invoice: %s', e)
|
|
data = {'token': token, 'status': 'failed'}
|
|
|
|
# Trigger transaction handling with the confirmed data
|
|
try:
|
|
tx_model = http.request.env['payment.transaction'].sudo()
|
|
handled = tx_model._handle_notification_data(data)
|
|
if handled:
|
|
return http.request.redirect('/shop/confirmation')
|
|
except Exception:
|
|
_logger.exception('Error handling PayDunya notification data')
|
|
|
|
return http.request.redirect('/')
|
|
|
|
@http.route('/payment/paydunya/cancel', type='http', auth='public', methods=['GET'], csrf=False)
|
|
def paydunya_cancel(self, **kwargs):
|
|
"""Handle cancellation from PayDunya."""
|
|
token = kwargs.get('token') or http.request.params.get('token')
|
|
_logger.info('PayDunya payment cancelled: token=%s', token)
|
|
return http.request.redirect('/shop/cart')
|
|
|
|
@http.route('/payment/paydunya/callback', type='http', auth='public', methods=['GET', 'POST'], csrf=False)
|
|
def paydunya_callback(self, **kwargs):
|
|
"""Handle IPN callback from PayDunya.
|
|
|
|
PayDunya sends data as application/x-www-form-urlencoded with 'data' key containing JSON.
|
|
"""
|
|
try:
|
|
payload = {}
|
|
data_str = http.request.params.get('data')
|
|
if data_str:
|
|
payload = {'data': data_str}
|
|
elif http.request.params:
|
|
payload = dict(http.request.params)
|
|
else:
|
|
raw_body = http.request.httprequest.get_data(as_text=True)
|
|
if raw_body:
|
|
try:
|
|
payload = json.loads(raw_body)
|
|
except Exception:
|
|
payload = {'data': raw_body}
|
|
|
|
_logger.info('PayDunya IPN callback received: %s', payload)
|
|
tx_model = http.request.env['payment.transaction'].sudo()
|
|
tx_model._handle_notification_data(payload)
|
|
except Exception:
|
|
_logger.exception('Error handling PayDunya callback')
|
|
|
|
# Always return 200 OK to PayDunya
|
|
return 'OK'
|