def portal_my_invoice_detail(self,
                                 invoice_id,
                                 access_token=None,
                                 report_type=None,
                                 download=False,
                                 **kw):
        # fmt: on
        # override in order to not retrieve release capital request as invoices
        try:
            invoice_sudo = self._document_check_access("account.invoice",
                                                       invoice_id,
                                                       access_token)
        except (AccessError, MissingError):
            return request.redirect("/my")
        if invoice_sudo.release_capital_request:
            report_ref = "easy_my_coop.action_cooperator_invoices"
        else:
            report_ref = "account.account_invoices"
        if report_type in ("html", "pdf", "text"):
            return self._show_report(
                model=invoice_sudo,
                report_type=report_type,
                report_ref=report_ref,
                download=download,
            )

        values = self._invoice_get_page_view_values(invoice_sudo, access_token,
                                                    **kw)
        PaymentProcessing.remove_payment_transaction(
            invoice_sudo.transaction_ids)
        return request.render("account.portal_invoice_page", values)
Exemple #2
0
    def payment_validate(self,
                         transaction_id=None,
                         sale_order_id=None,
                         **post):
        """ Method that should be called by the server when receiving an update
        for a transaction. State at this point :

         - UDPATE ME
        """
        if sale_order_id is None:
            order = request.website.sale_get_order()
        else:
            order = request.env['sale.order'].sudo().browse(sale_order_id)
            assert order.id == request.session.get('sale_last_order_id')

        if transaction_id:
            tx = request.env['payment.transaction'].sudo().browse(
                transaction_id)
            assert tx in order.transaction_ids()
        elif order:
            tx = order.get_portal_last_transaction()
        else:
            tx = None

        if not order or (order.amount_total and not tx):
            return request.redirect('/shop')

        if order and not order.amount_total and not tx:
            order.with_context(send_email=True).action_confirm()
            return request.redirect(order.get_portal_url())

        # clean context and session, then redirect to the confirmation page
        request.website.sale_reset()
        if tx and tx.state == 'draft':
            return request.redirect('/shop')

        PaymentProcessing.remove_payment_transaction(tx)

        values = {}

        if order.state == 'sale' and tx.state == 'done':
            partner = request.env.user.partner_id

            for line in order.order_line:
                partner_sale_line = request.env['website.sale.detail'].sudo(
                ).create({
                    'product_tree_name': line.product_id.id,
                    'is_gift': False,
                    'qty': line.product_uom_qty,
                    'res_partner_id': partner.id
                })
                print(partner_sale_line)

                partner.write({'sale_detail_ids': [(4, partner_sale_line.id)]})

                values.update({'tree_id': partner_sale_line})

        # return request.redirect('/shop/confirmation')
        # return request.redirect('/shopping-thankyou', {'tree_id': partner_sale_line.tree_id})
        return request.render('shop.shop_thank', values)
Exemple #3
0
    def payment_validate(self, transaction_id=None, sale_order_id=None, **post):
        """ Method that should be called by the server when receiving an update
        for a transaction. State at this point :

         - UDPATE ME
        """
        if sale_order_id is None:
            order = request.website.sale_get_order()
        else:
            order = request.env['sale.order'].sudo().browse(sale_order_id)
            assert order.id == request.session.get('sale_last_order_id')

        if transaction_id:
            tx = request.env['payment.transaction'].sudo().browse(transaction_id)
            assert tx in order.transaction_ids()
        elif order:
            tx = order.get_portal_last_transaction()
        else:
            tx = None

        if not order or (order.amount_total and not tx):
            return request.redirect('/shop')

        # clean context and session, then redirect to the confirmation page
        request.website.sale_reset()
        if tx and tx.state == 'draft':
            return request.redirect('/shop')

        PaymentProcessing.remove_payment_transaction(tx)
        return request.redirect('/shop/confirmation')
