Odoo的骚操作——json请求,http跳转

碰到odoo的一个骚操作,为什么说它骚,因为我们知道,一般json请求的返回值是json,然后由前端js来处理跳转之类的动作。如果请求是http,那么跳转之类的动作由浏览器根据返回值处理。odoo这个地方骚劲在于,前端的请求是以json方式进来的,它没有返回json,而是返回了一串bytes字节,然后页面居然跳转了。

具体内部机制有待进一步探究,先把代码放这里,给以后的开发留一个思路。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# website_sale/controllers/main.py
@http.route(['/shop/payment/transaction/',
'/shop/payment/transaction/<int:so_id>',
'/shop/payment/transaction/<int:so_id>/<string:access_token>'], type='json', auth="public", website=True)
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
"""
tx_type = 'form'
if save_token:
tx_type = 'form_save'

# In case the route is called directly from the JS (as done in Stripe payment method)
if so_id and access_token:
order = request.env['sale.order'].sudo().search([('id', '=', so_id), ('access_token', '=', access_token)])
elif so_id:
order = request.env['sale.order'].search([('id', '=', so_id)])
else:
order = request.website.sale_get_order()
if not order or not order.order_line or acquirer_id is None:
return False

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

# find or create transaction
tx = request.website.sale_get_transaction() or request.env['payment.transaction'].sudo()
acquirer = request.env['payment.acquirer'].browse(int(acquirer_id))
payment_token = request.env['payment.token'].sudo().browse(int(token)) if token else None
tx = tx._check_or_create_sale_tx(order, acquirer, payment_token=payment_token, tx_type=tx_type)
request.session['sale_transaction_id'] = tx.id
return tx.render_sale_button(order, '/shop/payment/validate')

tx.render_sale_button方法的返回值类似如下值:

1
2
3
4
5
<input type="hidden" name="data_set" data-remove-me="" data-action-url="/payment/transfer/feedback"/>
<input type="hidden" name="return_url" value="shop/confirmation"/>
<input type="hidden" name="reference" value="S01205"/>
<input type="hidden" name="amount" value="648"/>
<input type="hidden" name="currency" value="CNY"/>