You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Odoo13 自定义支付收单模块跳转流程开发问题咨询

Odoo 13 自定义支付收单模块实现方案

1. 支付收单配置模型继承

首先继承payment.acquirer新增收单平台所需的配置字段,示例代码:

# models/payment_acquirer.py
from odoo import models, fields
import requests

class PaymentAcquirerMoncash(models.Model):
    _inherit = 'payment.acquirer'

    provider = fields.Selection(
        selection_add=[('moncash', 'MonCash')],
        ondelete={'moncash': 'set default'}
    )
    moncash_merchant_id = fields.Char(string='商户ID', required_if_provider='moncash')
    moncash_secret_key = fields.Char(string='接口密钥', required_if_provider='moncash')
    moncash_api_base = fields.Char(string='收单平台接口根地址', default='https://收单平台接口域名')

2. 支付跳转链接生成逻辑

重写收单专属的表单参数生成方法,调用收单平台下单接口获取跳转链接,示例代码:

def moncash_form_generate_values(self, values):
    base_url = self.env['ir.config_parameter'].sudo().get_param('web.base.url')
    # 构造收单平台下单参数
    order_params = {
        'order_id': values['reference'],
        'amount': values['amount'],
        'currency': values['currency'].name,
        'notify_url': f"{base_url}/payment/moncash/callback",
        'return_url': f"{base_url}/payment/process",
    }
    # 请求收单平台下单接口获取支付跳转链接
    order_resp = requests.post(
        f"{self.moncash_api_base}/create_payment",
        json=order_params,
        auth=(self.moncash_merchant_id, self.moncash_secret_key)
    )
    order_data = order_resp.json()
    # 将支付链接传入前端模板
    values.update({
        'moncash_payment_url': order_data.get('payment_url'),
        'order_id': values['reference']
    })
    return values

新增前端支付表单模板,实现自动跳转逻辑,示例代码:

<!-- views/payment_templates.xml -->
<odoo>
    <template id="payment_moncash_form">
        <form t-att-action="moncash_payment_url" method="GET">
            <input type="hidden" name="orderID" t-att-value="order_id"/>
            <div class="text-center mt-3 mb-3">
                <p>正在跳转至支付页面,若未自动跳转请点击下方按钮</p>
                <button class="btn btn-primary" type="submit">立即支付</button>
            </div>
        </form>
        <script>
            document.addEventListener('DOMContentLoaded', function() {
                document.querySelector('form').submit();
            });
        </script>
    </template>
</odoo>

3. 异步回调接口实现

新增控制器处理收单平台的GET回调请求,主动核验交易状态后更新本地交易记录,示例代码:

# controllers/main.py
from odoo import http
from odoo.http import request
import logging

_logger = logging.getLogger(__name__)

class MoncashPaymentController(http.Controller):
    @http.route('/payment/moncash/callback', type='http', auth='public', methods=['GET'], csrf=False)
    def moncash_callback(self, **kw):
        order_id = kw.get('orderID')
        if not order_id:
            return 'FAIL: MISSING_ORDER_ID'
        # 查询对应交易记录
        tx = request.env['payment.transaction'].sudo().search([('reference', '=', order_id)], limit=1)
        if not tx:
            return 'FAIL: TRANSACTION_NOT_FOUND'
        # 主动调用收单平台查询接口核验交易真实性
        acquirer = tx.acquirer_id
        verify_resp = requests.get(
            f"{acquirer.moncash_api_base}/query_order",
            params={'orderID': order_id},
            auth=(acquirer.moncash_merchant_id, acquirer.moncash_secret_key)
        )
        verify_data = verify_resp.json()
        if verify_data.get('trade_status') == 'SUCCESS':
            tx._set_transaction_done()
            tx._post_process_after_done()
            return 'SUCCESS'
        else:
            tx._set_transaction_cancel()
            return 'FAIL: PAYMENT_FAILED'

4. 交易状态校验逻辑适配

继承payment.transaction模型,实现收单专属的交易匹配和校验方法:

# models/payment_transaction.py
from odoo import models, api
import requests

class PaymentTransactionMoncash(models.Model):
    _inherit = 'payment.transaction'

    @api.model
    def moncash_form_get_tx_from_data(self, data):
        order_id = data.get('orderID')
        return self.search([
            ('reference', '=', order_id),
            ('acquirer_id.provider', '=', 'moncash')
        ], limit=1)

    def moncash_form_validate(self, data):
        order_id = data.get('orderID')
        acquirer = self.acquirer_id
        # 核验交易状态
        verify_resp = requests.get(
            f"{acquirer.moncash_api_base}/query_order",
            params={'orderID': order_id},
            auth=(acquirer.moncash_merchant_id, acquirer.moncash_secret_key)
        )
        verify_data = verify_resp.json()
        if verify_data.get('trade_status') == 'SUCCESS':
            self._set_transaction_done()
            return True
        self._set_transaction_cancel(
            state_message=verify_data.get('fail_reason', '支付失败')
        )
        return False

注意事项

  • 所有第三方接口请求需要添加异常捕获逻辑,避免接口不可用时导致Odoo服务报错
  • 敏感配置字段建议使用Odoo加密存储能力,不要明文硬编码
  • 生产环境部署时需要确认收单平台的服务器IP段可以正常访问你的Odoo站点回调接口

内容的提问来源于stack exchange,提问作者Marceus jethro

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.27 03:06:01