PaymentOne
PaymentOne

开发文档

面向开发者的接入指引,覆盖易支付兼容、标准 API、签名、回调和联调流程。

Back home

PaymentOne 开发者接入指引

这份文档面向要把业务系统接入 PaymentOne 的开发者。PaymentOne 负责创建支付意图、展示聚合收银台、路由上游支付通道、同步支付状态,并在确认成功后通知你的业务系统。用户余额、订单状态、会员权益、订阅开通和幂等入账仍由业务系统自己负责。

选择接入方式

场景 推荐方式 接入成本
现有系统已经支持易支付 易支付兼容接入 把网关改成 https://payment.agentone.work/easypay,使用后台应用里的 PID 和 KEY
新系统或希望拿到结构化状态 标准 JSON API 接入 服务端调用 POST https://payment.agentone.work/v1/payment-intents,使用 HMAC-SHA256 签名
想让用户自己选择支付宝、微信、银行卡等方式 PaymentOne 聚合收银台 易支付兼容模式默认进入聚合收银台;标准 API 传 provider=paymentone
想在服务端指定上游通道 标准 API 指定 provider/method provider=stripe/easypaymethod=card/alipay/wxpay

接入前先在后台完成配置:

  1. 在“应用”里创建业务应用,复制易支付 PIDKEY,或标准 API 的应用 ID 和标准接口密钥。
  2. 在应用里填写允许通知的域名,例如 merchant.example.comnotify_url 的 host 必须匹配该配置。
  3. 在“支付通道”里创建并启用上游通道,例如 EasyPay、Stripe 或其他已接入 provider。
  4. 用一笔小额订单跑通创建支付、付款、异步通知、订单查询和重复通知幂等处理。

最小接入流程

不管选择易支付兼容模式还是标准 JSON API,业务系统都建议按下面的顺序实现:

  1. 在业务库里创建本地订单,状态为 pending,记录订单号、金额、币种和用户 ID。
  2. 服务端向 PaymentOne 创建支付,易支付模式调用 mapi.php 或跳转 submit.php,标准模式调用 POST /v1/payment-intents
  3. 前端打开 payurl / checkout_url,或展示 qrcode 给用户扫码。
  4. PaymentOne 收到上游支付成功事件后,向订单的 notify_url 投递回调。
  5. 业务系统验签,核对订单号、金额、币种和应用身份。
  6. 业务系统用本地唯一约束做幂等入账,把订单更新为已支付并发放权益。
  7. 业务系统返回 HTTP 2xx,建议正文返回 success
  8. 如果用户页面先跳回 return_url,只展示处理中页面,再由后端订单状态或查询接口确认结果。

易支付兼容接入

易支付兼容模式适合已有易支付 SDK、插件或配置页的系统。业务侧通常只需要替换网关地址,签名算法和核心字段沿用易支付习惯。

网关根地址 https://payment.agentone.work/easypay
应用标识 后台应用里的易支付 PID
应用密钥 后台应用里的易支付 KEY
签名方式 MD5
金额单位 元,最多两位小数,例如 9.90

接口总览

接口 方法 URL 用途 成功结果
跳转收银台 submit.php GET/POST https://payment.agentone.work/easypay/submit.php 浏览器表单或 URL 直接发起支付 302 跳转到 PaymentOne 收银台
API 创建支付 mapi.php POST https://payment.agentone.work/easypay/mapi.php 服务端创建订单并拿支付链接/二维码 JSON,code=1 时读取 payurlqrcodeimg
订单查询 api.php GET https://payment.agentone.work/easypay/api.php?act=order 按业务订单号查询支付状态 JSON,trade_statusWAIT_BUYER_PAYTRADE_SUCCESS
异步通知 notify_url POST 你在创建支付时传入的 notify_url PaymentOne 确认支付成功后通知业务系统 业务系统验签、核对金额、幂等入账后返回 2xx,建议正文为 success
页面返回 return_url GET 你在创建支付时传入的 return_url 用户支付后的浏览器跳转 只能展示结果页,不能作为入账依据

pid、key 和签名

所有创建支付请求都必须带 pidsignsign_type=MD5。签名步骤如下:

  1. 去掉 signsign_type 和值为空的字段。
  2. 按参数名 ASCII 升序排序。
  3. 拼接为 k=v,字段之间用 & 连接。
  4. 在拼接串末尾直接追加应用 KEY
  5. 对最终字符串做 MD5,得到小写十六进制摘要。