Exemple #4
0
    def payment_validate(self, transaction_id=None, sale_order_id=None, **post):
        """ Method that should be called by the server when receiving an update
        for a transaction. State at this point :

         - UDPATE ME
        """
        if sale_order_id is None:
            order = request.website.sale_get_order()
        else:
            order = request.env['sale.order'].sudo().browse(sale_order_id)
            assert order.id == request.session.get('sale_last_order_id')

        if transaction_id:
            tx = request.env['payment.transaction'].sudo().browse(transaction_id)
            assert tx in order.transaction_ids()
        elif order:
            tx = order.get_portal_last_transaction()
        else:
            tx = None

        if not order or (order.amount_total and not tx):
            return request.redirect('/shop')

        # clean context and session, then redirect to the confirmation page
        request.website.sale_reset()
        if tx and tx.state == 'draft':
            return request.redirect('/shop')

        PaymentProcessing.remove_payment_transaction(tx)
        return request.redirect('/shop/confirmation')
Exemple #5
0
    def payment_transaction(self, acquirer_id, save_token=False, so_id=None, access_token=None, token=None, **kwargs):
        """ Json method that creates a payment.transaction, used to create a
        transaction when the user clicks on 'pay now' button. After having
        created the transaction, the event continues and the user is redirected
        to the acquirer website.

        :param int acquirer_id: id of a payment.acquirer record. If not set the
                                user is redirected to the checkout page
        """
        # Ensure a payment acquirer is selected
        if not acquirer_id:
            return False

        try:
            acquirer_id = int(acquirer_id)
        except:
            return False

        # Retrieve the sale order
        if so_id:
            env = request.env['sale.order']
            domain = [('id', '=', so_id)]
            if access_token:
                env = env.sudo()
                domain.append(('access_token', '=', access_token))
            order = env.search(domain, limit=1)
        else:
            order = request.website.sale_get_order()

        # Ensure there is something to proceed
        if not order or (order and not order.order_line):
            return False

        assert order.partner_id.id != request.website.partner_id.id

        # Create transaction
        vals = {'acquirer_id': acquirer_id,
                'return_url': '/shop/payment/validate'}

        if save_token:
            vals['type'] = 'form_save'
        if token:
            vals['payment_token_id'] = int(token)

        transaction = order._create_payment_transaction(vals)

        # store the new transaction into the transaction list and if there's an old one, we remove it
        # until the day the ecommerce supports multiple orders at the same time
        last_tx_id = request.session.get('__website_sale_last_tx_id')
        last_tx = request.env['payment.transaction'].browse(last_tx_id).sudo().exists()
        if last_tx:
            PaymentProcessing.remove_payment_transaction(last_tx)
        PaymentProcessing.add_payment_transaction(transaction)
        request.session['__website_sale_last_tx_id'] = transaction.id
        return transaction.render_sale_button(order)
Exemple #6
0
    def payment_transaction(self, acquirer_id, save_token=False, so_id=None, access_token=None, token=None, **kwargs):
        """ Json method that creates a payment.transaction, used to create a
        transaction when the user clicks on 'pay now' button. After having
        created the transaction, the event continues and the user is redirected
        to the acquirer website.

        :param int acquirer_id: id of a payment.acquirer record. If not set the
                                user is redirected to the checkout page
        """
        # Ensure a payment acquirer is selected
        if not acquirer_id:
            return False

        try:
            acquirer_id = int(acquirer_id)
        except:
            return False

        # Retrieve the sale order
        if so_id:
            env = request.env['sale.order']
            domain = [('id', '=', so_id)]
            if access_token:
                env = env.sudo()
                domain.append(('access_token', '=', access_token))
            order = env.search(domain, limit=1)
        else:
            order = request.website.sale_get_order()

        # Ensure there is something to proceed
        if not order or (order and not order.order_line):
            return False

        assert order.partner_id.id != request.website.partner_id.id

        # Create transaction
        vals = {'acquirer_id': acquirer_id,
                'return_url': '/shop/payment/validate'}

        if save_token:
            vals['type'] = 'form_save'
        if token:
            vals['payment_token_id'] = int(token)

        transaction = order._create_payment_transaction(vals)

        # store the new transaction into the transaction list and if there's an old one, we remove it
        # until the day the ecommerce supports multiple orders at the same time
        last_tx_id = request.session.get('__website_sale_last_tx_id')
        last_tx = request.env['payment.transaction'].browse(last_tx_id).sudo().exists()
        if last_tx:
            PaymentProcessing.remove_payment_transaction(last_tx)
        PaymentProcessing.add_payment_transaction(transaction)
        request.session['__website_sale_last_tx_id'] = transaction.id
        return transaction.render_sale_button(order)
