Ejemplo n.º 1
0
    def payment_token(self, pm_id=None, **kwargs):
        """ Method that handles payment using saved tokens

        :param int pm_id: id of the payment.token that we want to use to pay.
        """
        order = request.website.sale_get_order()
        # do not crash if the user has already paid and try to pay again
        if not order:
            return request.redirect('/shop/?error=no_order')

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

        try:
            pm_id = int(pm_id)
        except ValueError:
            return request.redirect('/shop/?error=invalid_token_id')

        # We retrieve the token the user want to use to pay
        if not request.env['payment.token'].sudo().search_count(
            [('id', '=', pm_id)]):
            return request.redirect('/shop/?error=token_not_found')

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

        t_x = order._create_payment_transaction(vals)
        order.write({'payment_tx_id': t_x.id})
        PaymentProcessing.add_payment_transaction(t_x)
        return request.redirect('/payment/process')
Ejemplo n.º 2
0
    def appoint_pay_form(self, acquirer_id, appoint_id, save_token=False, access_token=None, **kwargs):
        success_url = kwargs.get('success_url', '/my/appointments')
        # callback_method = kwargs.get('callback_method', '')

        appoint_sudo = request.env['appointment'].sudo().browse(appoint_id)
        if not appoint_sudo:
            return False

        try:
            acquirer = int(acquirer_id)
        except:
            return False
        if request.env.user._is_public():
            save_token = False # we avoid to create a token for the public user
        vals = {
            'acquirer_id': acquirer_id,
            'return_url': success_url,
        }

        if save_token:
            vals['type'] = 'form_save'

        transaction = appoint_sudo._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(transaction)

        return transaction.render_appoint_button(
            appoint_sudo,
            submit_txt=_('Pay & Confirm'),
            render_values={
                'type': 'form_save' if save_token else 'form',
                'alias_usage': _('If we store your payment information on our server, subscription payments will be made automatically.'),
            }
        )
Ejemplo n.º 3
0
    def appoint_pay_token(self, appoint_id, pm_id=None, **kwargs):
        error_url = kwargs.get('error_url', '/my')
        success_url = kwargs.get('success_url', '/my')
        access_token = kwargs.get('access_token')
        params = {}
        if access_token:
            params['access_token'] = access_token

        appoint_sudo = request.env['appointment'].sudo().browse(appoint_id).exists()
        if not appoint_sudo:
            params['error'] = 'pay_appoint_invalid_doc'
            return request.redirect(_build_url_w_params(error_url, params))

        try:
            token = request.env['payment.token'].sudo().browse(int(pm_id))
        except (ValueError, TypeError):
            token = False
        token_owner = appoint_sudo.customer if request.env.user._is_public() else request.env.user.partner_id
        if not token or token.partner_id != token_owner:
            params['error'] = 'pay_invoice_invalid_token'
            return request.redirect(_build_url_w_params(error_url, params))

        vals = {
            'payment_token_id': token.id,
            'type': 'server2server',
            'return_url': success_url,
        }

        tx = appoint_sudo._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(tx)

        params['success'] = 'pay_invoice'
        return request.redirect(_build_url_w_params(success_url, params))
Ejemplo n.º 4
0
    def stripe_create_charge(self, **post):
        """ Create a payment transaction

        Expects the result from the user input from checkout.js popup"""
        TX = request.env['payment.transaction']
        tx = None
        if post.get('tx_ref'):
            tx = TX.sudo().search([('reference', '=', post['tx_ref'])])
        if not tx:
            tx_id = (post.get('tx_id') or request.session.get('sale_transaction_id') or
                     request.session.get('website_payment_tx_id'))
            tx = TX.sudo().browse(int(tx_id))
        if not tx:
            raise werkzeug.exceptions.NotFound()

        stripe_token = post['token']
        response = None
        if tx.type == 'form_save' and tx.partner_id:
            payment_token_id = request.env['payment.token'].sudo().create({
                'acquirer_id': tx.acquirer_id.id,
                'partner_id': tx.partner_id.id,
                'stripe_token': stripe_token
            })
            tx.payment_token_id = payment_token_id
            response = tx._create_stripe_charge(acquirer_ref=payment_token_id.acquirer_ref, email=stripe_token['email'])
        else:
            response = tx._create_stripe_charge(tokenid=stripe_token['id'], email=stripe_token['email'])
        _logger.info('Stripe: entering form_feedback with post data %s', pprint.pformat(response))
        if response:
            request.env['payment.transaction'].sudo().with_context(lang=None).form_feedback(response, 'stripe')
        # add the payment transaction into the session to let the page /payment/process to handle it
        PaymentProcessing.add_payment_transaction(tx)
        return "/payment/process"
