Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions addons/payment_adyen_paybylink/controllers/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,24 +37,30 @@ def adyen_notification(self, **post):
)
try:
# Check the integrity of the notification
tx_sudo = request.env['payment.transaction'].sudo().\
_adyen_form_get_tx_from_data(post)
self._verify_notification_signature(post, tx_sudo)

# Check whether the event of the notification succeeded and
# reshape the notification data for parsing
event_code = post['eventCode']
if event_code in ('AUTHORISATION', 'REFUND') and post['success'] == 'true':
post['authResult'] = 'AUTHORISED'
if event_code == 'REPORT_AVAILABLE' and post['success'] == 'true':
# 'merchantReference': ''
# 'psp_reference': 'settlement_detail_report_batch_554.xlsx'
journal = request.env['account.journal'].sudo()._adyen_get_journal_from_data(post)
journal.download_report(post)
else:
tx_sudo = request.env['payment.transaction'].sudo(). \
_adyen_form_get_tx_from_data(post)
self._verify_notification_signature(post, tx_sudo)

# Handle the notification data
request.env['payment.transaction'].sudo().form_feedback(
post, 'adyen')
# Check whether the event of the notification succeeded and
# reshape the notification data for parsing
if event_code in ('AUTHORISATION', 'REFUND') and post['success'] == 'true':
post['authResult'] = 'AUTHORISED'

# Handle fraud cases
elif (event_code == 'NOTIFICATION_OF_CHARGEBACK' and
post['success'] == 'true'):
tx_sudo.process_fraud_case(post)
# Handle the notification data
request.env['payment.transaction'].sudo().form_feedback(
post, 'adyen')

# Handle fraud cases
elif (event_code == 'NOTIFICATION_OF_CHARGEBACK' and
post['success'] == 'true'):
tx_sudo.process_fraud_case(post)

# Acknowledge the notification to avoid getting spammed
except ValidationError:
Expand Down Expand Up @@ -107,6 +113,7 @@ def _compute_signature(payload, hmac_key):
:return: The computed signature
:rtype: str
"""

def _flatten_dict(_value, _path_base='', _separator='.'):
""" Recursively generate a flat representation of a dict.

Expand Down
1 change: 1 addition & 0 deletions addons/payment_adyen_paybylink/models/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

from . import account_journal
from . import payment_acquirer
from . import payment_transaction
67 changes: 67 additions & 0 deletions addons/payment_adyen_paybylink/models/account_journal.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Part of Odoo. See LICENSE file for full copyright and licensing details.

import logging
import subprocess

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError, UserError

_logger = logging.getLogger(__name__)


def runcmd(cmd, verbose=False, *args, **kwargs):
process = subprocess.Popen(
cmd,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
text=True,
shell=True
)
std_out, std_err = process.communicate()
if verbose:
_logger.info(std_out.strip(), std_err)
pass


class AccountJournal(models.Model):
_inherit = 'account.journal'

@api.model
def _adyen_get_journal_from_data(self, data):
merchant_account = data.get('merchantAccountCode')
if not merchant_account:
error_msg = _('Missing merchantAccountCode in REPORT_AVAILABLE notification from Adyen.')
_logger.info(error_msg)
raise ValidationError(error_msg)
journal = self.env['account.journal'].search([("adyen_merchant_account", "=", merchant_account)])
if len(journal) != 1:
error_msg = _(f'Expected 1 journal for Adyen Merchant Account: {merchant_account}. Found {len(journal)}')
_logger.info(error_msg)
raise ValidationError(error_msg)
return journal

@api.model
def download_report(self, post):
""" Download bank statement report from Adyen to the server
"""
adyen_user = self.acquirer_id.adyen_report_user
adyen_pass = self.acquirer_id.adyen_report_password
if not adyen_user or not adyen_pass:
raise UserError(
f'User or password missing for acquirer {self.name} '
f'related to journal {self.acquirer_id.name}'
)
path = '/tmp/adyen/'
cmd = "mkdir -p {path} && wget -P {path} --http-user='{user}@Company.VANMOOF' " \
"--http-password='{pwd}' --no-check-certificate {url}".format(
path=path, user=adyen_user, pwd=adyen_pass, url=post["reason"])
try:
_logger.debug('Downloading {url} to {path}{file}'.format(
file=post['pspReference'], url=post["reason"], path=path))
runcmd(cmd, verbose=True)
return path + post['pspReference']
except Exception as e:
message = f"Download Failed for Ayden Report notification {post} \n " \
f"with the exception: {e.args[0]}."
_logger.error(message)
raise UserError(message)
6 changes: 4 additions & 2 deletions addons/payment_adyen_paybylink/models/payment_acquirer.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,15 @@
import logging
import re
import requests
import subprocess

from werkzeug import urls

from odoo import _, api, fields, models
from odoo.exceptions import ValidationError
from odoo.exceptions import ValidationError, UserError

from odoo.addons.payment_adyen_paybylink.const import API_ENDPOINT_VERSIONS


_logger = logging.getLogger(__name__)


Expand Down Expand Up @@ -40,6 +40,8 @@ class PaymentAcquirer(models.Model):
# the 'NOT NULL' constraint on those fields.
adyen_skin_code = fields.Char(default="Do not use this field")
adyen_skin_hmac_key = fields.Char(default="Do not use this field")
adyen_report_user = fields.Char(string="Report User")
adyen_report_password = fields.Char(string="Reporting Password")

@api.model_create_multi
def create(self, values_list):
Expand Down
10 changes: 10 additions & 0 deletions addons/payment_adyen_paybylink/views/payment_views.xml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,16 @@
</xpath>
<xpath expr="//field[@name='adyen_skin_code']" position='replace'></xpath>
<xpath expr="//field[@name='adyen_skin_hmac_key']" position='replace'></xpath>
<notebook attrs="{'invisible': ['&amp;', ('module_id', '!=', False), ('module_state', '!=', 'installed')]}" position="inside">
<page string="Reporting">
<group>
<field name="adyen_report_user"/>
<field name="adyen_report_password"
password="True"/>
</group>

</page>
</notebook>
</field>
</record>

Expand Down