签名原文不要 URL 编码。额外兼容字段如果参与请求,也必须参与签名。

sign_source = "money=9.90&name=Recharge&notify_url=https://merchant.example/pay/notify&out_trade_no=order_123&pid=1000&return_url=https://merchant.example/pay/return&type=alipay" + KEY
sign = md5_lower_hex(sign_source)

签名示例代码

PHP 易支付 MD5 示例:

function epay_sign(array $params, string $key): string {
    unset($params['sign'], $params['sign_type']);

    $filtered = [];
    foreach ($params as $name => $value) {
        if ($value === '' || $value === null) {
            continue;
        }
        $filtered[$name] = (string) $value;
    }

    ksort($filtered, SORT_STRING);

    $pairs = [];
    foreach ($filtered as $name => $value) {
        $pairs[] = $name . '=' . $value;
    }

    return md5(implode('&', $pairs) . $key);
}

Node.js 标准 API HMAC 示例:

import crypto from 'node:crypto';

function paymentoneSignature(secret, timestamp, rawBody) {
  return crypto
    .createHmac('sha256', secret)
    .update(`${timestamp}.${rawBody}`)
    .digest('hex');
}

const rawBody = JSON.stringify({
  app_order_id: 'order_123',
  amount: 990,
  currency: 'CNY',
  subject: 'Recharge',
  provider: 'paymentone',
  method: 'alipay',
  notify_url: 'https://merchant.example/pay/notify',
  return_url: 'https://merchant.example/pay/return'
});
const timestamp = Math.floor(Date.now() / 1000).toString();
const signature = paymentoneSignature(process.env.PAYMENTONE_SECRET, timestamp, rawBody);

Webhook 验签时使用收到的原始请求体,不要解析后再重新 JSON.stringify 或重新拼表单。

公共创建参数

submit.phpmapi.php 使用同一组核心参数。

字段 必填 说明
pid 后台应用里的易支付 PID
type 支付方式,常用 alipaywxpay;也兼容 qqpaybankjdpay
out_trade_no 业务订单号,同一应用内必须唯一;重复请求必须保持金额、标题、通知地址等字段一致
name 商品名或订单标题,会展示在收银台和后台排查信息里
money 金额,单位元,必须大于 0,最多两位小数
notify_url 建议必填 异步通知地址;不填则不会投递业务回调
return_url 建议必填 用户完成支付后的浏览器返回地址;不要在这里做入账
sign 按上面的 MD5 规则生成
sign_type 固定传 MD5
param 兼容字段,PaymentOne 会保存原始请求用于排查;当前回调不会回传,见下方兼容差异
cid 兼容字段,当前不用于 PaymentOne 路由
clientip 兼容字段,当前不用于 PaymentOne 路由
device 兼容字段,当前不用于 PaymentOne 路由

跳转收银台 submit.php

适合浏览器端通过表单发起支付。推荐使用 POST,也支持 GET

<form method="post" action="https://payment.agentone.work/easypay/submit.php">
  <input name="pid" value="1000">
  <input name="type" value="alipay">
  <input name="out_trade_no" value="order_123">
  <input name="name" value="Recharge">
  <input name="money" value="9.90">
  <input name="notify_url" value="https://merchant.example/pay/notify">
  <input name="return_url" value="https://merchant.example/pay/return">
  <input name="sign" value="<MD5签名>">
  <input name="sign_type" value="MD5">
  <button type="submit">Pay</button>
</form>

成功时 PaymentOne 返回 302 FoundLocation 指向 PaymentOne 聚合收银台。签名错误返回 HTTP 400 和纯文本 fail;创建支付失败通常返回 HTTP 502

API 创建支付 mapi.php

适合服务端创建订单后,把支付链接或二维码交给前端展示。

curl -X POST "https://payment.agentone.work/easypay/mapi.php" \
  -F "pid=1000" \
  -F "type=alipay" \
  -F "out_trade_no=order_123" \
  -F "name=Recharge" \
  -F "money=9.90" \
  -F "notify_url=https://merchant.example/pay/notify" \
  -F "return_url=https://merchant.example/pay/return" \
  -F "sign=<MD5签名>" \
  -F "sign_type=MD5"

成功响应示例:

