# API 直连接入

> 服务端直接调用创建直连交易接口提交卡信息或 token，自行处理 3DS 跳转，并通过 Webhook 确认支付、绑卡、订阅与预授权结果。

直连 API（Direct API）接入由商户自建支付页面并在服务端直接调用[创建直连交易](/zh/payments/api-reference/endpoints/direct-create-transaction)：卡信息或 token 由商户服务端提交，3DS 跳转由商户处理，最终结果通过 Webhook 确认。与收银台和 Web SDK 不同，卡数据会经过商户系统，因此本接入方式有 PCI DSS 合规门槛；换来的是完全自定义的支付体验，以及绑卡、token 支付、订阅续费和预授权等服务端场景的直接控制。Apple Pay、Google Pay 与本地支付方式在直连下的接入准备与专属流程见[支付方式](/zh/payments/online-payments/payment-methods)。

## 前提

开始前，先按[接入准备](/zh/payments/get-started/setup)获取 API 凭证，并将服务端的公网出口 IP 加入对应环境的白名单。每个请求都需按[请求签名](/zh/payments/get-started/request-signing)生成 `sign`。上线前，参考[沙盒测试](/zh/payments/get-started/testing)在沙盒环境验证集成中使用的全部场景。

API 直连接入另有 **PCI DSS 合规**门槛：在自建页面收集卡号、有效期和 CVC 并提交到 Onerway，商户必须持有有效的 PCI DSS 认证，通过 TLS 安全传输持卡人数据，不得存储 CVC 等敏感认证数据。不具备资质的商户请改用[收银台接入](/zh/payments/online-payments/checkout)或 [Web SDK 接入](/zh/payments/online-payments/sdk)，卡数据不会经过商户服务器。订阅续费和预授权请款不提交卡数据，不受此限制；卡 token 支付仍须提交 `cardInfo.cvv`，同样在 PCI DSS 范围内。

## 接入流程

<steps level="3">

### 在服务端创建交易

调用[创建直连交易](/zh/payments/api-reference/endpoints/direct-create-transaction)。交易模型由[字段 `productType`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-productType)、[字段 `subProductType`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-subProductType) 与[字段 `txnType`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-txnType) 共同决定；商户自行采集卡信息的卡支付传 `productType=CARD`、`subProductType=DIRECT`、`txnType=SALE`，并在[字段 `cardInfo`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-cardInfo) 中提交卡信息。

