示例#1
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))
示例#2
0
文件: main.py 项目: 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')
示例#3
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')
示例#4
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')
示例#5
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"
示例#6
0
文件: main.py 项目: 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"
示例#7
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')
示例#8
0
文件: payment.py 项目: Gorrice/odoo
    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))
示例#9
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.'),
            }
        )
示例#10
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")
示例#11
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')
示例#12
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)
示例#13
0
文件: main.py 项目: 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)
示例#14
0
文件: payment.py 项目: waqas36/odoo
    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.'
                  ),
            })
示例#15
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
示例#16
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.'
                  ),
            })
示例#17
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)
示例#18
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')
示例#19
0
文件: main.py 项目: eshiofune/dk-roma
    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"
示例#20
0
文件: payment.py 项目: Gorrice/odoo
    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.'),
            }
        )
示例#21
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.'),
            }
        )
示例#22
0
文件: payment.py 项目: waqas36/odoo
    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')
示例#23
0
文件: main.py 项目: 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")
示例#24
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')
示例#25
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')
示例#26
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')

        reference_values = order_id and {
            'sale_order_ids': [(4, order_id)]
        } or {}
        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])]

        reference_values = order_id and {
            'sale_order_ids': [(4, order_id)]
        } or {}
        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)
        secret = request.env['ir.config_parameter'].sudo().get_param(
            'database.secret')
        token_str = '%s%s%s' % (
            tx.id, tx.reference,
            float_repr(tx.amount,
                       precision_digits=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,
        }
        if not order_id:
            acquirer = acquirer.with_context(stripe_fees=True)
        return acquirer.sudo().render(tx.reference,
                                      float(amount),
                                      int(currency_id),
                                      values=render_values)
示例#27
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)
示例#28
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')
示例#29
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
示例#30
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
示例#31
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")