{
  "code": 1,
  "msg": "success",
  "trade_no": "paymentone_pi_xxx",
  "out_trade_no": "order_123",
  "payurl": "https://pay.example.com/checkout/pi_xxx",
  "qrcode": "https://pay.example.com/checkout/pi_xxx/qrcode.png",
  "img": "https://pay.example.com/checkout/pi_xxx/qrcode.png"
}

字段说明:

字段 说明
code 1 表示创建成功;-1 表示失败
msg 成功为 success,失败时是原因,例如 sign error
trade_no PaymentOne 或上游生成的支付交易号
out_trade_no 你的业务订单号
payurl 支付跳转地址,前端可直接打开
qrcode 二维码内容或二维码图片地址,取决于上游通道返回
img qrcode 保持一致,兼容旧易支付插件

请求成功不等于支付成功。mapi.php 只表示支付单创建成功,是否到账必须以后续 notify_url 通知或 api.php?act=order 查询为准。

订单查询 api.php

当前易支付兼容查询只支持查询单个订单:act=order

curl "https://payment.agentone.work/easypay/api.php?act=order&pid=1000&out_trade_no=order_123&key=<KEY>"

也可以不用 key,改为对 actpidout_trade_no 等查询参数做 MD5 签名并传 signsign_type=MD5

字段 必填 说明
act 固定为 order
pid 后台应用里的易支付 PID
out_trade_no 业务订单号
key 二选一 应用 KEY。适合服务端查询,不要放到浏览器或前端代码里
signsign_type 二选一 使用 MD5 签名查询;适合不想明文传 key 的场景

待支付响应示例:

{
  "code": 1,
  "msg": "success",
  "pid": "1000",
  "out_trade_no": "order_123",
  "trade_no": "paymentone_pi_xxx",
  "type": "alipay",
  "name": "Recharge",
  "money": "9.90",
  "status": 0,
  "trade_status": "WAIT_BUYER_PAY"
}

已支付时 status=1trade_status=TRADE_SUCCESS。查询接口会在订单仍是 createdpending 时尝试同步一次上游状态;如果上游暂时不可用,仍会返回本地当前状态。

返回码与错误

场景 submit.php mapi.php / api.php
签名错误、PID 不存在 HTTP 400,正文 fail HTTP 200{"code":-1,"msg":"sign error"}
金额格式错误 HTTP 502,正文 fail HTTP 200{"code":-1,"msg":"money must have at most two decimal places"}
重复订单字段不一致 HTTP 502,正文 fail HTTP 200{"code":-1,"msg":"idempotency mismatch: ... "}
查询订单不存在 不适用 HTTP 200{"code":-1,"msg":"order not found"}
查询不支持的 act 不适用 HTTP 200{"code":-1,"msg":"unsupported act"}

回调处理:异步通知 notify_url

PaymentOne 确认支付成功后,会向创建支付时传入的 notify_url 发起 POST 请求。

兼容易支付的通知体为 application/x-www-form-urlencoded

字段 说明
pid 应用 PID
trade_no PaymentOne 或上游交易号
out_trade_no 业务订单号
type 创建支付时传入的支付方式
name 商品名或订单标题
money 金额,单位元,保留两位小数
trade_status 支付成功为 TRADE_SUCCESS
sign 易支付 MD5 签名
sign_type MD5

通知请求还会带标准 Webhook 头:

Header 说明
X-App-Id PaymentOne 应用 ID
X-PaymentOne-Timestamp Unix 秒级时间戳
X-PaymentOne-Signature HMAC_SHA256_HEX(StandardSecret, "<timestamp>.<raw_body>")

兼容易支付系统时,至少校验表单里的 MD5 签名、pidout_trade_nomoneytrade_status=TRADE_SUCCESS。如果你是新系统,也建议同时校验标准 Webhook 头。

处理成功后返回 HTTP 2xx,正文建议返回纯文本 success。PaymentOne 当前以 HTTP 2xx 判断投递成功;如果业务返回 4xx、5xx 或网络超时,会进入失败重试和后台投递记录。

回调重试策略

Webhook 投递 worker 每 5 秒扫描一次待投递记录,每次 HTTP 请求超时时间为 10 秒。投递失败后会按 attempts^2 分钟退避重试:第 1 次失败约 1 分钟后重试,第 2 次失败约 4 分钟后重试,第 3 次失败约 9 分钟后重试,以此类推。累计 10 次失败后投递状态会变为 failed