Ejemplo n.º 5
0
    def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs):
        """ Use a token to perform a s2s transaction """
        error_url = kwargs.get('error_url', '/my')
        success_url = kwargs.get('success_url', '/my')
        access_token = kwargs.get('access_token')
        params = {}
        if access_token:
            params['access_token'] = access_token

        invoice_sudo = request.env['account.invoice'].sudo().browse(invoice_id).exists()
        if not invoice_sudo:
            params['error'] = 'pay_invoice_invalid_doc'
            return request.redirect(_build_url_w_params(error_url, params))

        try:
            token = request.env['payment.token'].sudo().browse(int(pm_id))
        except (ValueError, TypeError):
            token = False
        token_owner = invoice_sudo.partner_id if request.env.user._is_public() else request.env.user.partner_id
        if not token or token.partner_id != token_owner:
            params['error'] = 'pay_invoice_invalid_token'
            return request.redirect(_build_url_w_params(error_url, params))

        vals = {
            'payment_token_id': token.id,
            'type': 'server2server',
            'return_url': success_url,
        }

        tx = invoice_sudo._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(tx)

        params['success'] = 'pay_invoice'
        return request.redirect(_build_url_w_params(success_url, params))
Ejemplo n.º 6
0
Archivo: main.py Proyecto: bud-e/odoo
    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')
Ejemplo n.º 7
0
    def hyperpay_shopper_result(self, **post):
        acq = request.env['payment.acquirer'].sudo().search([('provider', '=',
                                                              'hyperpay')])
        if acq.state == 'enabled':
            url = live_domain
        else:
            url = test_domain
        url += '/' + post.get(
            'resourcePath') + "?entityId=%s" % (acq.hyperpay_merchant_id)
        headers = {
            "Authorization": "Bearer " + acq.hyperpay_authorization,
        }
        resp = requests.get(url=url, headers=headers).json()

        _logger.info(
            "-----/payment/hyperpay/result-----response------------%r----",
            resp)

        payment = request.env['payment.transaction'].sudo()
        tx = payment.search([('hyperpay_checkout_id', '=', post.get('id',
                                                                    ''))])
        tx = resp.get('customParameters',
                      {}).get('SHOPPER_tx_id') or tx and tx.id or ''
        resp.update({'tx_id': tx})
        if tx:
            PaymentProcessing.add_payment_transaction(payment.browse(int(tx)))

        res = payment.form_feedback(resp, 'hyperpay')
        return werkzeug.utils.redirect('/payment/process')
Ejemplo n.º 8
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)
Ejemplo n.º 9
0
    def ogone_s2s_create(self, **post):
        error = ''
        acq = request.env['payment.acquirer'].browse(
            int(post.get('acquirer_id')))
        try:
            token = acq.s2s_process(post)
        except Exception as e:
            # synthax error: 'CHECK ERROR: |Not a valid date\n\n50001111: None'
            token = False
            error = str(e).splitlines()[0].split('|')[-1] or ''

        if token and post.get('verify_validity'):
            baseurl = request.env['ir.config_parameter'].sudo().get_param(
                'web.base.url')
            params = {
                'accept_url': baseurl + '/payment/ogone/validate/accept',
                'decline_url': baseurl + '/payment/ogone/validate/decline',
                'exception_url': baseurl + '/payment/ogone/validate/exception',
                'return_url': post.get('return_url', baseurl)
            }
            tx = token.validate(**params)
            if tx and tx.html_3ds:
                return tx.html_3ds
            # add the payment transaction into the session to let the page /payment/process to handle it
            PaymentProcessing.add_payment_transaction(tx)
        return werkzeug.utils.redirect("/payment/process")