[字段 `txnOrderMsg`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-txnOrderMsg) 必须包含 `returnUrl`（3DS 等跳转流程的同步回跳地址）与 `notifyUrl`（Webhook 通知地址）。与收银台不同，直连接入由商户自行采集浏览器、设备与持卡人 IP 信息（如 `transactionIp`）并传入 `txnOrderMsg`；各子字段的必填条件见[字段 `txnOrderMsg` 的字段树](/zh/payments/api-reference/endpoints/direct-create-transaction#request-txnOrderMsg)。

### 按响应状态处理跳转

Onerway 判定是否需要 3DS 认证，同步响应的[字段 `status`](/zh/payments/api-reference/endpoints/direct-create-transaction#response-data-status) 可能直接是终态：

| 响应 | 处理 |
| --- | --- |
| `status=S` | 支付成功，等待 Webhook 后完成订单。 |
| `status=R` 且 `actionType=RedirectURL` | 将客户浏览器重定向到[字段 `redirectUrl`](/zh/payments/api-reference/endpoints/direct-create-transaction#response-data-redirectUrl) 完成 3DS 认证或本地支付方式页面。 |
| 其他取值 | 按 `status` 与 `respCode` 处理失败或处理中状态，完整取值见 API Reference。 |

原生 App 可在 WebView 中加载 `redirectUrl`，监听导航到 `returnUrl` 后关闭 WebView，再由服务端查询结果。

### 承接同步回跳

客户完成认证后经 `returnUrl` 返回商户页面。回跳只用于页面流转，不保证附带交易参数：建议在 `returnUrl` 上拼接商户订单号，客户返回时向其展示“处理中”，并由服务端通过[查询交易记录](/zh/payments/api-reference/endpoints/query-transactions)核实，不要以回跳 URL 上的任何参数作为订单处理依据。

### 以 Webhook 确认结果

Onerway 将最终结果 POST 到 `notifyUrl`。[确认支付结果](#%E7%A1%AE%E8%AE%A4%E6%94%AF%E4%BB%98%E7%BB%93%E6%9E%9C)一节说明验签、应答、重试与幂等处理。

</steps>

## 绑卡与 token 支付

直连接入的保存支付方式（绑卡）流程是：服务端提交卡信息生成 token，随后用 `tokenId` 发起 token 支付，并按需[查询](/zh/payments/api-reference/endpoints/list-saved-tokens)或[删除](/zh/payments/api-reference/endpoints/delete-card-token)已保存记录。客户自选保存与服务端绑卡的选择、三类 token 的区分见[保存支付方式](/zh/payments/online-payments/scenarios/saved-payment-methods)。

1. **生成卡 token**：调用[生成卡 token](/zh/payments/api-reference/endpoints/create-card-token)，提交卡信息与稳定的[字段 `merchantCustId`](/zh/payments/api-reference/endpoints/create-card-token#request-merchantCustId)，同时传入 `notifyUrl` 与 `returnUrl`。响应[字段 `status`](/zh/payments/api-reference/endpoints/create-card-token#response-data-status) `=R` 时，将持卡人重定向到 `redirectUrl` 完成 3DS 认证。
2. **确认保存结果**：以[保存支付方式结果通知](/zh/payments/api-reference/webhooks/payment-method-result)（`txnType=BIND_CARD`）为最终依据，仅当 `status=S` 时保存 `tokenId`；回跳到 `returnUrl` 与同步响应都不代表绑卡成功。也可调用[查询已保存 token](/zh/payments/api-reference/endpoints/list-saved-tokens)核对。
3. **发起 token 支付**：调用[创建直连交易](/zh/payments/api-reference/endpoints/direct-create-transaction)，传入 `subProductType=TOKEN` 与[字段 `tokenInfo`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-tokenInfo)（`tokenId` 为已保存的卡 token，`provider` 不传），并在 `cardInfo.cvv` 提交客户本次输入的 CVC，同时传入绑卡时使用的 `merchantCustId`。token 支付同样可能返回 `status=R` 要求 3DS 认证，处理方式与接入流程一致。
4. **管理已保存 token**：[查询已保存 token](/zh/payments/api-reference/endpoints/list-saved-tokens)返回每条绑定记录的 `id` 与 `tokenId`；客户要求删除卡时调用[删除卡 token](/zh/payments/api-reference/endpoints/delete-card-token)，入参是绑定记录的 `id`，不是 `tokenId`。

API 直连接入需额外注意：生成卡 token 与 token 支付都经手卡数据（token 支付须提交 `cardInfo.cvv`），两步都要求 PCI DSS。不具备资质的商户应让保存卡与复购都在收银台或 Web SDK 页面上完成。

## 订阅

托管订阅与自主管理订阅的选择、合约凭证与生命周期通知见[订阅支付](/zh/payments/online-payments/scenarios/subscriptions)。本节说明选定方案后在直连侧如何调用。三类请求都使用[创建直连交易](/zh/payments/api-reference/endpoints/direct-create-transaction)，传入 `subProductType=SUBSCRIBE` 与[字段 `subscription`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-subscription)，并以[字段 `subscription.requestType`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-subscription-requestType) 区分：

| `requestType` | 用途 | 关键输入 |
| --- | --- | --- |
| `0` | 初始订阅，建立合约 | `cardInfo` 或 `tokenInfo`、`merchantCustId`、`selfExecute`、计费周期与期数 |
| `1` | 自主管理订阅的本期扣款 | `contractId`、`tokenId`、`merchantCustId`、本期金额 |
| `2` | 托管订阅升级或降级 | `contractId`、`tokenId`、`changeMode`、`prorationMode` |

**初始订阅**成功后，保存[订阅扣款通知](/zh/payments/api-reference/webhooks/subscription-payment)中的 `contractId` 与 `tokenId`。初始订阅也可以在收银台或 Web SDK 完成，后续扣款与更新仍走直连接口。

**自主管理订阅续费**（`requestType=1`）传入 `contractId`、`tokenId`、`merchantCustId` 与本期金额，不传卡信息，因此续费环节没有 PCI DSS 要求。

**托管订阅升降级**（`requestType=2`）使用已存储的 `contractId` 与 `tokenId` 发起，生效时机由[字段 `subscription.changeMode`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-subscription-changeMode) 决定，差价由 `prorationMode` 决定按剩余天数自动计算还是由商户通过 `proration` 提交。

API 直连接入需额外注意：托管卡订阅同时传入 `subscription.bindCard=true` 时，会收到[保存支付方式结果通知](/zh/payments/api-reference/webhooks/payment-method-result)与订阅扣款通知两条 `transactionId` 不同的通知，应各自幂等处理。

## 预授权

预授权先冻结持卡人卡上的订单金额、暂不扣款。直连侧的 `txnType=AUTH` 适用于自行采集卡信息的卡支付和 token 支付（`subProductType=DIRECT` 或 `TOKEN`），不适用于本地支付方式、订阅或分期。

调用[创建直连交易](/zh/payments/api-reference/endpoints/direct-create-transaction)并传入 `txnType=AUTH`，其余参数与自行采集卡信息的卡支付或 token 支付相同；需要 3DS 时同样按 `status=R` 处理跳转。保存响应中的 `transactionId` 与 `paymentId`，后续请款或撤销调用[预授权请款或撤销](/zh/payments/api-reference/endpoints/capture-or-void-authorization)。

授权到请款或撤销的生命周期、通知、边界与状态判断见[预授权与请款](/zh/payments/online-payments/scenarios/pre-authorization)。

## 本地支付

本地支付方式与卡支付共用创建直连交易接口，差别只在参数组合与流程形态：传入 `productType=LPMS` 与[字段 `lpmsInfo`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-lpmsInfo)（`lpmsType` 指定支付方式，其余子字段按方式条件必填），`subProductType` 一次性扣款传 `DIRECT`、订阅传 `SUBSCRIBE`；本地支付方式不支持 `txnType=AUTH`。方式清单与可用性查询、跳转与延迟到账的处理、方式专属参数与订阅形态见[本地支付方式](/zh/payments/online-payments/payment-methods/local-payment-methods)。

API 直连接入需额外注意：`productType=ALL` 属于收银台的聚合展示概念，直连接口不支持，商户需自建支付方式列表，并自行处理 `status=R` 下的客户侧动作与回跳承接。

## 分账

分账是平台模式下的能力：平台商户以收款子商户的 `merchantNo` 创建支付，并传入[字段 `paymentMethodOptions`](/zh/payments/api-reference/endpoints/direct-create-transaction#request-paymentMethodOptions) 在其中的 `share` 设置 `profitShare=true`，该笔支付才可参与分账；其余参数与普通交易相同。同时设置 `profitShareRate` 时，`SALE` 或 `CAPTURE` 成功后由 Onerway 自动分账；不设置时由服务端通过 API 发起分账。需要接收自动分账及自动分账回退通知时，同时设置 `profitShareNotifyUrl`。`paymentMethodOptions` 按接口要求以 JSON 字符串提交。

自动分账与通过 API 发起分账的选择、结果通知、查询与分账回退见[分账](/zh/payments/online-payments/scenarios/profit-sharing)。

## 确认支付结果

API 直连接入的最终结果以 Webhook 为准，按场景分别见[支付结果通知](/zh/payments/api-reference/webhooks/payment-result)、[保存支付方式结果通知](/zh/payments/api-reference/webhooks/payment-method-result)、[订阅扣款通知](/zh/payments/api-reference/webhooks/subscription-payment)与[预授权、请款与撤销通知](/zh/payments/api-reference/webhooks/authorization-capture)。验签、应答与重试、幂等去重、状态判断与查询补偿的通用规则见 [Webhook 通知](/zh/payments/get-started/webhooks)。

API 直连接入需额外注意：本接入方式同时使用四类通知，Webhook 端点必须能接收所用场景涉及的全部通知类型；绑卡、订阅并绑卡、预授权及后续请款或撤销会产生多笔 `transactionId` 各不相同的关联通知，用 `paymentId`、`contractId` 关联。同步响应可能直接返回终态 `status=S`，仍应等待 Webhook 后再完成订单；客户已回跳但未收到 Webhook 时，用[查询交易记录](/zh/payments/api-reference/endpoints/query-transactions)补偿。

## 上线前检查

- 持有有效的 PCI DSS 认证，支付页面通过 TLS 传输且不存储 CVC。
- 已处理 `status=R` 跳转与 `returnUrl` 回跳，回跳后由服务端查询而非信任 URL 参数。
- Webhook 端点已按 [Webhook 通知](/zh/payments/get-started/webhooks#%E4%B8%8A%E7%BA%BF%E5%89%8D%E6%A3%80%E6%9F%A5)完成上线前检查，且能接收绑卡、订阅、预授权等所用场景的全部通知类型。
- 已保存的 `tokenId`、`contractId` 与 `paymentId` 以字符串存储并与客户或订单关联。
- 沙盒验证已覆盖 3DS Challenge、3DS Frictionless 以及所用的绑卡、订阅、预授权与本地支付场景。
