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

如何在Xero中添加发票?排查‘验证异常’报错原因

分析Xero发票创建时"A validation exception occurred"错误的原因

从你提供的代码和问题描述来看,有几个明确的问题会触发Xero API的验证异常,我来逐一拆解分析:

1. 未先持久化关联的联系人(核心问题)

你代码里注释掉了api.Contacts.Create(newContact),却直接把本地创建的newContact关联到了发票上。Xero的API要求发票关联的联系人必须是已经存在于Xero系统中的实体——也就是说,你必须先调用API创建并保存联系人,拿到系统返回的已持久化联系人对象后,再将其关联到发票。

现在你的代码里,newContact只是一个本地内存对象,并没有同步到Xero系统,Xero无法识别这个未保存的联系人,自然会抛出验证异常。

2. 发票行项目的金额逻辑矛盾

看你代码里的LineItem设置:

li.LineAmount = Convert.ToDecimal("200.00");
li.Quantity = Convert.ToDecimal("1.0000");
li.UnitAmount = Convert.ToDecimal("50.00");

Xero的验证规则要求LineAmount必须等于UnitAmount * Quantity(无折扣场景下)。这里50 * 1 = 50,但你手动设置了LineAmount=200,两者数值不匹配,这会直接触发验证失败。你要么去掉手动设置的LineAmount(让Xero自动计算),要么确保三者的数值逻辑一致。

3. 关联的基础数据可能不存在

另外,还要检查以下基础数据是否在你的Xero账套中存在:

  • li.AccountCode = "200":这个科目代码是否已经在Xero中创建?
  • li.ItemCode = "100":这个商品/服务代码是否已存在于Xero系统?
    如果这些基础数据不存在,Xero API同样会返回验证异常。

修复后的代码示例

把上述问题修正后,代码可以调整成这样:

private void button1_Click(object sender, EventArgs e)
{
    try
    {
        var api = new Xero.Api.Example.Applications.Private.Core(false);
        
        // 1. 先创建并保存联系人,拿到系统返回的已持久化对象
        Contact newContact = new Contact();
        newContact.Name = "Orac";
        var savedContact = api.Contacts.Create(newContact);
        
        // 2. 创建发票并关联已保存的联系人
        Invoice newInvoice = new Invoice();
        newInvoice.Contact = savedContact;
        newInvoice.Date = System.DateTime.Now;
        newInvoice.DueDate = System.DateTime.Now.AddMonths(1);
        newInvoice.Status = Xero.Api.Core.Model.Status.InvoiceStatus.Authorised;
        newInvoice.Type = Xero.Api.Core.Model.Types.InvoiceType.AccountsReceivable;
        
        List<LineItem> lines = new List<LineItem>();
        LineItem li = new LineItem();
        li.Quantity = Convert.ToDecimal("1.0000");
        li.ItemCode = "100"; // 确认该ItemCode在Xero中存在
        li.Description = "Webdev inv test";
        li.AccountCode = "200"; // 确认该AccountCode在Xero中存在
        li.UnitAmount = Convert.ToDecimal("50.00");
        // 去掉手动设置的LineAmount,让Xero自动计算,或设置为50.00保持一致
        lines.Add(li);
        
        newInvoice.LineItems = lines;
        
        // 3. 调用API创建发票
        var savedInvoice = api.Invoices.Create(newInvoice);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
        // 建议打印ex.InnerException的内容,Xero通常会在内部异常里给出具体的验证错误细节
    }
}

另外,建议你在catch块中输出ex.InnerException的信息,Xero的API通常会在内部异常里给出更精准的验证失败原因(比如“联系人不存在”、“行项目金额不匹配”等),这能帮你更快定位问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.29 08:35:57