Ejemplo n.º 10
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')
Ejemplo n.º 11
0
Archivo: main.py Proyecto: bud-e/odoo
    def payment_token(self, pm_id=None, **kwargs):
        """ Method that handles payment using saved tokens

        :param int pm_id: id of the payment.token that we want to use to pay.
        """
        order = request.website.sale_get_order()
        # do not crash if the user has already paid and try to pay again
        if not order:
            return request.redirect('/shop/?error=no_order')

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

        try:
            pm_id = int(pm_id)
        except ValueError:
            return request.redirect('/shop/?error=invalid_token_id')

        # We retrieve the token the user want to use to pay
        if not request.env['payment.token'].sudo().search_count([('id', '=', pm_id)]):
            return request.redirect('/shop/?error=token_not_found')

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

        tx = order._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(tx)
        return request.redirect('/payment/process')
Ejemplo n.º 12
0
    def payment_token(self, pm_id=None, **kwargs):
        """ Method that handles payment using saved tokens

        :param int pm_id: id of the payment.token that we want to use to pay.
        """
        order = request.website.sale_get_order()
        # do not crash if the user has already paid and try to pay again
        if not order:
            return request.redirect('/shop/?error=no_order')

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

        try:
            pm_id = int(pm_id)
        except ValueError:
            return request.redirect('/shop/?error=invalid_token_id')

        # We retrieve the token the user want to use to pay
        if not request.env['payment.token'].sudo().search_count([('id', '=', pm_id)]):
            return request.redirect('/shop/?error=token_not_found')
    
        # Create transaction
        vals = {'payment_token_id': pm_id, 'return_url': '/shop/payment/validate'}
    
        tx = order._create_payment_transaction(vals)
        pm_ids = request.env['payment.token'].browse(pm_id)
        if pm_ids.acquirer_id.provider == 'cxpay':
            if isinstance(tx, dict):
                url = '/payment_method/add?url=' + tx.get('url') + '&token=' +  str(pm_id)
                return request.redirect(url)
        PaymentProcessing.add_payment_transaction(tx)
        return request.redirect('/payment/process')
Ejemplo n.º 13
0
Archivo: main.py Proyecto: EdyKend/odoo
    def stripe_create_charge(self, **post):
        """ Create a payment transaction

        Expects the result from the user input from checkout.js popup"""
        TX = request.env['payment.transaction']
        tx = None
        if post.get('tx_ref'):
            tx = TX.sudo().search([('reference', '=', post['tx_ref'])])
        if not tx:
            tx_id = (post.get('tx_id') or request.session.get('sale_transaction_id') or
                     request.session.get('website_payment_tx_id'))
            tx = TX.sudo().browse(int(tx_id))
        if not tx:
            raise werkzeug.exceptions.NotFound()

        stripe_token = post['token']
        response = None
        if tx.type == 'form_save' and tx.partner_id:
            payment_token_id = request.env['payment.token'].sudo().create({
                'acquirer_id': tx.acquirer_id.id,
                'partner_id': tx.partner_id.id,
                'stripe_token': stripe_token
            })
            tx.payment_token_id = payment_token_id
            response = tx._create_stripe_charge(acquirer_ref=payment_token_id.acquirer_ref, email=stripe_token['email'])
        else:
            response = tx._create_stripe_charge(tokenid=stripe_token['id'], email=stripe_token['email'])
        _logger.info('Stripe: entering form_feedback with post data %s', pprint.pformat(response))
        if response:
            request.env['payment.transaction'].sudo().with_context(lang=None).form_feedback(response, 'stripe')
        # add the payment transaction into the session to let the page /payment/process to handle it
        PaymentProcessing.add_payment_transaction(tx)
        return "/payment/process"
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
 def cx_pay_paymment_approve(self, payment_id=False, token_id=False, **kwargs):
     payment_id = request.env['payment.transaction'].sudo().browse(payment_id)
     if kwargs.get('token-id'):
         payment_id.token_id = kwargs.get('token-id') 
     payment_id.cxpay_s2s_do_transaction_verify()
     payment_id.payment_token_id.cvv_no = False
     PaymentProcessing.add_payment_transaction(payment_id)
     return http.redirect_with_hash('/payment/process')