后台“Deliveries”页面可以查看每次投递的 URL、状态、尝试次数、下一次投递时间和最近错误。业务系统收到重复通知时必须幂等处理;已经入账的订单直接返回 2xx 即可。

页面返回 return_url

return_url 是用户浏览器跳回业务站点的地址。它可能发生在异步通知之前,也可能被用户刷新、复制或伪造,所以只适合展示“支付处理中/请稍候”的页面。

正确做法是:页面进入后用业务订单号查询你自己的后端状态;后端以 notify_url 幂等入账或服务端查询 api.php?act=order 的结果为准。

兼容差异

PaymentOne 的易支付兼容层覆盖支付接入主流程,但不是完整复制所有易支付平台行为。

PaymentOne 当前行为 接入建议
param 创建支付时会保存到原始请求,但业务回调当前不回传 param 老系统如果依赖 param 入账,请改为通过 out_trade_no 查本地订单上下文
cid 接收并参与签名,但当前不用于通道选择 在 PaymentOne 后台用支付通道优先级管理路由
clientipdevice 接收并参与签名,但当前不影响收银台展示 可继续传,避免旧插件改动
mapi.php 响应 返回 trade_noout_trade_nopayurlqrcodeimg 旧插件如依赖 O_idpayurl2,需要适配字段
成功判断 mapi.php 成功只代表支付单创建成功 入账只看 notify_url 或服务端查询结果

不支持接口

PaymentOne 当前不是完整的易支付商户后台 API,只提供支付接入所需的兼容面。

易支付常见接口 PaymentOne 当前状态 建议处理
act=balance 查询余额 不支持,返回 unsupported act 在 PaymentOne 后台查看通道和订单,不要让业务系统依赖余额查询
退款 / 提交订单退款 不支持易支付兼容退款接口 先在上游通道后台处理,或后续接入 PaymentOne 标准退款 API
微信小程序专用跳转 不支持 ZPAY 小程序式参数 使用 payurl 打开 PaymentOne 收银台,或展示 qrcode
批量订单查询、结算、商户管理类接口 不支持 通过后台页面和支付意图列表排查

标准 JSON API 接入

标准 API 适合新系统。它使用 JSON 请求、最小货币单位和 HMAC-SHA256 签名,字段更稳定,也更适合服务端集成。

接口总览

接口 方法 URL 说明
获取可用支付方式 GET https://payment.agentone.work/v1/payment-methods 返回当前启用且用户可见的 provider
创建支付意图 POST https://payment.agentone.work/v1/payment-intents 创建订单并返回 checkout_urlqrcode
查询支付意图 GET https://payment.agentone.work/v1/payment-intents/{payment_intent_id} 查询并尝试同步当前支付状态
主动同步状态 POST https://payment.agentone.work/v1/payment-intents/{payment_intent_id}/sync 强制向上游查询一次状态

provider/method 可用值

provider 决定 PaymentOne 使用哪个上游通道,method 表示支付方式。实际是否可用还取决于后台是否启用了对应支付通道。

provider method 说明
paymentone alipaywxpaycard 或留空 进入 PaymentOne 聚合收银台,让用户选择已启用方式
easypay alipaywxpayqqpaybankjdpay 直接创建 EasyPay 上游支付;上游账号可能只支持其中一部分
stripe cardstripe 创建 Stripe Checkout 支付
creem creem 仅在对应 provider 已配置时可用
waffo waffo 仅在对应 provider 已配置时可用
waffo_pancake waffo_pancakepancake 仅在对应 provider 已配置时可用

如果 provider 留空,PaymentOne 会根据 method 推断 provider:card 走 Stripe,alipay / wxpay 等走 EasyPay,未知值默认按 EasyPay 处理。新系统建议显式传 provider

请求认证

GET /v1/payment-methods 外,标准 API 都需要以下请求头:

Header 说明
X-App-Id 后台应用 ID
X-PaymentOne-Timestamp Unix 秒级时间戳,默认只接受 5 分钟窗口内的请求
X-PaymentOne-Signature HMAC_SHA256_HEX(secret, "<timestamp>.<raw_body>")

raw_body 必须是实际发送给 PaymentOne 的原始请求体字节。GET 或空 body 的 POST 也要签名,签名原文是 <timestamp>.

