wxpay-nodejs-sdk 0.2.4 → 0.2.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,16 +1,24 @@
1
1
  'use strict';
2
2
 
3
- var fs = require('fs');
3
+ var fs2 = require('fs');
4
4
  var os = require('os');
5
5
  var crypto2 = require('crypto');
6
+ var zlib = require('zlib');
6
7
 
7
8
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
8
9
 
9
- var fs__default = /*#__PURE__*/_interopDefault(fs);
10
+ var fs2__default = /*#__PURE__*/_interopDefault(fs2);
10
11
  var os__default = /*#__PURE__*/_interopDefault(os);
11
12
  var crypto2__default = /*#__PURE__*/_interopDefault(crypto2);
13
+ var zlib__default = /*#__PURE__*/_interopDefault(zlib);
12
14
 
13
15
  // src/core/client.ts
16
+
17
+ // package.json
18
+ var version = "0.2.6";
19
+
20
+ // src/version.ts
21
+ var SDK_VERSION = version;
14
22
  var CertificateManager = class {
15
23
  /** 平台证书缓存 Map<序列号, 证书信息> */
16
24
  certificates = /* @__PURE__ */ new Map();
@@ -65,6 +73,7 @@ var CertificateManager = class {
65
73
  * 获取用于验签的公钥
66
74
  *
67
75
  * 优先返回微信支付公钥(公钥模式),否则根据证书序列号查找平台证书。
76
+ * 在组合模式下,如果证书未找到,会回退到微信支付公钥。
68
77
  *
69
78
  * @param serialNo - 证书序列号或公钥ID
70
79
  * @returns PEM 格式的公钥,不存在则返回 null
@@ -77,7 +86,12 @@ var CertificateManager = class {
77
86
  return this.wxpayPublicKey;
78
87
  }
79
88
  const cert = this.certificates.get(serialNo);
80
- if (!cert) return null;
89
+ if (!cert) {
90
+ if (this.wxpayPublicKey) {
91
+ return this.wxpayPublicKey;
92
+ }
93
+ return null;
94
+ }
81
95
  const { ciphertext, nonce, associatedData, algorithm } = cert.encryptCertificate;
82
96
  if (algorithm === "RAW_PUBLIC_KEY") {
83
97
  return Buffer.from(ciphertext, "base64").toString("utf-8");
@@ -98,6 +112,17 @@ var CertificateManager = class {
98
112
  return null;
99
113
  }
100
114
  }
115
+ /**
116
+ * 判断当前是否为组合验签模式
117
+ *
118
+ * 当同时配置了微信支付公钥和平台证书时,返回 true。
119
+ * 组合模式用于平台证书→微信支付公钥的灰度迁移期间。
120
+ *
121
+ * @returns 是否为组合模式
122
+ */
123
+ isCombinedMode() {
124
+ return this.wxpayPublicKey !== null && this.certificates.size > 0;
125
+ }
101
126
  /**
102
127
  * 更新平台证书
103
128
  */
@@ -264,7 +289,6 @@ var MalformedMessageException = class extends WxPayError {
264
289
  };
265
290
 
266
291
  // src/utils/http.ts
267
- var SDK_VERSION = "0.2.1";
268
292
  function getUserAgent() {
269
293
  const platform = os__default.default.platform();
270
294
  const arch = os__default.default.arch();
@@ -466,14 +490,12 @@ var WxPayClient = class _WxPayClient {
466
490
  static PRODUCTION_BACKUP = "https://api2.mch.weixin.qq.com";
467
491
  /** 沙箱环境 API 地址 */
468
492
  static SANDBOX_BASE = "https://api.mch.weixin.qq.com/sandboxnew";
469
- /** SDK 版本号 */
470
- static SDK_VERSION = "0.2.1";
471
493
  /** 动态 User-Agent 字符串 */
472
494
  static USER_AGENT = (() => {
473
495
  const platform = os__default.default.platform();
474
496
  const arch = os__default.default.arch();
475
497
  const nodeVersion = process.version;
476
- return `wxpay-nodejs-sdk/${_WxPayClient.SDK_VERSION} (${platform} ${arch}) Node.js/${nodeVersion}`;
498
+ return `wxpay-nodejs-sdk/${SDK_VERSION} (${platform} ${arch}) Node.js/${nodeVersion}`;
477
499
  })();
478
500
  /** 商户号 */
479
501
  mchid;
@@ -484,6 +506,7 @@ var WxPayClient = class _WxPayClient {
484
506
  baseUrl;
485
507
  backupUrl;
486
508
  enableResponseVerification;
509
+ customFetch;
487
510
  /** 平台证书管理器 */
488
511
  certificates;
489
512
  constructor(options) {
@@ -495,6 +518,7 @@ var WxPayClient = class _WxPayClient {
495
518
  this.baseUrl = options.sandbox ? _WxPayClient.SANDBOX_BASE : _WxPayClient.PRODUCTION_BASE;
496
519
  this.backupUrl = options.sandbox ? null : _WxPayClient.PRODUCTION_BACKUP;
497
520
  this.enableResponseVerification = options.enableResponseVerification ?? true;
521
+ this.customFetch = options.customFetch ?? fetch;
498
522
  this.certificates = new CertificateManager(this.apiV3Key, options.platformCertificates);
499
523
  if (options.wxpayPublicKeyId && options.wxpayPublicKey) {
500
524
  const publicKey = this.resolvePublicKey(options.wxpayPublicKey);
@@ -576,7 +600,7 @@ var WxPayClient = class _WxPayClient {
576
600
  controller.abort();
577
601
  }, this.timeout);
578
602
  try {
579
- const response = await fetch(url, {
603
+ const response = await this.customFetch(url, {
580
604
  method,
581
605
  headers,
582
606
  signal: controller.signal
@@ -703,7 +727,7 @@ var WxPayClient = class _WxPayClient {
703
727
  controller.abort();
704
728
  }, this.timeout);
705
729
  try {
706
- const response = await fetch(url, {
730
+ const response = await this.customFetch(url, {
707
731
  method: "POST",
708
732
  headers,
709
733
  body,
@@ -779,7 +803,7 @@ var WxPayClient = class _WxPayClient {
779
803
  controller.abort();
780
804
  }, this.timeout);
781
805
  try {
782
- const response = await fetch(url, {
806
+ const response = await this.customFetch(url, {
783
807
  method,
784
808
  headers,
785
809
  body: bodyStr || void 0,
@@ -830,7 +854,7 @@ var WxPayClient = class _WxPayClient {
830
854
  if (Buffer.isBuffer(key)) return key;
831
855
  if (key.startsWith("-----BEGIN")) return key;
832
856
  try {
833
- return fs__default.default.readFileSync(key, "utf-8");
857
+ return fs2__default.default.readFileSync(key, "utf-8");
834
858
  } catch {
835
859
  return key;
836
860
  }
@@ -842,7 +866,7 @@ var WxPayClient = class _WxPayClient {
842
866
  if (Buffer.isBuffer(key)) return key.toString("utf-8");
843
867
  if (key.startsWith("-----BEGIN")) return key;
844
868
  try {
845
- return fs__default.default.readFileSync(key, "utf-8");
869
+ return fs2__default.default.readFileSync(key, "utf-8");
846
870
  } catch {
847
871
  return key;
848
872
  }
@@ -972,179 +996,384 @@ var CertificateService = class {
972
996
  return decrypted.toString("utf-8");
973
997
  }
974
998
  };
975
-
976
- // src/services/jsapi.ts
977
- var JsapiService = class {
978
- client;
979
- constructor(client) {
980
- this.client = client;
981
- }
982
- /**
983
- * JSAPI/小程序下单
984
- *
985
- * 商户通过此接口生成预付单并获取 prepay_id。
986
- * prepay_id 有效期为 2 小时,超过 2 小时需重新请求。
987
- *
988
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791856
989
- */
990
- async createOrder(request) {
991
- return this.client.post("/v3/pay/transactions/jsapi", request);
992
- }
993
- /**
994
- * 查询 JSAPI 支付订单
995
- *
996
- * 支持通过微信支付订单号或商户订单号查询订单状态。
997
- *
998
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791858 (微信支付订单号查询订单)
999
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791859 (商户订单号查询订单)
1000
- */
1001
- async queryOrderById(params) {
1002
- if (params.transactionId) {
1003
- return this.client.get(
1004
- `/v3/pay/transactions/id/${params.transactionId}`,
1005
- { mchid: this.client.mchid }
1006
- );
999
+ function generateAppPaySign(appId, timeStamp, nonceStr, prepayId, privateKey) {
1000
+ const signString = `${appId}
1001
+ ${timeStamp}
1002
+ ${nonceStr}
1003
+ prepay_id=${prepayId}
1004
+ `;
1005
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
1006
+ signer.update(signString);
1007
+ signer.end();
1008
+ return signer.sign(privateKey, "base64");
1009
+ }
1010
+ function buildAppBridgeConfig(appId, partnerId, prepayId, privateKey) {
1011
+ const timeStamp = String(Math.floor(Date.now() / 1e3));
1012
+ const nonceStr = generateNonceStr();
1013
+ const sign2 = generateAppPaySign(appId, timeStamp, nonceStr, prepayId, privateKey);
1014
+ return {
1015
+ appId,
1016
+ partnerId,
1017
+ prepayId,
1018
+ packageValue: "Sign=WXPay",
1019
+ nonceStr,
1020
+ timeStamp,
1021
+ sign: sign2
1022
+ };
1023
+ }
1024
+ function generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey) {
1025
+ const signString = `${appId}
1026
+ ${timeStamp}
1027
+ ${nonceStr}
1028
+ prepay_id=${prepayId}
1029
+ `;
1030
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
1031
+ signer.update(signString);
1032
+ signer.end();
1033
+ return signer.sign(privateKey, "base64");
1034
+ }
1035
+ function generateNonceStr() {
1036
+ return crypto2__default.default.randomUUID().replace(/-/g, "");
1037
+ }
1038
+ function buildJsapiBridgeConfig(appId, prepayId, privateKey) {
1039
+ const timeStamp = String(Math.floor(Date.now() / 1e3));
1040
+ const nonceStr = generateNonceStr();
1041
+ const paySign = generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey);
1042
+ return {
1043
+ appId,
1044
+ timeStamp,
1045
+ nonceStr,
1046
+ package: `prepay_id=${prepayId}`,
1047
+ signType: "RSA",
1048
+ paySign
1049
+ };
1050
+ }
1051
+ function buildMiniProgramBridgeConfig(appId, prepayId, privateKey) {
1052
+ const timeStamp = String(Math.floor(Date.now() / 1e3));
1053
+ const nonceStr = generateNonceStr();
1054
+ const paySign = generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey);
1055
+ return {
1056
+ timeStamp,
1057
+ nonceStr,
1058
+ package: `prepay_id=${prepayId}`,
1059
+ signType: "RSA",
1060
+ paySign
1061
+ };
1062
+ }
1063
+ function generatePayScorePaySign(appId, timeStamp, nonceStr, serviceId, outOrderNo, privateKey) {
1064
+ const packageStr = `service_id=${serviceId}&out_order_no=${outOrderNo}&need_sign_type=RSA`;
1065
+ const signString = `${appId}
1066
+ ${timeStamp}
1067
+ ${nonceStr}
1068
+ ${packageStr}
1069
+ `;
1070
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
1071
+ signer.update(signString);
1072
+ signer.end();
1073
+ return signer.sign(privateKey, "base64");
1074
+ }
1075
+ function buildPayScoreJsapiBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
1076
+ const timestamp = String(Math.floor(Date.now() / 1e3));
1077
+ const nonceStr = generateNonceStr();
1078
+ const sign2 = generatePayScorePaySign(
1079
+ appId,
1080
+ timestamp,
1081
+ nonceStr,
1082
+ serviceId,
1083
+ outOrderNo,
1084
+ privateKey
1085
+ );
1086
+ return {
1087
+ appid: appId,
1088
+ mchid: mchId,
1089
+ service_id: serviceId,
1090
+ out_order_no: outOrderNo,
1091
+ timestamp,
1092
+ nonce_str: nonceStr,
1093
+ sign_type: "RSA",
1094
+ sign: sign2
1095
+ };
1096
+ }
1097
+ function buildPayScoreMiniProgramBridgeConfig(mchId, serviceId, outOrderNo, appId, privateKey) {
1098
+ const timestamp = String(Math.floor(Date.now() / 1e3));
1099
+ const nonceStr = generateNonceStr();
1100
+ const sign2 = generatePayScorePaySign(
1101
+ appId,
1102
+ timestamp,
1103
+ nonceStr,
1104
+ serviceId,
1105
+ outOrderNo,
1106
+ privateKey
1107
+ );
1108
+ return {
1109
+ mchid: mchId,
1110
+ service_id: serviceId,
1111
+ out_order_no: outOrderNo,
1112
+ timestamp,
1113
+ nonce_str: nonceStr,
1114
+ sign_type: "RSA",
1115
+ sign: sign2
1116
+ };
1117
+ }
1118
+ function buildPayScoreAppBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
1119
+ const timestamp = String(Math.floor(Date.now() / 1e3));
1120
+ const nonceStr = generateNonceStr();
1121
+ const sign2 = generatePayScorePaySign(
1122
+ appId,
1123
+ timestamp,
1124
+ nonceStr,
1125
+ serviceId,
1126
+ outOrderNo,
1127
+ privateKey
1128
+ );
1129
+ return {
1130
+ appid: appId,
1131
+ mchid: mchId,
1132
+ service_id: serviceId,
1133
+ out_order_no: outOrderNo,
1134
+ timestamp,
1135
+ nonce_str: nonceStr,
1136
+ sign_type: "RSA",
1137
+ sign: sign2
1138
+ };
1139
+ }
1140
+ function buildMerchantTransferJsapiBridgeConfig(mchId, appId, packageInfo) {
1141
+ return {
1142
+ mchId,
1143
+ appId,
1144
+ package: packageInfo
1145
+ };
1146
+ }
1147
+ function buildMerchantTransferMiniProgramBridgeConfig(mchId, appId, packageInfo) {
1148
+ return {
1149
+ mchId,
1150
+ appId,
1151
+ package: packageInfo
1152
+ };
1153
+ }
1154
+ function buildMerchantTransferAuthorizationJsapiBridgeConfig(mchId, appId, packageInfo) {
1155
+ return {
1156
+ mchId,
1157
+ appId,
1158
+ package: packageInfo
1159
+ };
1160
+ }
1161
+ var PARKING_SERVICE_APPID = "wxbcad394b3d99dac9";
1162
+ var PARKING_SERVICE_PATH = "/pages/auth-creditpay/auth-creditpay";
1163
+ var PARKING_REPAY_APPID = "wx5e73c65404eee268";
1164
+ var PARKING_REPAY_PATH = "pages/invest_list/invest_list";
1165
+ function buildParkingQueryString(mchid, openid, plateNumber, plateColor) {
1166
+ const params = new URLSearchParams({
1167
+ mchid,
1168
+ openid,
1169
+ plate_number: plateNumber,
1170
+ plate_color: plateColor,
1171
+ trade_scene: "PARKING"
1172
+ });
1173
+ return params.toString();
1174
+ }
1175
+ function buildParkingMiniProgramBridgeConfig(mchid, openid, plateNumber, plateColor) {
1176
+ return {
1177
+ appId: PARKING_SERVICE_APPID,
1178
+ path: PARKING_SERVICE_PATH,
1179
+ extraData: {
1180
+ mchid,
1181
+ openid,
1182
+ plate_number: plateNumber,
1183
+ plate_color: plateColor,
1184
+ trade_scene: "PARKING"
1007
1185
  }
1008
- if (params.outTradeNo) {
1009
- return this.client.get(
1010
- `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,
1011
- { mchid: this.client.mchid }
1012
- );
1186
+ };
1187
+ }
1188
+ function buildParkingH5BridgeUrl(mchid, openid, plateNumber, plateColor) {
1189
+ const queryString = buildParkingQueryString(mchid, openid, plateNumber, plateColor);
1190
+ return `${PARKING_SERVICE_PATH}?${queryString}`;
1191
+ }
1192
+ function buildParkingAppBridgePath(mchid, openid, plateNumber, plateColor) {
1193
+ const queryString = buildParkingQueryString(mchid, openid, plateNumber, plateColor);
1194
+ return `${PARKING_SERVICE_PATH}?${queryString}`;
1195
+ }
1196
+ function buildParkingRepayBridgeConfig(mchid, openid) {
1197
+ return {
1198
+ appId: PARKING_REPAY_APPID,
1199
+ path: PARKING_REPAY_PATH,
1200
+ extraData: {
1201
+ mchid,
1202
+ nonce_str: generateNonceStr(),
1203
+ openid
1013
1204
  }
1014
- throw new Error("outTradeNo \u6216 transactionId \u5FC5\u987B\u63D0\u4F9B\u5176\u4E2D\u4E00\u4E2A");
1205
+ };
1206
+ }
1207
+ var H5_COUPON_URL = "https://action.weixin.qq.com/busifavor/getcouponinfo";
1208
+ function buildH5CouponUrl(params, signKey) {
1209
+ const signFields = {
1210
+ stock_id: params.stock_id,
1211
+ out_request_no: params.out_request_no,
1212
+ send_coupon_merchant: params.send_coupon_merchant,
1213
+ open_id: params.open_id
1214
+ };
1215
+ if (params.coupon_code) {
1216
+ signFields["coupon_code"] = params.coupon_code;
1015
1217
  }
1016
- /**
1017
- * 关闭订单
1018
- *
1019
- * 对于未支付的订单,商户可通过此接口关闭订单。
1020
- * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1021
- *
1022
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791860
1023
- */
1024
- async closeOrder(outTradeNo, request) {
1025
- return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);
1026
- }
1027
- /**
1028
- * 申请退款
1029
- *
1030
- * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1031
- * 仅支持支付成功后 1 年内的订单。
1032
- *
1033
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791862
1034
- */
1035
- async createRefund(request) {
1036
- return this.client.post("/v3/refund/domestic/refunds", request);
1037
- }
1038
- /**
1039
- * 查询退款单
1040
- *
1041
- * 通过商户退款单号查询退款状态。
1042
- *
1043
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791863
1044
- */
1045
- async queryRefund(params) {
1046
- return this.client.get(
1047
- `/v3/refund/domestic/refunds/${params.outRefundNo}`
1048
- );
1049
- }
1050
- /**
1051
- * 申请交易账单
1052
- *
1053
- * 商户可通过此接口获取交易账单的下载链接。
1054
- *
1055
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791866
1056
- */
1057
- async tradeBill(params) {
1058
- return this.client.get("/v3/bill/tradebill", params);
1059
- }
1060
- /**
1061
- * 申请资金账单
1062
- *
1063
- * 商户可通过此接口获取资金账单的下载链接。
1064
- *
1065
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791867
1066
- */
1067
- async fundFlowBill(params) {
1068
- return this.client.get("/v3/bill/fundflowbill", params);
1069
- }
1070
- /**
1071
- * 申请异常退款
1072
- *
1073
- * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1074
- * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1075
- *
1076
- * @param refundId - 微信支付退款单号
1077
- * @param request - 异常退款请求参数
1078
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791864
1079
- */
1080
- async applyAbnormalRefund(refundId, request) {
1081
- return this.client.post(
1082
- `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1083
- request
1084
- );
1218
+ const sortedKeys = Object.keys(signFields).sort();
1219
+ const signStr = sortedKeys.map((k) => `${k}=${signFields[k]}`).join("&") + `&key=${signKey}`;
1220
+ const sign2 = crypto2__default.default.createHmac("sha256", signKey).update(signStr).digest("hex").toUpperCase();
1221
+ const urlParams = new URLSearchParams({
1222
+ stock_id: params.stock_id,
1223
+ out_request_no: params.out_request_no,
1224
+ sign: sign2,
1225
+ send_coupon_merchant: params.send_coupon_merchant,
1226
+ open_id: params.open_id
1227
+ });
1228
+ if (params.coupon_code) {
1229
+ urlParams.set("coupon_code", params.coupon_code);
1085
1230
  }
1086
- /**
1087
- * 下载账单
1088
- *
1089
- * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1090
- * 下载地址 5 分钟内有效,请及时下载。
1091
- * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
1092
- *
1093
- * @param downloadUrl - 申请账单返回的 download_url
1094
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791868
1095
- */
1096
- async downloadBill(downloadUrl) {
1097
- return this.client.downloadRaw(downloadUrl);
1231
+ if (params.customize_send_time) {
1232
+ urlParams.set("customize_send_time", params.customize_send_time);
1098
1233
  }
1099
- };
1234
+ return `${H5_COUPON_URL}?${urlParams.toString()}#wechat_pay&wechat_redirect`;
1235
+ }
1236
+ function buildPayScoreDetailJsapiBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
1237
+ const timestamp = String(Math.floor(Date.now() / 1e3));
1238
+ const nonceStr = generateNonceStr();
1239
+ const sign2 = generatePayScorePaySign(
1240
+ appId,
1241
+ timestamp,
1242
+ nonceStr,
1243
+ serviceId,
1244
+ outOrderNo,
1245
+ privateKey
1246
+ );
1247
+ return {
1248
+ appid: appId,
1249
+ mchid: mchId,
1250
+ service_id: serviceId,
1251
+ out_order_no: outOrderNo,
1252
+ timestamp,
1253
+ nonce_str: nonceStr,
1254
+ sign_type: "RSA",
1255
+ sign: sign2
1256
+ };
1257
+ }
1258
+ function buildPayScoreDetailMiniProgramBridgeConfig(mchId, serviceId, outOrderNo, appId, privateKey) {
1259
+ const timestamp = String(Math.floor(Date.now() / 1e3));
1260
+ const nonceStr = generateNonceStr();
1261
+ const sign2 = generatePayScorePaySign(
1262
+ appId,
1263
+ timestamp,
1264
+ nonceStr,
1265
+ serviceId,
1266
+ outOrderNo,
1267
+ privateKey
1268
+ );
1269
+ return {
1270
+ mchid: mchId,
1271
+ service_id: serviceId,
1272
+ out_order_no: outOrderNo,
1273
+ timestamp,
1274
+ nonce_str: nonceStr,
1275
+ sign_type: "RSA",
1276
+ sign: sign2
1277
+ };
1278
+ }
1279
+ function buildPayScoreDetailAppBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
1280
+ const timestamp = String(Math.floor(Date.now() / 1e3));
1281
+ const nonceStr = generateNonceStr();
1282
+ const sign2 = generatePayScorePaySign(
1283
+ appId,
1284
+ timestamp,
1285
+ nonceStr,
1286
+ serviceId,
1287
+ outOrderNo,
1288
+ privateKey
1289
+ );
1290
+ return {
1291
+ appid: appId,
1292
+ mchid: mchId,
1293
+ service_id: serviceId,
1294
+ out_order_no: outOrderNo,
1295
+ timestamp,
1296
+ nonce_str: nonceStr,
1297
+ sign_type: "RSA",
1298
+ sign: sign2
1299
+ };
1300
+ }
1301
+ var MED_INS_APPID = "wxbcad394b3d99dac9";
1302
+ var MED_INS_PATH = "/pages/med-ins/pay/pay";
1303
+ function buildMedInsMiniProgramBridgeConfig(mchid, mixTradeNo) {
1304
+ return {
1305
+ appId: MED_INS_APPID,
1306
+ path: MED_INS_PATH,
1307
+ extraData: {
1308
+ mchid,
1309
+ mix_trade_no: mixTradeNo
1310
+ }
1311
+ };
1312
+ }
1313
+ function buildMedInsJsapiBridgeConfig(appId, mchId, mixTradeNo, privateKey) {
1314
+ const timestamp = String(Math.floor(Date.now() / 1e3));
1315
+ const nonceStr = generateNonceStr();
1316
+ const packageStr = `mchid=${mchId}&mix_trade_no=${mixTradeNo}`;
1317
+ const signString = `${appId}
1318
+ ${timestamp}
1319
+ ${nonceStr}
1320
+ ${packageStr}
1321
+ `;
1322
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
1323
+ signer.update(signString);
1324
+ signer.end();
1325
+ const sign2 = signer.sign(privateKey, "base64");
1326
+ return {
1327
+ appid: appId,
1328
+ mchid: mchId,
1329
+ mix_trade_no: mixTradeNo,
1330
+ timestamp,
1331
+ nonce_str: nonceStr,
1332
+ sign_type: "RSA",
1333
+ sign: sign2
1334
+ };
1335
+ }
1100
1336
 
1101
- // src/services/h5.ts
1102
- var H5Service = class {
1337
+ // src/services/base-payment.ts
1338
+ var BasePaymentService = class {
1103
1339
  client;
1104
1340
  constructor(client) {
1105
1341
  this.client = client;
1106
1342
  }
1107
- /**
1108
- * H5 支付下单
1109
- *
1110
- * 商户通过此接口生成 H5 支付链接(h5_url),用于在已配置 H5 支付域名的网页中
1111
- * 跳转并调起微信支付收银台。h5_url 有效期为 5 分钟,过期后需重新请求。
1112
- *
1113
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791834
1114
- */
1115
- async createOrder(request) {
1116
- return this.client.post("/v3/pay/transactions/h5", request);
1117
- }
1118
1343
  /**
1119
1344
  * 查询订单
1120
1345
  *
1121
1346
  * 支持通过微信支付订单号或商户订单号查询订单状态。
1122
- *
1123
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791837 (微信支付订单号查询订单)
1124
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791838 (商户订单号查询订单)
1125
1347
  */
1126
1348
  async queryOrderById(params) {
1127
1349
  if (params.transactionId) {
1128
- return this.client.get(
1129
- `/v3/pay/transactions/id/${params.transactionId}`,
1130
- { mchid: this.client.mchid }
1131
- );
1350
+ return this.queryOrderByTransactionId(params.transactionId);
1132
1351
  }
1133
1352
  if (params.outTradeNo) {
1134
- return this.client.get(
1135
- `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,
1136
- { mchid: this.client.mchid }
1137
- );
1353
+ return this.queryOrderByOutTradeNo(params.outTradeNo);
1138
1354
  }
1139
1355
  throw new Error("outTradeNo \u6216 transactionId \u5FC5\u987B\u63D0\u4F9B\u5176\u4E2D\u4E00\u4E2A");
1140
1356
  }
1357
+ /**
1358
+ * 通过商户订单号查询订单
1359
+ */
1360
+ async queryOrderByOutTradeNo(outTradeNo) {
1361
+ return this.client.get(`/v3/pay/transactions/out-trade-no/${outTradeNo}`, {
1362
+ mchid: this.client.mchid
1363
+ });
1364
+ }
1365
+ /**
1366
+ * 通过微信支付订单号查询订单
1367
+ */
1368
+ async queryOrderByTransactionId(transactionId) {
1369
+ return this.client.get(`/v3/pay/transactions/id/${transactionId}`, {
1370
+ mchid: this.client.mchid
1371
+ });
1372
+ }
1141
1373
  /**
1142
1374
  * 关闭订单
1143
1375
  *
1144
1376
  * 对于未支付的订单,商户可通过此接口关闭订单。
1145
- * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1146
- *
1147
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791839
1148
1377
  */
1149
1378
  async closeOrder(outTradeNo, request) {
1150
1379
  return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);
@@ -1153,9 +1382,6 @@ var H5Service = class {
1153
1382
  * 申请退款
1154
1383
  *
1155
1384
  * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1156
- * 仅支持支付成功后 1 年内的订单。
1157
- *
1158
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810597
1159
1385
  */
1160
1386
  async createRefund(request) {
1161
1387
  return this.client.post("/v3/refund/domestic/refunds", request);
@@ -1164,8 +1390,6 @@ var H5Service = class {
1164
1390
  * 查询退款单
1165
1391
  *
1166
1392
  * 通过商户退款单号查询退款状态。
1167
- *
1168
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810601
1169
1393
  */
1170
1394
  async queryRefund(params) {
1171
1395
  return this.client.get(
@@ -1176,11 +1400,6 @@ var H5Service = class {
1176
1400
  * 申请异常退款
1177
1401
  *
1178
1402
  * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1179
- * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1180
- *
1181
- * @param refundId - 微信支付退款单号
1182
- * @param request - 异常退款请求参数
1183
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810603
1184
1403
  */
1185
1404
  async applyAbnormalRefund(refundId, request) {
1186
1405
  return this.client.post(
@@ -1192,8 +1411,6 @@ var H5Service = class {
1192
1411
  * 申请交易账单
1193
1412
  *
1194
1413
  * 商户可通过此接口获取交易账单的下载链接。
1195
- *
1196
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810606
1197
1414
  */
1198
1415
  async tradeBill(params) {
1199
1416
  return this.client.get("/v3/bill/tradebill", params);
@@ -1202,8 +1419,6 @@ var H5Service = class {
1202
1419
  * 申请资金账单
1203
1420
  *
1204
1421
  * 商户可通过此接口获取资金账单的下载链接。
1205
- *
1206
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810609
1207
1422
  */
1208
1423
  async fundFlowBill(params) {
1209
1424
  return this.client.get("/v3/bill/fundflowbill", params);
@@ -1212,148 +1427,94 @@ var H5Service = class {
1212
1427
  * 下载账单
1213
1428
  *
1214
1429
  * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1215
- * 下载地址 5 分钟内有效,请及时下载。
1216
- * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
1217
- *
1218
- * @param downloadUrl - 申请账单返回的 download_url
1219
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810615
1220
1430
  */
1221
1431
  async downloadBill(downloadUrl) {
1222
1432
  return this.client.downloadRaw(downloadUrl);
1223
1433
  }
1224
1434
  };
1225
1435
 
1226
- // src/services/app.ts
1227
- var AppService = class {
1228
- client;
1229
- constructor(client) {
1230
- this.client = client;
1231
- }
1436
+ // src/services/jsapi.ts
1437
+ var JsapiService = class extends BasePaymentService {
1232
1438
  /**
1233
- * APP 支付下单
1439
+ * JSAPI/小程序下单
1234
1440
  *
1235
1441
  * 商户通过此接口生成预付单并获取 prepay_id。
1236
- * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。
1442
+ * prepay_id 有效期为 2 小时,超过 2 小时需重新请求。
1237
1443
  *
1238
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070347
1444
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791856
1239
1445
  */
1240
1446
  async createOrder(request) {
1241
- return this.client.post("/v3/pay/transactions/app", request);
1447
+ return this.client.post("/v3/pay/transactions/jsapi", request);
1242
1448
  }
1243
1449
  /**
1244
- * 查询订单
1450
+ * JSAPI 下单并生成调起支付参数
1245
1451
  *
1246
- * 支持通过微信支付订单号或商户订单号查询订单状态。
1452
+ * 封装了下单和调起支付参数生成两个步骤,一次调用即可获得
1453
+ * prepay_id 和前端 WeixinJSBridge.invoke() 所需的全部参数。
1247
1454
  *
1248
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070354 (微信支付订单号查询订单)
1249
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070356 (商户订单号查询订单)
1455
+ * @param request - 下单请求参数(需包含 appid)
1456
+ * @param privateKey - 商户私钥
1457
+ * @returns 下单响应 + 调起支付参数
1250
1458
  */
1251
- async queryOrderById(params) {
1252
- if (params.transactionId) {
1253
- return this.client.get(
1254
- `/v3/pay/transactions/id/${params.transactionId}`,
1255
- { mchid: this.client.mchid }
1256
- );
1257
- }
1258
- if (params.outTradeNo) {
1259
- return this.client.get(
1260
- `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,
1261
- { mchid: this.client.mchid }
1262
- );
1263
- }
1264
- throw new Error("outTradeNo \u6216 transactionId \u5FC5\u987B\u63D0\u4F9B\u5176\u4E2D\u4E00\u4E2A");
1459
+ async prepayWithRequestPayment(request, privateKey) {
1460
+ const response = await this.createOrder(request);
1461
+ const bridgeConfig = buildJsapiBridgeConfig(request.appid, response.data.prepay_id, privateKey);
1462
+ return { ...response, bridgeConfig };
1265
1463
  }
1464
+ };
1465
+
1466
+ // src/services/h5.ts
1467
+ var H5Service = class extends BasePaymentService {
1266
1468
  /**
1267
- * 关闭订单
1469
+ * H5 支付下单
1268
1470
  *
1269
- * 对于未支付的订单,商户可通过此接口关闭订单。
1270
- * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1471
+ * 商户通过此接口生成 H5 支付链接(h5_url),用于在已配置 H5 支付域名的网页中
1472
+ * 跳转并调起微信支付收银台。h5_url 有效期为 5 分钟,过期后需重新请求。
1271
1473
  *
1272
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070360
1474
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791834
1273
1475
  */
1274
- async closeOrder(outTradeNo, request) {
1275
- return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);
1476
+ async createOrder(request) {
1477
+ return this.client.post("/v3/pay/transactions/h5", request);
1276
1478
  }
1479
+ };
1480
+
1481
+ // src/services/app.ts
1482
+ var AppService = class extends BasePaymentService {
1277
1483
  /**
1278
- * 申请退款
1279
- *
1280
- * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1281
- * 仅支持支付成功后 1 年内的订单。
1282
- *
1283
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070371
1284
- */
1285
- async createRefund(request) {
1286
- return this.client.post("/v3/refund/domestic/refunds", request);
1287
- }
1288
- /**
1289
- * 查询退款单
1484
+ * APP 支付下单
1290
1485
  *
1291
- * 通过商户退款单号查询退款状态。
1486
+ * 商户通过此接口生成预付单并获取 prepay_id。
1487
+ * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。
1292
1488
  *
1293
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070374
1489
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070347
1294
1490
  */
1295
- async queryRefund(params) {
1296
- return this.client.get(
1297
- `/v3/refund/domestic/refunds/${params.outRefundNo}`
1298
- );
1491
+ async createOrder(request) {
1492
+ return this.client.post("/v3/pay/transactions/app", request);
1299
1493
  }
1300
1494
  /**
1301
- * 申请异常退款
1495
+ * APP 下单并生成调起支付参数
1302
1496
  *
1303
- * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1304
- * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1497
+ * 封装了下单和调起支付参数生成两个步骤,一次调用即可获得
1498
+ * prepay_id 和 APP 端调起支付所需的全部参数。
1305
1499
  *
1306
- * @param refundId - 微信支付退款单号
1307
- * @param request - 异常退款请求参数
1308
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070379
1500
+ * @param request - 下单请求参数(需包含 appid)
1501
+ * @param privateKey - 商户私钥
1502
+ * @returns 下单响应 + 调起支付参数
1309
1503
  */
1310
- async applyAbnormalRefund(refundId, request) {
1311
- return this.client.post(
1312
- `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1313
- request
1504
+ async prepayWithRequestPayment(request, privateKey) {
1505
+ const response = await this.createOrder(request);
1506
+ const bridgeConfig = buildAppBridgeConfig(
1507
+ request.appid,
1508
+ this.client.mchid,
1509
+ response.data.prepay_id,
1510
+ privateKey
1314
1511
  );
1315
- }
1316
- /**
1317
- * 申请交易账单
1318
- *
1319
- * 商户可通过此接口获取交易账单的下载链接。
1320
- *
1321
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070395
1322
- */
1323
- async tradeBill(params) {
1324
- return this.client.get("/v3/bill/tradebill", params);
1325
- }
1326
- /**
1327
- * 申请资金账单
1328
- *
1329
- * 商户可通过此接口获取资金账单的下载链接。
1330
- *
1331
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070400
1332
- */
1333
- async fundFlowBill(params) {
1334
- return this.client.get("/v3/bill/fundflowbill", params);
1335
- }
1336
- /**
1337
- * 下载账单
1338
- *
1339
- * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1340
- * 下载地址 5 分钟内有效,请及时下载。
1341
- * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
1342
- *
1343
- * @param downloadUrl - 申请账单返回的 download_url
1344
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070401
1345
- */
1346
- async downloadBill(downloadUrl) {
1347
- return this.client.downloadRaw(downloadUrl);
1512
+ return { ...response, bridgeConfig };
1348
1513
  }
1349
1514
  };
1350
1515
 
1351
1516
  // src/services/native.ts
1352
- var NativeService = class {
1353
- client;
1354
- constructor(client) {
1355
- this.client = client;
1356
- }
1517
+ var NativeService = class extends BasePaymentService {
1357
1518
  /**
1358
1519
  * Native 支付下单
1359
1520
  *
@@ -1368,47 +1529,39 @@ var NativeService = class {
1368
1529
  async createOrder(request) {
1369
1530
  return this.client.post("/v3/pay/transactions/native", request);
1370
1531
  }
1532
+ };
1533
+
1534
+ // src/services/base-combine.ts
1535
+ var BaseCombineService = class {
1536
+ client;
1537
+ constructor(client) {
1538
+ this.client = client;
1539
+ }
1371
1540
  /**
1372
- * 查询订单
1373
- *
1374
- * 支持通过微信支付订单号或商户订单号查询订单状态。
1541
+ * 查询合单订单
1375
1542
  *
1376
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791879 (微信支付订单号查询订单)
1377
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791880 (商户订单号查询订单)
1543
+ * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
1378
1544
  */
1379
1545
  async queryOrderById(params) {
1380
- if (params.transactionId) {
1381
- return this.client.get(
1382
- `/v3/pay/transactions/id/${params.transactionId}`,
1383
- { mchid: this.client.mchid }
1384
- );
1385
- }
1386
- if (params.outTradeNo) {
1387
- return this.client.get(
1388
- `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,
1389
- { mchid: this.client.mchid }
1390
- );
1391
- }
1392
- throw new Error("outTradeNo \u6216 transactionId \u5FC5\u987B\u63D0\u4F9B\u5176\u4E2D\u4E00\u4E2A");
1546
+ return this.client.get(
1547
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
1548
+ );
1393
1549
  }
1394
1550
  /**
1395
- * 关闭订单
1396
- *
1397
- * 对于未支付的订单,商户可通过此接口关闭订单。
1398
- * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1551
+ * 关闭合单订单
1399
1552
  *
1400
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791881
1553
+ * 对于未支付的合单订单,商户可通过此接口关闭订单。
1401
1554
  */
1402
- async closeOrder(outTradeNo, request) {
1403
- return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);
1555
+ async closeOrder(params, request) {
1556
+ return this.client.post(
1557
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1558
+ request
1559
+ );
1404
1560
  }
1405
1561
  /**
1406
1562
  * 申请退款
1407
1563
  *
1408
- * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1409
- * 仅支持支付成功后 1 年内的订单。
1410
- *
1411
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791883
1564
+ * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口对子单申请退款。
1412
1565
  */
1413
1566
  async createRefund(request) {
1414
1567
  return this.client.post("/v3/refund/domestic/refunds", request);
@@ -1417,8 +1570,6 @@ var NativeService = class {
1417
1570
  * 查询退款单
1418
1571
  *
1419
1572
  * 通过商户退款单号查询退款状态。
1420
- *
1421
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791884
1422
1573
  */
1423
1574
  async queryRefund(params) {
1424
1575
  return this.client.get(
@@ -1429,11 +1580,6 @@ var NativeService = class {
1429
1580
  * 申请异常退款
1430
1581
  *
1431
1582
  * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1432
- * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1433
- *
1434
- * @param refundId - 微信支付退款单号
1435
- * @param request - 异常退款请求参数
1436
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791885
1437
1583
  */
1438
1584
  async applyAbnormalRefund(refundId, request) {
1439
1585
  return this.client.post(
@@ -1445,8 +1591,6 @@ var NativeService = class {
1445
1591
  * 申请交易账单
1446
1592
  *
1447
1593
  * 商户可通过此接口获取交易账单的下载链接。
1448
- *
1449
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791887
1450
1594
  */
1451
1595
  async tradeBill(params) {
1452
1596
  return this.client.get("/v3/bill/tradebill", params);
@@ -1455,8 +1599,6 @@ var NativeService = class {
1455
1599
  * 申请资金账单
1456
1600
  *
1457
1601
  * 商户可通过此接口获取资金账单的下载链接。
1458
- *
1459
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791888
1460
1602
  */
1461
1603
  async fundFlowBill(params) {
1462
1604
  return this.client.get("/v3/bill/fundflowbill", params);
@@ -1465,11 +1607,6 @@ var NativeService = class {
1465
1607
  * 下载账单
1466
1608
  *
1467
1609
  * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1468
- * 下载地址 5 分钟内有效,请及时下载。
1469
- * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
1470
- *
1471
- * @param downloadUrl - 申请账单返回的 download_url
1472
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791889
1473
1610
  */
1474
1611
  async downloadBill(downloadUrl) {
1475
1612
  return this.client.downloadRaw(downloadUrl);
@@ -1477,11 +1614,7 @@ var NativeService = class {
1477
1614
  };
1478
1615
 
1479
1616
  // src/services/combine.ts
1480
- var CombineService = class {
1481
- client;
1482
- constructor(client) {
1483
- this.client = client;
1484
- }
1617
+ var CombineService = class extends BaseCombineService {
1485
1618
  /**
1486
1619
  * JSAPI 合单下单
1487
1620
  *
@@ -1500,94 +1633,10 @@ var CombineService = class {
1500
1633
  async createOrder(request) {
1501
1634
  return this.client.post("/v3/combine-transactions/jsapi", request);
1502
1635
  }
1503
- /**
1504
- * 查询合单订单
1505
- *
1506
- * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
1507
- *
1508
- * 订单状态(sub_orders[].trade_state):
1509
- * - SUCCESS:支付成功(终态)
1510
- * - NOTPAY:未支付
1511
- * - CLOSED:已关闭(终态)
1512
- *
1513
- * 注意:请勿使用非合单支付的查单接口查询合单订单。
1514
- *
1515
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421222
1516
- */
1517
- async queryOrderById(params) {
1518
- return this.client.get(
1519
- `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
1520
- );
1521
- }
1522
- /**
1523
- * 关闭合单订单
1524
- *
1525
- * 对于未支付的合单订单,商户可通过此接口关闭订单。
1526
- * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1527
- *
1528
- * 关键约束:
1529
- * - 只能整单关闭,不支持关闭部分子单
1530
- * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致
1531
- * - 仅支持未支付状态的订单
1532
- *
1533
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421225
1534
- */
1535
- async closeOrder(params, request) {
1536
- return this.client.post(
1537
- `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1538
- request
1539
- );
1540
- }
1541
- /**
1542
- * 申请退款
1543
- *
1544
- * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口对子单申请退款。
1545
- * 仅支持支付成功后 1 年内的订单。
1546
- *
1547
- * 注意:合单支付的订单无法通过合单总单号 combine_out_trade_no 退款,
1548
- * 需要传入子单的 transaction_id 或 out_trade_no。
1549
- *
1550
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421249
1551
- */
1552
- async createRefund(request) {
1553
- return this.client.post("/v3/refund/domestic/refunds", request);
1554
- }
1555
- /**
1556
- * 查询退款单
1557
- *
1558
- * 通过商户退款单号查询退款状态。
1559
- *
1560
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421261
1561
- */
1562
- async queryRefund(params) {
1563
- return this.client.get(
1564
- `/v3/refund/domestic/refunds/${params.outRefundNo}`
1565
- );
1566
- }
1567
- /**
1568
- * 申请异常退款
1569
- *
1570
- * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1571
- * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1572
- *
1573
- * @param refundId - 微信支付退款单号
1574
- * @param request - 异常退款请求参数
1575
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421269
1576
- */
1577
- async applyAbnormalRefund(refundId, request) {
1578
- return this.client.post(
1579
- `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1580
- request
1581
- );
1582
- }
1583
1636
  };
1584
1637
 
1585
1638
  // src/services/combine-h5.ts
1586
- var CombineH5Service = class {
1587
- client;
1588
- constructor(client) {
1589
- this.client = client;
1590
- }
1639
+ var CombineH5Service = class extends BaseCombineService {
1591
1640
  /**
1592
1641
  * H5 合单下单
1593
1642
  *
@@ -1609,111 +1658,10 @@ var CombineH5Service = class {
1609
1658
  async createOrder(request) {
1610
1659
  return this.client.post("/v3/combine-transactions/h5", request);
1611
1660
  }
1612
- /**
1613
- * 查询合单订单
1614
- *
1615
- * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
1616
- * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。
1617
- *
1618
- * 订单状态(sub_orders[].trade_state):
1619
- * - SUCCESS:支付成功(终态)
1620
- * - NOTPAY:未支付
1621
- * - CLOSED:已关闭(终态)
1622
- *
1623
- * 典型使用场景:
1624
- * - 用户支付后从收银台返回商户页面时,确认订单支付状态
1625
- * - 未收到支付成功回调通知时,主动查询确认订单状态
1626
- * - 关单前确认订单仍为未支付状态
1627
- *
1628
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421126
1629
- */
1630
- async queryOrderById(params) {
1631
- return this.client.get(
1632
- `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
1633
- );
1634
- }
1635
- /**
1636
- * 关闭合单订单
1637
- *
1638
- * 对于未支付的合单订单,商户可通过此接口关闭订单。
1639
- * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1640
- *
1641
- * 关键约束:
1642
- * - 只能整单关闭,不支持关闭部分子单
1643
- * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致
1644
- * - 仅支持未支付状态的订单
1645
- * - 关单后订单为失败终态
1646
- *
1647
- * 典型使用场景:
1648
- * - 用户超过商户系统内部规定的支付时间
1649
- * - 超过下单时设置的 time_expire 时间
1650
- * - 因特殊原因需在可支付时间范围内关闭订单
1651
- *
1652
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421130
1653
- */
1654
- async closeOrder(params, request) {
1655
- return this.client.post(
1656
- `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1657
- request
1658
- );
1659
- }
1660
- /**
1661
- * 申请退款(基于子单)
1662
- *
1663
- * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,
1664
- * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。
1665
- *
1666
- * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1667
- * 仅支持支付成功后 1 年内的订单。
1668
- *
1669
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421148
1670
- */
1671
- async createRefund(request) {
1672
- return this.client.post("/v3/refund/domestic/refunds", request);
1673
- }
1674
- /**
1675
- * 查询退款单
1676
- *
1677
- * 通过商户退款单号查询退款状态。
1678
- * 退款申请成功后,可通过此接口确认退款是否到账。
1679
- *
1680
- * 退款状态:
1681
- * - SUCCESS:退款成功
1682
- * - CLOSED:退款关闭
1683
- * - PROCESSING:退款处理中
1684
- * - ABNORMAL:退款异常
1685
- *
1686
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421156
1687
- */
1688
- async queryRefund(params) {
1689
- return this.client.get(
1690
- `/v3/refund/domestic/refunds/${params.outRefundNo}`
1691
- );
1692
- }
1693
- /**
1694
- * 申请异常退款
1695
- *
1696
- * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1697
- * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1698
- *
1699
- * @param refundId - 微信支付退款单号
1700
- * @param request - 异常退款请求参数
1701
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421164
1702
- */
1703
- async applyAbnormalRefund(refundId, request) {
1704
- return this.client.post(
1705
- `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1706
- request
1707
- );
1708
- }
1709
1661
  };
1710
1662
 
1711
1663
  // src/services/combine-app.ts
1712
- var CombineAppService = class {
1713
- client;
1714
- constructor(client) {
1715
- this.client = client;
1716
- }
1664
+ var CombineAppService = class extends BaseCombineService {
1717
1665
  /**
1718
1666
  * APP 合单下单
1719
1667
  *
@@ -1736,1349 +1684,999 @@ var CombineAppService = class {
1736
1684
  async createOrder(request) {
1737
1685
  return this.client.post("/v3/combine-transactions/app", request);
1738
1686
  }
1687
+ };
1688
+
1689
+ // src/services/combine-miniprogram.ts
1690
+ var CombineMiniProgramService = class extends BaseCombineService {
1739
1691
  /**
1740
- * 查询合单订单
1692
+ * 小程序合单下单
1741
1693
  *
1742
- * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
1743
- * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。
1694
+ * 商户通过此接口生成小程序合单预付单并获取 prepay_id。
1695
+ * 获取 prepay_id 后,配合 buildMiniProgramBridgeConfig 生成调起支付参数,
1696
+ * 通过小程序 wx.requestPayment() 方法唤起微信支付收银台。
1744
1697
  *
1745
- * 订单状态(sub_orders[].trade_state):
1746
- * - SUCCESS:支付成功(终态)
1747
- * - NOTPAY:未支付
1748
- * - CLOSED:已关闭(终态)
1698
+ * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。
1749
1699
  *
1750
- * 典型使用场景:
1751
- * - 用户支付后从微信收银台返回商户 APP 时,OpenSDK 回调 onResp 后确认订单支付状态
1752
- * - 未收到支付成功回调通知时,主动查询确认订单状态
1753
- * - 关单前确认订单仍为未支付状态
1700
+ * 关键约束:
1701
+ * - combine_mchid 需先申请发起合单支付权限
1702
+ * - sub_orders 中的 mchid 需先申请接收合单支付权限
1703
+ * - 合单发起方和子单参与方需绑定同一个 combine_appid
1704
+ * - combine_appid 必须为小程序 AppID
1705
+ * - combine_payer_info.openid 在小程序场景下可选(由运行环境隐式提供)
1706
+ * - 子单数量为 2-10 笔
1707
+ * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天
1754
1708
  *
1755
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557006
1709
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556931
1756
1710
  */
1757
- async queryOrderById(params) {
1758
- return this.client.get(
1759
- `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
1760
- );
1761
- }
1762
- /**
1763
- * 关闭合单订单
1764
- *
1765
- * 对于未支付的合单订单,商户可通过此接口关闭订单。
1766
- * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1767
- *
1768
- * 关键约束:
1769
- * - 只能整单关闭,不支持关闭部分子单
1770
- * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致
1771
- * - 仅支持未支付状态的订单
1772
- * - 关单后订单为失败终态
1773
- *
1774
- * 典型使用场景:
1775
- * - 用户超过商户系统内部规定的支付时间
1776
- * - 超过下单时设置的 time_expire 时间
1777
- * - 因特殊原因需在可支付时间范围内关闭订单
1778
- *
1779
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012577452
1780
- */
1781
- async closeOrder(params, request) {
1711
+ async createOrder(request) {
1782
1712
  return this.client.post(
1783
- `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1713
+ "/v3/combine-transactions/jsapi",
1784
1714
  request
1785
1715
  );
1786
1716
  }
1717
+ };
1718
+
1719
+ // src/services/combine-native.ts
1720
+ var CombineNativeService = class extends BaseCombineService {
1787
1721
  /**
1788
- * 申请退款(基于子单)
1789
- *
1790
- * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,
1791
- * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。
1792
- *
1793
- * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1794
- * 仅支持支付成功后 1 年内的订单。
1795
- *
1796
- * 注意:
1797
- * - 一笔订单最多支持 50 次部分退款,间隔至少 1 分钟
1798
- * - 重试时必须使用原商户退款单号,避免重复退款
1799
- * - 接口返回成功仅表示受理成功,最终结果以回调通知和查询接口为准
1800
- *
1801
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556524
1802
- */
1803
- async createRefund(request) {
1804
- return this.client.post("/v3/refund/domestic/refunds", request);
1805
- }
1806
- /**
1807
- * 查询退款单
1808
- *
1809
- * 通过商户退款单号查询退款状态。
1810
- * 退款申请成功后,可通过此接口确认退款是否到账。
1722
+ * Native 合单下单
1811
1723
  *
1812
- * 退款状态:
1813
- * - SUCCESS:退款成功
1814
- * - CLOSED:退款关闭
1815
- * - PROCESSING:退款处理中
1816
- * - ABNORMAL:退款异常
1724
+ * 商户通过此接口生成合单订单并获取二维码链接(code_url)。
1725
+ * 商户后端获取 code_url 后传递给前端,前端将其转换为二维码图片展示给用户。
1726
+ * 用户使用微信扫一扫扫描二维码后,将调起微信收银台完成支付。
1817
1727
  *
1818
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556587
1819
- */
1820
- async queryRefund(params) {
1821
- return this.client.get(
1822
- `/v3/refund/domestic/refunds/${params.outRefundNo}`
1823
- );
1824
- }
1825
- /**
1826
- * 申请异常退款
1728
+ * code_url 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求下单接口,
1729
+ * 获取新的 code_url。
1827
1730
  *
1828
- * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1829
- * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1731
+ * 关键约束:
1732
+ * - combine_mchid 需先申请发起合单支付权限
1733
+ * - sub_orders 中的 mchid 需先申请接收合单支付权限
1734
+ * - 合单发起方和子单参与方需绑定同一个 combine_appid
1735
+ * - 子单数量为 2-10 笔
1736
+ * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天
1737
+ * - 二维码不支持通过相册识别或长按识别二维码的方式完成支付
1830
1738
  *
1831
- * @param refundId - 微信支付退款单号
1832
- * @param request - 异常退款请求参数
1833
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013420988
1739
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556982
1834
1740
  */
1835
- async applyAbnormalRefund(refundId, request) {
1741
+ async createOrder(request) {
1836
1742
  return this.client.post(
1837
- `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1743
+ "/v3/combine-transactions/native",
1838
1744
  request
1839
1745
  );
1840
1746
  }
1841
- /**
1842
- * 申请交易账单
1843
- *
1844
- * 合单支付的订单账单是以子单为维度,每笔子单都会记录在各个子单商户账单内,
1845
- * 需要各个子单商户自己进行下载。
1846
- *
1847
- * 商户可通过此接口获取交易账单的下载链接,下载地址 5 分钟内有效。
1848
- *
1849
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556692
1850
- */
1851
- async tradeBill(params) {
1852
- return this.client.get("/v3/bill/tradebill", params);
1853
- }
1854
- /**
1855
- * 申请资金账单
1856
- *
1857
- * 商户可通过此接口获取资金账单的下载链接,下载地址 5 分钟内有效。
1858
- *
1859
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556748
1860
- */
1861
- async fundFlowBill(params) {
1862
- return this.client.get("/v3/bill/fundflowbill", params);
1863
- }
1864
- /**
1865
- * 下载账单
1866
- *
1867
- * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1868
- * 下载地址 5 分钟内有效,请及时下载。
1869
- * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
1870
- *
1871
- * @param downloadUrl - 申请账单返回的 download_url
1872
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012085923
1873
- */
1874
- async downloadBill(downloadUrl) {
1875
- return this.client.downloadRaw(downloadUrl);
1876
- }
1877
1747
  };
1878
1748
 
1879
- // src/services/combine-miniprogram.ts
1880
- var CombineMiniProgramService = class {
1749
+ // src/services/profitsharing.ts
1750
+ var ProfitSharingService = class {
1881
1751
  client;
1882
1752
  constructor(client) {
1883
1753
  this.client = client;
1884
1754
  }
1885
1755
  /**
1886
- * 小程序合单下单
1887
- *
1888
- * 商户通过此接口生成小程序合单预付单并获取 prepay_id。
1889
- * 获取 prepay_id 后,配合 buildMiniProgramBridgeConfig 生成调起支付参数,
1890
- * 通过小程序 wx.requestPayment() 方法唤起微信支付收银台。
1756
+ * 请求分账
1891
1757
  *
1892
- * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。
1758
+ * 微信订单支付成功后,商户通过此接口发起分账请求,将订单资金分给指定的接收方。
1759
+ * 此接口采用异步处理模式,受理请求后返回的结果非最终分账结果,
1760
+ * 最终分账结果需要通过查询分账结果接口获取。
1893
1761
  *
1894
- * 关键约束:
1895
- * - combine_mchid 需先申请发起合单支付权限
1896
- * - sub_orders 中的 mchid 需先申请接收合单支付权限
1897
- * - 合单发起方和子单参与方需绑定同一个 combine_appid
1898
- * - combine_appid 必须为小程序 AppID
1899
- * - combine_payer_info.openid 在小程序场景下可选(由运行环境隐式提供)
1900
- * - 子单数量为 2-10 笔
1901
- * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天
1762
+ * 单笔订单最多支持 50 次分账请求,每次请求最多支持 50 个接收方。
1902
1763
  *
1903
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556931
1764
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012524936
1904
1765
  */
1905
1766
  async createOrder(request) {
1906
- return this.client.post(
1907
- "/v3/combine-transactions/jsapi",
1908
- request
1909
- );
1767
+ return this.client.post("/v3/profitsharing/orders", request);
1910
1768
  }
1911
1769
  /**
1912
- * 查询合单订单
1913
- *
1914
- * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
1915
- * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。
1916
- *
1917
- * 订单状态(sub_orders[].trade_state):
1918
- * - SUCCESS:支付成功(终态)
1919
- * - NOTPAY:未支付
1920
- * - CLOSED:已关闭(终态)
1770
+ * 查询分账结果
1921
1771
  *
1922
- * 典型使用场景:
1923
- * - 用户支付后从收银台返回小程序页面时,requestPayment 回调后确认订单支付状态
1924
- * - 未收到支付成功回调通知时,主动查询确认订单状态
1925
- * - 关单前确认订单仍为未支付状态
1772
+ * 通过商户分账单号查询分账结果。
1773
+ * 发起分账请求后,可通过此接口主动查询分账的最终处理结果。
1926
1774
  *
1927
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421401
1775
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012525210
1928
1776
  */
1929
- async queryOrderById(params) {
1777
+ async queryOrder(params) {
1930
1778
  return this.client.get(
1931
- `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
1779
+ `/v3/profitsharing/orders/${params.outOrderNo}`,
1780
+ { transaction_id: params.transactionId }
1932
1781
  );
1933
1782
  }
1934
1783
  /**
1935
- * 关闭合单订单
1936
- *
1937
- * 对于未支付的合单订单,商户可通过此接口关闭订单。
1938
- * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1784
+ * 请求分账回退
1939
1785
  *
1940
- * 关键约束:
1941
- * - 只能整单关闭,不支持关闭部分子单
1942
- * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致
1943
- * - 仅支持未支付状态的订单
1944
- * - 关单后订单为失败终态
1786
+ * 对已经分账成功的订单,商户可以通过此接口将分账资金从接收方回退给分账方。
1787
+ * 此接口采用同步处理模式,会实时返回处理结果。
1945
1788
  *
1946
- * 典型使用场景:
1947
- * - 用户超过商户系统内部规定的支付时间
1948
- * - 超过下单时设置的 time_expire 时间
1949
- * - 因特殊原因需在可支付时间范围内关闭订单
1789
+ * 注意:
1790
+ * - 单笔分账单最多支持 50 次回退
1791
+ * - 回退窗口期为 180
1792
+ * - 仅支持对 MERCHANT_ID 类型且分账结果为 SUCCESS 的接收方进行回退
1793
+ * - 不支持对个人接收方的回退
1950
1794
  *
1951
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421404
1795
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012525287
1952
1796
  */
1953
- async closeOrder(params, request) {
1797
+ async createReturnOrder(request) {
1954
1798
  return this.client.post(
1955
- `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1799
+ "/v3/profitsharing/return-orders",
1956
1800
  request
1957
1801
  );
1958
1802
  }
1959
1803
  /**
1960
- * 申请退款(基于子单)
1804
+ * 查询分账回退结果
1805
+ *
1806
+ * 通过商户回退单号查询分账回退的处理结果。
1807
+ * 如果回退结果为 PROCESSING,请不要更换商户回退单号重复发起回退,
1808
+ * 否则会出现资金风险。
1961
1809
  *
1962
- * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,
1963
- * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。
1810
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012526279
1811
+ */
1812
+ async queryReturnOrder(params) {
1813
+ return this.client.get(
1814
+ `/v3/profitsharing/return-orders/${params.outReturnNo}`,
1815
+ { out_order_no: params.outOrderNo }
1816
+ );
1817
+ }
1818
+ /**
1819
+ * 解冻剩余资金
1964
1820
  *
1965
- * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1966
- * 仅支持支付成功后 1 年内的订单。
1821
+ * 将订单的金额全部解冻给本商户。
1822
+ * 适用于无需分账或分账完成后需将剩余冻结资金解冻给商户的场景。
1823
+ * 此接口采用异步处理模式。
1967
1824
  *
1968
1825
  * 注意:
1969
- * - 一笔订单最多支持 50 次部分退款,间隔至少 1 分钟
1970
- * - 重试时必须使用原商户退款单号,避免重复退款
1971
- * - 接口返回成功仅表示受理成功,最终结果以回调通知和查询接口为准
1826
+ * - 当分账已完成(金额全部分完)时,无需再请求此接口
1827
+ * - 同一分账单号多次请求视为同一请求(幂等)
1972
1828
  *
1973
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421410
1829
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012526374
1974
1830
  */
1975
- async createRefund(request) {
1976
- return this.client.post("/v3/refund/domestic/refunds", request);
1831
+ async unfreeze(request) {
1832
+ return this.client.post(
1833
+ "/v3/profitsharing/orders/unfreeze",
1834
+ request
1835
+ );
1977
1836
  }
1978
1837
  /**
1979
- * 查询退款单
1980
- *
1981
- * 通过商户退款单号查询退款状态。
1982
- * 退款申请成功后,可通过此接口确认退款是否到账。
1838
+ * 查询剩余待分金额
1983
1839
  *
1984
- * 退款状态:
1985
- * - SUCCESS:退款成功
1986
- * - CLOSED:退款关闭
1987
- * - PROCESSING:退款处理中
1988
- * - ABNORMAL:退款异常
1840
+ * 通过微信支付订单号查询该订单的剩余未分账金额。
1841
+ * 可用于判断是否可以继续分账以及剩余可分金额。
1989
1842
  *
1990
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421421
1843
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012457939
1991
1844
  */
1992
- async queryRefund(params) {
1845
+ async queryAmount(transactionId) {
1993
1846
  return this.client.get(
1994
- `/v3/refund/domestic/refunds/${params.outRefundNo}`
1847
+ `/v3/profitsharing/transactions/${transactionId}/amounts`
1995
1848
  );
1996
1849
  }
1997
1850
  /**
1998
- * 申请异常退款
1851
+ * 添加分账接收方
1999
1852
  *
2000
- * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
2001
- * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1853
+ * 商户在发起分账前,需要先通过此接口添加分账接收方。
1854
+ * 每个商户号最多添加 2 万个分账接收方。
1855
+ * 接收方全称(name 字段)需使用微信支付公钥进行 RSAES-OAEP 加密。
2002
1856
  *
2003
- * @param refundId - 微信支付退款单号
2004
- * @param request - 异常退款请求参数
2005
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421429
1857
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012528995
2006
1858
  */
2007
- async applyAbnormalRefund(refundId, request) {
1859
+ async addReceiver(request) {
2008
1860
  return this.client.post(
2009
- `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1861
+ "/v3/profitsharing/receivers/add",
2010
1862
  request
2011
1863
  );
2012
1864
  }
2013
1865
  /**
2014
- * 申请交易账单
1866
+ * 删除分账接收方
2015
1867
  *
2016
- * 合单支付的订单账单是以子单为维度,每笔子单都会记录在各个子单商户账单内,
2017
- * 需要各个子单商户自己进行下载。
1868
+ * 商户可以通过此接口删除已添加的分账接收方。
1869
+ * 删除后,该接收方将无法参与新的分账。
2018
1870
  *
2019
- * 商户可通过此接口获取交易账单的下载链接,下载地址 5 分钟内有效。
1871
+ * 注意:
1872
+ * - 删除接口有频率限制,请勿频繁调用
1873
+ * - 已参与分账的接收方仍可被删除,但不会影响已完成的交易
2020
1874
  *
2021
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421450
1875
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012529590
2022
1876
  */
2023
- async tradeBill(params) {
2024
- return this.client.get("/v3/bill/tradebill", params);
1877
+ async deleteReceiver(request) {
1878
+ return this.client.post(
1879
+ "/v3/profitsharing/receivers/delete",
1880
+ request
1881
+ );
2025
1882
  }
2026
1883
  /**
2027
- * 申请资金账单
1884
+ * 申请分账账单
2028
1885
  *
2029
- * 商户可通过此接口获取资金账单的下载链接,下载地址 5 分钟内有效。
1886
+ * 商户可通过此接口获取分账账单的下载链接。
1887
+ * 仅支持最近三个月的账单。
2030
1888
  *
2031
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421456
1889
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012529628
2032
1890
  */
2033
- async fundFlowBill(params) {
2034
- return this.client.get("/v3/bill/fundflowbill", params);
1891
+ async bill(params) {
1892
+ return this.client.get("/v3/profitsharing/bills", params);
2035
1893
  }
2036
1894
  /**
2037
- * 下载账单
1895
+ * 下载分账账单
2038
1896
  *
2039
- * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
2040
- * 下载地址 5 分钟内有效,请及时下载。
1897
+ * 通过申请分账账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1898
+ * 下载地址 30 秒内有效,请及时下载。
2041
1899
  * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
2042
1900
  *
2043
- * @param downloadUrl - 申请账单返回的 download_url
2044
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421461
1901
+ * @param downloadUrl - 申请分账账单返回的 download_url
2045
1902
  */
2046
1903
  async downloadBill(downloadUrl) {
2047
1904
  return this.client.downloadRaw(downloadUrl);
2048
1905
  }
2049
1906
  };
2050
1907
 
2051
- // src/services/combine-native.ts
2052
- var CombineNativeService = class {
1908
+ // src/services/payscore.ts
1909
+ var PayScoreService = class {
2053
1910
  client;
2054
1911
  constructor(client) {
2055
1912
  this.client = client;
2056
1913
  }
2057
1914
  /**
2058
- * Native 合单下单
2059
- *
2060
- * 商户通过此接口生成合单订单并获取二维码链接(code_url)。
2061
- * 商户后端获取 code_url 后传递给前端,前端将其转换为二维码图片展示给用户。
2062
- * 用户使用微信扫一扫扫描二维码后,将调起微信收银台完成支付。
1915
+ * 创建支付分订单
2063
1916
  *
2064
- * code_url 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求下单接口,
2065
- * 获取新的 code_url。
1917
+ * 当用户申请使用服务时,商户需调用此接口创建支付分订单。
1918
+ * 创单成功后订单状态 state 为 CREATED(已创建),返回的 package
1919
+ * 参数用于拉起支付分小程序确认订单页面。
2066
1920
  *
2067
- * 关键约束:
2068
- * - combine_mchid 需先申请发起合单支付权限
2069
- * - sub_orders 中的 mchid 需先申请接收合单支付权限
2070
- * - 合单发起方和子单参与方需绑定同一个 combine_appid
2071
- * - 子单数量为 2-10 笔
2072
- * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天
2073
- * - 二维码不支持通过相册识别或长按识别二维码的方式完成支付
1921
+ * - 需确认模式下,need_user_confirm 必须固定传 true
1922
+ * - risk_fund.name:先免模式可选 DEPOSIT/ADVANCE/CASH_DEPOSIT,先享模式固定 ESTIMATE_ORDER_COST
1923
+ * - risk_fund.amount 不可超过服务ID风险金额上限
1924
+ * - 该接口支持原参重入,相同参数重复调用可以返回成功
2074
1925
  *
2075
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556982
1926
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587900
2076
1927
  */
2077
1928
  async createOrder(request) {
2078
- return this.client.post(
2079
- "/v3/combine-transactions/native",
2080
- request
2081
- );
1929
+ return this.client.post("/v3/payscore/serviceorder", request);
2082
1930
  }
2083
1931
  /**
2084
- * 查询合单订单
2085
- *
2086
- * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
2087
- * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。
2088
- *
2089
- * 订单状态(sub_orders[].trade_state):
2090
- * - SUCCESS:支付成功(终态)
2091
- * - NOTPAY:未支付
2092
- * - CLOSED:已关闭(终态)
1932
+ * 查询支付分订单
2093
1933
  *
2094
- * 典型使用场景:
2095
- * - 用户扫码支付后,轮询确认订单支付状态
2096
- * - 未收到支付成功回调通知时,主动查询确认订单状态
2097
- * - 关单前确认订单仍为未支付状态
1934
+ * 通过商户服务订单号或回跳查询ID查询支付分订单状态和详情。
1935
+ * out_order_no 和 query_id 必须提供其中一个,不可同时提供。
2098
1936
  *
2099
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421316
1937
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587902
2100
1938
  */
2101
- async queryOrderById(params) {
2102
- return this.client.get(
2103
- `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
2104
- );
1939
+ async queryOrder(params) {
1940
+ const queryParams = {
1941
+ service_id: params.service_id,
1942
+ appid: params.appid
1943
+ };
1944
+ if (params.out_order_no) {
1945
+ queryParams["out_order_no"] = params.out_order_no;
1946
+ }
1947
+ if (params.query_id) {
1948
+ queryParams["query_id"] = params.query_id;
1949
+ }
1950
+ return this.client.get("/v3/payscore/serviceorder", queryParams);
2105
1951
  }
2106
1952
  /**
2107
- * 关闭合单订单
2108
- *
2109
- * 对于未支付的合单订单,商户可通过此接口关闭订单。
2110
- * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1953
+ * 取消支付分订单
2111
1954
  *
2112
- * 关键约束:
2113
- * - 只能整单关闭,不支持关闭部分子单
2114
- * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致
2115
- * - 仅支持未支付状态的订单
2116
- * - 关单后订单为失败终态
1955
+ * 取消已创建、用户已确认或待支付状态的支付分订单。
1956
+ * 可在订单状态为 CREATED、USER_CONFIRM(用户已确认)和 USER_PAYING(待支付)时调用。
2117
1957
  *
2118
- * 典型使用场景:
2119
- * - 用户超过商户系统内部规定的支付时间
2120
- * - 超过下单时设置的 time_expire 时间
2121
- * - 因特殊原因需在可支付时间范围内关闭订单
1958
+ * - 若因网络原因未获取到接口返回内容,可使用相同参数重试,该接口支持原参重入
1959
+ * - 待支付订单若用户正主动支付或系统正自动扣款时调用,可能报错,建议等待 3 分钟后重试
2122
1960
  *
2123
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421330
1961
+ * @param outOrderNo - 商户服务订单号
1962
+ * @param request - 取消订单请求参数
1963
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587905
2124
1964
  */
2125
- async closeOrder(params, request) {
1965
+ async cancelOrder(outOrderNo, request) {
2126
1966
  return this.client.post(
2127
- `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1967
+ `/v3/payscore/serviceorder/${outOrderNo}/cancel`,
2128
1968
  request
2129
1969
  );
2130
1970
  }
2131
1971
  /**
2132
- * 申请退款(基于子单)
2133
- *
2134
- * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,
2135
- * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。
1972
+ * 完结支付分订单
2136
1973
  *
2137
- * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
2138
- * 仅支持支付成功后 1 年内的订单。
1974
+ * 服务完成后,商户需调用此接口通知微信支付服务已结束。
1975
+ * 订单完结后,支付分会持续自动扣款,无需重复调用完结接口。
2139
1976
  *
2140
- * 注意:
2141
- * - 一笔订单最多支持 50 次部分退款,间隔至少 1 分钟
2142
- * - 重试时必须使用原商户退款单号,避免重复退款
2143
- * - 接口返回成功仅表示受理成功,最终结果以回调通知和查询接口为准
1977
+ * - total_amount = 后付费项目金额总和 - 优惠项目金额总和
1978
+ * - 先免模式:订单收款总金额 创单传的服务风险金额 服务ID风险金额上限
1979
+ * - 先享模式:订单收款总金额 ≤ 服务ID风险金额上限
1980
+ * - 调用完结接口后 collection.state 变为 USER_PAYING(待支付状态)
2144
1981
  *
2145
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421340
1982
+ * @param outOrderNo - 商户服务订单号
1983
+ * @param request - 完结订单请求参数
1984
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587955
2146
1985
  */
2147
- async createRefund(request) {
2148
- return this.client.post("/v3/refund/domestic/refunds", request);
1986
+ async completeOrder(outOrderNo, request) {
1987
+ return this.client.post(
1988
+ `/v3/payscore/serviceorder/${outOrderNo}/complete`,
1989
+ request
1990
+ );
2149
1991
  }
2150
1992
  /**
2151
- * 查询退款单
1993
+ * 修改订单金额
2152
1994
  *
2153
- * 通过商户退款单号查询退款状态。
2154
- * 退款申请成功后,可通过此接口确认退款是否到账。
1995
+ * 当订单处于 USER_PAYING(待支付)状态时,商户可调用此接口下调收款金额。
1996
+ * 修改成功后微信侧将按新金额发起扣款。
2155
1997
  *
2156
- * 退款状态:
2157
- * - SUCCESS:退款成功
2158
- * - CLOSED:退款关闭
2159
- * - PROCESSING:退款处理中
2160
- * - ABNORMAL:退款异常
1998
+ * - 只能下调扣款金额,不能上调
1999
+ * - total_amount = post_payments.amount 总和 - post_discounts.amount 总和
2161
2000
  *
2162
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421346
2001
+ * @param outOrderNo - 商户服务订单号
2002
+ * @param request - 修改订单金额请求参数
2003
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587957
2163
2004
  */
2164
- async queryRefund(params) {
2165
- return this.client.get(
2166
- `/v3/refund/domestic/refunds/${params.outRefundNo}`
2005
+ async modifyOrder(outOrderNo, request) {
2006
+ return this.client.post(
2007
+ `/v3/payscore/serviceorder/${outOrderNo}/modify`,
2008
+ request
2167
2009
  );
2168
2010
  }
2169
2011
  /**
2170
- * 申请异常退款
2012
+ * 同步订单状态
2171
2013
  *
2172
- * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
2173
- * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
2014
+ * 当支付分订单处于 USER_PAYING(待支付)状态,用户通过其他渠道支付后,
2015
+ * 商户可调用此接口将订单改为已完成状态,微信支付将不再发起扣款。
2174
2016
  *
2175
- * @param refundId - 微信支付退款单号
2176
- * @param request - 异常退款请求参数
2177
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421352
2017
+ * - type 固定传 Order_Paid
2018
+ * - paid_time 需满足:完结接口时间 < paid_time ≤ 同步接口时间 + 60 秒
2019
+ * - 若用户正在通过支付分收银台支付或自动扣款中,调用可能报错,可等 3 分钟后重试
2020
+ *
2021
+ * @param outOrderNo - 商户服务订单号
2022
+ * @param request - 同步订单状态请求参数
2023
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587962
2178
2024
  */
2179
- async applyAbnormalRefund(refundId, request) {
2025
+ async syncOrder(outOrderNo, request) {
2180
2026
  return this.client.post(
2181
- `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
2027
+ `/v3/payscore/serviceorder/${outOrderNo}/sync`,
2182
2028
  request
2183
2029
  );
2184
2030
  }
2185
2031
  /**
2186
- * 申请交易账单
2032
+ * 申请退款
2187
2033
  *
2188
- * 合单支付的订单账单是以子单为维度,每笔子单都会记录在各个子单商户账单内,
2189
- * 需要各个子单商户自己进行下载。
2034
+ * 支付分订单完结扣款后,如需退款可通过此接口发起。
2035
+ * transaction_id 来源于支付成功回调或查询支付分订单中的 collection.details。
2190
2036
  *
2191
- * 商户可通过此接口获取交易账单的下载链接,下载地址 5 分钟内有效。
2037
+ * @param request - 退款请求参数
2038
+ * @returns 退款结果
2192
2039
  *
2193
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421361
2040
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587971
2194
2041
  */
2195
- async tradeBill(params) {
2196
- return this.client.get("/v3/bill/tradebill", params);
2042
+ async applyRefund(request) {
2043
+ return this.client.post("/v3/refund/domestic/refunds", request);
2197
2044
  }
2198
2045
  /**
2199
- * 申请资金账单
2200
- *
2201
- * 商户可通过此接口获取资金账单的下载链接,下载地址 5 分钟内有效。
2046
+ * 查询单笔退款
2202
2047
  *
2203
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421365
2204
- */
2205
- async fundFlowBill(params) {
2206
- return this.client.get("/v3/bill/fundflowbill", params);
2207
- }
2208
- /**
2209
- * 下载账单
2048
+ * 通过商户退款单号查询退款状态和详情。
2210
2049
  *
2211
- * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
2212
- * 下载地址 5 分钟内有效,请及时下载。
2213
- * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
2050
+ * @param outRefundNo - 商户退款单号
2051
+ * @returns 退款详情
2214
2052
  *
2215
- * @param downloadUrl - 申请账单返回的 download_url
2216
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421368
2053
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587973
2217
2054
  */
2218
- async downloadBill(downloadUrl) {
2219
- return this.client.downloadRaw(downloadUrl);
2055
+ async queryRefund(outRefundNo) {
2056
+ return this.client.get(`/v3/refund/domestic/refunds/${outRefundNo}`);
2220
2057
  }
2221
2058
  };
2222
2059
 
2223
- // src/services/profitsharing.ts
2224
- var ProfitSharingService = class {
2060
+ // src/services/parking.ts
2061
+ var ParkingService = class {
2225
2062
  client;
2226
2063
  constructor(client) {
2227
2064
  this.client = client;
2228
2065
  }
2229
2066
  /**
2230
- * 请求分账
2067
+ * 创建停车入场
2231
2068
  *
2232
- * 微信订单支付成功后,商户通过此接口发起分账请求,将订单资金分给指定的接收方。
2233
- * 此接口采用异步处理模式,受理请求后返回的结果非最终分账结果,
2234
- * 最终分账结果需要通过查询分账结果接口获取。
2069
+ * 用户入场时调用此接口创建停车入场信息。
2070
+ * 根据返回的车牌状态判断用户是否开通支付分停车服务:
2071
+ * - state 为 NORMAL:正常,可使用支付分停车服务
2072
+ * - state 为 BLOCKED:不可用,通过 block_reason 获取具体原因
2235
2073
  *
2236
- * 单笔订单最多支持 50 次分账请求,每次请求最多支持 50 个接收方。
2074
+ * @param request - 创建停车入场请求参数
2075
+ * @returns 停车入场信息,包含入场ID和车牌状态
2237
2076
  *
2238
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012524936
2077
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533937
2239
2078
  */
2240
- async createOrder(request) {
2241
- return this.client.post("/v3/profitsharing/orders", request);
2079
+ async createEntry(request) {
2080
+ return this.client.post("/v3/vehicle/parking/parkings", request);
2242
2081
  }
2243
2082
  /**
2244
- * 查询分账结果
2083
+ * 查询车牌服务开通信息
2245
2084
  *
2246
- * 通过商户分账单号查询分账结果。
2247
- * 发起分账请求后,可通过此接口主动查询分账的最终处理结果。
2085
+ * 查询用户是否开通微信支付分停车服务。
2086
+ * 用于在用户未收到入场状态变更通知时,主动确认车牌服务开通状态。
2248
2087
  *
2249
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012525210
2088
+ * @param params - 查询参数,包含appid、车牌号、用户openid和车牌颜色
2089
+ * @returns 车牌服务开通信息,包含开通状态和开通时间
2090
+ *
2091
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534043
2250
2092
  */
2251
- async queryOrder(params) {
2252
- return this.client.get(
2253
- `/v3/profitsharing/orders/${params.outOrderNo}`,
2254
- { transaction_id: params.transactionId }
2255
- );
2093
+ async queryPlateService(params) {
2094
+ return this.client.get("/v3/vehicle/parking/services/find", {
2095
+ appid: params.appid,
2096
+ plate_number: params.plate_number,
2097
+ openid: params.openid,
2098
+ plate_color: params.plate_color
2099
+ });
2256
2100
  }
2257
2101
  /**
2258
- * 请求分账回退
2102
+ * 扣费受理
2259
2103
  *
2260
- * 对已经分账成功的订单,商户可以通过此接口将分账资金从接收方回退给分账方。
2261
- * 此接口采用同步处理模式,会实时返回处理结果。
2104
+ * 用户离场时调用此接口完成订单受理,微信支付进行异步扣款。
2262
2105
  *
2263
- * 注意:
2264
- * - 单笔分账单最多支持 50 次回退
2265
- * - 回退窗口期为 180 天
2266
- * - 仅支持对 MERCHANT_ID 类型且分账结果为 SUCCESS 的接收方进行回退
2267
- * - 不支持对个人接收方的回退
2106
+ * **重要**:必须确认接口返回的交易状态为 "ACCEPTED" 才能放行车辆。
2107
+ * 若未接收到该状态而放行车辆离场,造成的资金损失由商户侧自行承担。
2268
2108
  *
2269
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012525287
2109
+ * @param request - 扣费受理请求参数
2110
+ * @returns 扣费受理结果,包含交易状态
2111
+ *
2112
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534352
2270
2113
  */
2271
- async createReturnOrder(request) {
2114
+ async createTransaction(request) {
2272
2115
  return this.client.post(
2273
- "/v3/profitsharing/return-orders",
2116
+ "/v3/vehicle/transactions/parking",
2274
2117
  request
2275
2118
  );
2276
2119
  }
2277
2120
  /**
2278
- * 查询分账回退结果
2121
+ * 查询停车订单
2279
2122
  *
2280
- * 通过商户回退单号查询分账回退的处理结果。
2281
- * 如果回退结果为 PROCESSING,请不要更换商户回退单号重复发起回退,
2282
- * 否则会出现资金风险。
2123
+ * 通过商户订单号查询停车扣费订单状态和详情。
2124
+ * 如果在所有通知频率后没有收到微信侧回调,商户应调用此接口确认订单状态。
2283
2125
  *
2284
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012526279
2126
+ * @param outTradeNo - 商户系统内部订单号
2127
+ * @returns 停车订单信息,包含交易状态和支付详情
2128
+ *
2129
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534308
2285
2130
  */
2286
- async queryReturnOrder(params) {
2131
+ async queryTransaction(outTradeNo) {
2287
2132
  return this.client.get(
2288
- `/v3/profitsharing/return-orders/${params.outReturnNo}`,
2289
- { out_order_no: params.outOrderNo }
2133
+ `/v3/vehicle/transactions/out-trade-no/${outTradeNo}`
2290
2134
  );
2291
2135
  }
2292
2136
  /**
2293
- * 解冻剩余资金
2137
+ * 申请停车退款
2294
2138
  *
2295
- * 将订单的金额全部解冻给本商户。
2296
- * 适用于无需分账或分账完成后需将剩余冻结资金解冻给商户的场景。
2297
- * 此接口采用异步处理模式。
2139
+ * 交易时间超过一年的订单无法提交退款。
2140
+ * 微信支付退款支持单笔交易分多次退款(不超过50次),多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。
2141
+ * 申请退款总金额不能超过订单金额。
2142
+ * 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号。
2298
2143
  *
2299
- * 注意:
2300
- * - 当分账已完成(金额全部分完)时,无需再请求此接口
2301
- * - 同一分账单号多次请求视为同一请求(幂等)
2144
+ * **注意**:申请退款接口的返回仅代表业务的受理情况,具体退款是否成功,需要通过查询退款接口获取结果。
2302
2145
  *
2303
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012526374
2146
+ * @param request - 申请退款请求参数
2147
+ * @returns 退款受理结果
2148
+ *
2149
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557131
2304
2150
  */
2305
- async unfreeze(request) {
2306
- return this.client.post(
2307
- "/v3/profitsharing/orders/unfreeze",
2308
- request
2309
- );
2151
+ async applyRefund(request) {
2152
+ return this.client.post("/v3/refund/domestic/refunds", request);
2310
2153
  }
2311
2154
  /**
2312
- * 查询剩余待分金额
2155
+ * 查询单笔退款
2313
2156
  *
2314
- * 通过微信支付订单号查询该订单的剩余未分账金额。
2315
- * 可用于判断是否可以继续分账以及剩余可分金额。
2157
+ * 通过商户退款单号查询退款状态和详情。
2158
+ * 提交退款申请后,建议每分钟查询一次退款状态;超过5分钟仍为处理中时,逐步衰减查询频率。
2316
2159
  *
2317
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012457939
2160
+ * @param outRefundNo - 商户退款单号
2161
+ * @returns 退款详细信息
2162
+ *
2163
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557161
2318
2164
  */
2319
- async queryAmount(transactionId) {
2165
+ async queryRefund(outRefundNo) {
2320
2166
  return this.client.get(
2321
- `/v3/profitsharing/transactions/${transactionId}/amounts`
2167
+ `/v3/refund/domestic/refunds/${outRefundNo}`
2322
2168
  );
2323
2169
  }
2170
+ };
2171
+ var BillService = class {
2172
+ constructor(client) {
2173
+ this.client = client;
2174
+ }
2175
+ client;
2324
2176
  /**
2325
- * 添加分账接收方
2177
+ * 申请交易账单
2326
2178
  *
2327
- * 商户在发起分账前,需要先通过此接口添加分账接收方。
2328
- * 每个商户号最多添加 2 万个分账接收方。
2329
- * 接收方全称(name 字段)需使用微信支付公钥进行 RSAES-OAEP 加密。
2179
+ * 商户调用该接口获取交易账单的下载链接。次日 10:00 后获取前一天账单,
2180
+ * 支持三个月内的账单查询。
2330
2181
  *
2331
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012528995
2182
+ * @param params - 账单请求参数
2183
+ * @returns 包含 hash_type、hash_value 和 download_url 的响应
2184
+ *
2185
+ * @example
2186
+ * ```ts
2187
+ * const result = await billService.applyTradeBill({
2188
+ * bill_date: '2024-01-15',
2189
+ * bill_type: 'ALL',
2190
+ * tar_type: 'GZIP',
2191
+ * });
2192
+ * console.log(result.data.download_url);
2193
+ * ```
2332
2194
  */
2333
- async addReceiver(request) {
2334
- return this.client.post(
2335
- "/v3/profitsharing/receivers/add",
2336
- request
2337
- );
2195
+ async applyTradeBill(params) {
2196
+ return this.client.get("/v3/bill/tradebill", {
2197
+ bill_date: params.bill_date,
2198
+ bill_type: params.bill_type,
2199
+ tar_type: params.tar_type
2200
+ });
2338
2201
  }
2339
2202
  /**
2340
- * 删除分账接收方
2203
+ * 申请资金账单
2341
2204
  *
2342
- * 商户可以通过此接口删除已添加的分账接收方。
2343
- * 删除后,该接收方将无法参与新的分账。
2205
+ * 商户调用该接口获取资金账单的下载链接。次日 10:00 后获取前一天账单,
2206
+ * 支持三个月内的账单查询。
2344
2207
  *
2345
- * 注意:
2346
- * - 删除接口有频率限制,请勿频繁调用
2347
- * - 已参与分账的接收方仍可被删除,但不会影响已完成的交易
2208
+ * @param params - 账单请求参数
2209
+ * @returns 包含 hash_type、hash_value 和 download_url 的响应
2348
2210
  *
2349
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012529590
2211
+ * @example
2212
+ * ```ts
2213
+ * const result = await billService.applyFundFlowBill({
2214
+ * bill_date: '2024-01-15',
2215
+ * account_type: 'BASIC',
2216
+ * tar_type: 'GZIP',
2217
+ * });
2218
+ * console.log(result.data.download_url);
2219
+ * ```
2350
2220
  */
2351
- async deleteReceiver(request) {
2352
- return this.client.post(
2353
- "/v3/profitsharing/receivers/delete",
2354
- request
2355
- );
2221
+ async applyFundFlowBill(params) {
2222
+ return this.client.get("/v3/bill/fundflowbill", {
2223
+ bill_date: params.bill_date,
2224
+ account_type: params.account_type,
2225
+ tar_type: params.tar_type
2226
+ });
2356
2227
  }
2357
2228
  /**
2358
2229
  * 申请分账账单
2359
2230
  *
2360
- * 商户可通过此接口获取分账账单的下载链接。
2361
- * 仅支持最近三个月的账单。
2362
- *
2363
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012529628
2364
- */
2365
- async bill(params) {
2366
- return this.client.get("/v3/profitsharing/bills", params);
2367
- }
2368
- /**
2369
- * 下载分账账单
2231
+ * 商户调用该接口获取分账账单的下载链接。次日 10:00 后获取前一天账单,
2232
+ * 支持三个月内的账单查询。
2370
2233
  *
2371
- * 通过申请分账账单接口返回的 download_url,以 GET 方式下载账单原始文件。
2372
- * 下载地址 30 秒内有效,请及时下载。
2373
- * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
2234
+ * @param params - 账单请求参数
2235
+ * @returns 包含 hash_type、hash_value 和 download_url 的响应
2374
2236
  *
2375
- * @param downloadUrl - 申请分账账单返回的 download_url
2237
+ * @example
2238
+ * ```ts
2239
+ * const result = await billService.applyProfitSharingBill({
2240
+ * bill_date: '2024-01-15',
2241
+ * tar_type: 'GZIP',
2242
+ * });
2243
+ * console.log(result.data.download_url);
2244
+ * ```
2376
2245
  */
2377
- async downloadBill(downloadUrl) {
2378
- return this.client.downloadRaw(downloadUrl);
2379
- }
2380
- };
2381
-
2382
- // src/services/payscore.ts
2383
- var PayScoreService = class {
2384
- client;
2385
- constructor(client) {
2386
- this.client = client;
2246
+ async applyProfitSharingBill(params) {
2247
+ return this.client.get("/v3/bill/profitsharingbill", {
2248
+ bill_date: params.bill_date,
2249
+ tar_type: params.tar_type
2250
+ });
2387
2251
  }
2388
2252
  /**
2389
- * 创建支付分订单
2253
+ * 申请单个子商户资金账单
2390
2254
  *
2391
- * 当用户申请使用服务时,商户需调用此接口创建支付分订单。
2392
- * 创单成功后订单状态 state CREATED(已创建),返回的 package
2393
- * 参数用于拉起支付分小程序确认订单页面。
2255
+ * 服务商调用该接口获取单个子商户资金账单的下载链接。
2256
+ * 返回的账单文件使用 AES-256-GCM 加密,需用子商户的 API 证书私钥解密。
2394
2257
  *
2395
- * - 需确认模式下,need_user_confirm 必须固定传 true
2396
- * - risk_fund.name:先免模式可选 DEPOSIT/ADVANCE/CASH_DEPOSIT,先享模式固定 ESTIMATE_ORDER_COST
2397
- * - risk_fund.amount 不可超过服务ID风险金额上限
2398
- * - 该接口支持原参重入,相同参数重复调用可以返回成功
2258
+ * @param params - 账单请求参数
2259
+ * @returns 加密账单下载信息
2399
2260
  *
2400
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587900
2261
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013071235
2401
2262
  */
2402
- async createOrder(request) {
2403
- return this.client.post("/v3/payscore/serviceorder", request);
2263
+ async applySubMerchantFundFlowBill(params) {
2264
+ return this.client.get("/v3/bill/sub-merchant-fundflowbill", {
2265
+ sub_mchid: params.sub_mchid,
2266
+ bill_date: params.bill_date,
2267
+ account_type: params.account_type,
2268
+ algorithm: params.algorithm,
2269
+ tar_type: params.tar_type
2270
+ });
2404
2271
  }
2405
2272
  /**
2406
- * 查询支付分订单
2273
+ * 申请二级商户资金账单
2407
2274
  *
2408
- * 通过商户服务订单号或回跳查询ID查询支付分订单状态和详情。
2409
- * out_order_no query_id 必须提供其中一个,不可同时提供。
2275
+ * 电商平台调用该接口获取二级商户资金账单的下载链接。
2276
+ * 返回的账单文件使用 AES-256-GCM 加密,需用平台的 API 证书私钥解密。
2410
2277
  *
2411
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587902
2278
+ * @param params - 账单请求参数
2279
+ * @returns 加密账单下载信息
2280
+ *
2281
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013071235
2412
2282
  */
2413
- async queryOrder(params) {
2414
- const queryParams = {
2415
- service_id: params.service_id,
2416
- appid: params.appid
2417
- };
2418
- if (params.out_order_no) {
2419
- queryParams["out_order_no"] = params.out_order_no;
2420
- }
2421
- if (params.query_id) {
2422
- queryParams["query_id"] = params.query_id;
2423
- }
2424
- return this.client.get("/v3/payscore/serviceorder", queryParams);
2283
+ async applyEcommerceFundFlowBill(params) {
2284
+ return this.client.get("/v3/ecommerce/bill/fundflowbill", {
2285
+ bill_date: params.bill_date,
2286
+ account_type: params.account_type,
2287
+ tar_type: params.tar_type,
2288
+ algorithm: params.algorithm
2289
+ });
2425
2290
  }
2426
2291
  /**
2427
- * 取消支付分订单
2292
+ * 下载账单文件
2428
2293
  *
2429
- * 取消已创建、用户已确认或待支付状态的支付分订单。
2430
- * 可在订单状态为 CREATED、USER_CONFIRM(用户已确认)和 USER_PAYING(待支付)时调用。
2294
+ * 使用申请账单接口返回的 download_url 下载账单文件。
2295
+ * download_url 有效期为 5 分钟(分账账单为 30 秒),需及时下载。
2431
2296
  *
2432
- * - 若因网络原因未获取到接口返回内容,可使用相同参数重试,该接口支持原参重入
2433
- * - 待支付订单若用户正主动支付或系统正自动扣款时调用,可能报错,建议等待 3 分钟后重试
2297
+ * 下载完成后建议计算文件的 SHA1 哈希值,与申请账单接口返回的 hash_value
2298
+ * 进行比对,确保账单文件完整性。
2434
2299
  *
2435
- * @param outOrderNo - 商户服务订单号
2436
- * @param request - 取消订单请求参数
2437
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587905
2438
- */
2439
- async cancelOrder(outOrderNo, request) {
2440
- return this.client.post(
2441
- `/v3/payscore/serviceorder/${outOrderNo}/cancel`,
2442
- request
2443
- );
2444
- }
2445
- /**
2446
- * 完结支付分订单
2300
+ * @param downloadUrl - 申请账单接口返回的 download_url
2301
+ * @returns 包含原始账单文件 Buffer 的响应
2447
2302
  *
2448
- * 服务完成后,商户需调用此接口通知微信支付服务已结束。
2449
- * 订单完结后,支付分会持续自动扣款,无需重复调用完结接口。
2303
+ * @example
2304
+ * ```ts
2305
+ * // 先申请账单获取 download_url
2306
+ * const applyResult = await billService.applyTradeBill({
2307
+ * bill_date: '2024-01-15',
2308
+ * tar_type: 'GZIP',
2309
+ * });
2450
2310
  *
2451
- * - total_amount = 后付费项目金额总和 - 优惠项目金额总和
2452
- * - 先免模式:订单收款总金额 创单传的服务风险金额 ≤ 服务ID风险金额上限
2453
- * - 先享模式:订单收款总金额 ≤ 服务ID风险金额上限
2454
- * - 调用完结接口后 collection.state 变为 USER_PAYING(待支付状态)
2311
+ * // 下载账单文件
2312
+ * const downloadResult = await billService.downloadBill(
2313
+ * applyResult.data.download_url,
2314
+ * );
2455
2315
  *
2456
- * @param outOrderNo - 商户服务订单号
2457
- * @param request - 完结订单请求参数
2458
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587955
2316
+ * // 验证哈希值
2317
+ * const crypto = require('crypto');
2318
+ * const fileHash = crypto
2319
+ * .createHash('sha1')
2320
+ * .update(downloadResult.data)
2321
+ * .digest('hex');
2322
+ * console.log(fileHash === applyResult.data.hash_value); // true
2323
+ * ```
2459
2324
  */
2460
- async completeOrder(outOrderNo, request) {
2461
- return this.client.post(
2462
- `/v3/payscore/serviceorder/${outOrderNo}/complete`,
2463
- request
2464
- );
2325
+ async downloadBill(downloadUrl) {
2326
+ return this.client.downloadRaw(downloadUrl);
2465
2327
  }
2466
2328
  /**
2467
- * 修改订单金额
2329
+ * 下载账单文件并自动解压、校验摘要
2468
2330
  *
2469
- * 当订单处于 USER_PAYING(待支付)状态时,商户可调用此接口下调收款金额。
2470
- * 修改成功后微信侧将按新金额发起扣款。
2331
+ * 封装了完整的账单下载流程:
2332
+ * 1. 下载原始文件
2333
+ * 2. 自动检测并解压 GZIP 格式
2334
+ * 3. 可选:与申请账单返回的 hash_value 进行 SHA-1 摘要校验
2471
2335
  *
2472
- * - 只能下调扣款金额,不能上调
2473
- * - total_amount = post_payments.amount 总和 - post_discounts.amount 总和
2336
+ * @param downloadUrl - 申请账单接口返回的 download_url
2337
+ * @param expectedDigest - 期望的 SHA-1 摘要值(来自申请账单接口返回的 hash_value)
2338
+ * @returns 包含解压后账单文件 Buffer 的响应
2339
+ * @throws 如果摘要校验失败
2474
2340
  *
2475
- * @param outOrderNo - 商户服务订单号
2476
- * @param request - 修改订单金额请求参数
2477
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587957
2341
+ * @example
2342
+ * ```ts
2343
+ * const result = await billService.downloadAndVerifyBill(
2344
+ * applyResult.data.download_url,
2345
+ * applyResult.data.hash_value,
2346
+ * );
2347
+ * ```
2478
2348
  */
2479
- async modifyOrder(outOrderNo, request) {
2480
- return this.client.post(
2481
- `/v3/payscore/serviceorder/${outOrderNo}/modify`,
2482
- request
2483
- );
2349
+ async downloadAndVerifyBill(downloadUrl, expectedDigest) {
2350
+ const response = await this.client.downloadRaw(downloadUrl);
2351
+ let data = response.data;
2352
+ if (data.length >= 2 && data[0] === 31 && data[1] === 139) {
2353
+ data = zlib__default.default.gunzipSync(data);
2354
+ }
2355
+ if (expectedDigest) {
2356
+ const actualDigest = crypto2__default.default.createHash("sha1").update(data).digest("hex");
2357
+ if (actualDigest.toLowerCase() !== expectedDigest.toLowerCase()) {
2358
+ throw new Error(`\u8D26\u5355\u6458\u8981\u6821\u9A8C\u5931\u8D25: \u671F\u671B ${expectedDigest}, \u5B9E\u9645 ${actualDigest}`);
2359
+ }
2360
+ }
2361
+ return { ...response, data };
2362
+ }
2363
+ };
2364
+ var SUPPORTED_SIGNATURE_TYPES = /* @__PURE__ */ new Set(["WECHATPAY2-SHA256-RSA2048"]);
2365
+ var DEFAULT_SIGNATURE_TYPE = "WECHATPAY2-SHA256-RSA2048";
2366
+ var SUPPORTED_ALGORITHMS = /* @__PURE__ */ new Set(["AEAD_AES_256_GCM"]);
2367
+ var CallbackHandler = class {
2368
+ apiV3Key;
2369
+ certificates;
2370
+ constructor(apiV3Key, certificates) {
2371
+ this.apiV3Key = apiV3Key;
2372
+ this.certificates = certificates;
2484
2373
  }
2485
2374
  /**
2486
- * 同步订单状态
2487
- *
2488
- * 当支付分订单处于 USER_PAYING(待支付)状态,用户通过其他渠道支付后,
2489
- * 商户可调用此接口将订单改为已完成状态,微信支付将不再发起扣款。
2375
+ * 验证回调通知签名
2490
2376
  *
2491
- * - type 固定传 Order_Paid
2492
- * - paid_time 需满足:完结接口时间 < paid_time ≤ 同步接口时间 + 60 秒
2493
- * - 若用户正在通过支付分收银台支付或自动扣款中,调用可能报错,可等 3 分钟后重试
2377
+ * 使用微信支付平台公钥验证回调通知的签名。
2378
+ * 支持读取 Wechatpay-Signature-Type 头识别签名类型。
2494
2379
  *
2495
- * @param outOrderNo - 商户服务订单号
2496
- * @param request - 同步订单状态请求参数
2497
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587962
2380
+ * @param headers - 回调请求头
2381
+ * @param body - 回调请求体(原始 JSON 字符串)
2382
+ * @returns 签名验证是否通过
2383
+ * @throws 如果必填参数缺失、签名类型不支持或找不到对应的证书
2498
2384
  */
2499
- async syncOrder(outOrderNo, request) {
2500
- return this.client.post(
2501
- `/v3/payscore/serviceorder/${outOrderNo}/sync`,
2502
- request
2503
- );
2504
- }
2385
+ verifySignature(headers, body) {
2386
+ if (!headers["wechatpay-serial"]) {
2387
+ throw new Error("\u56DE\u8C03\u5934 wechatpay-serial \u4E0D\u80FD\u4E3A\u7A7A");
2388
+ }
2389
+ if (!headers["wechatpay-signature"]) {
2390
+ throw new Error("\u56DE\u8C03\u5934 wechatpay-signature \u4E0D\u80FD\u4E3A\u7A7A");
2391
+ }
2392
+ if (!headers["wechatpay-timestamp"]) {
2393
+ throw new Error("\u56DE\u8C03\u5934 wechatpay-timestamp \u4E0D\u80FD\u4E3A\u7A7A");
2394
+ }
2395
+ if (!headers["wechatpay-nonce"]) {
2396
+ throw new Error("\u56DE\u8C03\u5934 wechatpay-nonce \u4E0D\u80FD\u4E3A\u7A7A");
2397
+ }
2398
+ const signatureType = headers["wechatpay-signature-type"] ?? DEFAULT_SIGNATURE_TYPE;
2399
+ if (!SUPPORTED_SIGNATURE_TYPES.has(signatureType)) {
2400
+ throw new Error(`\u4E0D\u652F\u6301\u7684\u7B7E\u540D\u7C7B\u578B: ${signatureType}`);
2401
+ }
2402
+ const serialNo = headers["wechatpay-serial"];
2403
+ const publicKey = this.certificates.getPublicKey(serialNo);
2404
+ if (!publicKey) {
2405
+ throw new Error(`\u672A\u627E\u5230\u5E8F\u5217\u53F7\u4E3A ${serialNo} \u7684\u5E73\u53F0\u8BC1\u4E66\uFF0C\u8BF7\u786E\u4FDD\u5DF2\u914D\u7F6E\u5E73\u53F0\u8BC1\u4E66`);
2406
+ }
2407
+ return verifySignature(
2408
+ body,
2409
+ headers["wechatpay-signature"],
2410
+ headers["wechatpay-timestamp"],
2411
+ headers["wechatpay-nonce"],
2412
+ publicKey
2413
+ );
2414
+ }
2505
2415
  /**
2506
- * 申请退款
2507
- *
2508
- * 支付分订单完结扣款后,如需退款可通过此接口发起。
2509
- * transaction_id 来源于支付成功回调或查询支付分订单中的 collection.details。
2416
+ * 解密回调通知中的业务数据
2510
2417
  *
2511
- * @param request - 退款请求参数
2512
- * @returns 退款结果
2418
+ * 使用 AES-256-GCM 算法和 API V3 密钥解密 resource.ciphertext。
2513
2419
  *
2514
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587971
2420
+ * @param notification - 回调通知 JSON 对象
2421
+ * @returns 解密后的业务数据
2422
+ * @throws 如果通知结构无效、算法不匹配或解密失败
2515
2423
  */
2516
- async applyRefund(request) {
2517
- return this.client.post("/v3/refund/domestic/refunds", request);
2424
+ decryptNotification(notification) {
2425
+ const { resource } = notification;
2426
+ if (!resource.algorithm) {
2427
+ throw new Error("\u56DE\u8C03\u901A\u77E5 resource \u7F3A\u5C11 algorithm \u5B57\u6BB5");
2428
+ }
2429
+ if (!resource.ciphertext) {
2430
+ throw new Error("\u56DE\u8C03\u901A\u77E5 resource \u7F3A\u5C11 ciphertext \u5B57\u6BB5");
2431
+ }
2432
+ if (!resource.nonce) {
2433
+ throw new Error("\u56DE\u8C03\u901A\u77E5 resource \u7F3A\u5C11 nonce \u5B57\u6BB5");
2434
+ }
2435
+ if (!SUPPORTED_ALGORITHMS.has(resource.algorithm)) {
2436
+ throw new Error(`\u4E0D\u652F\u6301\u7684\u52A0\u5BC6\u7B97\u6CD5: ${resource.algorithm}`);
2437
+ }
2438
+ const plaintext = this.aesGcmDecrypt(
2439
+ resource.ciphertext,
2440
+ resource.associated_data,
2441
+ resource.nonce
2442
+ );
2443
+ let parsed;
2444
+ try {
2445
+ parsed = JSON.parse(plaintext);
2446
+ } catch (error) {
2447
+ throw new Error(
2448
+ `\u56DE\u8C03\u6570\u636E JSON \u89E3\u6790\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
2449
+ );
2450
+ }
2451
+ if (parsed === null || parsed === void 0 || typeof parsed !== "object") {
2452
+ throw new Error(`\u56DE\u8C03\u6570\u636E\u683C\u5F0F\u65E0\u6548: \u671F\u671B\u5BF9\u8C61\uFF0C\u5B9E\u9645\u4E3A ${typeof parsed}`);
2453
+ }
2454
+ const data = parsed;
2455
+ return {
2456
+ id: notification.id,
2457
+ create_time: notification.create_time,
2458
+ event_type: notification.event_type,
2459
+ resource_type: notification.resource_type,
2460
+ summary: notification.summary,
2461
+ data
2462
+ };
2518
2463
  }
2519
2464
  /**
2520
- * 查询单笔退款
2521
- *
2522
- * 通过商户退款单号查询退款状态和详情。
2523
- *
2524
- * @param outRefundNo - 商户退款单号
2525
- * @returns 退款详情
2465
+ * 处理回调通知(验证签名 + 解密数据)
2526
2466
  *
2527
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587973
2467
+ * @param headers - 回调请求头
2468
+ * @param body - 回调请求体(原始 JSON 字符串)
2469
+ * @returns 解密后的回调数据
2528
2470
  */
2529
- async queryRefund(outRefundNo) {
2530
- return this.client.get(`/v3/refund/domestic/refunds/${outRefundNo}`);
2471
+ process(headers, body) {
2472
+ const valid = this.verifySignature(headers, body);
2473
+ if (!valid) {
2474
+ throw new Error("\u56DE\u8C03\u901A\u77E5\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25");
2475
+ }
2476
+ const notification = JSON.parse(body);
2477
+ return this.decryptNotification(notification);
2531
2478
  }
2532
- };
2533
-
2534
- // src/services/parking.ts
2535
- var ParkingService = class {
2536
- client;
2537
- constructor(client) {
2538
- this.client = client;
2479
+ /**
2480
+ * 处理支付成功回调通知
2481
+ */
2482
+ processTransactionCallback(headers, body) {
2483
+ return this.process(headers, body);
2539
2484
  }
2540
2485
  /**
2541
- * 创建停车入场
2542
- *
2543
- * 用户入场时调用此接口创建停车入场信息。
2544
- * 根据返回的车牌状态判断用户是否开通支付分停车服务:
2545
- * - state 为 NORMAL:正常,可使用支付分停车服务
2546
- * - state 为 BLOCKED:不可用,通过 block_reason 获取具体原因
2547
- *
2548
- * @param request - 创建停车入场请求参数
2549
- * @returns 停车入场信息,包含入场ID和车牌状态
2550
- *
2551
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533937
2486
+ * 处理退款回调通知
2552
2487
  */
2553
- async createEntry(request) {
2554
- return this.client.post("/v3/vehicle/parking/parkings", request);
2488
+ processRefundCallback(headers, body) {
2489
+ return this.process(headers, body);
2555
2490
  }
2556
2491
  /**
2557
- * 查询车牌服务开通信息
2492
+ * 处理分账动账回调通知
2558
2493
  *
2559
- * 查询用户是否开通微信支付分停车服务。
2560
- * 用于在用户未收到入场状态变更通知时,主动确认车牌服务开通状态。
2494
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012289679
2495
+ */
2496
+ processProfitSharingCallback(headers, body) {
2497
+ return this.process(headers, body);
2498
+ }
2499
+ /**
2500
+ * 处理支付分用户确认订单回调通知
2561
2501
  *
2562
- * @param params - 查询参数,包含appid、车牌号、用户openid和车牌颜色
2563
- * @returns 车牌服务开通信息,包含开通状态和开通时间
2502
+ * 用户确认支付分订单后,微信支付会向商户发送此回调通知。
2503
+ * event_type 为 PAYSCORE.USER_CONFIRM。
2564
2504
  *
2565
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534043
2505
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587953
2566
2506
  */
2567
- async queryPlateService(params) {
2568
- return this.client.get("/v3/vehicle/parking/services/find", {
2569
- appid: params.appid,
2570
- plate_number: params.plate_number,
2571
- openid: params.openid,
2572
- plate_color: params.plate_color
2573
- });
2507
+ processPayScoreUserConfirmCallback(headers, body) {
2508
+ return this.process(headers, body);
2574
2509
  }
2575
2510
  /**
2576
- * 扣费受理
2511
+ * 处理支付分支付成功回调通知
2577
2512
  *
2578
- * 用户离场时调用此接口完成订单受理,微信支付进行异步扣款。
2513
+ * 支付分订单扣款成功后,微信支付会向商户发送此回调通知。
2514
+ * event_type 为 PAYSCORE.USER_PAID。
2579
2515
  *
2580
- * **重要**:必须确认接口返回的交易状态为 "ACCEPTED" 才能放行车辆。
2581
- * 若未接收到该状态而放行车辆离场,造成的资金损失由商户侧自行承担。
2516
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587960
2517
+ */
2518
+ processPayScoreUserPaidCallback(headers, body) {
2519
+ return this.process(headers, body);
2520
+ }
2521
+ /**
2522
+ * 处理停车入场状态变更回调通知
2582
2523
  *
2583
- * @param request - 扣费受理请求参数
2584
- * @returns 扣费受理结果,包含交易状态
2524
+ * 场内车牌状态发生变化后,微信支付通过此回调通知商户。
2525
+ * 例如用户开通/暂停支付分停车服务、用户移除车牌等。
2585
2526
  *
2586
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534352
2527
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284177
2587
2528
  */
2588
- async createTransaction(request) {
2589
- return this.client.post(
2590
- "/v3/vehicle/transactions/parking",
2591
- request
2592
- );
2529
+ processParkingEntryStatusCallback(headers, body) {
2530
+ return this.process(headers, body);
2593
2531
  }
2594
2532
  /**
2595
- * 查询停车订单
2596
- *
2597
- * 通过商户订单号查询停车扣费订单状态和详情。
2598
- * 如果在所有通知频率后没有收到微信侧回调,商户应调用此接口确认订单状态。
2533
+ * 处理停车订单支付结果回调通知
2599
2534
  *
2600
- * @param outTradeNo - 商户系统内部订单号
2601
- * @returns 停车订单信息,包含交易状态和支付详情
2535
+ * 扣费受理后,微信支付异步扣款完成时会发送此回调通知。
2536
+ * event_type 为 TRANSACTION.SUCCESS(支付成功)、TRANSACTION.FAIL(支付失败)
2537
+ * 或 TRANSACTION.PAY_BACK(还款)。
2602
2538
  *
2603
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534308
2539
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284311
2604
2540
  */
2605
- async queryTransaction(outTradeNo) {
2606
- return this.client.get(
2607
- `/v3/vehicle/transactions/out-trade-no/${outTradeNo}`
2608
- );
2541
+ processParkingTransactionCallback(headers, body) {
2542
+ return this.process(headers, body);
2609
2543
  }
2610
2544
  /**
2611
- * 申请停车退款
2545
+ * 处理停车退款结果回调通知
2612
2546
  *
2613
- * 交易时间超过一年的订单无法提交退款。
2614
- * 微信支付退款支持单笔交易分多次退款(不超过50次),多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。
2615
- * 申请退款总金额不能超过订单金额。
2616
- * 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号。
2547
+ * 退款完成后,微信支付会向商户发送此回调通知。
2548
+ * event_type 为 REFUND.SUCCESS(退款成功)、REFUND.ABNORMAL(退款异常)
2549
+ * 或 REFUND.CLOSED(退款关闭)。
2617
2550
  *
2618
- * **注意**:申请退款接口的返回仅代表业务的受理情况,具体退款是否成功,需要通过查询退款接口获取结果。
2551
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012083103
2552
+ */
2553
+ processParkingRefundCallback(headers, body) {
2554
+ return this.process(headers, body);
2555
+ }
2556
+ /**
2557
+ * 处理代金券核销事件回调通知
2619
2558
  *
2620
- * @param request - 申请退款请求参数
2621
- * @returns 退款受理结果
2559
+ * 用户使用券后,微信会把相关核销券信息发送给商户。
2560
+ * event_type 为 COUPON.USE。
2622
2561
  *
2623
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557131
2562
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285250
2624
2563
  */
2625
- async applyRefund(request) {
2626
- return this.client.post("/v3/refund/domestic/refunds", request);
2564
+ processCouponUseCallback(headers, body) {
2565
+ return this.process(headers, body);
2627
2566
  }
2628
2567
  /**
2629
- * 查询单笔退款
2630
- *
2631
- * 通过商户退款单号查询退款状态和详情。
2632
- * 提交退款申请后,建议每分钟查询一次退款状态;超过5分钟仍为处理中时,逐步衰减查询频率。
2568
+ * 处理合单支付成功回调通知
2633
2569
  *
2634
- * @param outRefundNo - 商户退款单号
2635
- * @returns 退款详细信息
2570
+ * 合单支付成功后,微信支付会向商户发送此回调通知。
2571
+ * event_type 为 TRANSACTION.SUCCESS。
2636
2572
  *
2637
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557161
2573
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421231
2638
2574
  */
2639
- async queryRefund(outRefundNo) {
2640
- return this.client.get(
2641
- `/v3/refund/domestic/refunds/${outRefundNo}`
2642
- );
2643
- }
2644
- };
2645
-
2646
- // src/services/bill.ts
2647
- var BillService = class {
2648
- constructor(client) {
2649
- this.client = client;
2575
+ processCombineTransactionCallback(headers, body) {
2576
+ return this.process(headers, body);
2650
2577
  }
2651
- client;
2652
2578
  /**
2653
- * 申请交易账单
2579
+ * 处理商家转账状态变更回调通知
2654
2580
  *
2655
- * 商户调用该接口获取交易账单的下载链接。次日 10:00 后获取前一天账单,
2656
- * 支持三个月内的账单查询。
2657
- *
2658
- * @param params - 账单请求参数
2659
- * @returns 包含 hash_type、hash_value 和 download_url 的响应
2581
+ * 转账单据状态变更后,微信支付会向商户发送此回调通知。
2582
+ * 包括转账成功、转账失败、已撤销等状态变更。
2660
2583
  *
2661
- * @example
2662
- * ```ts
2663
- * const result = await billService.applyTradeBill({
2664
- * bill_date: '2024-01-15',
2665
- * bill_type: 'ALL',
2666
- * tar_type: 'GZIP',
2667
- * });
2668
- * console.log(result.data.download_url);
2669
- * ```
2584
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012712115
2670
2585
  */
2671
- async applyTradeBill(params) {
2672
- return this.client.get("/v3/bill/tradebill", {
2673
- bill_date: params.bill_date,
2674
- bill_type: params.bill_type,
2675
- tar_type: params.tar_type
2676
- });
2586
+ processMerchantTransferCallback(headers, body) {
2587
+ return this.process(headers, body);
2677
2588
  }
2678
2589
  /**
2679
- * 申请资金账单
2680
- *
2681
- * 商户调用该接口获取资金账单的下载链接。次日 10:00 后获取前一天账单,
2682
- * 支持三个月内的账单查询。
2590
+ * 处理免确认收款授权变更回调通知
2683
2591
  *
2684
- * @param params - 账单请求参数
2685
- * @returns 包含 hash_type、hash_value 和 download_url 的响应
2592
+ * 用户确认授权或解除授权后,微信支付会向商户发送此回调通知。
2593
+ * 包括授权生效(TAKING_EFFECT)和授权关闭(CLOSED)等状态变更。
2686
2594
  *
2687
- * @example
2688
- * ```ts
2689
- * const result = await billService.applyFundFlowBill({
2690
- * bill_date: '2024-01-15',
2691
- * account_type: 'BASIC',
2692
- * tar_type: 'GZIP',
2693
- * });
2694
- * console.log(result.data.download_url);
2695
- * ```
2595
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4014512908
2696
2596
  */
2697
- async applyFundFlowBill(params) {
2698
- return this.client.get("/v3/bill/fundflowbill", {
2699
- bill_date: params.bill_date,
2700
- account_type: params.account_type,
2701
- tar_type: params.tar_type
2702
- });
2597
+ processMerchantTransferAuthorizationCallback(headers, body) {
2598
+ return this.process(headers, body);
2703
2599
  }
2704
2600
  /**
2705
- * 申请分账账单
2706
- *
2707
- * 商户调用该接口获取分账账单的下载链接。次日 10:00 后获取前一天账单,
2708
- * 支持三个月内的账单查询。
2601
+ * 处理支付分退款结果回调通知
2709
2602
  *
2710
- * @param params - 账单请求参数
2711
- * @returns 包含 hash_type、hash_value 和 download_url 的响应
2603
+ * 支付分订单退款完成后,微信支付会向商户发送此回调通知。
2604
+ * event_type REFUND.SUCCESS(退款成功)、REFUND.ABNORMAL(退款异常)
2605
+ * 或 REFUND.CLOSED(退款关闭)。
2712
2606
  *
2713
- * @example
2714
- * ```ts
2715
- * const result = await billService.applyProfitSharingBill({
2716
- * bill_date: '2024-01-15',
2717
- * tar_type: 'GZIP',
2718
- * });
2719
- * console.log(result.data.download_url);
2720
- * ```
2607
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587976
2721
2608
  */
2722
- async applyProfitSharingBill(params) {
2723
- return this.client.get("/v3/bill/profitsharingbill", {
2724
- bill_date: params.bill_date,
2725
- tar_type: params.tar_type
2726
- });
2609
+ processPayScoreRefundCallback(headers, body) {
2610
+ return this.process(headers, body);
2727
2611
  }
2728
2612
  /**
2729
- * 下载账单文件
2730
- *
2731
- * 使用申请账单接口返回的 download_url 下载账单文件。
2732
- * download_url 有效期为 5 分钟(分账账单为 30 秒),需及时下载。
2733
- *
2734
- * 下载完成后建议计算文件的 SHA1 哈希值,与申请账单接口返回的 hash_value
2735
- * 进行比对,确保账单文件完整性。
2736
- *
2737
- * @param downloadUrl - 申请账单接口返回的 download_url
2738
- * @returns 包含原始账单文件 Buffer 的响应
2739
- *
2740
- * @example
2741
- * ```ts
2742
- * // 先申请账单获取 download_url
2743
- * const applyResult = await billService.applyTradeBill({
2744
- * bill_date: '2024-01-15',
2745
- * tar_type: 'GZIP',
2746
- * });
2613
+ * 处理消费者投诉通知回调
2747
2614
  *
2748
- * // 下载账单文件
2749
- * const downloadResult = await billService.downloadBill(
2750
- * applyResult.data.download_url,
2751
- * );
2615
+ * 用户提交投诉、用户撤诉、用户确认投诉已处理完成时,
2616
+ * 微信支付会通过此回调通知商户。
2752
2617
  *
2753
- * // 验证哈希值
2754
- * const crypto = require('crypto');
2755
- * const fileHash = crypto
2756
- * .createHash('sha1')
2757
- * .update(downloadResult.data)
2758
- * .digest('hex');
2759
- * console.log(fileHash === applyResult.data.hash_value); // true
2760
- * ```
2618
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012289719
2761
2619
  */
2762
- async downloadBill(downloadUrl) {
2763
- return this.client.downloadRaw(downloadUrl);
2764
- }
2765
- };
2766
- var SUPPORTED_SIGNATURE_TYPES = /* @__PURE__ */ new Set(["WECHATPAY2-SHA256-RSA2048"]);
2767
- var DEFAULT_SIGNATURE_TYPE = "WECHATPAY2-SHA256-RSA2048";
2768
- var SUPPORTED_ALGORITHMS = /* @__PURE__ */ new Set(["AEAD_AES_256_GCM"]);
2769
- var CallbackHandler = class {
2770
- apiV3Key;
2771
- certificates;
2772
- constructor(apiV3Key, certificates) {
2773
- this.apiV3Key = apiV3Key;
2774
- this.certificates = certificates;
2620
+ processComplaintCallback(headers, body) {
2621
+ return this.process(headers, body);
2775
2622
  }
2776
2623
  /**
2777
- * 验证回调通知签名
2624
+ * 处理医保支付成功回调通知
2778
2625
  *
2779
- * 使用微信支付平台公钥验证回调通知的签名。
2780
- * 支持读取 Wechatpay-Signature-Type 头识别签名类型。
2626
+ * 医保自费混合订单支付成功后,微信支付会向商户发送此回调通知。
2627
+ * event_type MED_INS.SUCCESS。
2781
2628
  *
2782
- * @param headers - 回调请求头
2783
- * @param body - 回调请求体(原始 JSON 字符串)
2784
- * @returns 签名验证是否通过
2785
- * @throws 如果必填参数缺失、签名类型不支持或找不到对应的证书
2629
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781502
2786
2630
  */
2787
- verifySignature(headers, body) {
2788
- if (!headers["wechatpay-serial"]) {
2789
- throw new Error("\u56DE\u8C03\u5934 wechatpay-serial \u4E0D\u80FD\u4E3A\u7A7A");
2790
- }
2791
- if (!headers["wechatpay-signature"]) {
2792
- throw new Error("\u56DE\u8C03\u5934 wechatpay-signature \u4E0D\u80FD\u4E3A\u7A7A");
2793
- }
2794
- if (!headers["wechatpay-timestamp"]) {
2795
- throw new Error("\u56DE\u8C03\u5934 wechatpay-timestamp \u4E0D\u80FD\u4E3A\u7A7A");
2796
- }
2797
- if (!headers["wechatpay-nonce"]) {
2798
- throw new Error("\u56DE\u8C03\u5934 wechatpay-nonce \u4E0D\u80FD\u4E3A\u7A7A");
2799
- }
2800
- const signatureType = headers["wechatpay-signature-type"] ?? DEFAULT_SIGNATURE_TYPE;
2801
- if (!SUPPORTED_SIGNATURE_TYPES.has(signatureType)) {
2802
- throw new Error(`\u4E0D\u652F\u6301\u7684\u7B7E\u540D\u7C7B\u578B: ${signatureType}`);
2803
- }
2804
- const serialNo = headers["wechatpay-serial"];
2805
- const publicKey = this.certificates.getPublicKey(serialNo);
2806
- if (!publicKey) {
2807
- throw new Error(`\u672A\u627E\u5230\u5E8F\u5217\u53F7\u4E3A ${serialNo} \u7684\u5E73\u53F0\u8BC1\u4E66\uFF0C\u8BF7\u786E\u4FDD\u5DF2\u914D\u7F6E\u5E73\u53F0\u8BC1\u4E66`);
2808
- }
2809
- return verifySignature(
2810
- body,
2811
- headers["wechatpay-signature"],
2812
- headers["wechatpay-timestamp"],
2813
- headers["wechatpay-nonce"],
2814
- publicKey
2815
- );
2631
+ processMedInsSuccessCallback(headers, body) {
2632
+ return this.process(headers, body);
2816
2633
  }
2817
2634
  /**
2818
- * 解密回调通知中的业务数据
2635
+ * 处理医保退款回调通知
2819
2636
  *
2820
- * 使用 AES-256-GCM 算法和 API V3 密钥解密 resource.ciphertext。
2637
+ * 医保订单退款完成后,微信支付会向商户发送此回调通知。
2638
+ * event_type 为 MED_INS.REFUND.SUCCESS、MED_INS.REFUND.ABNORMAL 或 MED_INS.REFUND.CLOSED。
2821
2639
  *
2822
- * @param notification - 回调通知 JSON 对象
2823
- * @returns 解密后的业务数据
2824
- * @throws 如果通知结构无效、算法不匹配或解密失败
2640
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781502
2825
2641
  */
2826
- decryptNotification(notification) {
2827
- const { resource } = notification;
2828
- if (!resource.algorithm) {
2829
- throw new Error("\u56DE\u8C03\u901A\u77E5 resource \u7F3A\u5C11 algorithm \u5B57\u6BB5");
2830
- }
2831
- if (!resource.ciphertext) {
2832
- throw new Error("\u56DE\u8C03\u901A\u77E5 resource \u7F3A\u5C11 ciphertext \u5B57\u6BB5");
2833
- }
2834
- if (!resource.nonce) {
2835
- throw new Error("\u56DE\u8C03\u901A\u77E5 resource \u7F3A\u5C11 nonce \u5B57\u6BB5");
2836
- }
2837
- if (!SUPPORTED_ALGORITHMS.has(resource.algorithm)) {
2838
- throw new Error(`\u4E0D\u652F\u6301\u7684\u52A0\u5BC6\u7B97\u6CD5: ${resource.algorithm}`);
2839
- }
2840
- const plaintext = this.aesGcmDecrypt(
2841
- resource.ciphertext,
2842
- resource.associated_data,
2843
- resource.nonce
2844
- );
2845
- let parsed;
2846
- try {
2847
- parsed = JSON.parse(plaintext);
2848
- } catch (error) {
2849
- throw new Error(
2850
- `\u56DE\u8C03\u6570\u636E JSON \u89E3\u6790\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
2851
- );
2852
- }
2853
- if (parsed === null || parsed === void 0 || typeof parsed !== "object") {
2854
- throw new Error(`\u56DE\u8C03\u6570\u636E\u683C\u5F0F\u65E0\u6548: \u671F\u671B\u5BF9\u8C61\uFF0C\u5B9E\u9645\u4E3A ${typeof parsed}`);
2855
- }
2856
- const data = parsed;
2857
- return {
2858
- id: notification.id,
2859
- create_time: notification.create_time,
2860
- event_type: notification.event_type,
2861
- resource_type: notification.resource_type,
2862
- summary: notification.summary,
2863
- data
2864
- };
2642
+ processMedInsRefundCallback(headers, body) {
2643
+ return this.process(headers, body);
2865
2644
  }
2866
2645
  /**
2867
- * 处理回调通知(验证签名 + 解密数据)
2646
+ * 处理商圈会员积分服务授权结果回调通知
2868
2647
  *
2869
- * @param headers - 回调请求头
2870
- * @param body - 回调请求体(原始 JSON 字符串)
2871
- * @returns 解密后的回调数据
2648
+ * 用户在小程序内授权/解除授权商圈积分服务后,微信支付会向商户发送此回调通知。
2649
+ * event_type BUSINESS_CIRCLE.USER_AUTHORIZE BUSINESS_CIRCLE.USER_DEAUTHORIZE。
2650
+ *
2651
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285836
2872
2652
  */
2873
- process(headers, body) {
2874
- const valid = this.verifySignature(headers, body);
2875
- if (!valid) {
2876
- throw new Error("\u56DE\u8C03\u901A\u77E5\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25");
2877
- }
2878
- const notification = JSON.parse(body);
2879
- return this.decryptNotification(notification);
2653
+ processBusinessCircleAuthorizeCallback(headers, body) {
2654
+ return this.process(headers, body);
2880
2655
  }
2881
2656
  /**
2882
- * 处理支付成功回调通知
2657
+ * 处理商圈会员场内支付结果回调通知
2658
+ *
2659
+ * 用户在商圈内支付成功后,微信支付会向商户发送此回调通知。
2660
+ * event_type 为 TRANSACTION.SUCCESS。
2661
+ *
2662
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285856
2883
2663
  */
2884
- processTransactionCallback(headers, body) {
2664
+ processBusinessCircleTransactionCallback(headers, body) {
2885
2665
  return this.process(headers, body);
2886
2666
  }
2887
2667
  /**
2888
- * 处理退款回调通知
2668
+ * 处理商圈会员场内退款结果回调通知
2669
+ *
2670
+ * 商圈内交易退款完成后,微信支付会向商户发送此回调通知。
2671
+ * event_type 为 REFUND.SUCCESS、REFUND.ABNORMAL 或 REFUND.CLOSED。
2672
+ *
2673
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285869
2889
2674
  */
2890
- processRefundCallback(headers, body) {
2675
+ processBusinessCircleRefundCallback(headers, body) {
2891
2676
  return this.process(headers, body);
2892
2677
  }
2893
2678
  /**
2894
- * 处理分账动账回调通知
2895
- *
2896
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012289679
2897
- */
2898
- processProfitSharingCallback(headers, body) {
2899
- return this.process(headers, body);
2900
- }
2901
- /**
2902
- * 处理支付分用户确认订单回调通知
2903
- *
2904
- * 用户确认支付分订单后,微信支付会向商户发送此回调通知。
2905
- * event_type 为 PAYSCORE.USER_CONFIRM。
2906
- *
2907
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587953
2908
- */
2909
- processPayScoreUserConfirmCallback(headers, body) {
2910
- return this.process(headers, body);
2911
- }
2912
- /**
2913
- * 处理支付分支付成功回调通知
2914
- *
2915
- * 支付分订单扣款成功后,微信支付会向商户发送此回调通知。
2916
- * event_type 为 PAYSCORE.USER_PAID。
2917
- *
2918
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587960
2919
- */
2920
- processPayScoreUserPaidCallback(headers, body) {
2921
- return this.process(headers, body);
2922
- }
2923
- /**
2924
- * 处理停车入场状态变更回调通知
2925
- *
2926
- * 场内车牌状态发生变化后,微信支付通过此回调通知商户。
2927
- * 例如用户开通/暂停支付分停车服务、用户移除车牌等。
2928
- *
2929
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284177
2930
- */
2931
- processParkingEntryStatusCallback(headers, body) {
2932
- return this.process(headers, body);
2933
- }
2934
- /**
2935
- * 处理停车订单支付结果回调通知
2936
- *
2937
- * 扣费受理后,微信支付异步扣款完成时会发送此回调通知。
2938
- * event_type 为 TRANSACTION.SUCCESS(支付成功)、TRANSACTION.FAIL(支付失败)
2939
- * 或 TRANSACTION.PAY_BACK(还款)。
2940
- *
2941
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284311
2942
- */
2943
- processParkingTransactionCallback(headers, body) {
2944
- return this.process(headers, body);
2945
- }
2946
- /**
2947
- * 处理停车退款结果回调通知
2948
- *
2949
- * 退款完成后,微信支付会向商户发送此回调通知。
2950
- * event_type 为 REFUND.SUCCESS(退款成功)、REFUND.ABNORMAL(退款异常)
2951
- * 或 REFUND.CLOSED(退款关闭)。
2952
- *
2953
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012083103
2954
- */
2955
- processParkingRefundCallback(headers, body) {
2956
- return this.process(headers, body);
2957
- }
2958
- /**
2959
- * 处理代金券核销事件回调通知
2960
- *
2961
- * 用户使用券后,微信会把相关核销券信息发送给商户。
2962
- * event_type 为 COUPON.USE。
2963
- *
2964
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285250
2965
- */
2966
- processCouponUseCallback(headers, body) {
2967
- return this.process(headers, body);
2968
- }
2969
- /**
2970
- * 处理合单支付成功回调通知
2971
- *
2972
- * 合单支付成功后,微信支付会向商户发送此回调通知。
2973
- * event_type 为 TRANSACTION.SUCCESS。
2974
- *
2975
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421231
2976
- */
2977
- processCombineTransactionCallback(headers, body) {
2978
- return this.process(headers, body);
2979
- }
2980
- /**
2981
- * 处理商家转账状态变更回调通知
2982
- *
2983
- * 转账单据状态变更后,微信支付会向商户发送此回调通知。
2984
- * 包括转账成功、转账失败、已撤销等状态变更。
2985
- *
2986
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012712115
2987
- */
2988
- processMerchantTransferCallback(headers, body) {
2989
- return this.process(headers, body);
2990
- }
2991
- /**
2992
- * 处理免确认收款授权变更回调通知
2993
- *
2994
- * 用户确认授权或解除授权后,微信支付会向商户发送此回调通知。
2995
- * 包括授权生效(TAKING_EFFECT)和授权关闭(CLOSED)等状态变更。
2996
- *
2997
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4014512908
2998
- */
2999
- processMerchantTransferAuthorizationCallback(headers, body) {
3000
- return this.process(headers, body);
3001
- }
3002
- /**
3003
- * 处理支付分退款结果回调通知
3004
- *
3005
- * 支付分订单退款完成后,微信支付会向商户发送此回调通知。
3006
- * event_type 为 REFUND.SUCCESS(退款成功)、REFUND.ABNORMAL(退款异常)
3007
- * 或 REFUND.CLOSED(退款关闭)。
3008
- *
3009
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587976
3010
- */
3011
- processPayScoreRefundCallback(headers, body) {
3012
- return this.process(headers, body);
3013
- }
3014
- /**
3015
- * 处理消费者投诉通知回调
3016
- *
3017
- * 用户提交投诉、用户撤诉、用户确认投诉已处理完成时,
3018
- * 微信支付会通过此回调通知商户。
3019
- *
3020
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012289719
3021
- */
3022
- processComplaintCallback(headers, body) {
3023
- return this.process(headers, body);
3024
- }
3025
- /**
3026
- * 处理医保支付成功回调通知
3027
- *
3028
- * 医保自费混合订单支付成功后,微信支付会向商户发送此回调通知。
3029
- * event_type 为 MED_INS.SUCCESS。
3030
- *
3031
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781502
3032
- */
3033
- processMedInsSuccessCallback(headers, body) {
3034
- return this.process(headers, body);
3035
- }
3036
- /**
3037
- * 处理医保退款回调通知
3038
- *
3039
- * 医保订单退款完成后,微信支付会向商户发送此回调通知。
3040
- * event_type 为 MED_INS.REFUND.SUCCESS、MED_INS.REFUND.ABNORMAL 或 MED_INS.REFUND.CLOSED。
3041
- *
3042
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781502
3043
- */
3044
- processMedInsRefundCallback(headers, body) {
3045
- return this.process(headers, body);
3046
- }
3047
- /**
3048
- * 处理商圈会员积分服务授权结果回调通知
3049
- *
3050
- * 用户在小程序内授权/解除授权商圈积分服务后,微信支付会向商户发送此回调通知。
3051
- * event_type 为 BUSINESS_CIRCLE.USER_AUTHORIZE 或 BUSINESS_CIRCLE.USER_DEAUTHORIZE。
3052
- *
3053
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285836
3054
- */
3055
- processBusinessCircleAuthorizeCallback(headers, body) {
3056
- return this.process(headers, body);
3057
- }
3058
- /**
3059
- * 处理商圈会员场内支付结果回调通知
3060
- *
3061
- * 用户在商圈内支付成功后,微信支付会向商户发送此回调通知。
3062
- * event_type 为 TRANSACTION.SUCCESS。
3063
- *
3064
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285856
3065
- */
3066
- processBusinessCircleTransactionCallback(headers, body) {
3067
- return this.process(headers, body);
3068
- }
3069
- /**
3070
- * 处理商圈会员场内退款结果回调通知
3071
- *
3072
- * 商圈内交易退款完成后,微信支付会向商户发送此回调通知。
3073
- * event_type 为 REFUND.SUCCESS、REFUND.ABNORMAL 或 REFUND.CLOSED。
3074
- *
3075
- * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285869
3076
- */
3077
- processBusinessCircleRefundCallback(headers, body) {
3078
- return this.process(headers, body);
3079
- }
3080
- /**
3081
- * AES-256-GCM 解密
2679
+ * AES-256-GCM 解密
3082
2680
  *
3083
2681
  * @param ciphertext - Base64 编码的密文
3084
2682
  * @param associatedData - 附加数据(用于 AEAD 认证)
@@ -4545,346 +4143,1087 @@ var MerchantExclusiveCouponService = class {
4545
4143
  return this.client.get(`/v3/marketing/busifavor/users/coupons/${couponId}`, params);
4546
4144
  }
4547
4145
  };
4548
- function generateAppPaySign(appId, timeStamp, nonceStr, prepayId, privateKey) {
4549
- const signString = `${appId}
4550
- ${timeStamp}
4551
- ${nonceStr}
4552
- prepay_id=${prepayId}
4553
- `;
4554
- const signer = crypto2__default.default.createSign("RSA-SHA256");
4555
- signer.update(signString);
4556
- signer.end();
4557
- return signer.sign(privateKey, "base64");
4558
- }
4559
- function buildAppBridgeConfig(appId, partnerId, prepayId, privateKey) {
4560
- const timeStamp = String(Math.floor(Date.now() / 1e3));
4561
- const nonceStr = generateNonceStr();
4562
- const sign2 = generateAppPaySign(appId, timeStamp, nonceStr, prepayId, privateKey);
4563
- return {
4564
- appId,
4565
- partnerId,
4566
- prepayId,
4567
- packageValue: "Sign=WXPay",
4568
- nonceStr,
4569
- timeStamp,
4570
- sign: sign2
4571
- };
4572
- }
4573
- function generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey) {
4574
- const signString = `${appId}
4575
- ${timeStamp}
4576
- ${nonceStr}
4577
- prepay_id=${prepayId}
4578
- `;
4579
- const signer = crypto2__default.default.createSign("RSA-SHA256");
4580
- signer.update(signString);
4581
- signer.end();
4582
- return signer.sign(privateKey, "base64");
4583
- }
4584
- function generateNonceStr() {
4585
- return crypto2__default.default.randomUUID().replace(/-/g, "");
4586
- }
4587
- function buildJsapiBridgeConfig(appId, prepayId, privateKey) {
4588
- const timeStamp = String(Math.floor(Date.now() / 1e3));
4589
- const nonceStr = generateNonceStr();
4590
- const paySign = generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey);
4591
- return {
4592
- appId,
4593
- timeStamp,
4594
- nonceStr,
4595
- package: `prepay_id=${prepayId}`,
4596
- signType: "RSA",
4597
- paySign
4598
- };
4599
- }
4600
- function buildMiniProgramBridgeConfig(appId, prepayId, privateKey) {
4601
- const timeStamp = String(Math.floor(Date.now() / 1e3));
4602
- const nonceStr = generateNonceStr();
4603
- const paySign = generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey);
4604
- return {
4605
- timeStamp,
4606
- nonceStr,
4607
- package: `prepay_id=${prepayId}`,
4608
- signType: "RSA",
4609
- paySign
4610
- };
4611
- }
4612
- function generatePayScorePaySign(appId, timeStamp, nonceStr, serviceId, outOrderNo, privateKey) {
4613
- const packageStr = `service_id=${serviceId}&out_order_no=${outOrderNo}&need_sign_type=RSA`;
4614
- const signString = `${appId}
4615
- ${timeStamp}
4616
- ${nonceStr}
4617
- ${packageStr}
4618
- `;
4619
- const signer = crypto2__default.default.createSign("RSA-SHA256");
4620
- signer.update(signString);
4621
- signer.end();
4622
- return signer.sign(privateKey, "base64");
4623
- }
4624
- function buildPayScoreJsapiBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
4625
- const timestamp = String(Math.floor(Date.now() / 1e3));
4626
- const nonceStr = generateNonceStr();
4627
- const sign2 = generatePayScorePaySign(
4628
- appId,
4629
- timestamp,
4630
- nonceStr,
4631
- serviceId,
4632
- outOrderNo,
4633
- privateKey
4634
- );
4635
- return {
4636
- appid: appId,
4637
- mchid: mchId,
4638
- service_id: serviceId,
4639
- out_order_no: outOrderNo,
4640
- timestamp,
4641
- nonce_str: nonceStr,
4642
- sign_type: "RSA",
4643
- sign: sign2
4644
- };
4645
- }
4646
- function buildPayScoreMiniProgramBridgeConfig(mchId, serviceId, outOrderNo, appId, privateKey) {
4647
- const timestamp = String(Math.floor(Date.now() / 1e3));
4648
- const nonceStr = generateNonceStr();
4649
- const sign2 = generatePayScorePaySign(
4650
- appId,
4651
- timestamp,
4652
- nonceStr,
4653
- serviceId,
4654
- outOrderNo,
4655
- privateKey
4656
- );
4657
- return {
4658
- mchid: mchId,
4659
- service_id: serviceId,
4660
- out_order_no: outOrderNo,
4661
- timestamp,
4662
- nonce_str: nonceStr,
4663
- sign_type: "RSA",
4664
- sign: sign2
4665
- };
4666
- }
4667
- function buildPayScoreAppBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
4668
- const timestamp = String(Math.floor(Date.now() / 1e3));
4669
- const nonceStr = generateNonceStr();
4670
- const sign2 = generatePayScorePaySign(
4671
- appId,
4672
- timestamp,
4673
- nonceStr,
4674
- serviceId,
4675
- outOrderNo,
4676
- privateKey
4677
- );
4678
- return {
4679
- appid: appId,
4680
- mchid: mchId,
4681
- service_id: serviceId,
4682
- out_order_no: outOrderNo,
4683
- timestamp,
4684
- nonce_str: nonceStr,
4685
- sign_type: "RSA",
4686
- sign: sign2
4687
- };
4688
- }
4689
- function buildMerchantTransferJsapiBridgeConfig(mchId, appId, packageInfo) {
4690
- return {
4691
- mchId,
4692
- appId,
4693
- package: packageInfo
4694
- };
4695
- }
4696
- function buildMerchantTransferMiniProgramBridgeConfig(mchId, appId, packageInfo) {
4697
- return {
4698
- mchId,
4699
- appId,
4700
- package: packageInfo
4701
- };
4702
- }
4703
- function buildMerchantTransferAuthorizationJsapiBridgeConfig(mchId, appId, packageInfo) {
4704
- return {
4705
- mchId,
4706
- appId,
4707
- package: packageInfo
4708
- };
4709
- }
4710
- var PARKING_SERVICE_APPID = "wxbcad394b3d99dac9";
4711
- var PARKING_SERVICE_PATH = "/pages/auth-creditpay/auth-creditpay";
4712
- var PARKING_REPAY_APPID = "wx5e73c65404eee268";
4713
- var PARKING_REPAY_PATH = "pages/invest_list/invest_list";
4714
- function buildParkingQueryString(mchid, openid, plateNumber, plateColor) {
4715
- const params = new URLSearchParams({
4716
- mchid,
4717
- openid,
4718
- plate_number: plateNumber,
4719
- plate_color: plateColor,
4720
- trade_scene: "PARKING"
4721
- });
4722
- return params.toString();
4723
- }
4724
- function buildParkingMiniProgramBridgeConfig(mchid, openid, plateNumber, plateColor) {
4725
- return {
4726
- appId: PARKING_SERVICE_APPID,
4727
- path: PARKING_SERVICE_PATH,
4728
- extraData: {
4729
- mchid,
4730
- openid,
4731
- plate_number: plateNumber,
4732
- plate_color: plateColor,
4733
- trade_scene: "PARKING"
4734
- }
4735
- };
4736
- }
4737
- function buildParkingH5BridgeUrl(mchid, openid, plateNumber, plateColor) {
4738
- const queryString = buildParkingQueryString(mchid, openid, plateNumber, plateColor);
4739
- return `${PARKING_SERVICE_PATH}?${queryString}`;
4740
- }
4741
- function buildParkingAppBridgePath(mchid, openid, plateNumber, plateColor) {
4742
- const queryString = buildParkingQueryString(mchid, openid, plateNumber, plateColor);
4743
- return `${PARKING_SERVICE_PATH}?${queryString}`;
4744
- }
4745
- function buildParkingRepayBridgeConfig(mchid, openid) {
4746
- return {
4747
- appId: PARKING_REPAY_APPID,
4748
- path: PARKING_REPAY_PATH,
4749
- extraData: {
4750
- mchid,
4751
- nonce_str: generateNonceStr(),
4752
- openid
4753
- }
4754
- };
4755
- }
4756
- var H5_COUPON_URL = "https://action.weixin.qq.com/busifavor/getcouponinfo";
4757
- function buildH5CouponUrl(params, signKey) {
4758
- const signFields = {
4759
- stock_id: params.stock_id,
4760
- out_request_no: params.out_request_no,
4761
- send_coupon_merchant: params.send_coupon_merchant,
4762
- open_id: params.open_id
4763
- };
4764
- if (params.coupon_code) {
4765
- signFields["coupon_code"] = params.coupon_code;
4146
+
4147
+ // src/services/refund.ts
4148
+ var RefundService = class {
4149
+ client;
4150
+ constructor(client) {
4151
+ this.client = client;
4152
+ }
4153
+ /**
4154
+ * 申请退款
4155
+ *
4156
+ * 当交易发生之后一段时间内,由于买家或者卖家的原因需要退款时,
4157
+ * 卖家可以通过退款接口将支付款退还给买家。
4158
+ * 支持单笔交易分多次退款,多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。
4159
+ * 一笔退款失败后重新提交,要采用原来的退款单号。
4160
+ *
4161
+ * @param request - 退款请求参数,包含商户订单号、退款单号、退款金额等信息
4162
+ * @returns 退款申请结果,包含微信退款单号、退款状态等
4163
+ *
4164
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013071036
4165
+ */
4166
+ async create(request) {
4167
+ return this.client.post("/v3/refund/domestic/refunds", request);
4168
+ }
4169
+ /**
4170
+ * 查询单笔退款(通过商户退款单号)
4171
+ *
4172
+ * 提交退款申请后,通过调用该接口查询退款状态。
4173
+ * 退款有一定延时,建议在提交退款申请后1分钟再查询退款状态。
4174
+ *
4175
+ * @param params - 查询参数,需包含 outRefundNo(商户退款单号)
4176
+ * @returns 退款单详情,包含退款状态、退款金额、退款渠道等
4177
+ *
4178
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013071041
4179
+ */
4180
+ async queryByOutRefundNo(params) {
4181
+ return this.client.get(
4182
+ `/v3/refund/domestic/refunds/${params.outRefundNo}`
4183
+ );
4184
+ }
4185
+ /**
4186
+ * 发起异常退款
4187
+ *
4188
+ * 当退款因为用户账户异常而无法原路退回时,可使用此接口将退款资金
4189
+ * 退到用户的其他银行卡或商户的银行账户。
4190
+ *
4191
+ * @param refundId - 微信支付退款单号
4192
+ * @param request - 异常退款请求参数,包含退款方式、收款账户信息等
4193
+ * @returns 异常退款处理结果
4194
+ *
4195
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013071193
4196
+ */
4197
+ async applyAbnormalRefund(refundId, request) {
4198
+ return this.client.post(
4199
+ `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
4200
+ request
4201
+ );
4202
+ }
4203
+ };
4204
+
4205
+ // src/services/partner-jsapi.ts
4206
+ var PartnerJsapiService = class {
4207
+ client;
4208
+ constructor(client) {
4209
+ this.client = client;
4210
+ }
4211
+ /**
4212
+ * 服务商 JSAPI/小程序下单
4213
+ *
4214
+ * 服务商通过此接口代特约商户发起 JSAPI 支付下单,获取 prepay_id。
4215
+ *
4216
+ * @param request - 下单请求参数,需包含 sp_appid、sp_mchid、sub_mchid 等
4217
+ * @returns 下单结果,包含 prepay_id
4218
+ *
4219
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012738519
4220
+ */
4221
+ async createOrder(request) {
4222
+ return this.client.post(
4223
+ "/v3/pay/partner/transactions/jsapi",
4224
+ request
4225
+ );
4226
+ }
4227
+ /**
4228
+ * 通过商户订单号查询订单
4229
+ *
4230
+ * @param params - 查询参数,需包含 out_trade_no、sp_mchid、sub_mchid
4231
+ * @returns 订单详情
4232
+ *
4233
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012739008
4234
+ */
4235
+ async queryOrderByOutTradeNo(params) {
4236
+ return this.client.get(
4237
+ `/v3/pay/partner/transactions/out-trade-no/${params.out_trade_no}`,
4238
+ { sp_mchid: params.sp_mchid, sub_mchid: params.sub_mchid }
4239
+ );
4240
+ }
4241
+ /**
4242
+ * 通过微信支付订单号查询订单
4243
+ *
4244
+ * @param params - 查询参数,需包含 transaction_id、sp_mchid、sub_mchid
4245
+ * @returns 订单详情
4246
+ *
4247
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012738964
4248
+ */
4249
+ async queryOrderByTransactionId(params) {
4250
+ return this.client.get(
4251
+ `/v3/pay/partner/transactions/id/${params.transaction_id}`,
4252
+ { sp_mchid: params.sp_mchid, sub_mchid: params.sub_mchid }
4253
+ );
4254
+ }
4255
+ /**
4256
+ * 关闭订单
4257
+ *
4258
+ * 对于未支付的订单,服务商可通过此接口代特约商户关闭订单。
4259
+ *
4260
+ * @param outTradeNo - 商户订单号
4261
+ * @param request - 关单请求参数,需包含 sp_mchid、sub_mchid
4262
+ *
4263
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012739019
4264
+ */
4265
+ async closeOrder(outTradeNo, request) {
4266
+ return this.client.post(
4267
+ `/v3/pay/partner/transactions/out-trade-no/${outTradeNo}/close`,
4268
+ request
4269
+ );
4270
+ }
4271
+ /**
4272
+ * 服务商 JSAPI 下单并生成调起支付参数
4273
+ *
4274
+ * 封装了下单和调起支付参数生成两个步骤,一次调用即可获得
4275
+ * prepay_id 和前端 WeixinJSBridge.invoke() 所需的全部参数。
4276
+ *
4277
+ * @param request - 下单请求参数
4278
+ * @param privateKey - 商户私钥,用于生成调起支付签名
4279
+ * @returns 下单响应 + 调起支付参数
4280
+ */
4281
+ async prepayWithRequestPayment(request, privateKey) {
4282
+ const response = await this.createOrder(request);
4283
+ const bridgeConfig = buildJsapiBridgeConfig(
4284
+ request.sp_appid,
4285
+ response.data.prepay_id,
4286
+ privateKey
4287
+ );
4288
+ return { ...response, bridgeConfig };
4289
+ }
4290
+ };
4291
+
4292
+ // src/services/partner-app.ts
4293
+ var PartnerAppService = class {
4294
+ client;
4295
+ constructor(client) {
4296
+ this.client = client;
4297
+ }
4298
+ /**
4299
+ * 服务商 APP 下单
4300
+ *
4301
+ * @param request - 下单请求参数
4302
+ * @returns 下单结果,包含 prepay_id
4303
+ *
4304
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4013080231
4305
+ */
4306
+ async createOrder(request) {
4307
+ return this.client.post(
4308
+ "/v3/pay/partner/transactions/app",
4309
+ request
4310
+ );
4311
+ }
4312
+ /**
4313
+ * 通过商户订单号查询订单
4314
+ *
4315
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4013080235
4316
+ */
4317
+ async queryOrderByOutTradeNo(params) {
4318
+ return this.client.get(
4319
+ `/v3/pay/partner/transactions/out-trade-no/${params.out_trade_no}`,
4320
+ { sp_mchid: params.sp_mchid, sub_mchid: params.sub_mchid }
4321
+ );
4322
+ }
4323
+ /**
4324
+ * 通过微信支付订单号查询订单
4325
+ *
4326
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4013080234
4327
+ */
4328
+ async queryOrderByTransactionId(params) {
4329
+ return this.client.get(
4330
+ `/v3/pay/partner/transactions/id/${params.transaction_id}`,
4331
+ { sp_mchid: params.sp_mchid, sub_mchid: params.sub_mchid }
4332
+ );
4333
+ }
4334
+ /**
4335
+ * 关闭订单
4336
+ *
4337
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4013080236
4338
+ */
4339
+ async closeOrder(outTradeNo, request) {
4340
+ return this.client.post(
4341
+ `/v3/pay/partner/transactions/out-trade-no/${outTradeNo}/close`,
4342
+ request
4343
+ );
4344
+ }
4345
+ /**
4346
+ * 服务商 APP 下单并生成调起支付参数
4347
+ *
4348
+ * @param request - 下单请求参数
4349
+ * @param privateKey - 商户私钥
4350
+ * @returns 下单响应 + 调起支付参数
4351
+ */
4352
+ async prepayWithRequestPayment(request, privateKey) {
4353
+ const response = await this.createOrder(request);
4354
+ const bridgeConfig = buildAppBridgeConfig(
4355
+ request.sp_appid,
4356
+ this.client.mchid,
4357
+ response.data.prepay_id,
4358
+ privateKey
4359
+ );
4360
+ return { ...response, bridgeConfig };
4361
+ }
4362
+ };
4363
+
4364
+ // src/services/partner-h5.ts
4365
+ var PartnerH5Service = class {
4366
+ client;
4367
+ constructor(client) {
4368
+ this.client = client;
4369
+ }
4370
+ /**
4371
+ * 服务商 H5 下单
4372
+ *
4373
+ * @param request - 下单请求参数,需包含 scene_info.h5_info
4374
+ * @returns 下单结果,包含 h5_url
4375
+ *
4376
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012738604
4377
+ */
4378
+ async createOrder(request) {
4379
+ return this.client.post(
4380
+ "/v3/pay/partner/transactions/h5",
4381
+ request
4382
+ );
4383
+ }
4384
+ /**
4385
+ * 通过商户订单号查询订单
4386
+ *
4387
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012759661
4388
+ */
4389
+ async queryOrderByOutTradeNo(params) {
4390
+ return this.client.get(
4391
+ `/v3/pay/partner/transactions/out-trade-no/${params.out_trade_no}`,
4392
+ { sp_mchid: params.sp_mchid, sub_mchid: params.sub_mchid }
4393
+ );
4394
+ }
4395
+ /**
4396
+ * 通过微信支付订单号查询订单
4397
+ *
4398
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012738969
4399
+ */
4400
+ async queryOrderByTransactionId(params) {
4401
+ return this.client.get(
4402
+ `/v3/pay/partner/transactions/id/${params.transaction_id}`,
4403
+ { sp_mchid: params.sp_mchid, sub_mchid: params.sub_mchid }
4404
+ );
4405
+ }
4406
+ /**
4407
+ * 关闭订单
4408
+ *
4409
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012759669
4410
+ */
4411
+ async closeOrder(outTradeNo, request) {
4412
+ return this.client.post(
4413
+ `/v3/pay/partner/transactions/out-trade-no/${outTradeNo}/close`,
4414
+ request
4415
+ );
4416
+ }
4417
+ };
4418
+
4419
+ // src/services/partner-native.ts
4420
+ var PartnerNativeService = class {
4421
+ client;
4422
+ constructor(client) {
4423
+ this.client = client;
4424
+ }
4425
+ /**
4426
+ * 服务商 Native 下单
4427
+ *
4428
+ * @param request - 下单请求参数
4429
+ * @returns 下单结果,包含 code_url
4430
+ *
4431
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012738659
4432
+ */
4433
+ async createOrder(request) {
4434
+ return this.client.post(
4435
+ "/v3/pay/partner/transactions/native",
4436
+ request
4437
+ );
4438
+ }
4439
+ /**
4440
+ * 通过商户订单号查询订单
4441
+ *
4442
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012759714
4443
+ */
4444
+ async queryOrderByOutTradeNo(params) {
4445
+ return this.client.get(
4446
+ `/v3/pay/partner/transactions/out-trade-no/${params.out_trade_no}`,
4447
+ { sp_mchid: params.sp_mchid, sub_mchid: params.sub_mchid }
4448
+ );
4449
+ }
4450
+ /**
4451
+ * 通过微信支付订单号查询订单
4452
+ *
4453
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012738971
4454
+ */
4455
+ async queryOrderByTransactionId(params) {
4456
+ return this.client.get(
4457
+ `/v3/pay/partner/transactions/id/${params.transaction_id}`,
4458
+ { sp_mchid: params.sp_mchid, sub_mchid: params.sub_mchid }
4459
+ );
4460
+ }
4461
+ /**
4462
+ * 关闭订单
4463
+ *
4464
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012759725
4465
+ */
4466
+ async closeOrder(outTradeNo, request) {
4467
+ return this.client.post(
4468
+ `/v3/pay/partner/transactions/out-trade-no/${outTradeNo}/close`,
4469
+ request
4470
+ );
4471
+ }
4472
+ };
4473
+
4474
+ // src/services/partner-transfer.ts
4475
+ var PartnerTransferService = class {
4476
+ client;
4477
+ constructor(client) {
4478
+ this.client = client;
4479
+ }
4480
+ /**
4481
+ * 服务商发起商家转账
4482
+ *
4483
+ * @param request - 转账请求参数
4484
+ * @returns 转账结果
4485
+ *
4486
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012716434
4487
+ */
4488
+ async createTransfer(request) {
4489
+ return this.client.post(
4490
+ "/v3/fund-app/mch-transfer/partner/transfer-bills",
4491
+ request
4492
+ );
4493
+ }
4494
+ /**
4495
+ * 通过商户单号查询转账单
4496
+ *
4497
+ * @param outBillNo - 商户转账单号
4498
+ * @param subMchid - 特约商户号
4499
+ * @returns 转账单详情
4500
+ */
4501
+ async queryTransferByOutBillNo(outBillNo, subMchid) {
4502
+ return this.client.get(
4503
+ `/v3/fund-app/mch-transfer/partner/transfer-bills/out-bill-no/${outBillNo}`,
4504
+ { sub_mchid: subMchid }
4505
+ );
4506
+ }
4507
+ /**
4508
+ * 通过微信单号查询转账单
4509
+ *
4510
+ * @param transferBillNo - 微信转账单号
4511
+ * @param subMchid - 特约商户号
4512
+ * @returns 转账单详情
4513
+ */
4514
+ async queryTransferByTransferBillNo(transferBillNo, subMchid) {
4515
+ return this.client.get(
4516
+ `/v3/fund-app/mch-transfer/partner/transfer-bills/transfer-bill-no/${transferBillNo}`,
4517
+ { sub_mchid: subMchid }
4518
+ );
4519
+ }
4520
+ /**
4521
+ * 撤销转账
4522
+ *
4523
+ * @param outBillNo - 商户转账单号
4524
+ * @param subMchid - 特约商户号
4525
+ */
4526
+ async cancelTransfer(outBillNo, subMchid) {
4527
+ return this.client.post(
4528
+ `/v3/fund-app/mch-transfer/partner/transfer-bills/out-bill-no/${outBillNo}/cancel`,
4529
+ { sub_mchid: subMchid }
4530
+ );
4531
+ }
4532
+ // ============= 电子回单 =============
4533
+ /**
4534
+ * 商户单号申请电子回单
4535
+ *
4536
+ * 申请条件:
4537
+ * - 转账单据状态为 SUCCESS
4538
+ * - 传入了收款用户姓名
4539
+ * - 六个月内的转账单据
4540
+ *
4541
+ * 回单有效期为90天,过期需重新申请。
4542
+ *
4543
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012716452
4544
+ */
4545
+ async applyElecSignByOutBillNo(request) {
4546
+ return this.client.post(
4547
+ "/v3/fund-app/mch-transfer/partner/elecsign/out-bill-no",
4548
+ request
4549
+ );
4550
+ }
4551
+ /**
4552
+ * 商户单号查询电子回单
4553
+ *
4554
+ * 当申请单状态为 FINISHED 时,返回回单文件的下载地址和摘要信息。
4555
+ * 下载地址有效期为10分钟,过期后需重新调用此接口获取。
4556
+ *
4557
+ * @param outBillNo - 商户单号
4558
+ * @param subMchid - 特约商户号
4559
+ *
4560
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012716436
4561
+ */
4562
+ async queryElecSignByOutBillNo(outBillNo, subMchid) {
4563
+ return this.client.get(
4564
+ `/v3/fund-app/mch-transfer/partner/elecsign/out-bill-no/${outBillNo}`,
4565
+ { sub_mchid: subMchid }
4566
+ );
4567
+ }
4568
+ /**
4569
+ * 微信单号申请电子回单
4570
+ *
4571
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012716456
4572
+ */
4573
+ async applyElecSignByTransferBillNo(request) {
4574
+ return this.client.post(
4575
+ "/v3/fund-app/mch-transfer/partner/elecsign/transfer-bill-no",
4576
+ request
4577
+ );
4578
+ }
4579
+ /**
4580
+ * 微信单号查询电子回单
4581
+ *
4582
+ * @param transferBillNo - 微信转账单号
4583
+ * @param subMchid - 特约商户号
4584
+ *
4585
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4012716455
4586
+ */
4587
+ async queryElecSignByTransferBillNo(transferBillNo, subMchid) {
4588
+ return this.client.get(
4589
+ `/v3/fund-app/mch-transfer/partner/elecsign/transfer-bill-no/${transferBillNo}`,
4590
+ { sub_mchid: subMchid }
4591
+ );
4592
+ }
4593
+ /**
4594
+ * 下载电子回单
4595
+ *
4596
+ * 通过申请电子回单接口返回的 download_url,以 GET 方式下载回单原始文件。
4597
+ * 下载地址有效期为 10 分钟,过期后需重新调用查询接口获取。
4598
+ * 返回的 data 为 PDF 文件的 Buffer。
4599
+ *
4600
+ * @param downloadUrl - 查询电子回单返回的 download_url
4601
+ * @returns 电子回单文件 Buffer
4602
+ *
4603
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4013866774
4604
+ */
4605
+ async downloadElecSign(downloadUrl) {
4606
+ return this.client.downloadRaw(downloadUrl);
4607
+ }
4608
+ // ============= 用户授权免确认模式 =============
4609
+ /**
4610
+ * 发起转账并完成免确认收款授权
4611
+ *
4612
+ * 在发起转账的同时申请免确认收款授权,用户确认收款时可同时完成授权。
4613
+ * 授权成功后,后续转账无需用户逐笔确认。
4614
+ *
4615
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4014399293
4616
+ */
4617
+ async createTransferWithAuthorization(request) {
4618
+ return this.client.post(
4619
+ "/v3/fund-app/mch-transfer/partner/transfer-bills/pre-transfer-with-authorization",
4620
+ request
4621
+ );
4622
+ }
4623
+ /**
4624
+ * 发起免确认收款授权
4625
+ *
4626
+ * 直接申请免确认收款授权,不发起转账。
4627
+ * 用户需在24小时内完成授权,未确认记录保留30天。
4628
+ * 同一微信号在同商户下待确认+已授权状态的授权单最多5个。
4629
+ *
4630
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4015901167
4631
+ */
4632
+ async createAuthorization(request) {
4633
+ return this.client.post(
4634
+ "/v3/fund-app/mch-transfer/partner/user-confirm-authorization",
4635
+ request
4636
+ );
4637
+ }
4638
+ /**
4639
+ * 商户单号查询授权结果
4640
+ *
4641
+ * @param request - 查询请求参数
4642
+ *
4643
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4014399423
4644
+ */
4645
+ async queryAuthorizationByOutAuthorizationNo(request) {
4646
+ const { sub_mchid, out_authorization_no, is_display_authorization } = request;
4647
+ return this.client.get(
4648
+ `/v3/fund-app/mch-transfer/partner/user-confirm-authorization/out-authorization-no/${out_authorization_no}`,
4649
+ { sub_mchid, is_display_authorization }
4650
+ );
4651
+ }
4652
+ /**
4653
+ * 用户授权后转账
4654
+ *
4655
+ * 用户完成授权后,商户可直接发起转账,无需用户逐笔确认收款。
4656
+ * 需要提供 authorization_id 或 out_authorization_no(二选一)。
4657
+ *
4658
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4014399371
4659
+ */
4660
+ async createTransferAfterAuthorization(request) {
4661
+ return this.client.post(
4662
+ "/v3/fund-app/mch-transfer/partner/transfer-bills/transfer",
4663
+ request
4664
+ );
4665
+ }
4666
+ /**
4667
+ * 解除免确认收款授权
4668
+ *
4669
+ * 商户可调用此接口帮助用户发起解除授权。
4670
+ * 用户也可通过微信支付入账消息的收款设置操作关闭授权。
4671
+ *
4672
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4015653811
4673
+ */
4674
+ async closeAuthorization(request) {
4675
+ const { sub_mchid, out_authorization_no } = request;
4676
+ return this.client.post(
4677
+ `/v3/fund-app/mch-transfer/partner/user-confirm-authorization/out-authorization-no/${out_authorization_no}/close`,
4678
+ { sub_mchid }
4679
+ );
4680
+ }
4681
+ };
4682
+
4683
+ // src/services/transfer-batch.ts
4684
+ var TransferBatchService = class {
4685
+ client;
4686
+ constructor(client) {
4687
+ this.client = client;
4688
+ }
4689
+ /**
4690
+ * 发起批量转账
4691
+ *
4692
+ * @param request - 批量转账请求参数
4693
+ * @returns 批量转账结果
4694
+ */
4695
+ async initiateBatchTransfer(request) {
4696
+ return this.client.post("/v3/transfer/batches", request);
4697
+ }
4698
+ /**
4699
+ * 通过微信批次单号查询批次单
4700
+ *
4701
+ * @param batchId - 微信批次单号
4702
+ * @param params - 可选查询参数
4703
+ * @returns 批次单详情
4704
+ */
4705
+ async getTransferBatchByNo(batchId, params) {
4706
+ return this.client.get(
4707
+ `/v3/transfer/batches/batch-id/${batchId}`,
4708
+ params
4709
+ );
4710
+ }
4711
+ /**
4712
+ * 通过商家批次单号查询批次单
4713
+ *
4714
+ * @param outBatchNo - 商家批次单号
4715
+ * @param params - 可选查询参数
4716
+ * @returns 批次单详情
4717
+ */
4718
+ async getTransferBatchByOutNo(outBatchNo, params) {
4719
+ return this.client.get(
4720
+ `/v3/transfer/batches/out-batch-no/${outBatchNo}`,
4721
+ params
4722
+ );
4723
+ }
4724
+ /**
4725
+ * 通过微信明细单号查询明细单
4726
+ *
4727
+ * @param batchId - 微信批次单号
4728
+ * @param detailId - 微信明细单号
4729
+ * @returns 明细单详情
4730
+ */
4731
+ async getTransferDetailByNo(batchId, detailId) {
4732
+ return this.client.get(
4733
+ `/v3/transfer/batches/batch-id/${batchId}/details/detail-id/${detailId}`
4734
+ );
4735
+ }
4736
+ /**
4737
+ * 通过商家明细单号查询明细单
4738
+ *
4739
+ * @param outBatchNo - 商家批次单号
4740
+ * @param outDetailNo - 商家明细单号
4741
+ * @returns 明细单详情
4742
+ */
4743
+ async getTransferDetailByOutNo(outBatchNo, outDetailNo) {
4744
+ return this.client.get(
4745
+ `/v3/transfer/batches/out-batch-no/${outBatchNo}/details/out-detail-no/${outDetailNo}`
4746
+ );
4747
+ }
4748
+ };
4749
+
4750
+ // src/services/partner-transfer-batch.ts
4751
+ var PartnerTransferBatchService = class {
4752
+ client;
4753
+ constructor(client) {
4754
+ this.client = client;
4755
+ }
4756
+ /**
4757
+ * 发起服务商批量转账
4758
+ *
4759
+ * @param request - 批量转账请求参数
4760
+ * @returns 批量转账结果
4761
+ */
4762
+ async initiateBatchTransfer(request) {
4763
+ return this.client.post(
4764
+ "/v3/partner-transfer/batches",
4765
+ request
4766
+ );
4767
+ }
4768
+ /**
4769
+ * 通过微信批次单号查询批次单
4770
+ *
4771
+ * @param batchId - 微信批次单号
4772
+ * @param params - 可选查询参数
4773
+ * @returns 批次单详情
4774
+ */
4775
+ async getTransferBatchByNo(batchId, params) {
4776
+ return this.client.get(
4777
+ `/v3/partner-transfer/batches/batch-id/${batchId}`,
4778
+ params
4779
+ );
4780
+ }
4781
+ /**
4782
+ * 通过商家批次单号查询批次单
4783
+ *
4784
+ * @param outBatchNo - 商家批次单号
4785
+ * @param params - 可选查询参数
4786
+ * @returns 批次单详情
4787
+ */
4788
+ async getTransferBatchByOutNo(outBatchNo, params) {
4789
+ return this.client.get(
4790
+ `/v3/partner-transfer/batches/out-batch-no/${outBatchNo}`,
4791
+ params
4792
+ );
4793
+ }
4794
+ /**
4795
+ * 通过微信明细单号查询明细单
4796
+ *
4797
+ * @param batchId - 微信批次单号
4798
+ * @param detailId - 微信明细单号
4799
+ * @returns 明细单详情
4800
+ */
4801
+ async getTransferDetailByNo(batchId, detailId) {
4802
+ return this.client.get(
4803
+ `/v3/partner-transfer/batches/batch-id/${batchId}/details/detail-id/${detailId}`
4804
+ );
4805
+ }
4806
+ /**
4807
+ * 通过商家明细单号查询明细单
4808
+ *
4809
+ * @param outBatchNo - 商家批次单号
4810
+ * @param outDetailNo - 商家明细单号
4811
+ * @returns 明细单详情
4812
+ */
4813
+ async getTransferDetailByOutNo(outBatchNo, outDetailNo) {
4814
+ return this.client.get(
4815
+ `/v3/partner-transfer/batches/out-batch-no/${outBatchNo}/details/out-detail-no/${outDetailNo}`
4816
+ );
4817
+ }
4818
+ };
4819
+
4820
+ // src/services/ecommerce-profitsharing.ts
4821
+ var EcommerceProfitSharingService = class {
4822
+ client;
4823
+ constructor(client) {
4824
+ this.client = client;
4825
+ }
4826
+ /**
4827
+ * 请求分账
4828
+ *
4829
+ * @param request - 分账请求参数
4830
+ * @returns 分账结果
4831
+ */
4832
+ async createOrder(request) {
4833
+ return this.client.post(
4834
+ "/v3/ecommerce/profitsharing/orders",
4835
+ request
4836
+ );
4837
+ }
4838
+ /**
4839
+ * 查询分账结果
4840
+ *
4841
+ * @param subMchid - 特约商户号
4842
+ * @param transactionId - 微信支付订单号
4843
+ * @param outOrderNo - 商户分账单号
4844
+ * @returns 分账结果详情
4845
+ */
4846
+ async queryOrder(subMchid, transactionId, outOrderNo) {
4847
+ return this.client.get(
4848
+ "/v3/ecommerce/profitsharing/orders",
4849
+ { sub_mchid: subMchid, transaction_id: transactionId, out_order_no: outOrderNo }
4850
+ );
4851
+ }
4852
+ /**
4853
+ * 请求分账回退
4854
+ *
4855
+ * @param request - 分账回退请求参数
4856
+ * @returns 回退结果
4857
+ */
4858
+ async createReturnOrder(request) {
4859
+ return this.client.post(
4860
+ "/v3/ecommerce/profitsharing/returnorders",
4861
+ request
4862
+ );
4863
+ }
4864
+ /**
4865
+ * 查询分账回退结果
4866
+ *
4867
+ * @param subMchid - 特约商户号
4868
+ * @param orderId - 微信分账单号
4869
+ * @param outReturnNo - 商户回退单号
4870
+ * @returns 回退结果详情
4871
+ */
4872
+ async queryReturnOrder(subMchid, orderId, outReturnNo) {
4873
+ return this.client.get(
4874
+ "/v3/ecommerce/profitsharing/returnorders",
4875
+ { sub_mchid: subMchid, order_id: orderId, out_return_no: outReturnNo }
4876
+ );
4877
+ }
4878
+ /**
4879
+ * 完结分账
4880
+ *
4881
+ * @param request - 完结分账请求参数
4882
+ */
4883
+ async finishOrder(request) {
4884
+ return this.client.post("/v3/ecommerce/profitsharing/finish-order", request);
4885
+ }
4886
+ /**
4887
+ * 请求售后服务分账
4888
+ *
4889
+ * @param request - 售后服务分账请求参数
4890
+ * @returns 售后服务分账结果
4891
+ */
4892
+ async createAfterSalesOrder(request) {
4893
+ return this.client.post(
4894
+ "/v3/ecommerce/profitsharing/after-sales-orders",
4895
+ request
4896
+ );
4897
+ }
4898
+ /**
4899
+ * 查询售后服务分账结果
4900
+ *
4901
+ * @param subMchid - 子商户号
4902
+ * @param transactionId - 微信支付订单号
4903
+ * @returns 售后服务分账结果详情
4904
+ */
4905
+ async queryAfterSalesOrder(subMchid, transactionId) {
4906
+ return this.client.get(
4907
+ "/v3/ecommerce/profitsharing/after-sales-orders",
4908
+ { sub_mchid: subMchid, transaction_id: transactionId }
4909
+ );
4910
+ }
4911
+ /**
4912
+ * 查询订单剩余待分金额
4913
+ *
4914
+ * @param transactionId - 微信支付订单号
4915
+ * @returns 订单剩余待分金额
4916
+ */
4917
+ async queryOrderAmount(transactionId) {
4918
+ return this.client.get(
4919
+ `/v3/ecommerce/profitsharing/orders/${transactionId}/amounts`
4920
+ );
4921
+ }
4922
+ /**
4923
+ * 添加分账接收方
4924
+ *
4925
+ * @param request - 添加接收方请求参数
4926
+ * @returns 添加接收方结果
4927
+ */
4928
+ async addReceiver(request) {
4929
+ return this.client.post(
4930
+ "/v3/ecommerce/profitsharing/receivers/add",
4931
+ request
4932
+ );
4933
+ }
4934
+ /**
4935
+ * 删除分账接收方
4936
+ *
4937
+ * @param request - 删除接收方请求参数
4938
+ * @returns 删除接收方结果
4939
+ */
4940
+ async deleteReceiver(request) {
4941
+ return this.client.post(
4942
+ "/v3/ecommerce/profitsharing/receivers/delete",
4943
+ request
4944
+ );
4945
+ }
4946
+ };
4947
+
4948
+ // src/services/ecommerce-refund.ts
4949
+ var EcommerceRefundService = class {
4950
+ client;
4951
+ constructor(client) {
4952
+ this.client = client;
4766
4953
  }
4767
- const sortedKeys = Object.keys(signFields).sort();
4768
- const signStr = sortedKeys.map((k) => `${k}=${signFields[k]}`).join("&") + `&key=${signKey}`;
4769
- const sign2 = crypto2__default.default.createHmac("sha256", signKey).update(signStr).digest("hex").toUpperCase();
4770
- const urlParams = new URLSearchParams({
4771
- stock_id: params.stock_id,
4772
- out_request_no: params.out_request_no,
4773
- sign: sign2,
4774
- send_coupon_merchant: params.send_coupon_merchant,
4775
- open_id: params.open_id
4776
- });
4777
- if (params.coupon_code) {
4778
- urlParams.set("coupon_code", params.coupon_code);
4954
+ /**
4955
+ * 申请退款
4956
+ *
4957
+ * @param request - 退款请求参数
4958
+ * @returns 退款结果
4959
+ *
4960
+ * @see https://pay.weixin.qq.com/doc/v3/partner/4013080625
4961
+ */
4962
+ async create(request) {
4963
+ return this.client.post("/v3/ecommerce/refunds/apply", request);
4779
4964
  }
4780
- if (params.customize_send_time) {
4781
- urlParams.set("customize_send_time", params.customize_send_time);
4965
+ /**
4966
+ * 查询单笔退款(通过商户退款单号)
4967
+ *
4968
+ * @param subMchid - 特约商户号
4969
+ * @param outRefundNo - 商户退款单号
4970
+ * @returns 退款详情
4971
+ */
4972
+ async queryByOutRefundNo(subMchid, outRefundNo) {
4973
+ return this.client.get(
4974
+ `/v3/ecommerce/refunds/out-refund-no/${outRefundNo}`,
4975
+ { sub_mchid: subMchid }
4976
+ );
4782
4977
  }
4783
- return `${H5_COUPON_URL}?${urlParams.toString()}#wechat_pay&wechat_redirect`;
4978
+ /**
4979
+ * 查询单笔退款(通过微信支付退款单号)
4980
+ *
4981
+ * @param subMchid - 特约商户号
4982
+ * @param refundId - 微信支付退款单号
4983
+ * @returns 退款详情
4984
+ */
4985
+ async queryByRefundId(subMchid, refundId) {
4986
+ return this.client.get(`/v3/ecommerce/refunds/id/${refundId}`, {
4987
+ sub_mchid: subMchid
4988
+ });
4989
+ }
4990
+ /**
4991
+ * 垫付退款回补
4992
+ *
4993
+ * 当电商平台已垫付退款给用户,后续从二级商户处回补该笔退款资金。
4994
+ *
4995
+ * @param request - 垫付回补请求参数
4996
+ * @returns 垫付回补结果
4997
+ */
4998
+ async createReturnAdvance(request) {
4999
+ return this.client.post(
5000
+ `/v3/ecommerce/refunds/${request.refund_id}/return-advance`,
5001
+ { sub_mchid: request.sub_mchid }
5002
+ );
5003
+ }
5004
+ /**
5005
+ * 查询垫付回补结果
5006
+ *
5007
+ * @param subMchid - 特约商户号
5008
+ * @param refundId - 微信退款单号
5009
+ * @returns 垫付回补结果
5010
+ */
5011
+ async queryReturnAdvance(subMchid, refundId) {
5012
+ return this.client.get(
5013
+ `/v3/ecommerce/refunds/${refundId}/return-advance`,
5014
+ { sub_mchid: subMchid }
5015
+ );
5016
+ }
5017
+ };
5018
+
5019
+ // src/services/ecommerce-subsidy.ts
5020
+ var EcommerceSubsidyService = class {
5021
+ client;
5022
+ constructor(client) {
5023
+ this.client = client;
5024
+ }
5025
+ /**
5026
+ * 请求补差
5027
+ *
5028
+ * @param request - 补差请求参数
5029
+ * @returns 补差结果
5030
+ */
5031
+ async create(request) {
5032
+ return this.client.post(
5033
+ "/v3/ecommerce/subsidies/create",
5034
+ request
5035
+ );
5036
+ }
5037
+ /**
5038
+ * 请求补差回退
5039
+ *
5040
+ * @param request - 补差回退请求参数
5041
+ * @returns 回退结果
5042
+ */
5043
+ async returnSubsidy(request) {
5044
+ return this.client.post(
5045
+ "/v3/ecommerce/subsidies/return",
5046
+ request
5047
+ );
5048
+ }
5049
+ /**
5050
+ * 取消补差
5051
+ *
5052
+ * @param request - 取消补差请求参数
5053
+ * @returns 取消补差结果
5054
+ */
5055
+ async cancelSubsidy(request) {
5056
+ return this.client.post(
5057
+ "/v3/ecommerce/subsidies/cancel",
5058
+ request
5059
+ );
5060
+ }
5061
+ };
5062
+
5063
+ // src/services/brand-profitsharing.ts
5064
+ var BrandProfitSharingService = class {
5065
+ client;
5066
+ constructor(client) {
5067
+ this.client = client;
5068
+ }
5069
+ /**
5070
+ * 请求分账
5071
+ *
5072
+ * @param request - 分账请求参数
5073
+ * @returns 分账结果
5074
+ */
5075
+ async createOrder(request) {
5076
+ return this.client.post(
5077
+ "/v3/brand/profitsharing/orders",
5078
+ request
5079
+ );
5080
+ }
5081
+ /**
5082
+ * 查询分账结果
5083
+ *
5084
+ * @param brandMchid - 品牌主商户号
5085
+ * @param subMchid - 特约商户号
5086
+ * @param transactionId - 微信支付订单号
5087
+ * @param outOrderNo - 商户分账单号
5088
+ * @returns 分账结果详情
5089
+ */
5090
+ async queryOrder(brandMchid, subMchid, transactionId, outOrderNo) {
5091
+ return this.client.get("/v3/brand/profitsharing/orders", {
5092
+ brand_mchid: brandMchid,
5093
+ sub_mchid: subMchid,
5094
+ transaction_id: transactionId,
5095
+ out_order_no: outOrderNo
5096
+ });
5097
+ }
5098
+ /**
5099
+ * 请求分账回退
5100
+ *
5101
+ * @param request - 分账回退请求参数
5102
+ * @returns 回退结果
5103
+ */
5104
+ async createReturnOrder(request) {
5105
+ return this.client.post(
5106
+ "/v3/brand/profitsharing/returnorders",
5107
+ request
5108
+ );
5109
+ }
5110
+ /**
5111
+ * 查询分账回退结果
5112
+ *
5113
+ * @param brandMchid - 品牌主商户号
5114
+ * @param subMchid - 特约商户号
5115
+ * @param orderId - 微信分账单号
5116
+ * @param outReturnNo - 商户回退单号
5117
+ * @returns 回退结果详情
5118
+ */
5119
+ async queryReturnOrder(brandMchid, subMchid, orderId, outReturnNo) {
5120
+ return this.client.get(
5121
+ "/v3/brand/profitsharing/returnorders",
5122
+ {
5123
+ brand_mchid: brandMchid,
5124
+ sub_mchid: subMchid,
5125
+ order_id: orderId,
5126
+ out_return_no: outReturnNo
5127
+ }
5128
+ );
5129
+ }
5130
+ /**
5131
+ * 完结分账
5132
+ *
5133
+ * @param request - 完结分账请求参数
5134
+ */
5135
+ async finishOrder(request) {
5136
+ return this.client.post("/v3/brand/profitsharing/finish-order", request);
5137
+ }
5138
+ /**
5139
+ * 查询最大分账比例
5140
+ *
5141
+ * @param brandMchid - 品牌主商户号
5142
+ * @returns 最大分账比例
5143
+ */
5144
+ async queryBrandMerchantRatio(brandMchid) {
5145
+ return this.client.get(
5146
+ `/v3/brand/profitsharing/brand-configs/${brandMchid}`
5147
+ );
5148
+ }
5149
+ /**
5150
+ * 查询订单剩余待分金额
5151
+ *
5152
+ * @param transactionId - 微信支付订单号
5153
+ * @returns 订单剩余待分金额
5154
+ */
5155
+ async queryOrderAmount(transactionId) {
5156
+ return this.client.get(
5157
+ `/v3/brand/profitsharing/orders/${transactionId}/amounts`
5158
+ );
5159
+ }
5160
+ /**
5161
+ * 添加分账接收方
5162
+ *
5163
+ * @param request - 添加接收方请求参数
5164
+ * @returns 添加接收方结果
5165
+ */
5166
+ async addReceiver(request) {
5167
+ return this.client.post(
5168
+ "/v3/brand/profitsharing/receivers/add",
5169
+ request
5170
+ );
5171
+ }
5172
+ /**
5173
+ * 删除分账接收方
5174
+ *
5175
+ * @param request - 删除接收方请求参数
5176
+ * @returns 删除接收方结果
5177
+ */
5178
+ async deleteReceiver(request) {
5179
+ return this.client.post(
5180
+ "/v3/brand/profitsharing/receivers/delete",
5181
+ request
5182
+ );
5183
+ }
5184
+ };
5185
+ function loadCertificate(certificate) {
5186
+ return new crypto2__default.default.X509Certificate(certificate);
4784
5187
  }
4785
- function buildPayScoreDetailJsapiBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
4786
- const timestamp = String(Math.floor(Date.now() / 1e3));
4787
- const nonceStr = generateNonceStr();
4788
- const sign2 = generatePayScorePaySign(
4789
- appId,
4790
- timestamp,
4791
- nonceStr,
4792
- serviceId,
4793
- outOrderNo,
4794
- privateKey
4795
- );
4796
- return {
4797
- appid: appId,
4798
- mchid: mchId,
4799
- service_id: serviceId,
4800
- out_order_no: outOrderNo,
4801
- timestamp,
4802
- nonce_str: nonceStr,
4803
- sign_type: "RSA",
4804
- sign: sign2
4805
- };
5188
+ function loadCertificateFromPath(path) {
5189
+ return new crypto2__default.default.X509Certificate(fs2__default.default.readFileSync(path, "utf-8"));
4806
5190
  }
4807
- function buildPayScoreDetailMiniProgramBridgeConfig(mchId, serviceId, outOrderNo, appId, privateKey) {
4808
- const timestamp = String(Math.floor(Date.now() / 1e3));
4809
- const nonceStr = generateNonceStr();
4810
- const sign2 = generatePayScorePaySign(
4811
- appId,
4812
- timestamp,
4813
- nonceStr,
4814
- serviceId,
4815
- outOrderNo,
4816
- privateKey
4817
- );
4818
- return {
4819
- mchid: mchId,
4820
- service_id: serviceId,
4821
- out_order_no: outOrderNo,
4822
- timestamp,
4823
- nonce_str: nonceStr,
4824
- sign_type: "RSA",
4825
- sign: sign2
4826
- };
5191
+ function loadPrivateKey(key) {
5192
+ if (Buffer.isBuffer(key)) return key.toString("utf-8");
5193
+ if (key.startsWith("-----BEGIN")) return key;
5194
+ try {
5195
+ return fs2__default.default.readFileSync(key, "utf-8");
5196
+ } catch {
5197
+ return key;
5198
+ }
4827
5199
  }
4828
- function buildPayScoreDetailAppBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
4829
- const timestamp = String(Math.floor(Date.now() / 1e3));
4830
- const nonceStr = generateNonceStr();
4831
- const sign2 = generatePayScorePaySign(
4832
- appId,
4833
- timestamp,
4834
- nonceStr,
4835
- serviceId,
4836
- outOrderNo,
4837
- privateKey
4838
- );
4839
- return {
4840
- appid: appId,
4841
- mchid: mchId,
4842
- service_id: serviceId,
4843
- out_order_no: outOrderNo,
4844
- timestamp,
4845
- nonce_str: nonceStr,
4846
- sign_type: "RSA",
4847
- sign: sign2
4848
- };
5200
+ function loadPublicKey(key) {
5201
+ if (Buffer.isBuffer(key)) return key.toString("utf-8");
5202
+ if (key.startsWith("-----BEGIN")) return key;
5203
+ try {
5204
+ return fs2__default.default.readFileSync(key, "utf-8");
5205
+ } catch {
5206
+ return key;
5207
+ }
4849
5208
  }
4850
- var MED_INS_APPID = "wxbcad394b3d99dac9";
4851
- var MED_INS_PATH = "/pages/med-ins/pay/pay";
4852
- function buildMedInsMiniProgramBridgeConfig(mchid, mixTradeNo) {
4853
- return {
4854
- appId: MED_INS_APPID,
4855
- path: MED_INS_PATH,
4856
- extraData: {
4857
- mchid,
4858
- mix_trade_no: mixTradeNo
4859
- }
4860
- };
5209
+ function getCertificateSerialNumber(cert) {
5210
+ return cert.serialNumber.toUpperCase();
4861
5211
  }
4862
- function buildMedInsJsapiBridgeConfig(appId, mchId, mixTradeNo, privateKey) {
4863
- const timestamp = String(Math.floor(Date.now() / 1e3));
4864
- const nonceStr = generateNonceStr();
4865
- const packageStr = `mchid=${mchId}&mix_trade_no=${mixTradeNo}`;
4866
- const signString = `${appId}
4867
- ${timestamp}
4868
- ${nonceStr}
4869
- ${packageStr}
4870
- `;
4871
- const signer = crypto2__default.default.createSign("RSA-SHA256");
4872
- signer.update(signString);
4873
- signer.end();
4874
- const sign2 = signer.sign(privateKey, "base64");
4875
- return {
4876
- appid: appId,
4877
- mchid: mchId,
4878
- mix_trade_no: mixTradeNo,
4879
- timestamp,
4880
- nonce_str: nonceStr,
4881
- sign_type: "RSA",
4882
- sign: sign2
4883
- };
5212
+ function isCertificateExpired(cert, now) {
5213
+ const checkTime = now ?? /* @__PURE__ */ new Date();
5214
+ const validTo = new Date(cert.validTo);
5215
+ return checkTime > validTo;
5216
+ }
5217
+ function isCertificateValid(cert, now) {
5218
+ const checkTime = now ?? /* @__PURE__ */ new Date();
5219
+ const validFrom = new Date(cert.validFrom);
5220
+ const validTo = new Date(cert.validTo);
5221
+ return checkTime >= validFrom && checkTime <= validTo;
4884
5222
  }
4885
5223
 
4886
5224
  exports.AppService = AppService;
4887
5225
  exports.BillService = BillService;
5226
+ exports.BrandProfitSharingService = BrandProfitSharingService;
4888
5227
  exports.BusinessCircleService = BusinessCircleService;
4889
5228
  exports.CallbackHandler = CallbackHandler;
4890
5229
  exports.CertificateManager = CertificateManager;
@@ -4897,6 +5236,9 @@ exports.CombineService = CombineService;
4897
5236
  exports.ComplaintService = ComplaintService;
4898
5237
  exports.CouponService = CouponService;
4899
5238
  exports.DecryptionException = DecryptionException;
5239
+ exports.EcommerceProfitSharingService = EcommerceProfitSharingService;
5240
+ exports.EcommerceRefundService = EcommerceRefundService;
5241
+ exports.EcommerceSubsidyService = EcommerceSubsidyService;
4900
5242
  exports.GoldPlanService = GoldPlanService;
4901
5243
  exports.H5Service = H5Service;
4902
5244
  exports.HttpException = HttpException;
@@ -4909,16 +5251,24 @@ exports.MerchantExclusiveCouponService = MerchantExclusiveCouponService;
4909
5251
  exports.MerchantTransferService = MerchantTransferService;
4910
5252
  exports.NativeService = NativeService;
4911
5253
  exports.ParkingService = ParkingService;
5254
+ exports.PartnerAppService = PartnerAppService;
5255
+ exports.PartnerH5Service = PartnerH5Service;
5256
+ exports.PartnerJsapiService = PartnerJsapiService;
5257
+ exports.PartnerNativeService = PartnerNativeService;
5258
+ exports.PartnerTransferBatchService = PartnerTransferBatchService;
5259
+ exports.PartnerTransferService = PartnerTransferService;
4912
5260
  exports.PartnershipService = PartnershipService;
4913
5261
  exports.PayGiftActivityService = PayGiftActivityService;
4914
5262
  exports.PayScoreService = PayScoreService;
4915
5263
  exports.PayrollCardService = PayrollCardService;
4916
5264
  exports.ProfitSharingService = ProfitSharingService;
5265
+ exports.RefundService = RefundService;
4917
5266
  exports.RetailStoreService = RetailStoreService;
4918
5267
  exports.ScanAndRideService = ScanAndRideService;
4919
5268
  exports.SecurityService = SecurityService;
4920
5269
  exports.ServiceException = ServiceException;
4921
5270
  exports.SmartGuideService = SmartGuideService;
5271
+ exports.TransferBatchService = TransferBatchService;
4922
5272
  exports.ValidationException = ValidationException;
4923
5273
  exports.WxPayClient = WxPayClient;
4924
5274
  exports.WxPayError = WxPayError;
@@ -4952,7 +5302,14 @@ exports.generateNonce = generateNonce;
4952
5302
  exports.generateNonceStr = generateNonceStr;
4953
5303
  exports.generatePayScorePaySign = generatePayScorePaySign;
4954
5304
  exports.generatePaySign = generatePaySign;
5305
+ exports.getCertificateSerialNumber = getCertificateSerialNumber;
5306
+ exports.isCertificateExpired = isCertificateExpired;
5307
+ exports.isCertificateValid = isCertificateValid;
4955
5308
  exports.isTimestampValid = isTimestampValid;
5309
+ exports.loadCertificate = loadCertificate;
5310
+ exports.loadCertificateFromPath = loadCertificateFromPath;
5311
+ exports.loadPrivateKey = loadPrivateKey;
5312
+ exports.loadPublicKey = loadPublicKey;
4956
5313
  exports.oaepDecrypt = oaepDecrypt;
4957
5314
  exports.oaepEncrypt = oaepEncrypt;
4958
5315
  exports.registerSensitiveFields = registerSensitiveFields;