Exemple #7
0
    def payment_validate(self, transaction_id=None, sale_order_id=None, **post):
        """ Method that should be called by the server when receiving an update
        for a transaction. State at this point :

         - UDPATE ME
        """
        if sale_order_id is None:
            order = request.website.sale_get_order()
        else:
            order = request.env['sale.order'].sudo().browse(sale_order_id)
            assert order.id == request.session.get('sale_last_order_id')

        if transaction_id:
            tx = request.env['payment.transaction'].sudo().browse(transaction_id)
            assert tx in order.transaction_ids()
        elif order:
            tx = order.get_portal_last_transaction()
        else:
            tx = None

        if not order or (order.amount_total and not tx):
            return request.redirect('/shop')

        #added by sagar
        if order:
            values = {
                'sale_id':order.id,
            }
            for line in order.order_line:
                order_date = datetime.datetime.strftime(order.date_order, '%d-%m-%Y')
                end_date = order.date_order + timedelta(days=line.product_id.no_of_days)
                end_date = datetime.datetime.strftime(end_date, '%d-%m-%Y')

                values.update({
                    'plan':line.product_id.id,
                    'days':line.product_id.no_of_days,
                    'amount':line.price_total,
                    'start_date':order_date,
                    'end_date':end_date,
                    'payment_date':order_date,
                    'partner_id':order.partner_id.id
                })
            if values:
                new_transaction_history_id = request.env['transaction.history'].sudo().create(values)

        ################

        # clean context and session, then redirect to the confirmation page
        request.website.sale_reset()
        if tx and tx.state == 'draft':
            return request.redirect('/shop')

        PaymentProcessing.remove_payment_transaction(tx)
        return request.redirect('/shop/confirmation')
Exemple #8
0
    def portal_my_invoice_detail(self, invoice_id, access_token=None, report_type=None, download=False, **kw):
        try:
            invoice_sudo = self._document_check_access('account.invoice', invoice_id, access_token)
        except (AccessError, MissingError):
            return request.redirect('/my')

        if report_type in ('html', 'pdf', 'text'):
            return self._show_report(model=invoice_sudo, report_type=report_type, report_ref='account.account_invoices', download=download)

        values = self._invoice_get_page_view_values(invoice_sudo, access_token, **kw)
        PaymentProcessing.remove_payment_transaction(invoice_sudo.transaction_ids)
        return request.render("account.portal_invoice_page", values)
Exemple #9
0
    def portal_my_invoice_detail(self, invoice_id, access_token=None, report_type=None, download=False, **kw):
        try:
            invoice_sudo = self._document_check_access('account.invoice', invoice_id, access_token)
        except (AccessError, MissingError):
            return request.redirect('/my')

        if report_type in ('html', 'pdf', 'text'):
            return self._show_report(model=invoice_sudo, report_type=report_type, report_ref='account.account_invoices', download=download)

        values = self._invoice_get_page_view_values(invoice_sudo, access_token, **kw)
        PaymentProcessing.remove_payment_transaction(invoice_sudo.transaction_ids)
        return request.render("account.portal_invoice_page", values)