raw_body = exact JSON bytes sent to PaymentOne
timestamp = unix_seconds()
signature = hmac_sha256_hex(StandardSecret, timestamp + "." + raw_body)

创建支付意图

curl -X POST "https://payment.agentone.work/v1/payment-intents" \
  -H "Content-Type: application/json" \
  -H "X-App-Id: demo" \
  -H "X-PaymentOne-Timestamp: <timestamp>" \
  -H "X-PaymentOne-Signature: <signature>" \
  --data '{
    "app_order_id": "order_123",
    "amount": 990,
    "currency": "CNY",
    "subject": "Recharge",
    "provider": "paymentone",
    "method": "alipay",
    "return_url": "https://merchant.example/pay/return",
    "notify_url": "https://merchant.example/pay/notify",
    "metadata": {
      "user_id": "user_123"
    }
  }'

请求字段:

字段 必填 说明
app_order_id 业务订单号,同一应用内唯一;重复请求必须保持关键字段一致
amount 最小货币单位,CNY 990 表示 9.90 元
currency 默认 CNY;Stripe 卡支付通常传 Stripe 支持的币种
subject 订单标题
provider paymentone 进入聚合收银台;也可指定 stripeeasypay
method 支付方式,例如 cardalipaywxpay
notify_url 建议必填 支付结果异步通知地址;host 必须在应用允许通知域名内
return_url 建议必填 用户完成支付后的浏览器返回地址
metadata 字符串键值对象,用于排查或业务关联

响应字段:

字段 说明
payment_intent_id PaymentOne 支付意图 ID
app_order_id 业务订单号
status createdpendingpaidfailedexpiredcancelled
provider 实际路由到的 provider
provider_trade_no 上游交易号或 PaymentOne 收银台交易号
amountcurrency 金额和币种
subject 订单标题
checkout_url 支付跳转地址,前端优先使用这个字段
qrcode 上游返回的二维码内容或图片地址
expires_at 过期时间,可能为空
paid_at 支付完成时间,未支付时为空

创建成功响应:

{
  "payment_intent_id": "pi_123",
  "app_order_id": "order_123",
  "status": "pending",
  "provider": "paymentone",
  "provider_trade_no": "paymentone_pi_123",
  "amount": 990,
  "currency": "CNY",
  "subject": "Recharge",
  "checkout_url": "https://pay.example.com/checkout/pi_123",
  "qrcode": "https://pay.example.com/checkout/pi_123/qrcode.png",
  "expires_at": null,
  "paid_at": null
}

查询待支付响应:

{
  "payment_intent_id": "pi_123",
  "app_order_id": "order_123",
  "status": "pending",
  "provider": "easypay",
  "provider_trade_no": "epay_20260703123456",
  "amount": 990,
  "currency": "CNY",
  "subject": "Recharge",
  "checkout_url": "https://pay.example.com/pay/epay_20260703123456",
  "qrcode": "https://pay.example.com/qrcode/epay_20260703123456.png",
  "expires_at": "2026-07-03T08:30:00Z",
  "paid_at": null
}

查询已支付响应:

{
  "payment_intent_id": "pi_123",
  "app_order_id": "order_123",
  "status": "paid",
  "provider": "easypay",
  "provider_trade_no": "epay_20260703123456",
  "amount": 990,
  "currency": "CNY",
  "subject": "Recharge",
  "checkout_url": "https://pay.example.com/pay/epay_20260703123456",
  "qrcode": "https://pay.example.com/qrcode/epay_20260703123456.png",
  "expires_at": "2026-07-03T08:30:00Z",
  "paid_at": "2026-07-03T08:10:12Z"
}

查询和同步

查询支付意图:

curl -X GET "https://payment.agentone.work/v1/payment-intents/{payment_intent_id}" \
  -H "X-App-Id: demo" \
  -H "X-PaymentOne-Timestamp: <timestamp>" \
  -H "X-PaymentOne-Signature: <signature-for-empty-body>"

主动同步:

curl -X POST "https://payment.agentone.work/v1/payment-intents/{payment_intent_id}/sync" \
  -H "X-App-Id: demo" \
  -H "X-PaymentOne-Timestamp: <timestamp>" \
  -H "X-PaymentOne-Signature: <signature-for-empty-body>"

