> ## Documentation Index
> Fetch the complete documentation index at: https://waffo.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# 税务集成

## 本章你能收获什么

读完本章，你可以：

* 根据你的商品定价方式，以及是否需要申报自己计算的税额，选择税前定价、两价齐传或含税定价。
* 知道哪些税项需要由 Waffo 配置，以及接入前需要确认哪些业务规则。
* 正确构造支付和退款请求，处理查询与 Webhook 中的金额变化、空值和错误。

一次性支付（`ONE_TIME_PAYMENT`）支持税前定价、两价齐传和含税定价三种方式。

下文的支付请求示例使用 [`POST /api/v1/order/create`](/docs/api-reference/order-create/create-new-order)，结果通过 [`POST /api/v1/order/inquiry`](/docs/api-reference/order-inquiry/order-inquiry) 查询。

Subscription 仅支持税前定价，不支持两价齐传和含税定价；请求字段请参阅 [Subscription 创建 API](/docs/api-reference/subscription-create/create-subscription)。

## 选择传参方式

先判断你的商品价格是否已经含税，再判断是否需要向 Waffo 申报你计算的税额。三种方式由请求中的金额字段组合决定。

| 你的业务需要 | 建议方式 | 为什么选择它 |
| - | - | - |
| 你维护税前商品价，希望 Waffo 根据适用配置和实际支付资料计算税 | 税前定价 | 你只提供税前金额；适用的用户税费会加入支付金额 |
| 你希望由自己的系统计算税额，并在支付前向用户展示税额和含税总价 | 两价齐传 | 你提交两价和国家；Waffo 按配置校验或接受申报值，并在后续支付流程计算最终税额 |
| 你维护的是含税总价，希望 Waffo 拆出税前价和税额 | 含税定价 | 你只提供含税总价，由 Waffo 完成拆分；不需要自己先拆税 |

