PAYATHON 2026

如何在 C# 中使用 XeroCoreApi 获取 invoice URL?

支付小周

结论

普通的 Invoice 对象不能直接作为发票页面 URL。付款创建成功后,需要调用 Xero 的 Online Invoice 接口获取 OnlineInvoiceUrl,再将用户重定向到这个地址。

如果当前使用的 XeroCoreApi 版本提供 OnlineInvoice 方法,可以这样写:

Payment createdPayment = _api.Payments.Create(payment);

OnlineInvoice onlineInvoice =
    _api.Invoices.OnlineInvoice(payingInvoice.InvoiceID);

Response.Redirect(onlineInvoice.OnlineInvoiceUrl);

完整示例

Invoice payingInvoice = _api.Invoices.Find("xyz");

Payment payment = new Payment
{
    Invoice = payingInvoice,
    Account = new Account
    {
        Code = "xyz"
    },
    Amount = "xyz",
    Date = DateTime.Now
};

Payment createdPayment = _api.Payments.Create(payment);

OnlineInvoice onlineInvoice =
    _api.Invoices.OnlineInvoice(payingInvoice.InvoiceID);

if (onlineInvoice != null &&
    !string.IsNullOrWhiteSpace(onlineInvoice.OnlineInvoiceUrl))
{
    Response.Redirect(onlineInvoice.OnlineInvoiceUrl);
}
else
{
    // 根据业务需要跳转到付款结果页,或提示无法取得在线发票链接
    Response.Redirect("/payment/success");
}

这里要使用 Xero 返回的 InvoiceID,不能使用发票编号 InvoiceNumber。如果 "xyz" 是发票编号,应先查出对应的 Invoice,再用它的 InvoiceID 请求在线发票地址。

为什么不能直接拼接 URL

Xero API 中的发票数据与 Xero 网页端的页面地址并不是同一个概念:

  • Invoice 保存发票的业务数据。
  • OnlineInvoiceUrl 是供客户查看的在线发票链接。
  • Xero 后台管理页面的地址属于界面实现细节,不应根据组织 ID、发票 ID 等信息自行拼接。

因此,应通过 Online Invoice 接口获取 Xero 生成的链接,不要写死或猜测网页地址。

不同 SDK 版本的差异

不同版本的 XeroCoreApi 可能采用不同的方法名称。有些版本可能不提供:

_api.Invoices.OnlineInvoice(invoiceId)

遇到这种情况,可以升级 SDK,或者直接调用底层 Accounting API 的在线发票端点:

GET /Invoices/{InvoiceID}/OnlineInvoice

再从响应的 OnlineInvoiceUrl 字段中读取地址。具体写法取决于项目实际引用的 Xero SDK 版本。

注意事项

  • 确认 _api.Payments.Create(payment) 成功后再跳转。
  • 不要根据 Payment 的创建结果推测发票 URL。在线发票链接需要单独获取。
  • OnlineInvoiceUrl 通常是可分享链接,不要将它写入日志,也不要暴露给无关用户。
  • 如果接口未返回有效 URL,应跳转到付款成功页作为后备处理,避免用户看到空白页或异常。
  • payment.Amount 的实际类型取决于 SDK 版本。如果该属性是 decimal 类型,应传入 100.00m 这样的数值,而不是字符串。
  • 如果业务需要的是供工作人员使用的 Xero 后台发票编辑页面,而非客户查看的在线发票页面,OnlineInvoiceUrl 并不适用。Xero API 通常不会将后台界面 URL 作为稳定的 API 字段返回。

备注:内容仅供参考。