如何通过 Odoo API RPC 创建发票关联付款?
支付阿杰
结论
在 Odoo 11 中,为发票创建付款时,建议使用付款登记向导 account.register.payments,然后调用 create_payments()。调用时,需要通过 context 传入待付款发票:
{
'active_model': 'account.invoice',
'active_ids': [invoice_id],
'active_id': invoice_id
}
这套流程会创建 account.payment、过账付款,并核销付款与发票。单独调用 account.payment.create() 通常无法完成整个流程,因为新建的付款记录仍是草稿状态。
XML-RPC 示例
以下示例基于这些条件:
- 发票已经确认,状态为
open; invoice_id是account.invoice的记录 ID;journal_id是银行或现金日记账;payment_method_id是可用于收款的方法,例如手工付款方式;- 当前用户有创建和过账付款的权限。
import xmlrpc.client
from datetime import date
url = 'https://odoo.example.com'
db = 'your_database'
username = 'api@example.com'
password = 'your_password'
common = xmlrpc.client.ServerProxy(
'{}/xmlrpc/2/common'.format(url)
)
uid = common.authenticate(db, username, password, {})
if not uid:
raise RuntimeError('Odoo authentication failed')
models = xmlrpc.client.ServerProxy(
'{}/xmlrpc/2/object'.format(url)
)
invoice_id = 123
journal_id = 8
payment_method_id = 1
context = {
'active_model': 'account.invoice',
'active_ids': [invoice_id],
'active_id': invoice_id,
}
wizard_id = models.execute_kw(
db,
uid,
password,
'account.register.payments',
'create',
[{
'payment_date': date.today().strftime('%Y-%m-%d'),
'journal_id': journal_id,
'payment_method_id': payment_method_id,
}],
{
'context': context,
}
)
result = models.execute_kw(
db,
uid,
password,
'account.register.payments',
'create_payments',
[[wizard_id]],
{
'context': context,
}
)
print(result)
付款金额可以省略,向导通常会根据 active_ids 中未付发票的金额填入默认值。如果只支付部分金额,可以在创建向导时指定 amount:
wizard_id = models.execute_kw(
db,
uid,
password,
'account.register.payments',
'create',
[{
'amount': 500.00,
'payment_date': '2026-08-31',
'journal_id': journal_id,
'payment_method_id': payment_method_id,
'communication': 'INV/2026/001',
}],
{
'context': context,
}
)
查询可用的付款方式
不要默认 payment_method_id 一定是 1。可以先读取付款日记账允许使用的收款方式:
journal = models.execute_kw(
db,
uid,
password,
'account.journal',
'read',
[[journal_id]],
{
'fields': [
'name',
'type',
'inbound_payment_method_ids',
]
}
)[0]
print(journal)
处理客户发票付款时,应从 inbound_payment_method_ids 中选择一个 ID。退款和供应商付款的方向不同,可能需要使用 outbound_payment_method_ids。
也可以查询手工付款方式:
payment_methods = models.execute_kw(
db,
uid,
password,
'account.payment.method',
'search_read',
[[
['payment_type', '=', 'inbound'],
['code', '=', 'manual'],
]],
{
'fields': ['id', 'name', 'code', 'payment_type'],
'limit': 10,
}
)
print(payment_methods)
直接创建 account.payment
如果不使用向导,也可以直接创建 account.payment,将发票写入 invoice_ids,再调用 post():
payment_id = models.execute_kw(
db,
uid,
password,
'account.payment',
'create',
[{
'payment_type': 'inbound',
'partner_type': 'customer',
'partner_id': partner_id,
'amount': 500.00,
'currency_id': currency_id,
'journal_id': journal_id,
'payment_method_id': payment_method_id,
'payment_date': '2026-08-31',
'communication': 'INV/2026/001',
'invoice_ids': [(4, invoice_id, 0)],
}]
)
models.execute_kw(
db,
uid,
password,
'account.payment',
'post',
[[payment_id]]
)
其中:
'invoice_ids': [(4, invoice_id, 0)]
这是 Odoo 的关系字段命令,作用是把已有发票加入 invoice_ids,不会创建新发票。
普通客户发票通常使用:
'payment_type': 'inbound'
'partner_type': 'customer'
供应商账单付款通常使用:
'payment_type': 'outbound'
'partner_type': 'supplier'
直接创建付款时,需要自行确保合作伙伴、币种、金额、付款方向和日记账都与发票一致。使用 account.register.payments 向导通常更稳妥,也更接近 Odoo 后台点击“登记付款”按钮时执行的业务流程。
注意事项
- 发票必须已经确认,并处于可付款状态。草稿发票无法正常核销。
create_payments()接收向导记录 ID 列表,因此参数需要写成[[wizard_id]]。- 创建向导和调用
create_payments()时都应传入context,否则向导可能无法确定目标发票。 - 日期应使用
YYYY-MM-DD格式。 - 日记账一般应为
bank或cash类型。 - 多币种付款还可能受公司币种、付款日汇率和差额处理规则影响。
account.register.payments是临时模型,不应把向导记录 ID 当作最终付款 ID 保存。执行完成后,应在account.payment中查询实际生成的付款。- Odoo 11 的第三方模块可能会覆盖付款向导或增加必填字段。如果使用标准参数仍提示缺少字段,可以先通过
fields_get查看当前数据库中该模型的实际字段定义。
备注:内容仅供参考。