Exemple #10
0
    def stripe_checkout_do_payment(self,
                                   acquirer_id=None,
                                   order_id=None,
                                   invoice_id=None,
                                   token=None,
                                   **kwargs):
        order = request.website.sale_get_order()
        acquirer = request.env['payment.acquirer'].browse(int(acquirer_id))

        assert order.partner_id.id != request.website.partner_id.id
        # tx_obj => object that will use to create transcation record can be sale order or account invoice
        tx_obj = order
        vals = {
            'payment_token_id': int(token) if token else None,
            'return_url': '/shop/payment/validate',
            'type': 'server2server'
        }

        if not token:
            vals['acquirer_id'] = int(acquirer_id)

        if order_id:
            tx_obj, data = self._get_order_tx_vals(order_id, **kwargs)
            vals.update(data)
        elif invoice_id:
            tx_obj, data = self._get_invoice_tx_vals(invoice_id, **kwargs)
            vals.update(data)
        if not token:
            vals['acquirer_id'] = int(acquirer_id)
        if not tx_obj:
            return {
                'status': False,
                'message':
                _("Error occurred while processing your transaction.")
            }

        transaction = tx_obj._create_payment_transaction(vals)

        last_tx_id = request.session.get('__website_sale_last_tx_id')
        last_tx = request.env['payment.transaction'].browse(
            last_tx_id).sudo().exists()
        if last_tx:
            PaymentProcessing.remove_payment_transaction(last_tx)
        PaymentProcessing.add_payment_transaction(transaction)
        request.session['__website_sale_last_tx_id'] = transaction.id

        res = transaction.create_payment(kwargs)
        return res
Exemple #11
0
    def api_payment_transaction(self, acquirer_id, **kwargs):
        """ Json method that creates a payment.transaction, used to create a
        transaction when the user clicks on 'pay now' button. After having
        created the transaction, the event continues and the user is redirected
        to the acquirer website.

        :param int acquirer_id: id of a payment.acquirer record. If not set the
                                user is redirected to the checkout page
        """
        # Ensure a payment acquirer is selected
        if not acquirer_id:
            return False

        try:
            acquirer_id = int(acquirer_id)
        except:
            return False

        order = request.website.sale_get_order()

        # Ensure there is something to proceed
        if not order or (order and not order.order_line):
            return False

        assert order.partner_id.id != request.website.partner_id.id

        # Create transaction
        vals = {
            'acquirer_id': acquirer_id,
            'return_url': '/shop/payment/validate'
        }

        transaction = order._create_payment_transaction(vals)

        # store the new transaction into the transaction list and if there's an old one, we remove it
        # until the day the ecommerce supports multiple orders at the same time
        last_tx_id = request.session.get('__website_sale_last_tx_id')
        last_tx = request.env['payment.transaction'].browse(
            last_tx_id).sudo().exists()
        if last_tx:
            PaymentProcessing.remove_payment_transaction(last_tx)
        PaymentProcessing.add_payment_transaction(transaction)
        request.session['__website_sale_last_tx_id'] = transaction.id

        return transaction.render_sale_api_values(order)
    def payment_validate(self,
                         transaction_id=None,
                         sale_order_id=None,
                         **post):
        if sale_order_id is None:
            order = request.website.sale_get_order()
        else:
            order = request.env['sale.order'].sudo().browse(sale_order_id)
            assert order.id == request.session.get('sale_last_order_id')

        if transaction_id:
            tx = request.env['payment.transaction'].sudo().browse(
                transaction_id)
            assert tx in order.transaction_ids()
        elif order:
            tx = order.get_portal_last_transaction()
        else:
            tx = None

        if not order or (order.amount_total and not tx):
            return request.redirect('/shop')

        if order and not order.amount_total and not tx:
            return request.redirect(order.get_portal_url())

        # clean context and session, then redirect to the confirmation page
        request.website.sale_reset()
        if tx and tx.state == 'draft':
            return request.redirect('/shop')

        PaymentProcessing.remove_payment_transaction(tx)

        order.message_subscribe(partner_ids=[3], subtype_ids=[1, 7, 8])
        order.message_post(
            body=_('A new order has been placed using %s payment method.') %
            order.transaction_ids[0].acquirer_id.name,
            partner_ids=[3],
            record_name=order.display_name,
            res_id=order.id,
            model='sale.order',
            subtype_id=1,
            notif_layout='mail.mail_notification_light')
        return request.redirect('/shop/confirmation')
