PAYATHON 2026

2019R2 REST API 创建 SalesOrder 时无法同时添加 Payment

支付老李

结论

在 Acumatica 2019 R2 中,可以通过一次 PUT SalesOrder 请求创建 SalesOrder,同时在 Payments 集合中创建一张新的 AR Payment,并将其应用到订单。

需要注意 ReferenceNbr 的区别:

  • 不提供 ReferenceNbr:系统会尝试创建新的 Payment。
  • 提供 ReferenceNbr:系统会查找并应用已有的 Payment。
  • PaymentMethod: "CC" 不代表信用卡已经完成收款。它通常还依赖客户支付方式、处理中心、现金账户,以及可能需要的支付令牌配置。只传 "CC" 和 PaymentRef,很容易在 ARPaymentEntry.Persist() 阶段失败。
  • PXOuterException 说明 Payment 的某个字段没有通过业务校验,但当前响应并未返回具体的字段错误。因此,不能仅凭这段异常判断 JSON 结构有误。

建议先选择一个已确认支持手工录入且不依赖信用卡处理中心的支付方式,例如 CASH 或 CHECK,用它验证单请求流程。成功后,再处理 CC 所需的支付配置和交易流程。

最小化请求示例

下面的最小请求用于验证创建订单、创建 Payment,并将 Payment 应用到订单的完整流程。客户、库存、支付方式和现金账户都必须替换为当前站点中真实有效且相互匹配的值。

PUT /entity/Default/18.200.001/SalesOrder
Content-Type: application/json
{
  "OrderType": {
    "value": "SO"
  },
  "CustomerID": {
    "value": "35"
  },
  "Description": {
    "value": "ecommerce order"
  },
  "Details": [
    {
      "InventoryID": {
        "value": "item1"
      },
      "OrderQty": {
        "value": 1
      },
      "UOM": {
        "value": "EA"
      },
      "UnitPrice": {
        "value": 320.00
      }
    }
  ],
  "Payments": [
    {
      "DocType": {
        "value": "Payment"
      },
      "PaymentMethod": {
        "value": "CASH"
      },
      "CashAccount": {
        "value": "MERCHANT"
      },
      "PaymentRef": {
        "value": "ECOM-12345"
      },
      "PaymentAmount": {
        "value": 326.00
      },
      "AppliedToOrder": {
        "value": 326.00
      }
    }
  ]
}

如果该支付方式要求填写支付参考号,PaymentRef 应使用符合其规则的外部参考号。创建新 Payment 时不要填写 ReferenceNbr,因为这个字段表示 Acumatica 中已经存在的 AR Payment 编号。

最小请求成功后,再逐项加入地址覆盖、运费、税额和其他订单字段。这样更容易区分订单字段错误和支付字段错误。

为什么原请求容易失败

异常最终出现在:

PX.Objects.AR.ARPaymentEntry.Persist()

同时显示:

Inserting 'AR Payment' record raised at least one error.

这说明 SalesOrder 已进入保存流程,但新建的 AR Payment 没有通过 Acumatica 的业务校验。应重点检查以下几项。

1. CC 支付方式需要额外配置

如果 "CC" 表示信用卡支付方式,通常需要满足以下条件:

  • Payment Method 已启用,并允许用于 Accounts Receivable。
  • MERCHANT Cash Account 已与该 Payment Method 关联。
  • 当前分支可以使用该 Payment Method。
  • 客户拥有适用的 Customer Payment Method,或者当前业务流程允许不指定客户支付实例。
  • 如果启用了集成支付处理,还需要满足 Processing Center、支付令牌和交易状态方面的要求。

PaymentRef: "12345" 只是支付参考号,不能替代信用卡令牌、授权或捕获交易。

排查时,可以先将 CC 改为不需要处理中心的支付方式。如果同一请求改用 CASH 或 CHECK 后能够成功,问题就在信用卡支付配置或处理流程,而不是 Payments JSON 集合本身。

2. Payment Method 与 Cash Account 必须匹配

即使 MERCHANT Cash Account 确实存在,也不代表它能与任意 Payment Method 搭配使用。可以先在界面中手工创建一张客户、支付方式和现金账户均与请求相同的 AR Payment。

