wxpay-nodejs-sdk 0.2.1 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,12 +1,14 @@
1
1
  'use strict';
2
2
 
3
3
  var fs = require('fs');
4
- var crypto4 = require('crypto');
4
+ var os = require('os');
5
+ var crypto2 = require('crypto');
5
6
 
6
7
  function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
8
 
8
9
  var fs__default = /*#__PURE__*/_interopDefault(fs);
9
- var crypto4__default = /*#__PURE__*/_interopDefault(crypto4);
10
+ var os__default = /*#__PURE__*/_interopDefault(os);
11
+ var crypto2__default = /*#__PURE__*/_interopDefault(crypto2);
10
12
 
11
13
  // src/core/client.ts
12
14
  var CertificateManager = class {
@@ -18,6 +20,8 @@ var CertificateManager = class {
18
20
  wxpayPublicKeyId = null;
19
21
  /** API V3 密钥 */
20
22
  apiV3Key;
23
+ /** 自动更新定时器 */
24
+ autoUpdateTimer = null;
21
25
  constructor(apiV3Key, certificates) {
22
26
  this.apiV3Key = apiV3Key;
23
27
  if (certificates) {
@@ -32,6 +36,21 @@ var CertificateManager = class {
32
36
  get serialNos() {
33
37
  return Array.from(this.certificates.keys());
34
38
  }
39
+ /**
40
+ * 获取最新的证书序列号或公钥ID
41
+ *
42
+ * 优先返回微信支付公钥ID(公钥模式),否则返回第一个平台证书序列号。
43
+ * 用于设置请求头 Wechatpay-Serial,告知微信支付客户端支持验签的证书。
44
+ *
45
+ * @returns 序列号字符串,无配置时返回 undefined
46
+ */
47
+ getNewestSerial() {
48
+ if (this.wxpayPublicKeyId) {
49
+ return this.wxpayPublicKeyId;
50
+ }
51
+ const keys = Array.from(this.certificates.keys());
52
+ return keys.length > 0 ? keys[0] : void 0;
53
+ }
35
54
  /**
36
55
  * 设置微信支付公钥(公钥模式)
37
56
  *
@@ -64,7 +83,7 @@ var CertificateManager = class {
64
83
  return Buffer.from(ciphertext, "base64").toString("utf-8");
65
84
  }
66
85
  try {
67
- const decipher = crypto4__default.default.createDecipheriv(
86
+ const decipher = crypto2__default.default.createDecipheriv(
68
87
  "aes-256-gcm",
69
88
  Buffer.from(this.apiV3Key, "utf-8"),
70
89
  Buffer.from(nonce, "utf-8")
@@ -115,9 +134,68 @@ var CertificateManager = class {
115
134
  this.wxpayPublicKey = null;
116
135
  this.wxpayPublicKeyId = null;
117
136
  }
137
+ /**
138
+ * 启动自动更新
139
+ *
140
+ * 定期调用更新函数刷新平台证书。适用于生产环境的证书自动维护。
141
+ *
142
+ * @param updateFn - 证书更新函数,返回最新的证书 Map
143
+ * @param options - 自动更新配置选项
144
+ * @returns 停止更新的函数
145
+ *
146
+ * @example
147
+ * ```ts
148
+ * const manager = new CertificateManager(apiV3Key);
149
+ * const stop = manager.startAutoUpdate(
150
+ * async () => {
151
+ * const certs = await downloadCertificates();
152
+ * return certs;
153
+ * },
154
+ * { intervalMs: 60 * 60 * 1000 }
155
+ * );
156
+ * // 稍后停止
157
+ * stop();
158
+ * ```
159
+ */
160
+ startAutoUpdate(updateFn, options) {
161
+ const intervalMs = options?.intervalMs ?? 60 * 60 * 1e3;
162
+ this.stopAutoUpdate();
163
+ const doUpdate = async () => {
164
+ try {
165
+ const certs = await updateFn();
166
+ for (const [serialNo, publicKey] of certs) {
167
+ this.setPublicKey(serialNo, publicKey);
168
+ }
169
+ options?.onSuccess?.(Array.from(certs.keys()));
170
+ } catch (error) {
171
+ options?.onError?.(error instanceof Error ? error : new Error(String(error)));
172
+ }
173
+ };
174
+ void doUpdate();
175
+ this.autoUpdateTimer = setInterval(() => {
176
+ void doUpdate();
177
+ }, intervalMs);
178
+ return () => {
179
+ this.stopAutoUpdate();
180
+ };
181
+ }
182
+ /**
183
+ * 停止自动更新
184
+ */
185
+ stopAutoUpdate() {
186
+ if (this.autoUpdateTimer) {
187
+ clearInterval(this.autoUpdateTimer);
188
+ this.autoUpdateTimer = null;
189
+ }
190
+ }
118
191
  };
119
-
120
- // src/utils/http.ts
192
+ var SDK_VERSION = "0.2.1";
193
+ function getUserAgent() {
194
+ const platform = os__default.default.platform();
195
+ const arch = os__default.default.arch();
196
+ const nodeVersion = process.version;
197
+ return `wxpay-nodejs-sdk/${SDK_VERSION} (${platform} ${arch}) Node.js/${nodeVersion}`;
198
+ }
121
199
  var WxPayError = class extends Error {
122
200
  /** HTTP 状态码 */
123
201
  status;
@@ -170,13 +248,16 @@ function parseResponseHeaders(headers) {
170
248
  return result;
171
249
  }
172
250
  function createRequestHeaders(options) {
173
- return {
251
+ const headers = {
174
252
  Authorization: options.authorization,
175
253
  Accept: options.accept ?? "application/json",
176
254
  "Content-Type": options.contentType ?? "application/json",
177
- "User-Agent": "wxpay-nodejs-sdk/0.1.0",
178
- ...options.additional
255
+ "User-Agent": getUserAgent()
179
256
  };
257
+ if (options.wechatPaySerial) {
258
+ headers["Wechatpay-Serial"] = options.wechatPaySerial;
259
+ }
260
+ return { ...headers, ...options.additional };
180
261
  }
181
262
  async function parseResponse(response, verify) {
182
263
  const headers = parseResponseHeaders(response.headers);
@@ -245,7 +326,7 @@ ${body}
245
326
  `;
246
327
  }
247
328
  function sign(signString, privateKey) {
248
- const signer = crypto4__default.default.createSign("RSA-SHA256");
329
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
249
330
  signer.update(signString);
250
331
  signer.end();
251
332
  return signer.sign(privateKey, "base64");
@@ -254,36 +335,68 @@ function buildAuthorization(mchid, serialNo, timestamp, nonce, signature) {
254
335
  return `WECHATPAY2-SHA256-RSA2048 mchid="${mchid}",nonce_str="${nonce}",timestamp="${timestamp}",serial_no="${serialNo}",signature="${signature}"`;
255
336
  }
256
337
  function generateNonce() {
257
- return crypto4__default.default.randomUUID().replace(/-/g, "");
338
+ return crypto2__default.default.randomUUID().replace(/-/g, "");
339
+ }
340
+ var RESPONSE_EXPIRED_SECONDS = 5 * 60;
341
+ function isTimestampValid(timestamp) {
342
+ const responseTime = parseInt(timestamp, 10);
343
+ if (isNaN(responseTime)) return false;
344
+ const now = Math.floor(Date.now() / 1e3);
345
+ return Math.abs(now - responseTime) < RESPONSE_EXPIRED_SECONDS;
258
346
  }
259
347
  function verifySignature(body, signature, timestamp, nonce, publicKey) {
348
+ if (!isTimestampValid(timestamp)) {
349
+ return false;
350
+ }
260
351
  const signString = `${timestamp}
261
352
  ${nonce}
262
353
  ${body}
263
354
  `;
264
- const verifier = crypto4__default.default.createVerify("RSA-SHA256");
355
+ const verifier = crypto2__default.default.createVerify("RSA-SHA256");
265
356
  verifier.update(signString);
266
357
  verifier.end();
267
358
  return verifier.verify(publicKey, signature, "base64");
268
359
  }
269
360
  function oaepEncrypt(plaintext, publicKey) {
270
- const encrypted = crypto4__default.default.publicEncrypt(
361
+ const encrypted = crypto2__default.default.publicEncrypt(
271
362
  {
272
363
  key: publicKey,
273
- padding: crypto4__default.default.constants.RSA_PKCS1_OAEP_PADDING,
274
- oaepHash: "sha256"
364
+ padding: crypto2__default.default.constants.RSA_PKCS1_OAEP_PADDING,
365
+ oaepHash: "sha1"
275
366
  },
276
367
  Buffer.from(plaintext, "utf-8")
277
368
  );
278
369
  return encrypted.toString("base64");
279
370
  }
371
+ function oaepDecrypt(ciphertext, privateKey) {
372
+ const decrypted = crypto2__default.default.privateDecrypt(
373
+ {
374
+ key: privateKey,
375
+ padding: crypto2__default.default.constants.RSA_PKCS1_OAEP_PADDING,
376
+ oaepHash: "sha1"
377
+ },
378
+ Buffer.from(ciphertext, "base64")
379
+ );
380
+ return decrypted.toString("utf-8");
381
+ }
280
382
 
281
383
  // src/core/client.ts
282
384
  var WxPayClient = class _WxPayClient {
283
- /** 生产环境 API 地址 */
385
+ /** 生产环境 API 主域名 */
284
386
  static PRODUCTION_BASE = "https://api.mch.weixin.qq.com";
387
+ /** 生产环境 API 备用域名(跨城容灾) */
388
+ static PRODUCTION_BACKUP = "https://api2.mch.weixin.qq.com";
285
389
  /** 沙箱环境 API 地址 */
286
390
  static SANDBOX_BASE = "https://api.mch.weixin.qq.com/sandboxnew";
391
+ /** SDK 版本号 */
392
+ static SDK_VERSION = "0.2.1";
393
+ /** 动态 User-Agent 字符串 */
394
+ static USER_AGENT = (() => {
395
+ const platform = os__default.default.platform();
396
+ const arch = os__default.default.arch();
397
+ const nodeVersion = process.version;
398
+ return `wxpay-nodejs-sdk/${_WxPayClient.SDK_VERSION} (${platform} ${arch}) Node.js/${nodeVersion}`;
399
+ })();
287
400
  /** 商户号 */
288
401
  mchid;
289
402
  apiV3Key;
@@ -291,6 +404,7 @@ var WxPayClient = class _WxPayClient {
291
404
  privateKey;
292
405
  timeout;
293
406
  baseUrl;
407
+ backupUrl;
294
408
  enableResponseVerification;
295
409
  /** 平台证书管理器 */
296
410
  certificates;
@@ -301,6 +415,7 @@ var WxPayClient = class _WxPayClient {
301
415
  this.privateKey = this.resolvePrivateKey(options.privateKey);
302
416
  this.timeout = options.timeout ?? 3e4;
303
417
  this.baseUrl = options.sandbox ? _WxPayClient.SANDBOX_BASE : _WxPayClient.PRODUCTION_BASE;
418
+ this.backupUrl = options.sandbox ? null : _WxPayClient.PRODUCTION_BACKUP;
304
419
  this.enableResponseVerification = options.enableResponseVerification ?? true;
305
420
  this.certificates = new CertificateManager(this.apiV3Key, options.platformCertificates);
306
421
  if (options.wxpayPublicKeyId && options.wxpayPublicKey) {
@@ -372,8 +487,12 @@ var WxPayClient = class _WxPayClient {
372
487
  const headers = {
373
488
  Authorization: authorization,
374
489
  Accept: "application/json",
375
- "User-Agent": "wxpay-nodejs-sdk/0.1.0"
490
+ "User-Agent": _WxPayClient.USER_AGENT
376
491
  };
492
+ const serial = this.certificates.getNewestSerial();
493
+ if (serial) {
494
+ headers["Wechatpay-Serial"] = serial;
495
+ }
377
496
  const controller = new AbortController();
378
497
  const timeoutId = setTimeout(() => {
379
498
  controller.abort();
@@ -495,8 +614,12 @@ var WxPayClient = class _WxPayClient {
495
614
  Authorization: authorization,
496
615
  Accept: "application/json",
497
616
  "Content-Type": `multipart/form-data; boundary=${boundary}`,
498
- "User-Agent": "wxpay-nodejs-sdk/0.1.0"
617
+ "User-Agent": _WxPayClient.USER_AGENT
499
618
  };
619
+ const serial = this.certificates.getNewestSerial();
620
+ if (serial) {
621
+ headers["Wechatpay-Serial"] = serial;
622
+ }
500
623
  const controller = new AbortController();
501
624
  const timeoutId = setTimeout(() => {
502
625
  controller.abort();
@@ -537,67 +660,90 @@ var WxPayClient = class _WxPayClient {
537
660
  }
538
661
  /**
539
662
  * 通用 HTTP 请求方法
663
+ *
664
+ * 支持跨城容灾:当主域名请求失败(网络错误、超时)时,自动切换到备用域名重试。
540
665
  */
541
666
  async request(method, path, params, body, extraHeaders) {
542
- const url = buildUrl(this.baseUrl, path, params);
543
667
  const bodyStr = body ? JSON.stringify(body) : "";
544
668
  const timestamp = Math.floor(Date.now() / 1e3);
545
669
  const nonce = generateNonce();
546
- const urlObj = new URL(url);
547
- const signPath = urlObj.pathname + urlObj.search;
548
- const signString = buildSignString({
549
- method: method.toUpperCase(),
550
- path: signPath,
551
- timestamp,
552
- nonce,
553
- body: bodyStr
670
+ const headers = createRequestHeaders({
671
+ authorization: "",
672
+ wechatPaySerial: this.certificates.getNewestSerial(),
673
+ additional: extraHeaders
554
674
  });
555
- const signature = sign(signString, this.privateKey);
556
- const authorization = buildAuthorization(
557
- this.mchid,
558
- this.serialNo,
559
- timestamp,
560
- nonce,
561
- signature
562
- );
563
- const headers = createRequestHeaders({ authorization, additional: extraHeaders });
564
- const controller = new AbortController();
565
- const timeoutId = setTimeout(() => {
566
- controller.abort();
567
- }, this.timeout);
568
- try {
569
- const response = await fetch(url, {
570
- method,
571
- headers,
572
- body: bodyStr || void 0,
573
- signal: controller.signal
675
+ const urls = [this.baseUrl];
676
+ if (this.backupUrl) {
677
+ urls.push(this.backupUrl);
678
+ }
679
+ let lastError;
680
+ for (const baseUrl of urls) {
681
+ const url = buildUrl(baseUrl, path, params);
682
+ const urlObj = new URL(url);
683
+ const signPath = urlObj.pathname + urlObj.search;
684
+ const signString = buildSignString({
685
+ method: method.toUpperCase(),
686
+ path: signPath,
687
+ timestamp,
688
+ nonce,
689
+ body: bodyStr
574
690
  });
575
- return await parseResponse(response, this.createVerifier());
576
- } catch (error) {
577
- if (error instanceof WxPayError) {
578
- throw error;
579
- }
580
- if (error instanceof DOMException && error.name === "AbortError") {
581
- throw new WxPayError(
582
- 0,
583
- {},
584
- {
585
- code: "REQUEST_TIMEOUT",
586
- message: `\u8BF7\u6C42\u8D85\u65F6 (${this.timeout}ms)`
691
+ const signature = sign(signString, this.privateKey);
692
+ headers["Authorization"] = buildAuthorization(
693
+ this.mchid,
694
+ this.serialNo,
695
+ timestamp,
696
+ nonce,
697
+ signature
698
+ );
699
+ const controller = new AbortController();
700
+ const timeoutId = setTimeout(() => {
701
+ controller.abort();
702
+ }, this.timeout);
703
+ try {
704
+ const response = await fetch(url, {
705
+ method,
706
+ headers,
707
+ body: bodyStr || void 0,
708
+ signal: controller.signal
709
+ });
710
+ return await parseResponse(response, this.createVerifier());
711
+ } catch (error) {
712
+ lastError = error;
713
+ const isNetworkError = !(error instanceof WxPayError) && !(error instanceof DOMException && error.name === "AbortError");
714
+ if (!isNetworkError || urls.indexOf(baseUrl) === urls.length - 1) {
715
+ if (error instanceof WxPayError) throw error;
716
+ if (error instanceof DOMException && error.name === "AbortError") {
717
+ throw new WxPayError(
718
+ 0,
719
+ {},
720
+ {
721
+ code: "REQUEST_TIMEOUT",
722
+ message: `\u8BF7\u6C42\u8D85\u65F6 (${this.timeout}ms)`
723
+ }
724
+ );
587
725
  }
588
- );
589
- }
590
- throw new WxPayError(
591
- 0,
592
- {},
593
- {
594
- code: "NETWORK_ERROR",
595
- message: error instanceof Error ? error.message : "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"
726
+ throw new WxPayError(
727
+ 0,
728
+ {},
729
+ {
730
+ code: "NETWORK_ERROR",
731
+ message: error instanceof Error ? error.message : "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"
732
+ }
733
+ );
596
734
  }
597
- );
598
- } finally {
599
- clearTimeout(timeoutId);
735
+ } finally {
736
+ clearTimeout(timeoutId);
737
+ }
600
738
  }
739
+ throw new WxPayError(
740
+ 0,
741
+ {},
742
+ {
743
+ code: "NETWORK_ERROR",
744
+ message: lastError instanceof Error ? lastError.message : "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"
745
+ }
746
+ );
601
747
  }
602
748
  /**
603
749
  * 解析私钥:支持直接传入内容或文件路径
@@ -637,6 +783,75 @@ var WxPayClient = class _WxPayClient {
637
783
  };
638
784
  }
639
785
  };
786
+ var CertificateService = class {
787
+ client;
788
+ apiV3Key;
789
+ certificateManager;
790
+ constructor(client, apiV3Key, certificateManager) {
791
+ this.client = client;
792
+ this.apiV3Key = apiV3Key;
793
+ this.certificateManager = certificateManager;
794
+ }
795
+ /**
796
+ * 下载平台证书列表
797
+ *
798
+ * 调用微信支付 /v3/certificates 接口获取当前可用的平台证书。
799
+ * 返回的证书内容已解密为 PEM 格式。
800
+ *
801
+ * @returns 解密后的平台证书列表
802
+ */
803
+ async downloadCertificates() {
804
+ const response = await this.client.get("/v3/certificates");
805
+ const decryptedCerts = response.data.data.map((cert) => {
806
+ const pem = this.decryptCertificate(cert.encryptCertificate);
807
+ return {
808
+ serialNo: cert.serialNo,
809
+ effectiveTime: cert.effectiveTime,
810
+ expireTime: cert.expireTime,
811
+ certificatePem: pem
812
+ };
813
+ });
814
+ return {
815
+ status: response.status,
816
+ headers: response.headers,
817
+ data: decryptedCerts
818
+ };
819
+ }
820
+ /**
821
+ * 下载并更新本地平台证书缓存
822
+ *
823
+ * 下载最新的平台证书列表,解密后自动更新 CertificateManager 中的缓存。
824
+ * 适用于定时更新证书的场景。
825
+ *
826
+ * @returns 更新后的证书列表
827
+ */
828
+ async downloadAndUpdate() {
829
+ const response = await this.downloadCertificates();
830
+ for (const cert of response.data) {
831
+ this.certificateManager.setPublicKey(cert.serialNo, cert.certificatePem);
832
+ }
833
+ return response.data;
834
+ }
835
+ /**
836
+ * 使用 AES-256-GCM 解密证书内容
837
+ *
838
+ * @param encrypted - 加密的证书信息
839
+ * @returns PEM 格式的证书内容
840
+ */
841
+ decryptCertificate(encrypted) {
842
+ const key = Buffer.from(this.apiV3Key, "utf-8");
843
+ const nonce = Buffer.from(encrypted.nonce, "utf-8");
844
+ const aad = Buffer.from(encrypted.associatedData, "utf-8");
845
+ const ciphertextBuffer = Buffer.from(encrypted.ciphertext, "base64");
846
+ const authTag = ciphertextBuffer.subarray(-16);
847
+ const encryptedData = ciphertextBuffer.subarray(0, -16);
848
+ const decipher = crypto2__default.default.createDecipheriv("aes-256-gcm", key, nonce);
849
+ decipher.setAuthTag(authTag);
850
+ decipher.setAAD(aad);
851
+ const decrypted = Buffer.concat([decipher.update(encryptedData), decipher.final()]);
852
+ return decrypted.toString("utf-8");
853
+ }
854
+ };
640
855
 
641
856
  // src/services/jsapi.ts
642
857
  var JsapiService = class {
@@ -2428,6 +2643,7 @@ var BillService = class {
2428
2643
  return this.client.downloadRaw(downloadUrl);
2429
2644
  }
2430
2645
  };
2646
+ var SUPPORTED_SIGNATURE_TYPES = /* @__PURE__ */ new Set(["WECHATPAY2-SHA256-RSA2048"]);
2431
2647
  var CallbackHandler = class {
2432
2648
  apiV3Key;
2433
2649
  certificates;
@@ -2439,13 +2655,19 @@ var CallbackHandler = class {
2439
2655
  * 验证回调通知签名
2440
2656
  *
2441
2657
  * 使用微信支付平台公钥验证回调通知的签名。
2658
+ * 支持读取 Wechatpay-Signature-Type 头识别签名类型。
2442
2659
  *
2443
2660
  * @param headers - 回调请求头
2444
2661
  * @param body - 回调请求体(原始 JSON 字符串)
2445
2662
  * @returns 签名验证是否通过
2663
+ * @throws 如果签名类型不支持或找不到对应的证书
2446
2664
  */
2447
2665
  verifySignature(headers, body) {
2666
+ const signatureType = headers["wechatpay-signature-type"];
2448
2667
  const serialNo = headers["wechatpay-serial"];
2668
+ if (signatureType && !SUPPORTED_SIGNATURE_TYPES.has(signatureType)) {
2669
+ throw new Error(`\u4E0D\u652F\u6301\u7684\u7B7E\u540D\u7C7B\u578B: ${signatureType}`);
2670
+ }
2449
2671
  const publicKey = this.certificates.getPublicKey(serialNo);
2450
2672
  if (!publicKey) {
2451
2673
  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`);
@@ -2722,7 +2944,7 @@ var CallbackHandler = class {
2722
2944
  const ciphertextBuffer = Buffer.from(ciphertext, "base64");
2723
2945
  const authTag = ciphertextBuffer.subarray(-16);
2724
2946
  const encryptedData = ciphertextBuffer.subarray(0, -16);
2725
- const decipher = crypto4__default.default.createDecipheriv("aes-256-gcm", key, Buffer.from(nonce, "utf-8"));
2947
+ const decipher = crypto2__default.default.createDecipheriv("aes-256-gcm", key, Buffer.from(nonce, "utf-8"));
2726
2948
  decipher.setAuthTag(authTag);
2727
2949
  decipher.setAAD(Buffer.from(associatedData, "utf-8"));
2728
2950
  const decrypted = Buffer.concat([decipher.update(encryptedData), decipher.final()]);
@@ -3850,13 +4072,327 @@ var SecurityService = class {
3850
4072
  return this.client.post("/v3/security/echo", request);
3851
4073
  }
3852
4074
  };
4075
+
4076
+ // src/services/payrollcard.ts
4077
+ var PayrollCardService = class {
4078
+ client;
4079
+ constructor(client) {
4080
+ this.client = client;
4081
+ }
4082
+ /**
4083
+ * 查询授权关系
4084
+ *
4085
+ * 查询商户与用户之间的微工卡授权关系。
4086
+ *
4087
+ * @param params - 查询参数
4088
+ * @returns 授权关系信息
4089
+ */
4090
+ async queryAuthorization(params) {
4091
+ return this.client.get("/v3/payroll-card/relations", params);
4092
+ }
4093
+ /**
4094
+ * 生成预授权 token
4095
+ *
4096
+ * 生成微工卡预授权 token,用于后续核身操作。
4097
+ *
4098
+ * @param request - 预授权请求参数
4099
+ * @returns 预授权 token 信息
4100
+ */
4101
+ async createToken(request) {
4102
+ return this.client.post("/v3/payroll-card/tokens", request);
4103
+ }
4104
+ /**
4105
+ * 核身预下单
4106
+ *
4107
+ * 创建核身预下单,获取核身参数。
4108
+ *
4109
+ * @param request - 核身预下单请求参数
4110
+ * @returns 核身参数信息
4111
+ */
4112
+ async createAuthentication(request) {
4113
+ return this.client.post("/v3/payroll-card/authentications", request);
4114
+ }
4115
+ /**
4116
+ * 查询核身结果
4117
+ *
4118
+ * 根据商户请求号查询核身结果。
4119
+ *
4120
+ * @param outRequestNo - 商户请求号
4121
+ * @param params - 查询参数
4122
+ * @returns 核身结果信息
4123
+ */
4124
+ async queryAuthentication(outRequestNo, params) {
4125
+ return this.client.get(
4126
+ `/v3/payroll-card/authentications/out-request-no/${outRequestNo}`,
4127
+ params
4128
+ );
4129
+ }
4130
+ /**
4131
+ * 发起批量转账
4132
+ *
4133
+ * 通过工资卡渠道发起批量转账。
4134
+ *
4135
+ * @param request - 批量转账请求参数
4136
+ * @returns 批量转账结果
4137
+ */
4138
+ async createTransferBatch(request) {
4139
+ return this.client.post("/v3/payroll-card/transfer-batches", request);
4140
+ }
4141
+ };
4142
+
4143
+ // src/services/scanandride.ts
4144
+ var ScanAndRideService = class {
4145
+ client;
4146
+ constructor(client) {
4147
+ this.client = client;
4148
+ }
4149
+ /**
4150
+ * 开通用户服务
4151
+ *
4152
+ * 用户授权开通刷码乘车服务。
4153
+ *
4154
+ * @param request - 开通服务请求参数
4155
+ * @returns 开通结果
4156
+ */
4157
+ async createUserService(request) {
4158
+ return this.client.post("/v3/qrcode/user-services", request);
4159
+ }
4160
+ /**
4161
+ * 查询用户服务状态
4162
+ *
4163
+ * 查询用户是否已开通刷码乘车服务。
4164
+ *
4165
+ * @param outRequestNo - 商户请求号
4166
+ * @param params - 查询参数
4167
+ * @returns 用户服务状态
4168
+ */
4169
+ async queryUserService(outRequestNo, params) {
4170
+ return this.client.get(`/v3/qrcode/user-services/out-request-no/${outRequestNo}`, params);
4171
+ }
4172
+ /**
4173
+ * 扣费受理
4174
+ *
4175
+ * 发起刷码乘车扣费请求。
4176
+ *
4177
+ * @param request - 扣费请求参数
4178
+ * @returns 扣费受理结果
4179
+ */
4180
+ async createTransaction(request) {
4181
+ return this.client.post("/v3/qrcode/transactions", request);
4182
+ }
4183
+ /**
4184
+ * 查询扣费订单
4185
+ *
4186
+ * 根据商户订单号查询扣费订单状态。
4187
+ *
4188
+ * @param outTradeNo - 商户订单号
4189
+ * @param params - 查询参数
4190
+ * @returns 订单信息
4191
+ */
4192
+ async queryTransaction(outTradeNo, params) {
4193
+ return this.client.get(`/v3/qrcode/transactions/out-trade-no/${outTradeNo}`, params);
4194
+ }
4195
+ };
4196
+
4197
+ // src/services/retailstore.ts
4198
+ var RetailStoreService = class {
4199
+ client;
4200
+ constructor(client) {
4201
+ this.client = client;
4202
+ }
4203
+ /**
4204
+ * 创建门店活动
4205
+ *
4206
+ * @param request - 活动创建请求参数
4207
+ * @returns 创建结果
4208
+ */
4209
+ async createActivity(request) {
4210
+ return this.client.post("/v3/marketing/goldplan/retailstore/activities", request);
4211
+ }
4212
+ /**
4213
+ * 查询门店活动详情
4214
+ *
4215
+ * @param activityId - 活动ID
4216
+ * @returns 活动详情
4217
+ */
4218
+ async queryActivity(activityId) {
4219
+ return this.client.get(`/v3/marketing/goldplan/retailstore/activities/${activityId}`);
4220
+ }
4221
+ /**
4222
+ * 更新门店活动
4223
+ *
4224
+ * @param activityId - 活动ID
4225
+ * @param request - 更新请求参数
4226
+ * @returns 更新结果
4227
+ */
4228
+ async updateActivity(activityId, request) {
4229
+ return this.client.patch(
4230
+ `/v3/marketing/goldplan/retailstore/activities/${activityId}`,
4231
+ request
4232
+ );
4233
+ }
4234
+ /**
4235
+ * 创建门店资质
4236
+ *
4237
+ * @param request - 资质创建请求参数
4238
+ * @returns 创建结果
4239
+ */
4240
+ async createQualification(request) {
4241
+ return this.client.post("/v3/marketing/goldplan/retailstore/qualifications", request);
4242
+ }
4243
+ /**
4244
+ * 查询门店资质
4245
+ *
4246
+ * @param qualificationId - 资质ID
4247
+ * @returns 资质详情
4248
+ */
4249
+ async queryQualification(qualificationId) {
4250
+ return this.client.get(`/v3/marketing/goldplan/retailstore/qualifications/${qualificationId}`);
4251
+ }
4252
+ };
4253
+
4254
+ // src/services/goldplan.ts
4255
+ var GoldPlanService = class {
4256
+ client;
4257
+ constructor(client) {
4258
+ this.client = client;
4259
+ }
4260
+ /**
4261
+ * 查询商户零钱余额
4262
+ *
4263
+ * @param mchid - 商户号
4264
+ * @returns 零钱余额信息
4265
+ */
4266
+ async queryBalance(mchid) {
4267
+ return this.client.get(`/v3/merchant/fund/balance/${mchid}`);
4268
+ }
4269
+ /**
4270
+ * 查询商户零钱流水
4271
+ *
4272
+ * @param mchid - 商户号
4273
+ * @param params - 查询参数
4274
+ * @returns 零钱流水列表
4275
+ */
4276
+ async queryFlow(mchid, params) {
4277
+ return this.client.get(`/v3/merchant/fund/flow`, { mchid, ...params });
4278
+ }
4279
+ /**
4280
+ * 查询商家零钱状态
4281
+ *
4282
+ * @param mchid - 商户号
4283
+ * @returns 零钱状态信息
4284
+ */
4285
+ async queryStatus(mchid) {
4286
+ return this.client.get(`/v3/merchant/fund/status/${mchid}`);
4287
+ }
4288
+ };
4289
+
4290
+ // src/services/lovefeast.ts
4291
+ var LoveFeastService = class {
4292
+ client;
4293
+ constructor(client) {
4294
+ this.client = client;
4295
+ }
4296
+ /**
4297
+ * 创建爱心餐品牌
4298
+ *
4299
+ * @param request - 品牌创建请求参数
4300
+ * @returns 创建结果
4301
+ */
4302
+ async createBrand(request) {
4303
+ return this.client.post("/v3/lovefeast/brands", request);
4304
+ }
4305
+ /**
4306
+ * 查询爱心餐品牌
4307
+ *
4308
+ * @param brandId - 品牌ID
4309
+ * @returns 品牌详情
4310
+ */
4311
+ async queryBrand(brandId) {
4312
+ return this.client.get(`/v3/lovefeast/brands/${brandId}`);
4313
+ }
4314
+ /**
4315
+ * 创建爱心餐订单
4316
+ *
4317
+ * @param request - 订单创建请求参数
4318
+ * @returns 订单创建结果
4319
+ */
4320
+ async createOrder(request) {
4321
+ return this.client.post("/v3/lovefeast/orders", request);
4322
+ }
4323
+ /**
4324
+ * 查询爱心餐订单
4325
+ *
4326
+ * @param outTradeNo - 商户订单号
4327
+ * @param params - 查询参数
4328
+ * @returns 订单详情
4329
+ */
4330
+ async queryOrder(outTradeNo, params) {
4331
+ return this.client.get(`/v3/lovefeast/orders/out-trade-no/${outTradeNo}`, params);
4332
+ }
4333
+ };
4334
+
4335
+ // src/services/merchant-exclusive-coupon.ts
4336
+ var MerchantExclusiveCouponService = class {
4337
+ client;
4338
+ constructor(client) {
4339
+ this.client = client;
4340
+ }
4341
+ /**
4342
+ * 创建优惠券批次
4343
+ *
4344
+ * @param request - 批次创建请求参数
4345
+ * @returns 创建结果
4346
+ */
4347
+ async createCouponStock(request) {
4348
+ return this.client.post("/v3/marketing/busifavor/stocks", request);
4349
+ }
4350
+ /**
4351
+ * 查询优惠券批次详情
4352
+ *
4353
+ * @param stockId - 批次ID
4354
+ * @returns 批次详情
4355
+ */
4356
+ async queryCouponStock(stockId) {
4357
+ return this.client.get(`/v3/marketing/busifavor/stocks/${stockId}`);
4358
+ }
4359
+ /**
4360
+ * 发放优惠券
4361
+ *
4362
+ * @param request - 发放请求参数
4363
+ * @returns 发放结果
4364
+ */
4365
+ async sendCoupon(request) {
4366
+ return this.client.post("/v3/marketing/busifavor/coupons", request);
4367
+ }
4368
+ /**
4369
+ * 查询用户优惠券
4370
+ *
4371
+ * @param openid - 用户标识
4372
+ * @param params - 查询参数
4373
+ * @returns 用户优惠券列表
4374
+ */
4375
+ async queryUserCoupons(openid, params) {
4376
+ return this.client.get(`/v3/marketing/busifavor/users/${openid}/coupons`, params);
4377
+ }
4378
+ /**
4379
+ * 查询优惠券详情
4380
+ *
4381
+ * @param couponId - 优惠券ID
4382
+ * @param params - 查询参数
4383
+ * @returns 优惠券详情
4384
+ */
4385
+ async queryCoupon(couponId, params) {
4386
+ return this.client.get(`/v3/marketing/busifavor/users/coupons/${couponId}`, params);
4387
+ }
4388
+ };
3853
4389
  function generateAppPaySign(appId, timeStamp, nonceStr, prepayId, privateKey) {
3854
4390
  const signString = `${appId}
3855
4391
  ${timeStamp}
3856
4392
  ${nonceStr}
3857
4393
  prepay_id=${prepayId}
3858
4394
  `;
3859
- const signer = crypto4__default.default.createSign("RSA-SHA256");
4395
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
3860
4396
  signer.update(signString);
3861
4397
  signer.end();
3862
4398
  return signer.sign(privateKey, "base64");
@@ -3881,13 +4417,13 @@ ${timeStamp}
3881
4417
  ${nonceStr}
3882
4418
  prepay_id=${prepayId}
3883
4419
  `;
3884
- const signer = crypto4__default.default.createSign("RSA-SHA256");
4420
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
3885
4421
  signer.update(signString);
3886
4422
  signer.end();
3887
4423
  return signer.sign(privateKey, "base64");
3888
4424
  }
3889
4425
  function generateNonceStr() {
3890
- return crypto4__default.default.randomUUID().replace(/-/g, "");
4426
+ return crypto2__default.default.randomUUID().replace(/-/g, "");
3891
4427
  }
3892
4428
  function buildJsapiBridgeConfig(appId, prepayId, privateKey) {
3893
4429
  const timeStamp = String(Math.floor(Date.now() / 1e3));
@@ -3921,7 +4457,7 @@ ${timeStamp}
3921
4457
  ${nonceStr}
3922
4458
  ${packageStr}
3923
4459
  `;
3924
- const signer = crypto4__default.default.createSign("RSA-SHA256");
4460
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
3925
4461
  signer.update(signString);
3926
4462
  signer.end();
3927
4463
  return signer.sign(privateKey, "base64");
@@ -4071,7 +4607,7 @@ function buildH5CouponUrl(params, signKey) {
4071
4607
  }
4072
4608
  const sortedKeys = Object.keys(signFields).sort();
4073
4609
  const signStr = sortedKeys.map((k) => `${k}=${signFields[k]}`).join("&") + `&key=${signKey}`;
4074
- const sign2 = crypto4__default.default.createHmac("sha256", signKey).update(signStr).digest("hex").toUpperCase();
4610
+ const sign2 = crypto2__default.default.createHmac("sha256", signKey).update(signStr).digest("hex").toUpperCase();
4075
4611
  const urlParams = new URLSearchParams({
4076
4612
  stock_id: params.stock_id,
4077
4613
  out_request_no: params.out_request_no,
@@ -4173,7 +4709,7 @@ ${timestamp}
4173
4709
  ${nonceStr}
4174
4710
  ${packageStr}
4175
4711
  `;
4176
- const signer = crypto4__default.default.createSign("RSA-SHA256");
4712
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
4177
4713
  signer.update(signString);
4178
4714
  signer.end();
4179
4715
  const sign2 = signer.sign(privateKey, "base64");
@@ -4193,6 +4729,7 @@ exports.BillService = BillService;
4193
4729
  exports.BusinessCircleService = BusinessCircleService;
4194
4730
  exports.CallbackHandler = CallbackHandler;
4195
4731
  exports.CertificateManager = CertificateManager;
4732
+ exports.CertificateService = CertificateService;
4196
4733
  exports.CombineAppService = CombineAppService;
4197
4734
  exports.CombineH5Service = CombineH5Service;
4198
4735
  exports.CombineMiniProgramService = CombineMiniProgramService;
@@ -4200,17 +4737,23 @@ exports.CombineNativeService = CombineNativeService;
4200
4737
  exports.CombineService = CombineService;
4201
4738
  exports.ComplaintService = ComplaintService;
4202
4739
  exports.CouponService = CouponService;
4740
+ exports.GoldPlanService = GoldPlanService;
4203
4741
  exports.H5Service = H5Service;
4204
4742
  exports.JsapiService = JsapiService;
4743
+ exports.LoveFeastService = LoveFeastService;
4205
4744
  exports.MedInsService = MedInsService;
4206
4745
  exports.MediaService = MediaService;
4746
+ exports.MerchantExclusiveCouponService = MerchantExclusiveCouponService;
4207
4747
  exports.MerchantTransferService = MerchantTransferService;
4208
4748
  exports.NativeService = NativeService;
4209
4749
  exports.ParkingService = ParkingService;
4210
4750
  exports.PartnershipService = PartnershipService;
4211
4751
  exports.PayGiftActivityService = PayGiftActivityService;
4212
4752
  exports.PayScoreService = PayScoreService;
4753
+ exports.PayrollCardService = PayrollCardService;
4213
4754
  exports.ProfitSharingService = ProfitSharingService;
4755
+ exports.RetailStoreService = RetailStoreService;
4756
+ exports.ScanAndRideService = ScanAndRideService;
4214
4757
  exports.SecurityService = SecurityService;
4215
4758
  exports.SmartGuideService = SmartGuideService;
4216
4759
  exports.WxPayClient = WxPayClient;
@@ -4241,6 +4784,8 @@ exports.generateNonce = generateNonce;
4241
4784
  exports.generateNonceStr = generateNonceStr;
4242
4785
  exports.generatePayScorePaySign = generatePayScorePaySign;
4243
4786
  exports.generatePaySign = generatePaySign;
4787
+ exports.isTimestampValid = isTimestampValid;
4788
+ exports.oaepDecrypt = oaepDecrypt;
4244
4789
  exports.oaepEncrypt = oaepEncrypt;
4245
4790
  exports.sign = sign;
4246
4791
  exports.verifySignature = verifySignature;