自算税额时，请确认 [自算税额校验策略](#自算税额校验策略)。

传入含税价后，优惠、换汇和手续费仍可能影响用户最终实付金额。字段组合及示例见下文“集成细节”。

## 由 Waffo 配置的税项

以下税项由 Waffo 配置。请向 Waffo 说明所需的交易行为，并分别确认 Sandbox 和 Production 的配置。

| 配置项 | 可配置内容 | 对你的集成的影响 |
| - | - | - |
| 税服务范围 | `Calculation Only` / `Full Tax Service` | 决定 Waffo 是否负责税款缴纳，具体分工见 [税服务选项的区别](#税服务选项的区别) |
| 商品税类映射和默认税类 | 将商品名称映射到税类，并指定默认税类；未匹配时可拒绝交易或使用默认税类 | 请与 Waffo 确认 `goodsInfo.goodsName` 的映射及未匹配时的处理；名称变化可能影响计税 |
| 自算税额校验策略 | `Strict` / `Loose`，详见 [选项说明](#自算税额校验策略) | 仅适用于两价齐传，决定如何处理申报税额差异 |

### 税服务选项的区别

* **`Calculation Only`**：Waffo 计算税额并在支付时向用户代收，通过 Settlement 将代收税款划付给你；你负责向税务机关缴纳。拆税完成后，每笔税额可从 [订单查询 API](/docs/api-reference/order-inquiry/order-inquiry) 的 `orderTaxAmount` 和对应 Webhook 中读取。
* **`Full Tax Service`**：Waffo 负责税额计算、税款收取及缴纳；接入前请与 Waffo 确认适用范围和分工。

### 自算税额校验策略

此配置仅适用于两价齐传。税前定价和含税定价不使用这项申报税额校验。

**Strict**

比较你申报的税额与 Waffo 计算值。不一致时，可由 Waffo 配置为拒绝交易，或使用 Waffo 计算值覆盖。

**Loose**

接受申报税额，不与 Waffo 计算值比较。例如，税前价 `100.00`、含税价 `110.00` 时，申报税额为 `10.00`；`Loose` 接受该申报值，仍会检查金额组合、税配置及必需参数。

创建时接受申报值，不代表最终税额或用户实付已确定；请以订单查询或 Webhook 为准。

## 集成细节

### 准备接入

税配置由 Waffo 管理。接入前，请提供 Merchant ID、Sandbox 或 Production 环境、销售国家和商品类别，并确认该环境已具备所需的税协议和支付方式。

本页的含税价是订单币种下的价格。它不表示 Merchant 承担税，也不保证等于经过换汇、手续费和优惠处理后的用户实付金额。

### 创建订单传参

金额都使用字符串，币种取 `orderCurrency`。至少提供一个金额基数；含税价必须大于零，并符合币种精度要求。国家代码使用 ISO 3166-1 alpha-3，例如 `PHL`。详见 [金额与币种](/docs/zh/developer-docs/core-concepts/currency)。

| 方式 | `orderAmount` | `taxInfo.orderAmountInclTax` | `taxInfo.taxCountry` | 处理效果 |
| - | - | - | - | - |
| 税前定价 | 传税前价 | 不传 | 不传 | Waffo 根据匹配的配置计算税；适用的用户税费加入支付金额 |
| 两价齐传 | 传税前价 | 传含税价，且不小于税前价 | 必填 | Waffo 按配置处理两价差额所代表的申报税，再按实际支付流程计算最终税额 |
| 含税定价 | 不传 | 传含税总价 | 不传 | Waffo 从含税金额中拆出税；完成拆税后，`orderAmount` 变为税前金额 |

税前定价时，请省略整个 `taxInfo`；传空对象 `{}` 也会因字段组合不合法返回 `A0003`。省略 `taxInfo` 不代表要求免税。

以下 JSON 只展示创建订单请求中的税相关片段。你仍需补全 Merchant、支付方式、用户、请求标识、时间和签名等通用参数。

为比较三种方式，假设订单与支付币种均为 USD、适用税率为 10%、没有优惠和额外手续费。以下税率及金额仅用于解释计算，不代表 `PHL` 的实际税率或你的税协议；两价齐传的结果取决于你实际配置下的申报校验策略。

**税前定价**

```json theme={null}
{
  "orderCurrency": "USD",
  "orderAmount": "100.00"
}
```

在上述假设下，税为 `10.00`，用户支付 `110.00`。如果没有匹配的应税配置，不能仅凭此示例认定一定加收 `10.00`。

**两价齐传**

```json theme={null}
{
  "orderCurrency": "USD",
  "orderAmount": "100.00",
  "taxInfo": {
    "taxCountry": "PHL",
    "orderAmountInclTax": "110.00"
  }
}
```

两价差额 `10.00` 是你申报的税额。Waffo 按税协议的申报校验策略处理该差额，并检查可用支付方式。具体行为由 [自算税额校验策略](#自算税额校验策略) 决定。传入两价不会修改你的税率配置。

**含税定价**

```json theme={null}
{
  "orderCurrency": "USD",
  "taxInfo": {
    "orderAmountInclTax": "110.00"
  }
}
```

在上述假设下，拆税完成后返回税前价 `100.00` 和税额 `10.00`，不是在 `110.00` 上再加一次税。不要同时传 `orderAmount` 或 `taxCountry`。

### 读取支付结果

创建响应返回订单标识、状态和后续动作，不包含本节的税金额字段。创建订单后，请使用 [`POST /api/v1/order/inquiry`](/docs/api-reference/order-inquiry/order-inquiry) 读取这些字段。订单查询和 `PAYMENT_NOTIFICATION` 返回下表中的税字段；查询字段位于响应的 `data` 对象中，Webhook 外层结构请参阅 [事件类型文档](/docs/zh/developer-docs/webhook/event-types)。

| 字段 | 币种或含义 | 接入注意点 |
| - | - | - |
| `orderCurrency` | 订单币种 | `orderAmount`、`orderTaxAmount` 和含税订单金额都按此币种理解 |
| `orderAmount` | 拆税完成后的税前订单金额 | 含税定价尚未拆税时，可能暂为含税金额；不要从创建时的中间值推断最终税前价 |
| `orderTaxAmount` | 订单币种税额 | 可能为空。为空表示尚未拆分或无税结果，不能直接当作已确定的零税额 |
| `taxInfo.orderAmountInclTax` | 当前最终折后含税订单金额 | 两价齐传或含税定价才返回该组；拆税完成后等于 `orderAmount + orderTaxAmount`，不是优惠前请求原值 |
| `taxInfo.taxCountry` | 创建时申报的计税国家 | 两价齐传才有申报值；含税定价下可能为空，不是通用的最终账单国家回显 |
| `finalDealAmount`、`userCurrency` | 用户支付金额及其币种 | 完成支付后用它们核对用户实付；不要拿订单币种税额直接与另一币种的金额相加 |

税前定价的响应可以有 `orderTaxAmount`，同时没有 `taxInfo`。因此，`taxInfo` 是否存在不能用于判断是否收税。

含税定价的中间态也可能同时出现 `orderAmount = "110.00"`、`orderTaxAmount` 为空和 `taxInfo.orderAmountInclTax = "110.00"`。此时不要再次减税或加税。保存你的请求原值，并以最终查询或 Webhook 中的状态和金额核对结果。

完整字段和响应示例请参阅 [订单查询 API](/docs/api-reference/order-inquiry/order-inquiry)。

`orderTaxAmount` 已包含在含税总价的表达中，不要再次加到 `finalDealAmount` 上。支付未完成时，不要把当前计算金额当成已扣款金额。Webhook 的验签和状态处理见 [Webhook 概览](/docs/zh/developer-docs/webhook/overview)。

### 退款如何传参

退款金额同样使用订单币种。`refundAmount` 表示税前退款金额；是否可以传 `taxInfo.refundAmountInclTax`，由原支付单的传参方式决定。

| 原支付单方式 | 允许的退款传法 | 不允许的传法 |
| - | - | - |
| 税前定价 | 只传 `refundAmount` | 传含税退款金额 |
| 两价齐传 | 只传 `refundAmount`，或同时传 `refundAmount` 与 `taxInfo.refundAmountInclTax` | 只传含税退款金额 |
| 含税定价 | 只传 `refundAmount`，或只传 `taxInfo.refundAmountInclTax`，二选一 | 同时传两价 |

以下为 `POST /api/v1/order/refund` 的局部请求；你仍需补齐原单号、退款请求标识、原因等通用参数。

**仅税前金额**

适用于三种原支付单。只传 `refundAmount`，由 Waffo 计算相应退税。

```json theme={null}
{
  "refundAmount": "50.00"
}
```

**同时传两价**

仅适用于两价齐传的原支付单。申报税前 `50.00`、含税 `55.00`，差额仍按已配置的自算税额校验策略处理。

```json theme={null}
{
  "refundAmount": "50.00",
  "taxInfo": {
    "refundAmountInclTax": "55.00"
  }
}
```

**仅含税金额**

仅适用于含税定价的原支付单。只传含税退款额，由 Waffo 换算税前退款金额。

```json theme={null}
{
  "taxInfo": {
    "refundAmountInclTax": "55.00"
  }
}
```

以上金额沿用前文的假设。全额退款应基于原单最终金额和当前可退余额，不要照搬优惠前的请求原值。部分退款的税额由 Waffo 计算并校验累计金额；不要自行按订单比例舍入后当作权威退税结果。

退款查询 [`POST /api/v1/refund/inquiry`](/docs/api-reference/refund-inquiry/refund-inquiry) 和 `REFUND_NOTIFICATION` 中，重点读取：

| 字段 | 接入注意点 |
| - | - |
| `refundAmount` | 归一后的税前退款金额，使用原订单币种；含税输入可能被换算成不同的数值 |
| `orderTaxAmount` | 本次退税在订单币种下的金额，不是整笔支付单的原税额；可能为空，零税结果也可能明确返回 `"0"` |
| `taxInfo.refundAmountInclTax` | 有退税结果且原单采用两价或含税定价时返回，等于本次 `refundAmount + orderTaxAmount`；不能假设所有中间态都有该组 |
| `finalDealAmount`、`userCurrency` | 用户实际收到的退款金额及币种；可能包含退税和可退手续费，不能只用 `refundAmount` 核对到账 |
| `remainingRefundAmount` | 原订单币种下剩余可退的税前订单金额，不是含税余额，也不是用户支付币种的余额 |

退款进行中或失败时，返回的计算金额不代表用户已经收到退款；请结合最终成功状态核对到账。

重试同一 `paymentRequestId` 或 `refundRequestId` 时，请保持原金额、含税金额及传参方式不变。先查询未知结果，再决定下一步，详见 [幂等性](/docs/zh/developer-docs/core-concepts/idempotency)。

### 常见错误

| 错误码 | 含义及处理 |
| - | - |
| `A0003` | 检查金额格式、字段组合和国家等参数；税前定价须省略 `taxInfo`（空对象 `{}` 也不允许），含税定价不要传 `taxCountry` |
| `A0051` | 申报税额被 Waffo 拒绝，例如严格比较后按拒单策略处理；检查两价、国家、计税资料及协议策略，不要仅修改幂等键重试同一错误金额 |
| `A0052` | 没有可支持该申报税额的支付方式，或传了 `taxInfo` 但没有税协议；联系 Waffo 核实配置和支持范围 |
| `A0053` | 缺少校验申报税额所需的账单资料，例如邮编；按 [创建订单 API](/docs/api-reference/order-create/create-new-order) 补齐必需参数后再提交 |

### 接入核对

* 在目标环境向 Waffo 确认税协议、商品信息和账单资料要求。
* 按一种定价方式构造请求，并验证无税、应税、缺邮编，以及申报不符时各已开通策略的结果。
* 分别保存请求原值、订单币种金额与用户支付币种金额。
* 校验含税定价在创建中间态和支付完成后的字段变化。
* 按原支付单类型验证全额及部分退款，并核对查询和 Webhook。


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.