GET 查询会在必要时尝试同步;POST /sync 会强制请求上游状态。两者响应结构都和创建支付意图一致。业务系统可以把查询作为补偿手段,但最终入账仍建议以 Webhook 幂等处理为主。

标准 Webhook

标准 API 创建的订单支付成功后,PaymentOne 会向 notify_url 发送 JSON:

{
  "event_id": "evt_123",
  "type": "payment.succeeded",
  "payment_intent_id": "pi_123",
  "app_id": "demo",
  "app_order_id": "order_123",
  "amount": 990,
  "currency": "CNY",
  "provider": "stripe",
  "provider_trade_no": "cs_test_123",
  "paid_at": "2026-07-02T10:20:30Z"
}

通知头:

Header 说明
Content-Type application/json
X-App-Id PaymentOne 应用 ID
X-PaymentOne-Timestamp Unix 秒级时间戳
X-PaymentOne-Signature HMAC_SHA256_HEX(StandardSecret, "<timestamp>.<raw_body>")

验签通过后,再核对 app_idapp_order_idamountcurrency 和本地订单是否一致。处理成功返回任意 HTTP 2xx。

业务侧幂等要求

不要只看“通知到了”就入账。每次通知至少检查:

  1. 签名合法,时间戳在可接受窗口内。
  2. app_idpid 属于当前业务系统。
  3. app_order_idout_trade_no 能匹配本地订单。
  4. 金额和币种与本地订单一致。
  5. 订单尚未入账;如果已经入账,直接返回成功。

推荐以业务订单号或 PaymentOne payment_intent_id 建唯一入账约束。重复通知只能更新日志,不能重复增加余额或发放权益。

测试与联调

本地联调可以使用 mock provider,避免真实扣款:

PAYMENTONE_MOCK_PROVIDERS=true \
PAYMENTONE_WEBHOOK_ALLOW_PRIVATE_HOSTS=true \
PAYMENTONE_WEBHOOK_ALLOWED_HOSTS=localhost,127.0.0.1 \
PAYMENTONE_PUBLIC_BASE_URL=http://localhost:8080 \
go run ./cmd/paymentone

PAYMENTONE_MOCK_PROVIDERS=true 会为未配置的 provider 注册 mock provider。创建支付后打开 checkout_url,mock 收银台会显示“标记为已支付”按钮,点击后 PaymentOne 会把订单标记为 paid 并向 notify_url 投递回调。

本地回调到 localhost127.0.0.1 或内网地址时,需要 PAYMENTONE_WEBHOOK_ALLOW_PRIVATE_HOSTS=true。生产环境不要打开这个开关,生产环境应使用 HTTPS 的公网回调地址,并在应用里配置允许通知域名。

建议至少验证这些场景:

  • 签名正确时能创建支付,签名错误时会失败。
  • notify_url 收到成功通知后能验签、核对金额并幂等入账。
  • 重复投递同一订单不会重复发放权益。
  • return_url 先到达时页面只展示处理中,不直接入账。
  • 使用 api.php?act=order 或标准查询接口能补偿确认订单状态。

上线检查清单

  • 已在后台应用里配置允许通知域名,生产环境不要放开任意 host。
  • 已启用真实支付通道,并在上游后台配置 PaymentOne 的 provider webhook 地址。
  • 业务系统已实现回调验签、金额核对、订单幂等和失败日志。
  • 标准 API 请求全部在服务端签名,前端只拿 checkout_urlqrcode
  • 不要在前端暴露 KEY 或标准接口密钥,不要把密钥写入公开日志。
  • 已验证 submit.phpmapi.phpapi.php?act=ordernotify_urlreturn_url 的完整流程。
  • 已用重复通知、重复创建订单、金额不一致、签名错误等场景做过测试。

排错顺序

  1. 创建支付失败:先看 pid / X-App-Id、签名、金额格式、应用密钥和 provider 是否启用。
  2. 支付页无法打开:检查 payurl / checkout_url 是否为空,以及聚合收银台是否有可用支付方式。
  3. 订单一直 pending:用后台支付意图详情和 api.php?act=order / 标准查询接口确认当前状态。
  4. 回调未到账:查看 Webhook 投递列表,确认 notify_url host 是否允许、下游是否返回 2xx、是否超时。
  5. 业务未入账:先查业务侧幂等表,再查 PaymentOne 支付状态、通知签名和投递记录。