You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 

222 lines
8.6 KiB

# -*- coding: utf-8 -*-
###############################################################################
#
# Cybrosys Technologies Pvt. Ltd.
#
# Copyright (C) 2023-TODAY Cybrosys Technologies(<https://www.cybrosys.com>)
# Author: Ansil pv (odoo@cybrosys.com)
#
# You can modify it under the terms of the GNU AFFERO
# GENERAL PUBLIC LICENSE (AGPL v3), Version 3.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU AFFERO GENERAL PUBLIC LICENSE (AGPL v3) for more details.
#
# You should have received a copy of the GNU AFFERO GENERAL PUBLIC LICENSE
# (AGPL v3) along with this program.
# If not, see <http://www.gnu.org/licenses/>.
#
###############################################################################
# Import required libraries (make sure it is installed!)
import logging
from odoo import _, models
from odoo.exceptions import ValidationError
import requests
from wallee import Configuration
from wallee.api import (
TransactionServiceApi,
TransactionPaymentPageServiceApi,
CustomerServiceApi,
)
from wallee.models import (
LineItem,
LineItemType,
TransactionCreate,
CustomerCreate,
CustomerPostalAddressCreate,
)
_logger = logging.getLogger(__name__)
class PaymentTransaction(models.Model):
_inherit = "payment.transaction"
def _get_specific_rendering_values(self, processing_values):
"""
For get specific rendering values and execute execute_payment
function
"""
res = super()._get_specific_rendering_values(processing_values)
if self.provider_code != "wallee":
return res
return self.execute_payment()
def execute_payment(self):
"""Fetching data and Executing Payment
:return: The response content."""
odoo_base_url = self.env["ir.config_parameter"].get_param("web.base.url")
sale_order = (
self.env["payment.transaction"]
.search([("id", "=", self.id)])
.sale_order_ids
)
if self.provider_id.code == "wallee":
config = Configuration(
user_id=self.provider_id.wallee_user_id,
api_secret=self.provider_id.wallee_user_secret_key,
# set a custom request timeout if needed. (If not set, then the
# default value is: 25 seconds)
request_timeout=30,
)
transaction_service = TransactionServiceApi(configuration=config)
customer_service = CustomerServiceApi(configuration=config)
transaction_payment_page_service = TransactionPaymentPageServiceApi(
configuration=config
)
line_items = []
for index, lines in enumerate(sale_order.order_line):
locals()[f"line_item_{index}"] = LineItem(
name=lines.product_id.name,
unique_id=str(lines.id),
sku=lines.product_id.detailed_type,
quantity=lines.product_uom_qty,
amount_including_tax=lines.price_total,
type=LineItemType.PRODUCT,
)
line_items.append(locals()[f"line_item_{index}"])
address_create = CustomerCreate(
customer_id=str(sale_order.partner_id.id),
email_address=sale_order.partner_id.email,
family_name="",
given_name=sale_order.partner_id.name,
street=sale_order.partner_id.street,
postcode=sale_order.partner_id.zip,
city=sale_order.partner_id.city,
country=sale_order.partner_id.country_id,
postal_state=sale_order.partner_id.state_id,
)
user_address = CustomerPostalAddressCreate(
customer_id=str(sale_order.partner_id.id),
email_address=sale_order.partner_id.email,
family_name="",
given_name=sale_order.partner_id.name,
street=sale_order.partner_id.street,
postcode=sale_order.partner_id.zip,
city=sale_order.partner_id.city,
country=sale_order.partner_id.country_id.name,
postal_state=sale_order.partner_id.state_id.name,
)
# create transaction model
transaction = TransactionCreate(
customer_id=sale_order.partner_id.id,
merchant_reference=sale_order.name,
invoice_merchant_reference=sale_order.name,
line_items=line_items,
auto_confirmation_enabled=True,
currency=self.env.user.currency_id.name,
shipping_address=user_address,
billing_address=user_address,
failed_url=f"{odoo_base_url}/webhook",
success_url=f"{odoo_base_url}/webhook",
)
transaction_create = transaction_service.create(
space_id=self.provider_id.wallee_user_space_id, transaction=transaction
)
payment_page_url = transaction_payment_page_service.payment_page_url(
space_id=self.provider_id.wallee_user_space_id, id=transaction_create.id
)
self.provider_reference = transaction_create.id
response = requests.request("POST", payment_page_url)
return {"api_url": payment_page_url}
def _get_tx_from_notification_data(self, provider_code, notification_data):
"""
Get payment status from Wallee.
:param provider_code: The code of the provider handling the transaction
:param notification_data: The data received from Wallee notification.
:return: The transaction matching the reference.
"""
tx = super()._get_tx_from_notification_data(provider_code, notification_data)
if provider_code != "wallee":
return tx
reference = notification_data.get("reference")
if not reference:
raise ValidationError(
"Wallee: "
+ _(
"No reference found.",
)
)
tx = self.search(
[
("reference", "=", notification_data.get("reference")),
("provider_code", "=", "wallee"),
]
)
if not tx:
raise ValidationError(
"Wallee: "
+ _(
"No transaction found " "matching reference %s.",
notification_data.get("reference"),
)
)
return tx
def _handle_notification_data(self, provider_code, notification_data):
"""
Handle the notification data received from Wallee.
This method retrieves the transaction corresponding to the
notification data, processes the notification data, and executes the
callback.
:param provider_code: The code of the provider handling the transaction
:param notification_data: The data received from Wallee notification.
:return: The transaction object.
"""
tx = self._get_tx_from_notification_data(provider_code, notification_data)
tx._process_notification_data(notification_data)
tx._execute_callback()
return tx
def _process_notification_data(self, notification_data):
"""
Process the notification data received from Wallee.
This method processes the notification data and updates the payment
state of the transaction accordingly.
:param notification_data: The data received from Wallee notification.
"""
super()._process_notification_data(notification_data)
if self.provider_code != "wallee":
return
status = notification_data.get("state")
if status == "FULFILL":
self._set_done(state_message="Authorised")
elif status in (
"COMPLETED",
"PENDING",
"CONFIRMED",
"PROCESSING",
"AUTHORIZED",
):
self._set_pending(
state_message="Authorised but on hold for " "further anti-fraud review"
)
elif status in ("FAILED", "VOIDED", "DECLINE"):
self._set_canceled(state_message="Error")
else:
_logger.warning(
"received unrecognized payment state %s for "
"transaction with reference %s",
notification_data.get("reference"),
)
self._set_error("wallee: " + _("Invalid payment status."))