Ejemplo n.º 16
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)
Ejemplo n.º 17
0
Archivo: main.py Proyecto: bud-e/odoo
    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)
Ejemplo n.º 18
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')
Ejemplo n.º 19
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)
Ejemplo n.º 20
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)
Ejemplo n.º 21
0
    def invoice_pay_form(self,
                         acquirer_id,
                         invoice_id,
                         save_token=False,
                         access_token=None,
                         **kwargs):
        """ Json method that creates a payment.transaction, used to create a
        transaction when the user clicks on 'pay now' button on the payment
        form.

        :return html: form containing all values related to the acquirer to
                      redirect customers to the acquirer website """
        invoice_sudo = request.env['account.move'].sudo().browse(invoice_id)
        if not invoice_sudo:
            return False

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

        if request.env.user._is_public():
            save_token = False  # we avoid to create a token for the public user

        success_url = kwargs.get(
            'success_url', "%s?%s" %
            (invoice_sudo.access_url, url_encode(
                {'access_token': access_token}) if access_token else ''))
        vals = {
            'acquirer_id': acquirer_id,
            'return_url': success_url,
        }

        if save_token:
            vals['type'] = 'form_save'

        transaction = invoice_sudo._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(transaction)

        return transaction.render_invoice_button(
            invoice_sudo,
            submit_txt=_('Pay & Confirm'),
            render_values={
                'type':
                'form_save' if save_token else 'form',
                'alias_usage':
                _('If we store your payment information on our server, subscription payments will be made automatically.'
                  ),
            })
Ejemplo n.º 22
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
Ejemplo n.º 23
0
    def payment_transaction_token(self,
                                  acquirer_id,
                                  order_id,
                                  save_token=False,
                                  access_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

        order = request.env['sale.order'].sudo().browse(order_id)
        if not order or not order.order_line or not order.has_to_be_paid():
            return False

        # Create transaction
        vals = {
            'acquirer_id': acquirer_id,
            'type': order._get_payment_type(),
            'return_url': order.get_portal_url(),
        }

        transaction = order._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(transaction)
        return transaction.render_sale_button(
            order,
            submit_txt=_('Pay & Confirm'),
            render_values={
                'type':
                order._get_payment_type(),
                'alias_usage':
                _('If we store your payment information on our server, subscription payments will be made automatically.'
                  ),
            })
Ejemplo n.º 24
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)
Ejemplo n.º 25
0
    def payment(self, account_id, uuid=None, **kw):
        account_res = request.env['sale.subscription']
        invoice_res = request.env['account.move']
        get_param = ''
        if uuid:
            account = account_res.sudo().browse(account_id)
            if uuid != account.uuid:
                raise NotFound()
        else:
            account = account_res.browse(account_id)

        # no change
        if int(kw.get('pm_id', 0)) > 0:
            account.payment_token_id = int(kw['pm_id'])

        # if no payment has been selected for this account, then we display redirect to /my/subscription with an error message
        if len(account.payment_token_id) == 0:
            get_param = 'message=No payment method have been selected for this subscription.&message_class=alert-danger'
            return request.redirect('/my/subscription/%s/%s?%s' %
                                    (account.id, account.uuid, get_param))

        # we can't call _recurring_invoice because we'd miss 3DS, redoing the whole payment here
        payment_token = account.payment_token_id
        if payment_token:
            invoice_values = account.sudo()._prepare_invoice()
            new_invoice = invoice_res.sudo().create(invoice_values)
            tx = account.sudo().with_context(off_session=False)._do_payment(
                payment_token, new_invoice)[0]
            PaymentProcessing.add_payment_transaction(tx)
            if tx.html_3ds:
                return tx.html_3ds
            get_param = self.payment_succes_msg if tx.renewal_allowed else self.payment_fail_msg
            if tx.renewal_allowed:
                account.send_success_mail(tx, new_invoice)
                msg_body = 'Manual payment succeeded. Payment reference: <a href=# data-oe-model=payment.transaction data-oe-id=%d>%s</a>; Amount: %s. Invoice <a href=# data-oe-model=account.move data-oe-id=%d>View Invoice</a>.' % (
                    tx.id, tx.reference, tx.amount, new_invoice.id)
                account.message_post(body=msg_body)
            elif tx.state != 'pending':
                # a pending status might indicate that the customer has to authenticate, keep the invoice for post-processing
                # NOTE: this might cause a lot of draft invoices to stay alive; i'm afraid this can't be helped
                #       since the payment flow is divided in 2 in that case and the draft invoice must survive after the request
                new_invoice.unlink()

        return request.redirect('/payment/process')
    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')