如果界面中也报错,应先修正站点配置。如果界面可以保存,则记录系统自动填入的字段,再与 REST 请求逐项对比。

3. Payment 与 Prepayment 不能随意互换

DocType 必须使用端点元数据接受的枚举值,并与实际业务用途一致:

"DocType": {
  "value": "Payment"
}

或:

"DocType": {
  "value": "Prepayment"
}

两者都会创建 AR 文档,但适用的业务规则并不完全相同。诊断时建议先使用普通 Payment,避免同时触发预付款特有的配置和校验条件。

4. 应用金额不能违反订单和支付余额规则

金额通常需要满足:

AppliedToOrder <= PaymentAmount
AppliedToOrder <= 当前允许应用到订单的金额

原请求中的两个金额都是 326.00,数值上没有超过 Payment Amount,但仍需确认订单货币、支付货币、订单余额,以及站点对超额应用的限制。

不要用 $1 之类的测试金额来判断 API 是否支持嵌套 Payment。即使请求失败,原因也可能是 Payment Method、Cash Account 或客户配置,与应用金额无关。

信用卡交易的正确边界

通过 Payments 集合创建 AR Payment,不一定会执行信用卡授权或捕获。这些操作需要分开看:

  1. 创建 AR Payment 记录;
  2. 对信用卡执行 authorize、capture,或导入外部交易;
  3. 将 Payment 应用到 SalesOrder。

如果 ecommerce 平台已经通过外部支付网关完成收款,可以考虑使用专门的支付方式记录外部结算,并把网关交易号写入 PaymentRef。这个支付方式是否应该配置为 CC,取决于当前 Acumatica 站点的支付处理设计。

如果需要由 Acumatica 调用 Processing Center 完成信用卡授权或捕获,通常还要执行对应的 Action,不能假定嵌套的 Payments 数组会自动完成整个信用卡处理流程。2019 R2 中可用的具体 Action 和字段,应以当前实例发布的 Endpoint 定义为准。

关于 $expand=Payments 返回空数组

$expand=Payments 返回空数组,不能证明订单没有关联 Payment。还需要分别确认:

  • AR Payment 文档是否存在;
  • Payment 是否已生成针对该 SalesOrder 的应用记录;
  • 当前 Endpoint 是否正确映射了 Payments 子实体;
  • 当前 2019 R2 构建版本是否存在该子实体的读取问题。

可以按以下方式检查:

  1. 在 AR Payment 界面中,通过 PaymentRef 或 Payment 的 ReferenceNbr 查找文档;
  2. 检查 Payment 的 Applications 中是否包含目标 SalesOrder;
  3. 检查 Web Service Endpoints 中 SalesOrder/Payments 的字段和关系映射;
  4. 直接查询 AR Payment 实体,不要只依赖 SalesOrder?$expand=Payments。

推荐排查顺序

先发送一个最小请求,只包含订单头、一个明细行和一个使用 CASH 或 CHECK 的 Payment。请求成功后,按下面的顺序逐步恢复字段:

  1. 地址和联系人覆盖;
  2. Shipping Settings;
  3. Freight 和 Tax;
  4. 实际 Payment Method;
  5. 最后切换到 CC,并加入相应的客户支付方式或处理中心配置。

如果最小请求仍然失败,应在 Acumatica Trace 中查看 PXOuterException 包含的内部字段错误。REST 响应中的 Operation failed 只是外层错误信息,真正原因通常是某个明确的业务错误,例如:

Payment Method cannot be found.
Cash Account is not associated with the Payment Method.
Payment Reference is required.
Customer Payment Method is required.
The document is out of balance.

这些只是常见错误类型,不表示当前实例一定会返回其中某一条。最终原因应以 Trace 记录的字段级错误为准。

因此,无须强制把流程拆成先创建 SalesOrder、再创建 Payment 两个请求。单请求能否成功,取决于 Payment Method 是否允许直接创建 AR Payment。对于需要信用卡授权、捕获或令牌化的场景,额外的支付处理步骤仍可能无法省略。

备注:内容仅供参考。