- 金融科技
- 后端
【免费下载链接】pay
可能是我用过的最优雅的 Alipay/WeChat/Douyin/Unipay/江苏银行 的支付 SDK 扩展包了
本篇技术指南围绕 yansongda/pay 扩展包中江苏银行(Jsb)e融支付提供商的订单查询能力展开,完整讲解Pay::jsb()->query($order)方法签名、交易支付订单与退款订单两种查询场景的调用方式、必需配置参数,以及底层插件调用链的实现原理。读完本文,你将能独立完成江苏银行 e融支付订单状态的查询接入,并理解查询请求的组装、加签、验签与响应校验全过程。
方法签名与使用概览
江苏银行 e融支付在 yansongda/pay 中内置了query快捷方法,用于查询交易支付订单或退款订单的状态。其方法签名如下:
| 方法名 | 参数 | 返回值 |
|---|---|---|
| query | array $order | Collection |
$order:订单参数数组,核心字段为outTradeNo(商户订单号或退款单号);- 返回值:
Yansongda\Supports\Collection类型的结果集合,包含江苏银行返回的订单/退款查询结果字段。
从源码看,query方法定义在 src/Provider/Jsb.php 中,方法内部会触发MethodCalled事件,并通过__call将调用路由到\Yansongda\Pay\Shortcut\Jsb\QueryShortcut,即查询场景对应的插件编排(详见下文「底层插件调用链解析」)。
查询交易支付订单
当需要查询一笔交易支付订单的支付状态时,使用商户生成的交易订单号outTradeNo作为入参:
Pay::config($this->config); // 查询交易支付订单 $order = [ 'outTradeNo' => '1514027114', ]; $result = Pay::jsb()->query($order);执行成功后,$result中即包含江苏银行返回的交易订单查询结果。需要注意的是:
outTradeNo必须与支付下单时传入的商户订单号一致,否则无法命中订单;- 江苏银行 e融支付的订单号由商户侧生成并自行管理,建议保持唯一性;
- 与支付下单(
scan)场景不同,查询场景不需要notify_url等回调类参数。
查询退款订单
当需要查询一笔退款订单的退款处理状态时,将退款单号填入outTradeNo字段即可(参考官方退款接口约定,退款单号通常带有RK-前缀):
Pay::config($this->config); // 查询退款单号查询退款订单 $order = [ 'outTradeNo' => 'RK-1514027114', ]; $result = Pay::jsb()->query($order);这里有一个容易被忽略的关键点:交易支付订单与退款订单共用query方法和outTradeNo字段,SDK 与江苏银行网关通过传入的单号语义(普通商户单号 /RK-前缀退款单号)自动区分查询目标。发起退款时对应使用Pay::jsb()->refund($order)(见 src/Provider/Jsb.php),退款成功后即可用该退款单号回查退款状态。
配置参数说明
原文档明确说明:所有订单配置参数和官方无任何差别,兼容所有功能,所有参数请参考官方支付文档。这意味着订单级(业务级)参数完全沿用江苏银行 e融支付的官方字段定义,SDK 不做二次裁剪。
同时,凡是客观性、可自动推导的参数(如service、deviceNo、sign、signType、createData、createTime、msgId、version、charset等),扩展包已在插件层自动组装,调用方无需(也不应)手动传入。开发者只需要关注两类内容:
- 业务参数:如
outTradeNo(查询/退款场景)、totalFee、proInfo(支付场景,参考 web/docs/v3/jsb/pay.md); - 商户配置参数:在
Pay::config()中完成江苏银行商户资质与证书配置。
江苏银行提供商的配置类为 src/Config/JsbConfig.php,其中validateRequired()校验了 4 个必填项,缺一不可:
| 配置项 | 是否必填 | 说明 |
|---|---|---|
| partnerId | 必填 | 商户号/合作商户标识 |
| publicKeyCode | 必填 | 公钥编号 |
| mchSecretCertPath | 必填 | 商户私钥证书路径(用于请求加签) |
| jsbPublicCertPath | 必填 | 江苏银行公钥证书路径(用于响应验签) |
| svrCode | 选填 | 服务代码(由签约/环境决定) |
| notifyUrl | 选填 | 异步通知地址(支付下单时必需) |
| mode | 选填 | 运行模式:MODE_NORMAL或MODE_SANDBOX |
mode决定请求网关地址,见 src/Provider/Jsb.php:
- 正式环境(
MODE_NORMAL):https://mybank.jsbchina.cn:577/eis/merchant/merchantServices.htm - 沙箱环境(
MODE_SANDBOX):https://epaytest.jsbchina.cn:9999/eis/merchant/merchantServices.htm
注意:江苏银行无服务商(platform)模式,
supportedModes()仅允许MODE_NORMAL与MODE_SANDBOX(见 src/Config/JsbConfig.php)。相关配置校验逻辑可进一步参考 tests/Config/JsbConfigTest.php。
底层插件调用链解析
query快捷方法并非黑盒,它由一条清晰的插件链协作完成「拼装公共参数 → 组装业务参数 → 加签 → 请求 → 验签 → 校验响应 → 解析」。QueryShortcut的插件编排见 src/Shortcut/Jsb/QueryShortcut.php:
[ StartPlugin::class, QueryPlugin::class, AddPayloadSignPlugin::class, AddRadarPlugin::class, VerifySignaturePlugin::class, ResponsePlugin::class, ParserPlugin::class, ]各环节职责如下:
1. StartPlugin:注入公共参数
src/Plugin/Jsb/StartPlugin.php 为所有 Jsb 请求注入公共参数:createData(当天日期Ymd)、createTime(当前时间His)、bizDate、msgId(UUID v4)、svrCode、partnerId、channelNo(固定为m)、publicKeyCode、version(v1.0.0)、charset(utf-8),并设置QueryPacker作为请求打包器。
2. QueryPlugin:区分查询业务
src/Plugin/Jsb/Pay/Scan/QueryPlugin.php 是查询场景的业务插件,向请求负载合并两个固定字段:
service固定为payCheck(查询服务标识);deviceNo固定为1234567890(设备号,SDK 自动处理)。
这与支付(service为atPay,见 src/Plugin/Jsb/Pay/Scan/PayPlugin.php)和退款(service为payRefund,见 src/Plugin/Jsb/Pay/Scan/RefundPlugin.php)形成区分,也正是三种场景共用一套插件框架却能各司其职的原因。
3. AddPayloadSignPlugin:RSA 加签
src/Plugin/Jsb/AddPayloadSignPlugin.php 读取商户私钥证书(mch_secret_cert_path),对负载按 Key 排序后拼接字符串,使用openssl_sign签名并 Base64 编码,最终合并signType => 'RSA'与sign两个字段。若私钥证书缺失,会抛出CONFIG_JSB_INVALID配置异常。
4. AddRadarPlugin 与网络请求
AddRadarPlugin负责解析出目标网关地址(具体实现位于 src/Plugin/Jsb/AddRadarPlugin.php),配合 src/Traits/JsbTrait.php 中getJsbUrl()的降级逻辑:若雷达未解析出完整 URL,则回落到当前mode对应的网关地址。
5. VerifySignaturePlugin:响应验签
src/Plugin/Jsb/VerifySignaturePlugin.php 在收到响应后,从响应体中提取签名数据并调用verifyJsbSign()(src/Traits/JsbTrait.php):使用江苏银行公钥证书(jsb_public_cert_path)通过openssl_verify校验签名,签名缺失或校验失败均抛出InvalidSignException。该插件同时兼容江苏银行两种响应报文格式(含&-&分隔符的原始报文与 query 拼接格式),保证验签口径与官方一致。
6. ResponsePlugin:响应合法性校验
src/Plugin/Jsb/ResponsePlugin.php 对响应做两道检查:
- HTTP 状态码必须处于 2xx 区间,否则抛出
RESPONSE_CODE_WRONG异常; - 业务返回码
respCode必须为000000,否则抛出RESPONSE_BUSINESS_CODE_WRONG异常,异常信息中携带respCode与respMsg便于排查。
这意味着query()正常返回时,$result中的订单数据已经是通过网关签名校验与业务码校验的可靠数据,无需调用方再做二次判断。
7. ParserPlugin:结果解析
链尾的ParserPlugin将响应报文解析为Collection对象返回给调用方,即方法签名中声明的返回值类型。
返回值与后续处理建议
query()返回的Collection可直接以数组下标方式读取查询结果中的字段(如订单状态、交易金额、支付时间等),字段名与江苏银行官方查询接口的返回字段一一对应。建议的后续处理流程:
- 先判断是否抛出异常(
InvalidSignException/InvalidResponseException/InvalidConfigException等),异常即代表查询链路异常,不应继续处理返回数据; - 正常返回后,根据业务需要轮询订单状态直至终态(支付成功/退款成功),或结合异步回调通知(参考 web/docs/v3/jsb/callback.md)与主动查询双通道对账;
- 江苏银行官方返回报文的格式说明可参考 web/docs/v3/jsb/response.md。
适用范围与限制
query是江苏银行提供商当前支持的三类核心操作之一(scan扫码支付、query查询、refund退款,详见 web/docs/v3/jsb/all.md);- 江苏银行不支持
cancel与close方法,调用会抛出PARAMS_METHOD_NOT_SUPPORTED异常(见 src/Provider/Jsb.php); - 本扩展包对江苏银行的接入遵循「商户自行生成单号、SDK 自动处理客观参数」的约定,因此
outTradeNo的生成规则、退款单号前缀(示例为RK-)需与商户在江苏银行的签约口径保持一致。
若需要更底层的自由调用能力(如自定义插件组合),可参考 web/docs/v3/jsb/all.md 中基于Pay::epay()->pay($allPlugins, $params)的插件直调示例;对应插件的单元测试位于 tests/Plugin/Jsb/ 目录,可作为理解各插件行为的补充材料。
- 金融科技
- 后端
【免费下载链接】pay
可能是我用过的最优雅的 Alipay/WeChat/Douyin/Unipay/江苏银行 的支付 SDK 扩展包了
相关推荐
把 9 大 AI 可观测性数据源接入 Experiential:Braintrust、LangSmith、LangFuse 摄入配方
把 9 大 AI 可观测性数据源接入 Experiential:Braintrust、LangSmith、LangFuse 摄入配方 Experiential
金融科技后端Navicat Mac版无限试用重置:3种方法告别14天限制困扰
Navicat Mac版无限试用重置:3种方法告别14天限制困扰 还在为Navicat Premium的14天试用期到期而烦恼吗?作为Mac用户必备的数据库管理
金融科技后端EasyWeChat 4.x 微信支付订单操作全指南:统一下单、订单查询与关闭订单
EasyWeChat 4.x 微信支付订单操作全指南:统一下单、订单查询与关闭订单 本指南围绕 EasyWeChat 4.x 的 Pay\Application
后端即时通讯
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考