Exemple #13
0
    def monero_transaction(self, verify_validity=False, **kwargs):
        """
        Function creates a transaction and
        payment token using the sessions sales order
        Calls MoneroSalesOrder.salesorder_payment_sync()
        :param verify_validity:
        :param kwargs:
        :return:
        """
        sales_order = request.website.sale_get_order()
        _logger.info(f"received sales_order: {sales_order.id}")
        _logger.info(f"processing sales_order: {sales_order.id}")

        # Ensure there is something to proceed
        if not sales_order or (sales_order and not sales_order.order_line):
            return False

        assert sales_order.partner_id.id != request.website.partner_id.id
        # at this time the sales order has to be in xmr
        # the user cannot use a fiat pricelist when checking out
        # this won't be fixed until after a job is added to automatically
        # update res.currency.rate
        currency = request.env["res.currency"].sudo().browse(
            sales_order.currency_id.id)
        if currency.name != "XMR":
            raise Exception(
                "This pricelist is not supported, go back and select the "
                "Monero Pricelist")

        payment_acquirer_id = int(kwargs.get("acquirer_id"))

        payment_partner_id = int(kwargs.get("partner_id"))

        wallet_sub_address = SubAddress(kwargs.get("wallet_address"))

        # define payment token
        payment_token = {
            "name": wallet_sub_address.__repr__(),
            "partner_id": payment_partner_id,
            # partner_id creating sales order
            "active": False,
            # token shoudn't be active, the subaddress shouldn't be reused
            "acquirer_id": payment_acquirer_id,
            # surrogate key for payment acquirer
            "acquirer_ref": "payment.payment_acquirer_monero_rpc",
        }

        _logger.info(f"creating payment token "
                     f"for sales_order: {sales_order.id}")
        token = request.env["payment.token"].sudo().create(payment_token)
        token_id = token.id
        token_short_name = token.short_name

        # assign values for transaction creation
        tx_val = {
            "amount": sales_order.amount_total,
            "reference": sales_order.name,
            "currency_id": sales_order.currency_id.id,
            "partner_id": sales_order.partner_id.id,
            # Referencing the Sale Order Partner ID
            "payment_token_id": token_id,  # Associating the Payment Token ID.
            "acquirer_id": payment_acquirer_id,  # Payment Acquirer - Monero
            "state": "pending",
            # tx is pending,
            # because the customer will know the address to send the tx to,
            # but hasn't yet sent it
        }

        _logger.info(f"getting the transaction "
                     f"for sales_order: {sales_order.id}")
        # transaction = sales_order._create_payment_transaction(tx_val)
        transaction = sales_order.get_portal_last_transaction()
        if transaction.id is False:
            transaction = sales_order._create_payment_transaction(tx_val)
            _logger.info(f"created transaction: {transaction.id}")
        else:
            _logger.info(f"retrieved transaction: {transaction.id}")

        # store the new transaction into
        # the transaction list and if there's an old one, we remove it
        # until the day the ecommerce supports multiple orders at the same time
        last_tx_id = request.session.get("__website_sale_last_tx_id")
        last_tx = request.env["payment.transaction"].browse(
            last_tx_id).sudo().exists()
        if last_tx:
            PaymentProcessing.remove_payment_transaction(last_tx)
        PaymentProcessing.add_payment_transaction(transaction)
        request.session["__website_sale_last_tx_id"] = transaction.id

        # Sale Order is quotation sent
        #   , so the state should be set to "sent"
        #   , until the transaction has been verified
        _logger.info(f'setting sales_order state to "sent" '
                     f"for sales_order: {sales_order.id}")
        request.env.user.sale_order_ids.sudo().update({
            "require_payment": "true",
            "state": "sent"
        })

        payment_acquirer = (
            request.env["payment.acquirer"].sudo().browse(payment_acquirer_id))
        # set queue channel and max_retries settings
        # for queue depending on num conf settings
        num_conf_req = int(payment_acquirer.num_confirmation_required)
        if num_conf_req == 0:
            queue_channel = "monero_zeroconf_processing"
            queue_max_retries = 44
        else:
            queue_channel = "monero_secure_processing"
            queue_max_retries = num_conf_req * 25

        # Add payment token and sale order to transaction processing queue

        sales_order.with_delay(
            channel=queue_channel,
            max_retries=queue_max_retries).process_transaction(
                transaction, token, num_conf_req)

        if transaction:
            res = {
                "result": True,
                "id": token_id,
                "short_name": token_short_name,
                "3d_secure": False,
                "verified": False,
            }

            if verify_validity is not False:
                token.validate()
                res["verified"] = token.verified

            return res