Ejemplo n.º 27
0
    def yoco_verify_charge(self, **post):
        """ Verify a payment transaction

        Expects the result from the user input from flwpbf-inline.js popup"""
        TX = request.env['payment.transaction']
        tx = None
        data = {
            'acquirer_id': post.get('acquirer_id'),
            'token': post.get('token'),
            'amount': round(post.get('amount'), 2),
            'currency': post.get('currency')
        }
        if post.get('tx_ref'):
            tx = TX.sudo().search([('reference', '=', post.get('tx_ref'))])
        if not tx:
            tx_id = (post.get('id')
                     or request.session.get('sale_transaction_id')
                     or request.session.get('website_payment_tx_id'))
            tx = TX.sudo().browse(int(tx_id))
        if not tx:
            raise werkzeug.exceptions.NotFound()

        if tx.type == 'form_save' and tx.partner_id:
            payment_token_id = request.env['payment.token'].sudo().create({
                'acquirer_id':
                tx.acquirer_id.id,
                'partner_id':
                tx.partner_id.id,
            })
            tx.payment_token_id = payment_token_id
            response = tx._yoco_verify_charge(data)
        else:
            response = tx._yoco_verify_charge(data)
        _logger.info('Yoco: entering form_feedback with post data %s',
                     pprint.pformat(response))
        if response:
            request.env['payment.transaction'].sudo().with_context(
                lang=None).form_feedback(post, 'yoco')
        # add the payment transaction into the session to let the page /payment/process to handle it
        PaymentProcessing.add_payment_transaction(tx)
        return "/payment/process"
