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