Exemple #14
0
	def payment_validate(self, transaction_id=None, sale_order_id=None, **post):
		""" Method that should be called by the server when receiving an update
		for a transaction. State at this point :

		 - UDPATE ME
		"""
		if sale_order_id is None:
			order = request.website.sale_get_order()
		else:
			order = request.env['sale.order'].sudo().browse(sale_order_id)
			assert order.id == request.session.get('sale_last_order_id')

		if transaction_id:
			tx = request.env['payment.transaction'].sudo().browse(transaction_id)
			assert tx in order.transaction_ids()
		elif order:
			tx = order.get_portal_last_transaction()
		else:
			tx = None

		if not order or (order.amount_total and not tx):
			return request.redirect('/shop')

		if tx.acquirer_id.provider == 'cod':
			payment_acquirer_obj = request.env['payment.acquirer'].sudo().search([('id','=', tx.acquirer_id.id)]) 
		
			order = request.website.sale_get_order()
			product_obj = request.env['product.product'].browse()
			extra_fees_product = request.env['ir.model.data'].get_object_reference('bi_website_cash_on_delivery', 'product_product_fees')[1]
			product_ids = product_obj.sudo().search([('product_tmpl_id.id', '=', extra_fees_product)])
			
			order_line_obj = request.env['sale.order.line'].sudo().search([])
			
			
			flag = 0
			for i in order_line_obj:
				if i.product_id.id == product_ids.id and i.order_id.id == order.id:
					flag = flag + 1
			
			if flag == 0:
				order_line_obj.sudo().create({
						'product_id': product_ids.id,
						'name': 'Extra Fees',
						'price_unit': payment_acquirer_obj.delivery_fees,
						'order_id': order.id,
						'product_uom':product_ids.uom_id.id,
					
					})
			
			#order.force_quotation_send()
			order.with_context(send_email=True).action_confirm()
			request.website.sale_reset()
			return request.render("website_sale.confirmation", {'order': order})

		if (not order.amount_total and not tx) or tx.state in ['pending', 'done', 'authorized']:
			if (not order.amount_total and not tx):
				# Orders are confirmed by payment transactions, but there is none for free orders,
				# (e.g. free events), so confirm immediately
				order.with_context(send_email=True).action_confirm()
		elif tx and tx.state == 'cancel':
			# cancel the quotation
			order.action_cancel()
		# clean context and session, then redirect to the confirmation page
		request.website.sale_reset()
		if tx and tx.state == 'draft':
			return request.redirect('/shop')

		PaymentProcessing.remove_payment_transaction(tx)
		return request.redirect('/shop/confirmation')
    def solana_transaction(self, verify_validity=False, **kwargs):
        """
        Function creates a transaction and payment token using the sessions sales order
        Calls SolanaSalesOrder.salesorder_payment_sync()
        :param verify_validity:
        :param kwargs:
        :return:
        """
        sales_order = request.website.sale_get_order()
        _logger.info(f'received sales_order: {sales_order.id}')
        _logger.info(f'processing sales_order: {sales_order.id}')

        # Ensure there is something to proceed
        if not sales_order or (sales_order and not sales_order.order_line):
            return False

        assert sales_order.partner_id.id != request.website.partner_id.id

        payment_acquirer_id = int(kwargs.get('acquirer_id'))

        payment_partner_id = int(kwargs.get('partner_id'))

        # TODO verify the wallet_address is a valid solana address
        # TODO verify that the specified address has the needed amount in it
        source_wallet_address = kwargs.get('wallet_address')

        # define payment token
        payment_token = {
            'name':
            str(source_wallet_address).strip() + ' - ' + kwargs.get('type'),
            # name = 'source_wallet_address' + ' - payment_type'; eg: ejh98hja... - SOL/BTC/USDC/ETH
            'partner_id':
            payment_partner_id,  # partner_id creating sales order
            'active': True,
            'acquirer_id':
            payment_acquirer_id,  # surrogate key for payment acquirer
            'acquirer_ref': 'cryptocurrency'  # this should be the tx hash?
        }

        # TODO reuse token
        _logger.info(
            f'creating payment token for sales_order: {sales_order.id}')
        token = request.env['payment.token'].sudo().create(payment_token)
        token_id = token.id
        token_short_name = token.short_name

        # assign values for transaction creation
        tx_val = {
            'amount': sales_order.amount_total,
            'reference': sales_order.name,
            'currency_id': sales_order.currency_id.id,
            'partner_id':
            sales_order.partner_id.id,  # Referencing the Sale Order Partner ID
            'payment_token_id': token_id,  # Associating the Payment Token ID.
            'acquirer_id': payment_acquirer_id,  # Payment Acquirer - Solana
            'state':
            'pending',  # tx is pending, because the customer will know the address to send the tx to,
            # but hasn't yet sent it
        }

        _logger.info(
            f'getting the transaction for sales_order: {sales_order.id}')
        # transaction = sales_order._create_payment_transaction(tx_val)
        transaction = sales_order.get_portal_last_transaction()
        if transaction.id is False:
            transaction = sales_order._create_payment_transaction(tx_val)
            _logger.info(f'created transaction: {transaction.id}')
        else:
            _logger.info(f'retrieved transaction: {transaction.id}')

        # store the new transaction into the transaction list and if there's an old one, we remove it
        # until the day the ecommerce supports multiple orders at the same time
        last_tx_id = request.session.get('__website_sale_last_tx_id')
        last_tx = request.env['payment.transaction'].browse(
            last_tx_id).sudo().exists()
        if last_tx:
            PaymentProcessing.remove_payment_transaction(last_tx)
        PaymentProcessing.add_payment_transaction(transaction)
        request.session['__website_sale_last_tx_id'] = transaction.id

        # Sale Order is quotation sent
        #   , so the state should be set to "sent"
        #   , until the transaction has been verified
        _logger.info(
            f'setting sales_order state to "sent" for sales_order: {sales_order.id}'
        )
        request.env.user.sale_order_ids.sudo().update({'state': 'sent'})

        if transaction:
            res = {
                'result': True,
                'id': token_id,
                'short_name': token_short_name,
                '3d_secure': False,
                'verified': False,
            }

            if verify_validity != False:
                token.validate()
                res['verified'] = token.verified

            return res
    def confirm_order(self, **post):
        order = request.website.sale_get_order()

        user_id = request.env.user

        redirection = self.checkout_redirection(order)
        if redirection:
            return redirection

        transaction_id = None

        if transaction_id:
            tx = request.env['payment.transaction'].sudo().browse(
                transaction_id)
            assert tx in order.transaction_ids()
        elif order:
            tx = order.get_portal_last_transaction()
        else:
            tx = None
        email = post.get('email')
        name = post.get('name')
        phone = post.get('phone')
        pickup_type = post.get('pickup_type')

        city = post.get('city')
        street = post.get('street')
        zip1 = post.get('zip')
        state_id = post.get('state_id')
        country_id = post.get('country_id')

        if pickup_type in ['pickup_paystore', 'pickup_paynow']:
            if email and name and phone:
                partner = request.env['res.partner'].search(
                    [('email', '=', post.get('email'))], limit=1)

                if request.website.is_public_user():
                    if not partner:
                        partner = request.env['res.partner'].sudo().create({
                            'name':
                            post.get('name'),
                            'email':
                            post.get('email'),
                            'phone':
                            post.get('phone'),
                        })

                    order.write({
                        'partner_id': partner.id,
                        'partner_invoice_id': partner.id,
                        'partner_shipping_id': partner.id,
                    })

                if not partner:
                    partner = request.env['res.partner'].sudo().create({
                        'name':
                        post.get('name'),
                        'email':
                        post.get('email'),
                        'phone':
                        post.get('phone'),
                        'type':
                        'other',
                        'parent_id':
                        user_id.partner_id.id
                    })

                order.write({
                    'checkout_option': post.get('pickup_type'),
                    'pickup_id': partner.id,
                })

                order.onchange_partner_shipping_id()
                order.order_line._compute_tax_id()
                request.session['sale_last_order_id'] = order.id
                request.website.sale_get_order(update_pricelist=True)

                if pickup_type == 'pickup_paystore':
                    order.with_context(send_email=True).action_confirm()
                    request.website.sale_reset()
                    PaymentProcessing.remove_payment_transaction(tx)
                    return request.render("website_sale.confirmation",
                                          {'order': order})

                if pickup_type == 'pickup_paynow':
                    extra_step = request.website.viewref(
                        'website_sale.extra_info_option')
                    if extra_step.active:
                        return request.redirect("/shop/extra_info")

                    return request.redirect("/shop/payment")

        elif pickup_type in ['paynow_delivery', 'payon_delivery']:
            if email and name and phone and city and street and country_id:
                partner = request.env['res.partner'].search(
                    [('email', '=', email)], limit=1)
                if request.website.is_public_user():
                    if not partner:
                        partner = request.env['res.partner'].sudo().create({
                            'name':
                            name,
                            'email':
                            email,
                            'phone':
                            phone,
                            'city':
                            city,
                            'street':
                            street,
                            'zip':
                            zip1,
                            'state_id':
                            int(state_id) or False,
                            'country_id':
                            int(country_id) or False,
                        })

                    order.write({
                        'partner_id': partner.id,
                        'partner_invoice_id': partner.id,
                        'partner_shipping_id': partner.id,
                    })

                if not partner:
                    partner = request.env['res.partner'].sudo().create({
                        'name':
                        name,
                        'email':
                        email,
                        'phone':
                        phone,
                        'type':
                        'other',
                        'parent_id':
                        user_id.partner_id.id,
                        'city':
                        city,
                        'street':
                        street,
                        'zip':
                        zip1,
                        'state_id':
                        int(state_id) or False,
                        'country_id':
                        int(country_id) or False,
                    })

                order.write({
                    'checkout_option': post.get('pickup_type'),
                    'pickup_id': partner.id,
                })

                order.onchange_partner_shipping_id()
                order.order_line._compute_tax_id()
                request.session['sale_last_order_id'] = order.id
                request.website.sale_get_order(update_pricelist=True)

                if pickup_type == 'paynow_delivery':
                    extra_step = request.website.viewref(
                        'website_sale.extra_info_option')
                    if extra_step.active:
                        return request.redirect("/shop/extra_info")

                    return request.redirect("/shop/payment")

                if pickup_type == 'payon_delivery':
                    order.with_context(send_email=True).action_confirm()
                    request.website.sale_reset()
                    PaymentProcessing.remove_payment_transaction(tx)
                    return request.render("website_sale.confirmation",
                                          {'order': order})

        else:
            order = request.website.sale_get_order()

            redirection = self.checkout_redirection(order)
            if redirection:
                return redirection

            order.onchange_partner_shipping_id()
            order.order_line._compute_tax_id()
            request.session['sale_last_order_id'] = order.id
            request.website.sale_get_order(update_pricelist=True)
            extra_step = request.website.viewref(
                'website_sale.extra_info_option')
            if extra_step.active:
                return request.redirect("/shop/extra_info")

            return request.redirect("/shop/payment")