Ejemplo n.º 28
0
    def payment_transaction_token(self, acquirer_id, order_id, save_token=False, access_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

        order = request.env['sale.order'].sudo().browse(order_id)
        if not order or not order.order_line or not order.has_to_be_paid():
            return False

        # Create transaction
        vals = {
            'acquirer_id': acquirer_id,
            'type': order._get_payment_type(),
            'return_url': order.get_portal_url(),
        }

        transaction = order._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(transaction)
        return transaction.render_sale_button(
            order,
            submit_txt=_('Pay & Confirm'),
            render_values={
                'type': order._get_payment_type(),
                'alias_usage': _('If we store your payment information on our server, subscription payments will be made automatically.'),
            }
        )
Ejemplo n.º 29
0
    def invoice_pay_token(self, invoice_id, pm_id=None, **kwargs):
        """ Use a token to perform a s2s transaction """
        error_url = kwargs.get('error_url', '/my')
        access_token = kwargs.get('access_token')
        params = {}
        if access_token:
            params['access_token'] = access_token

        invoice_sudo = request.env['account.move'].sudo().browse(
            invoice_id).exists()
        if not invoice_sudo:
            params['error'] = 'pay_invoice_invalid_doc'
            return request.redirect(_build_url_w_params(error_url, params))

        success_url = kwargs.get(
            'success_url', "%s?%s" %
            (invoice_sudo.access_url, url_encode(
                {'access_token': access_token}) if access_token else ''))
        try:
            token = request.env['payment.token'].sudo().browse(int(pm_id))
        except (ValueError, TypeError):
            token = False
        token_owner = invoice_sudo.partner_id if request.env.user._is_public(
        ) else request.env.user.partner_id
        if not token or token.partner_id != token_owner:
            params['error'] = 'pay_invoice_invalid_token'
            return request.redirect(_build_url_w_params(error_url, params))

        vals = {
            'payment_token_id': token.id,
            'type': 'server2server',
            'return_url': _build_url_w_params(success_url, params),
        }

        tx = invoice_sudo._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(tx)

        params['success'] = 'pay_invoice'
        return request.redirect('/payment/process')
Ejemplo n.º 30
0
    def invoice_pay_form(self, acquirer_id, invoice_id, save_token=False, access_token=None, **kwargs):
        """ Json method that creates a payment.transaction, used to create a
        transaction when the user clicks on 'pay now' button on the payment
        form.

        :return html: form containing all values related to the acquirer to
                      redirect customers to the acquirer website """
        success_url = kwargs.get('success_url', '/my')

        invoice_sudo = request.env['account.invoice'].sudo().browse(invoice_id)
        if not invoice_sudo:
            return False

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

        if request.env.user._is_public():
            save_token = False # we avoid to create a token for the public user
        vals = {
            'acquirer_id': acquirer_id,
            'return_url': success_url,
        }

        if save_token:
            vals['type'] = 'form_save'

        transaction = invoice_sudo._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(transaction)

        return transaction.render_invoice_button(
            invoice_sudo,
            submit_txt=_('Pay & Confirm'),
            render_values={
                'type': 'form_save' if save_token else 'form',
                'alias_usage': _('If we store your payment information on our server, subscription payments will be made automatically.'),
            }
        )
Ejemplo n.º 31
0
Archivo: main.py Proyecto: EdyKend/odoo
    def ogone_s2s_create(self, **post):
        error = ''
        acq = request.env['payment.acquirer'].browse(int(post.get('acquirer_id')))
        try:
            token = acq.s2s_process(post)
        except Exception as e:
            # synthax error: 'CHECK ERROR: |Not a valid date\n\n50001111: None'
            token = False
            error = str(e).splitlines()[0].split('|')[-1] or ''

        if token and post.get('verify_validity'):
            baseurl = request.env['ir.config_parameter'].sudo().get_param('web.base.url')
            params = {
                'accept_url': baseurl + '/payment/ogone/validate/accept',
                'decline_url': baseurl + '/payment/ogone/validate/decline',
                'exception_url': baseurl + '/payment/ogone/validate/exception',
                'return_url': post.get('return_url', baseurl)
                }
            tx = token.validate(**params)
            if tx and tx.html_3ds:
                return tx.html_3ds
            # add the payment transaction into the session to let the page /payment/process to handle it
            PaymentProcessing.add_payment_transaction(tx)
        return werkzeug.utils.redirect("/payment/process")
Ejemplo n.º 32
0
    def payment_token(self, order_id, pm_id=None, **kwargs):

        order = request.env['sale.order'].sudo().browse(order_id)
        if not order:
            return request.redirect("/my/orders")
        if not order.order_line or pm_id is None or not order.has_to_be_paid():
            return request.redirect(order.get_portal_url())

        # try to convert pm_id into an integer, if it doesn't work redirect the user to the quote
        try:
            pm_id = int(pm_id)
        except ValueError:
            return request.redirect(order.get_portal_url())

        # Create transaction
        vals = {
            'payment_token_id': pm_id,
            'type': 'server2server',
            'return_url': order.get_portal_url(),
        }

        tx = order._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(tx)
        return request.redirect('/payment/process')
Ejemplo n.º 33
0
    def payment_token(self, order_id, pm_id=None, **kwargs):

        order = request.env['sale.order'].sudo().browse(order_id)
        if not order:
            return request.redirect("/my/orders")
        if not order.order_line or pm_id is None or not order.has_to_be_paid():
            return request.redirect(order.get_portal_url())

        # try to convert pm_id into an integer, if it doesn't work redirect the user to the quote
        try:
            pm_id = int(pm_id)
        except ValueError:
            return request.redirect(order.get_portal_url())

        # Create transaction
        vals = {
            'payment_token_id': pm_id,
            'type': 'server2server',
            'return_url': order.get_portal_url(),
        }

        tx = order._create_payment_transaction(vals)
        PaymentProcessing.add_payment_transaction(tx)
        return request.redirect('/payment/process')
Ejemplo n.º 34
0
    def transaction(self,
                    acquirer_id,
                    reference,
                    amount,
                    currency_id,
                    partner_id=False,
                    **kwargs):
        acquirer = request.env["payment.acquirer"].browse(acquirer_id)
        order_id = kwargs.get("order_id")
        # BizzAppDev Customization Start
        invoice_id = kwargs.get("invoice_id")
        # BizzAppDev Customization End

        reference_values = (order_id and {
            "sale_order_ids": [(4, order_id)]
        } or {})
        # BizzAppDev Customization Start
        if invoice_id:
            reference_values.update({"invoice_ids": [(4, int(invoice_id))]})
        # BizzAppDev Customization End

        reference = request.env["payment.transaction"]._compute_reference(
            values=reference_values, prefix=reference)

        values = {
            "acquirer_id":
            int(acquirer_id),
            "reference":
            reference,
            "amount":
            float(amount),
            "currency_id":
            int(currency_id),
            "partner_id":
            partner_id,
            "type":
            "form_save"
            if acquirer.save_token != "none" and partner_id else "form",
        }

        if order_id:
            values["sale_order_ids"] = [(6, 0, [order_id])]
        # BizzAppDev Customization Start
        if invoice_id:
            values["invoice_ids"] = [(6, 0, [invoice_id])]
        # BizzAppDev Customization End
        reference_values = (order_id and {
            "sale_order_ids": [(4, order_id)]
        } or {})
        if invoice_id:
            reference_values.update({"invoice_ids": [(4, int(invoice_id))]})
        reference_values.update(acquirer_id=int(acquirer_id))
        values["reference"] = request.env[
            "payment.transaction"]._compute_reference(values=reference_values,
                                                      prefix=reference)
        tx = (request.env["payment.transaction"].sudo().with_context(
            lang=None).create(values))
        tx = request.env["payment.transaction"].sudo().browse(tx.id)
        secret = (request.env["ir.config_parameter"].sudo().get_param(
            "database.secret"))
        token_str = "%s%s%s" % (
            tx.id,
            tx.reference,
            round(tx.amount, tx.currency_id.decimal_places),
        )
        token = hmac.new(secret.encode("utf-8"), token_str.encode("utf-8"),
                         hashlib.sha256).hexdigest()
        tx.return_url = "/website_payment/confirm?tx_id=%d&access_token=%s" % (
            tx.id,
            token,
        )

        PaymentProcessing.add_payment_transaction(tx)
        render_values = {
            "partner_id": partner_id,
        }
        return acquirer.sudo().render(tx.reference,
                                      float(amount),
                                      int(currency_id),
                                      values=render_values)
Ejemplo n.º 35
0
    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")
Ejemplo n.º 36
0
    def payment_token(self, pm_id=None, **kwargs):
        """ OVERRIDING METHOD FROM odoo/addons/website_sale/controllers/main.py
        Method that handles payment using saved tokens
        :param int pm_id: id of the payment.token that we want to use to pay.

        This route is requested after payment submission :
            /shop/payment/solana/submit - it's only called if the buyer doesn't provide an existing payment token
        """

        # order already created, get it
        sales_order = request.website.sale_get_order()
        _logger.info(f'received token for sales_order: {sales_order.id}')
        _logger.info(f'processing token for sales_order: {sales_order.id}')

        # do not crash if the user has already paid and try to pay again
        if not sales_order:
            _logger.error('no order found')
            return request.redirect('/shop/?error=no_order')

        # see overriden method
        assert sales_order.partner_id.id != request.website.partner_id.id

        try:
            # pm_id is passed, make sure it's a valid int
            pm_id = int(pm_id)
        except ValueError:
            _logger.error('invalid token id')
            return request.redirect('/shop/?error=invalid_token_id')

        # payment token already created, get it
        token = request.env['payment.token'].sudo().browse(pm_id)

        if not token:
            return request.redirect('/shop/?error=token_not_found')

        # has the transaction already been created?
        tx_id = request.session["__website_sale_last_tx_id"]
        if tx_id:
            # transaction was already established in /shop/payment/solana/submit
            transaction = request.env['payment.transaction'].sudo().browse(
                tx_id)
            PaymentProcessing.add_payment_transaction(transaction)
            # clear the tx in session, because we're done with it
            request.session["__website_sale_last_tx_id"] = None
            return request.redirect('/shop/payment/validate')
        else:
            # transaction hasn't been created
            tx_val = {
                'payment_token_id': pm_id,
                'return_url': '/shop/payment/validate'
            }
            transaction = sales_order._create_payment_transaction(tx_val)
            _logger.info(
                f'created transaction: {transaction.id} for payment token: {token.id}'
            )
            _logger.info(f'token.acquirer_ref = {token.acquirer_ref}')
            if transaction.acquirer_id.is_cryptocurrency:
                _logger.info(
                    f'Processing cryptocurrency payment acquirer: {transaction.acquirer_id.name}'
                )
                _logger.info(
                    f'setting sales_order state to "sent" for sales_order: {sales_order.id}'
                )
                sales_order.sudo().update({'state': 'sent'})
                _logger.info(
                    f'setting transaction state to "pending" for sales_order: {sales_order.id}'
                )
                transaction.sudo().update({'state': 'pending'})
                PaymentProcessing.add_payment_transaction(transaction)
                return request.redirect('/shop/payment/validate')

            PaymentProcessing.add_payment_transaction(transaction)
            return request.redirect('/payment/process')
Ejemplo n.º 37
0
    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
Ejemplo n.º 38
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')
Ejemplo n.º 39
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
Ejemplo n.º 40
0
    def payment_token(self, pm_id=None, **kwargs):
        """OVERRIDING METHOD FROM odoo/addons/website_sale/controllers/main.py
        Method that handles payment using saved tokens
        :param int pm_id: id of the payment.token that we want to use to pay.

        This route is requested after payment submission :
            /shop/payment/monero/submit - it's called everytime,
            since we will use monero sub addresses
            as one time addresses
        """

        # order already created, get it
        sales_order = request.website.sale_get_order()
        _logger.info(f"received token for sales_order: {sales_order.id}")
        _logger.info(f"processing token for sales_order: {sales_order.id}")

        # do not crash if the user has already paid and try to pay again
        if not sales_order:
            _logger.error("no order found")
            return request.redirect("/shop/?error=no_order")

        # see overriden method
        assert sales_order.partner_id.id != request.website.partner_id.id

        try:
            # pm_id is passed, make sure it's a valid int
            pm_id = int(pm_id)
        except ValueError:
            _logger.error("invalid token id")
            return request.redirect("/shop/?error=invalid_token_id")

        # payment token already created, get it
        token = request.env["payment.token"].sudo().browse(pm_id)

        if not token:
            return request.redirect("/shop/?error=token_not_found")

        # has the transaction already been created?
        tx_id = request.session["__website_sale_last_tx_id"]
        if tx_id:
            # transaction was already
            # established in /shop/payment/monero/submit
            transaction = request.env["payment.transaction"].sudo().browse(
                tx_id)
            PaymentProcessing.add_payment_transaction(transaction)
            # clear the tx in session, because we're done with it
            request.session["__website_sale_last_tx_id"] = None
            return request.redirect("/shop/payment/validate")
        else:
            # transaction hasn't been created
            tx_val = {
                "payment_token_id": pm_id,
                "return_url": "/shop/payment/validate"
            }
            transaction = sales_order._create_payment_transaction(tx_val)
            _logger.info(f"created transaction: {transaction.id} "
                         f"for payment token: {token.id}")
            if transaction.acquirer_id.is_cryptocurrency:
                _logger.info(
                    f"Processing cryptocurrency "
                    f"payment acquirer: {transaction.acquirer_id.name}")
                _logger.info(f"setting sales_order state to "
                             f'"sent" for sales_order: {sales_order.id}')
                sales_order.sudo().update({"state": "sent"})
                _logger.info(f"setting transaction state to "
                             f'"pending" for sales_order: {sales_order.id}')
                transaction.sudo().update({"state": "pending"})
                PaymentProcessing.add_payment_transaction(transaction)
                return request.redirect("/shop/payment/validate")

            PaymentProcessing.add_payment_transaction(transaction)
            return request.redirect("/payment/process")