wxpay-nodejs-sdk 0.2.1 → 0.2.3

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,63 @@ 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
192
 
120
- // src/utils/http.ts
193
+ // src/utils/exceptions.ts
121
194
  var WxPayError = class extends Error {
122
195
  /** HTTP 状态码 */
123
196
  status;
@@ -140,7 +213,64 @@ var WxPayError = class extends Error {
140
213
  get isServerError() {
141
214
  return this.status >= 500 && this.status < 600;
142
215
  }
216
+ /**
217
+ * 判断是否为特定错误码
218
+ *
219
+ * @param code - 错误码
220
+ * @returns 是否匹配
221
+ */
222
+ isApiError(code) {
223
+ return this.detail.code === code;
224
+ }
225
+ };
226
+ var ServiceException = class extends WxPayError {
227
+ /** 微信支付业务错误码 */
228
+ errorCode;
229
+ /** 微信支付业务错误信息 */
230
+ errorMessage;
231
+ constructor(status, headers, detail) {
232
+ super(status, headers, detail);
233
+ this.name = "ServiceException";
234
+ this.errorCode = detail.code;
235
+ this.errorMessage = detail.message;
236
+ }
237
+ };
238
+ var HttpException = class extends WxPayError {
239
+ constructor(message, cause) {
240
+ super(0, {}, { code: "NETWORK_ERROR", message });
241
+ this.name = "HttpException";
242
+ if (cause) {
243
+ this.cause = cause;
244
+ }
245
+ }
246
+ };
247
+ var ValidationException = class extends WxPayError {
248
+ constructor(message) {
249
+ super(0, {}, { code: "SIGN_ERROR", message });
250
+ this.name = "ValidationException";
251
+ }
143
252
  };
253
+ var DecryptionException = class extends WxPayError {
254
+ constructor(message) {
255
+ super(0, {}, { code: "DECRYPT_ERROR", message });
256
+ this.name = "DecryptionException";
257
+ }
258
+ };
259
+ var MalformedMessageException = class extends WxPayError {
260
+ constructor(message) {
261
+ super(0, {}, { code: "PARSE_ERROR", message });
262
+ this.name = "MalformedMessageException";
263
+ }
264
+ };
265
+
266
+ // src/utils/http.ts
267
+ var SDK_VERSION = "0.2.1";
268
+ function getUserAgent() {
269
+ const platform = os__default.default.platform();
270
+ const arch = os__default.default.arch();
271
+ const nodeVersion = process.version;
272
+ return `wxpay-nodejs-sdk/${SDK_VERSION} (${platform} ${arch}) Node.js/${nodeVersion}`;
273
+ }
144
274
  function buildUrl(base, path, params) {
145
275
  const url = new URL(path, base);
146
276
  if (params) {
@@ -170,13 +300,16 @@ function parseResponseHeaders(headers) {
170
300
  return result;
171
301
  }
172
302
  function createRequestHeaders(options) {
173
- return {
303
+ const headers = {
174
304
  Authorization: options.authorization,
175
305
  Accept: options.accept ?? "application/json",
176
306
  "Content-Type": options.contentType ?? "application/json",
177
- "User-Agent": "wxpay-nodejs-sdk/0.1.0",
178
- ...options.additional
307
+ "User-Agent": getUserAgent()
179
308
  };
309
+ if (options.wechatPaySerial) {
310
+ headers["Wechatpay-Serial"] = options.wechatPaySerial;
311
+ }
312
+ return { ...headers, ...options.additional };
180
313
  }
181
314
  async function parseResponse(response, verify) {
182
315
  const headers = parseResponseHeaders(response.headers);
@@ -199,7 +332,7 @@ async function parseResponse(response, verify) {
199
332
  message: `HTTP ${response.status}: ${response.statusText}`
200
333
  };
201
334
  }
202
- throw new WxPayError(response.status, headers, errorDetail);
335
+ throw new ServiceException(response.status, headers, errorDetail);
203
336
  }
204
337
  if (verify) {
205
338
  const signature = headers["wechatpay-signature"];
@@ -209,10 +342,7 @@ async function parseResponse(response, verify) {
209
342
  if (signature && timestamp && nonce && serial) {
210
343
  const valid = verify(rawBody, signature, timestamp, nonce, serial);
211
344
  if (!valid) {
212
- throw new WxPayError(response.status, headers, {
213
- code: "SIGN_ERROR",
214
- message: "\u5E94\u7B54\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25"
215
- });
345
+ throw new ValidationException("\u5E94\u7B54\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25");
216
346
  }
217
347
  }
218
348
  }
@@ -224,10 +354,9 @@ async function parseResponse(response, verify) {
224
354
  }
225
355
  data = parsed;
226
356
  } catch (error) {
227
- throw new WxPayError(response.status, headers, {
228
- code: "PARSE_ERROR",
229
- message: error instanceof Error ? error.message : "\u54CD\u5E94\u6570\u636E\u89E3\u6790\u5931\u8D25"
230
- });
357
+ throw new MalformedMessageException(
358
+ error instanceof Error ? error.message : "\u54CD\u5E94\u6570\u636E\u89E3\u6790\u5931\u8D25"
359
+ );
231
360
  }
232
361
  return {
233
362
  status: response.status,
@@ -245,7 +374,13 @@ ${body}
245
374
  `;
246
375
  }
247
376
  function sign(signString, privateKey) {
248
- const signer = crypto4__default.default.createSign("RSA-SHA256");
377
+ if (!signString) {
378
+ throw new Error("\u7B7E\u540D\u4E32\u4E0D\u80FD\u4E3A\u7A7A");
379
+ }
380
+ if (!privateKey) {
381
+ throw new Error("\u5546\u6237\u79C1\u94A5\u4E0D\u80FD\u4E3A\u7A7A");
382
+ }
383
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
249
384
  signer.update(signString);
250
385
  signer.end();
251
386
  return signer.sign(privateKey, "base64");
@@ -254,36 +389,92 @@ function buildAuthorization(mchid, serialNo, timestamp, nonce, signature) {
254
389
  return `WECHATPAY2-SHA256-RSA2048 mchid="${mchid}",nonce_str="${nonce}",timestamp="${timestamp}",serial_no="${serialNo}",signature="${signature}"`;
255
390
  }
256
391
  function generateNonce() {
257
- return crypto4__default.default.randomUUID().replace(/-/g, "");
392
+ return crypto2__default.default.randomUUID().replace(/-/g, "");
393
+ }
394
+ var RESPONSE_EXPIRED_SECONDS = 5 * 60;
395
+ function isTimestampValid(timestamp) {
396
+ const responseTime = parseInt(timestamp, 10);
397
+ if (isNaN(responseTime)) return false;
398
+ const now = Math.floor(Date.now() / 1e3);
399
+ return Math.abs(now - responseTime) < RESPONSE_EXPIRED_SECONDS;
258
400
  }
259
401
  function verifySignature(body, signature, timestamp, nonce, publicKey) {
402
+ if (!signature) {
403
+ throw new Error("\u7B7E\u540D\u503C(signature)\u4E0D\u80FD\u4E3A\u7A7A");
404
+ }
405
+ if (!timestamp) {
406
+ throw new Error("\u65F6\u95F4\u6233(timestamp)\u4E0D\u80FD\u4E3A\u7A7A");
407
+ }
408
+ if (!nonce) {
409
+ throw new Error("\u968F\u673A\u4E32(nonce)\u4E0D\u80FD\u4E3A\u7A7A");
410
+ }
411
+ if (!publicKey) {
412
+ throw new Error("\u516C\u94A5(publicKey)\u4E0D\u80FD\u4E3A\u7A7A");
413
+ }
414
+ if (!isTimestampValid(timestamp)) {
415
+ return false;
416
+ }
260
417
  const signString = `${timestamp}
261
418
  ${nonce}
262
419
  ${body}
263
420
  `;
264
- const verifier = crypto4__default.default.createVerify("RSA-SHA256");
421
+ const verifier = crypto2__default.default.createVerify("RSA-SHA256");
265
422
  verifier.update(signString);
266
423
  verifier.end();
267
424
  return verifier.verify(publicKey, signature, "base64");
268
425
  }
269
426
  function oaepEncrypt(plaintext, publicKey) {
270
- const encrypted = crypto4__default.default.publicEncrypt(
427
+ if (!publicKey) {
428
+ throw new Error("\u52A0\u5BC6\u516C\u94A5\u4E0D\u80FD\u4E3A\u7A7A");
429
+ }
430
+ if (!plaintext) {
431
+ return "";
432
+ }
433
+ const encrypted = crypto2__default.default.publicEncrypt(
271
434
  {
272
435
  key: publicKey,
273
- padding: crypto4__default.default.constants.RSA_PKCS1_OAEP_PADDING,
274
- oaepHash: "sha256"
436
+ padding: crypto2__default.default.constants.RSA_PKCS1_OAEP_PADDING,
437
+ oaepHash: "sha1"
275
438
  },
276
439
  Buffer.from(plaintext, "utf-8")
277
440
  );
278
441
  return encrypted.toString("base64");
279
442
  }
443
+ function oaepDecrypt(ciphertext, privateKey) {
444
+ if (!privateKey) {
445
+ throw new Error("\u89E3\u5BC6\u79C1\u94A5\u4E0D\u80FD\u4E3A\u7A7A");
446
+ }
447
+ if (!ciphertext) {
448
+ return "";
449
+ }
450
+ const decrypted = crypto2__default.default.privateDecrypt(
451
+ {
452
+ key: privateKey,
453
+ padding: crypto2__default.default.constants.RSA_PKCS1_OAEP_PADDING,
454
+ oaepHash: "sha1"
455
+ },
456
+ Buffer.from(ciphertext, "base64")
457
+ );
458
+ return decrypted.toString("utf-8");
459
+ }
280
460
 
281
461
  // src/core/client.ts
282
462
  var WxPayClient = class _WxPayClient {
283
- /** 生产环境 API 地址 */
463
+ /** 生产环境 API 主域名 */
284
464
  static PRODUCTION_BASE = "https://api.mch.weixin.qq.com";
465
+ /** 生产环境 API 备用域名(跨城容灾) */
466
+ static PRODUCTION_BACKUP = "https://api2.mch.weixin.qq.com";
285
467
  /** 沙箱环境 API 地址 */
286
468
  static SANDBOX_BASE = "https://api.mch.weixin.qq.com/sandboxnew";
469
+ /** SDK 版本号 */
470
+ static SDK_VERSION = "0.2.1";
471
+ /** 动态 User-Agent 字符串 */
472
+ static USER_AGENT = (() => {
473
+ const platform = os__default.default.platform();
474
+ const arch = os__default.default.arch();
475
+ const nodeVersion = process.version;
476
+ return `wxpay-nodejs-sdk/${_WxPayClient.SDK_VERSION} (${platform} ${arch}) Node.js/${nodeVersion}`;
477
+ })();
287
478
  /** 商户号 */
288
479
  mchid;
289
480
  apiV3Key;
@@ -291,6 +482,7 @@ var WxPayClient = class _WxPayClient {
291
482
  privateKey;
292
483
  timeout;
293
484
  baseUrl;
485
+ backupUrl;
294
486
  enableResponseVerification;
295
487
  /** 平台证书管理器 */
296
488
  certificates;
@@ -301,6 +493,7 @@ var WxPayClient = class _WxPayClient {
301
493
  this.privateKey = this.resolvePrivateKey(options.privateKey);
302
494
  this.timeout = options.timeout ?? 3e4;
303
495
  this.baseUrl = options.sandbox ? _WxPayClient.SANDBOX_BASE : _WxPayClient.PRODUCTION_BASE;
496
+ this.backupUrl = options.sandbox ? null : _WxPayClient.PRODUCTION_BACKUP;
304
497
  this.enableResponseVerification = options.enableResponseVerification ?? true;
305
498
  this.certificates = new CertificateManager(this.apiV3Key, options.platformCertificates);
306
499
  if (options.wxpayPublicKeyId && options.wxpayPublicKey) {
@@ -372,8 +565,12 @@ var WxPayClient = class _WxPayClient {
372
565
  const headers = {
373
566
  Authorization: authorization,
374
567
  Accept: "application/json",
375
- "User-Agent": "wxpay-nodejs-sdk/0.1.0"
568
+ "User-Agent": _WxPayClient.USER_AGENT
376
569
  };
570
+ const serial = this.certificates.getNewestSerial();
571
+ if (serial) {
572
+ headers["Wechatpay-Serial"] = serial;
573
+ }
377
574
  const controller = new AbortController();
378
575
  const timeoutId = setTimeout(() => {
379
576
  controller.abort();
@@ -495,8 +692,12 @@ var WxPayClient = class _WxPayClient {
495
692
  Authorization: authorization,
496
693
  Accept: "application/json",
497
694
  "Content-Type": `multipart/form-data; boundary=${boundary}`,
498
- "User-Agent": "wxpay-nodejs-sdk/0.1.0"
695
+ "User-Agent": _WxPayClient.USER_AGENT
499
696
  };
697
+ const serial = this.certificates.getNewestSerial();
698
+ if (serial) {
699
+ headers["Wechatpay-Serial"] = serial;
700
+ }
500
701
  const controller = new AbortController();
501
702
  const timeoutId = setTimeout(() => {
502
703
  controller.abort();
@@ -537,67 +738,90 @@ var WxPayClient = class _WxPayClient {
537
738
  }
538
739
  /**
539
740
  * 通用 HTTP 请求方法
741
+ *
742
+ * 支持跨城容灾:当主域名请求失败(网络错误、超时)时,自动切换到备用域名重试。
540
743
  */
541
744
  async request(method, path, params, body, extraHeaders) {
542
- const url = buildUrl(this.baseUrl, path, params);
543
745
  const bodyStr = body ? JSON.stringify(body) : "";
544
746
  const timestamp = Math.floor(Date.now() / 1e3);
545
747
  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
748
+ const headers = createRequestHeaders({
749
+ authorization: "",
750
+ wechatPaySerial: this.certificates.getNewestSerial(),
751
+ additional: extraHeaders
554
752
  });
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
753
+ const urls = [this.baseUrl];
754
+ if (this.backupUrl) {
755
+ urls.push(this.backupUrl);
756
+ }
757
+ let lastError;
758
+ for (const baseUrl of urls) {
759
+ const url = buildUrl(baseUrl, path, params);
760
+ const urlObj = new URL(url);
761
+ const signPath = urlObj.pathname + urlObj.search;
762
+ const signString = buildSignString({
763
+ method: method.toUpperCase(),
764
+ path: signPath,
765
+ timestamp,
766
+ nonce,
767
+ body: bodyStr
574
768
  });
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)`
769
+ const signature = sign(signString, this.privateKey);
770
+ headers["Authorization"] = buildAuthorization(
771
+ this.mchid,
772
+ this.serialNo,
773
+ timestamp,
774
+ nonce,
775
+ signature
776
+ );
777
+ const controller = new AbortController();
778
+ const timeoutId = setTimeout(() => {
779
+ controller.abort();
780
+ }, this.timeout);
781
+ try {
782
+ const response = await fetch(url, {
783
+ method,
784
+ headers,
785
+ body: bodyStr || void 0,
786
+ signal: controller.signal
787
+ });
788
+ return await parseResponse(response, this.createVerifier());
789
+ } catch (error) {
790
+ lastError = error;
791
+ const isNetworkError = !(error instanceof WxPayError) && !(error instanceof DOMException && error.name === "AbortError");
792
+ if (!isNetworkError || urls.indexOf(baseUrl) === urls.length - 1) {
793
+ if (error instanceof WxPayError) throw error;
794
+ if (error instanceof DOMException && error.name === "AbortError") {
795
+ throw new WxPayError(
796
+ 0,
797
+ {},
798
+ {
799
+ code: "REQUEST_TIMEOUT",
800
+ message: `\u8BF7\u6C42\u8D85\u65F6 (${this.timeout}ms)`
801
+ }
802
+ );
587
803
  }
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"
804
+ throw new WxPayError(
805
+ 0,
806
+ {},
807
+ {
808
+ code: "NETWORK_ERROR",
809
+ message: error instanceof Error ? error.message : "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"
810
+ }
811
+ );
596
812
  }
597
- );
598
- } finally {
599
- clearTimeout(timeoutId);
813
+ } finally {
814
+ clearTimeout(timeoutId);
815
+ }
600
816
  }
817
+ throw new WxPayError(
818
+ 0,
819
+ {},
820
+ {
821
+ code: "NETWORK_ERROR",
822
+ message: lastError instanceof Error ? lastError.message : "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"
823
+ }
824
+ );
601
825
  }
602
826
  /**
603
827
  * 解析私钥:支持直接传入内容或文件路径
@@ -638,6 +862,117 @@ var WxPayClient = class _WxPayClient {
638
862
  }
639
863
  };
640
864
 
865
+ // src/utils/sensitive.ts
866
+ var sensitiveFields = /* @__PURE__ */ new Map();
867
+ function registerSensitiveFields(typeName, fields) {
868
+ sensitiveFields.set(typeName, new Set(fields));
869
+ }
870
+ function getSensitiveFields(typeName) {
871
+ return sensitiveFields.get(typeName) ?? /* @__PURE__ */ new Set();
872
+ }
873
+ function encryptSensitiveFields(obj, typeName, publicKey) {
874
+ const fields = getSensitiveFields(typeName);
875
+ if (fields.size === 0) return obj;
876
+ const result = { ...obj };
877
+ for (const field of fields) {
878
+ const value = result[field];
879
+ if (typeof value === "string" && value.length > 0) {
880
+ result[field] = oaepEncrypt(value, publicKey);
881
+ }
882
+ }
883
+ return result;
884
+ }
885
+ function decryptSensitiveFields(obj, typeName, privateKey) {
886
+ const fields = getSensitiveFields(typeName);
887
+ if (fields.size === 0) return obj;
888
+ const result = { ...obj };
889
+ for (const field of fields) {
890
+ const value = result[field];
891
+ if (typeof value === "string" && value.length > 0) {
892
+ try {
893
+ result[field] = oaepDecrypt(value, privateKey);
894
+ } catch {
895
+ }
896
+ }
897
+ }
898
+ return result;
899
+ }
900
+ function encryptSensitiveFieldsInArray(arr, typeName, publicKey) {
901
+ return arr.map((item) => encryptSensitiveFields(item, typeName, publicKey));
902
+ }
903
+ function decryptSensitiveFieldsInArray(arr, typeName, privateKey) {
904
+ return arr.map((item) => decryptSensitiveFields(item, typeName, privateKey));
905
+ }
906
+ var CertificateService = class {
907
+ client;
908
+ apiV3Key;
909
+ certificateManager;
910
+ constructor(client, apiV3Key, certificateManager) {
911
+ this.client = client;
912
+ this.apiV3Key = apiV3Key;
913
+ this.certificateManager = certificateManager;
914
+ }
915
+ /**
916
+ * 下载平台证书列表
917
+ *
918
+ * 调用微信支付 /v3/certificates 接口获取当前可用的平台证书。
919
+ * 返回的证书内容已解密为 PEM 格式。
920
+ *
921
+ * @returns 解密后的平台证书列表
922
+ */
923
+ async downloadCertificates() {
924
+ const response = await this.client.get("/v3/certificates");
925
+ const decryptedCerts = response.data.data.map((cert) => {
926
+ const pem = this.decryptCertificate(cert.encryptCertificate);
927
+ return {
928
+ serialNo: cert.serialNo,
929
+ effectiveTime: cert.effectiveTime,
930
+ expireTime: cert.expireTime,
931
+ certificatePem: pem
932
+ };
933
+ });
934
+ return {
935
+ status: response.status,
936
+ headers: response.headers,
937
+ data: decryptedCerts
938
+ };
939
+ }
940
+ /**
941
+ * 下载并更新本地平台证书缓存
942
+ *
943
+ * 下载最新的平台证书列表,解密后自动更新 CertificateManager 中的缓存。
944
+ * 适用于定时更新证书的场景。
945
+ *
946
+ * @returns 更新后的证书列表
947
+ */
948
+ async downloadAndUpdate() {
949
+ const response = await this.downloadCertificates();
950
+ for (const cert of response.data) {
951
+ this.certificateManager.setPublicKey(cert.serialNo, cert.certificatePem);
952
+ }
953
+ return response.data;
954
+ }
955
+ /**
956
+ * 使用 AES-256-GCM 解密证书内容
957
+ *
958
+ * @param encrypted - 加密的证书信息
959
+ * @returns PEM 格式的证书内容
960
+ */
961
+ decryptCertificate(encrypted) {
962
+ const key = Buffer.from(this.apiV3Key, "utf-8");
963
+ const nonce = Buffer.from(encrypted.nonce, "utf-8");
964
+ const aad = Buffer.from(encrypted.associatedData, "utf-8");
965
+ const ciphertextBuffer = Buffer.from(encrypted.ciphertext, "base64");
966
+ const authTag = ciphertextBuffer.subarray(-16);
967
+ const encryptedData = ciphertextBuffer.subarray(0, -16);
968
+ const decipher = crypto2__default.default.createDecipheriv("aes-256-gcm", key, nonce);
969
+ decipher.setAuthTag(authTag);
970
+ decipher.setAAD(aad);
971
+ const decrypted = Buffer.concat([decipher.update(encryptedData), decipher.final()]);
972
+ return decrypted.toString("utf-8");
973
+ }
974
+ };
975
+
641
976
  // src/services/jsapi.ts
642
977
  var JsapiService = class {
643
978
  client;
@@ -2428,6 +2763,9 @@ var BillService = class {
2428
2763
  return this.client.downloadRaw(downloadUrl);
2429
2764
  }
2430
2765
  };
2766
+ var SUPPORTED_SIGNATURE_TYPES = /* @__PURE__ */ new Set(["WECHATPAY2-SHA256-RSA2048"]);
2767
+ var DEFAULT_SIGNATURE_TYPE = "WECHATPAY2-SHA256-RSA2048";
2768
+ var SUPPORTED_ALGORITHMS = /* @__PURE__ */ new Set(["AEAD_AES_256_GCM"]);
2431
2769
  var CallbackHandler = class {
2432
2770
  apiV3Key;
2433
2771
  certificates;
@@ -2439,12 +2777,30 @@ var CallbackHandler = class {
2439
2777
  * 验证回调通知签名
2440
2778
  *
2441
2779
  * 使用微信支付平台公钥验证回调通知的签名。
2780
+ * 支持读取 Wechatpay-Signature-Type 头识别签名类型。
2442
2781
  *
2443
2782
  * @param headers - 回调请求头
2444
2783
  * @param body - 回调请求体(原始 JSON 字符串)
2445
2784
  * @returns 签名验证是否通过
2785
+ * @throws 如果必填参数缺失、签名类型不支持或找不到对应的证书
2446
2786
  */
2447
2787
  verifySignature(headers, body) {
2788
+ if (!headers["wechatpay-serial"]) {
2789
+ throw new Error("\u56DE\u8C03\u5934 wechatpay-serial \u4E0D\u80FD\u4E3A\u7A7A");
2790
+ }
2791
+ if (!headers["wechatpay-signature"]) {
2792
+ throw new Error("\u56DE\u8C03\u5934 wechatpay-signature \u4E0D\u80FD\u4E3A\u7A7A");
2793
+ }
2794
+ if (!headers["wechatpay-timestamp"]) {
2795
+ throw new Error("\u56DE\u8C03\u5934 wechatpay-timestamp \u4E0D\u80FD\u4E3A\u7A7A");
2796
+ }
2797
+ if (!headers["wechatpay-nonce"]) {
2798
+ throw new Error("\u56DE\u8C03\u5934 wechatpay-nonce \u4E0D\u80FD\u4E3A\u7A7A");
2799
+ }
2800
+ const signatureType = headers["wechatpay-signature-type"] ?? DEFAULT_SIGNATURE_TYPE;
2801
+ if (!SUPPORTED_SIGNATURE_TYPES.has(signatureType)) {
2802
+ throw new Error(`\u4E0D\u652F\u6301\u7684\u7B7E\u540D\u7C7B\u578B: ${signatureType}`);
2803
+ }
2448
2804
  const serialNo = headers["wechatpay-serial"];
2449
2805
  const publicKey = this.certificates.getPublicKey(serialNo);
2450
2806
  if (!publicKey) {
@@ -2465,10 +2821,22 @@ var CallbackHandler = class {
2465
2821
  *
2466
2822
  * @param notification - 回调通知 JSON 对象
2467
2823
  * @returns 解密后的业务数据
2468
- * @throws 如果解密后的数据为空或格式无效
2824
+ * @throws 如果通知结构无效、算法不匹配或解密失败
2469
2825
  */
2470
2826
  decryptNotification(notification) {
2471
2827
  const { resource } = notification;
2828
+ if (!resource.algorithm) {
2829
+ throw new Error("\u56DE\u8C03\u901A\u77E5 resource \u7F3A\u5C11 algorithm \u5B57\u6BB5");
2830
+ }
2831
+ if (!resource.ciphertext) {
2832
+ throw new Error("\u56DE\u8C03\u901A\u77E5 resource \u7F3A\u5C11 ciphertext \u5B57\u6BB5");
2833
+ }
2834
+ if (!resource.nonce) {
2835
+ throw new Error("\u56DE\u8C03\u901A\u77E5 resource \u7F3A\u5C11 nonce \u5B57\u6BB5");
2836
+ }
2837
+ if (!SUPPORTED_ALGORITHMS.has(resource.algorithm)) {
2838
+ throw new Error(`\u4E0D\u652F\u6301\u7684\u52A0\u5BC6\u7B97\u6CD5: ${resource.algorithm}`);
2839
+ }
2472
2840
  const plaintext = this.aesGcmDecrypt(
2473
2841
  resource.ciphertext,
2474
2842
  resource.associated_data,
@@ -2716,13 +3084,26 @@ var CallbackHandler = class {
2716
3084
  * @param associatedData - 附加数据(用于 AEAD 认证)
2717
3085
  * @param nonce - 随机串
2718
3086
  * @returns 解密后的明文字符串
3087
+ * @throws 如果密文格式无效或解密失败
2719
3088
  */
2720
3089
  aesGcmDecrypt(ciphertext, associatedData, nonce) {
3090
+ if (!ciphertext) {
3091
+ throw new Error("\u5BC6\u6587(ciphertext)\u4E0D\u80FD\u4E3A\u7A7A");
3092
+ }
3093
+ if (!nonce) {
3094
+ throw new Error("\u968F\u673A\u4E32(nonce)\u4E0D\u80FD\u4E3A\u7A7A");
3095
+ }
3096
+ if (this.apiV3Key.length !== 32) {
3097
+ throw new Error("APIv3 \u5BC6\u94A5\u65E0\u6548\uFF0C\u957F\u5EA6\u5FC5\u987B\u4E3A 32 \u4E2A\u5B57\u8282");
3098
+ }
2721
3099
  const key = Buffer.from(this.apiV3Key, "utf-8");
2722
3100
  const ciphertextBuffer = Buffer.from(ciphertext, "base64");
3101
+ if (ciphertextBuffer.length <= 16) {
3102
+ throw new Error("\u5BC6\u6587\u957F\u5EA6\u65E0\u6548\uFF0C\u5FC5\u987B\u5927\u4E8E 16 \u5B57\u8282\uFF08\u542B AuthTag\uFF09");
3103
+ }
2723
3104
  const authTag = ciphertextBuffer.subarray(-16);
2724
3105
  const encryptedData = ciphertextBuffer.subarray(0, -16);
2725
- const decipher = crypto4__default.default.createDecipheriv("aes-256-gcm", key, Buffer.from(nonce, "utf-8"));
3106
+ const decipher = crypto2__default.default.createDecipheriv("aes-256-gcm", key, Buffer.from(nonce, "utf-8"));
2726
3107
  decipher.setAuthTag(authTag);
2727
3108
  decipher.setAAD(Buffer.from(associatedData, "utf-8"));
2728
3109
  const decrypted = Buffer.concat([decipher.update(encryptedData), decipher.final()]);
@@ -3850,13 +4231,327 @@ var SecurityService = class {
3850
4231
  return this.client.post("/v3/security/echo", request);
3851
4232
  }
3852
4233
  };
4234
+
4235
+ // src/services/payrollcard.ts
4236
+ var PayrollCardService = class {
4237
+ client;
4238
+ constructor(client) {
4239
+ this.client = client;
4240
+ }
4241
+ /**
4242
+ * 查询授权关系
4243
+ *
4244
+ * 查询商户与用户之间的微工卡授权关系。
4245
+ *
4246
+ * @param params - 查询参数
4247
+ * @returns 授权关系信息
4248
+ */
4249
+ async queryAuthorization(params) {
4250
+ return this.client.get("/v3/payroll-card/relations", params);
4251
+ }
4252
+ /**
4253
+ * 生成预授权 token
4254
+ *
4255
+ * 生成微工卡预授权 token,用于后续核身操作。
4256
+ *
4257
+ * @param request - 预授权请求参数
4258
+ * @returns 预授权 token 信息
4259
+ */
4260
+ async createToken(request) {
4261
+ return this.client.post("/v3/payroll-card/tokens", request);
4262
+ }
4263
+ /**
4264
+ * 核身预下单
4265
+ *
4266
+ * 创建核身预下单,获取核身参数。
4267
+ *
4268
+ * @param request - 核身预下单请求参数
4269
+ * @returns 核身参数信息
4270
+ */
4271
+ async createAuthentication(request) {
4272
+ return this.client.post("/v3/payroll-card/authentications", request);
4273
+ }
4274
+ /**
4275
+ * 查询核身结果
4276
+ *
4277
+ * 根据商户请求号查询核身结果。
4278
+ *
4279
+ * @param outRequestNo - 商户请求号
4280
+ * @param params - 查询参数
4281
+ * @returns 核身结果信息
4282
+ */
4283
+ async queryAuthentication(outRequestNo, params) {
4284
+ return this.client.get(
4285
+ `/v3/payroll-card/authentications/out-request-no/${outRequestNo}`,
4286
+ params
4287
+ );
4288
+ }
4289
+ /**
4290
+ * 发起批量转账
4291
+ *
4292
+ * 通过工资卡渠道发起批量转账。
4293
+ *
4294
+ * @param request - 批量转账请求参数
4295
+ * @returns 批量转账结果
4296
+ */
4297
+ async createTransferBatch(request) {
4298
+ return this.client.post("/v3/payroll-card/transfer-batches", request);
4299
+ }
4300
+ };
4301
+
4302
+ // src/services/scanandride.ts
4303
+ var ScanAndRideService = class {
4304
+ client;
4305
+ constructor(client) {
4306
+ this.client = client;
4307
+ }
4308
+ /**
4309
+ * 开通用户服务
4310
+ *
4311
+ * 用户授权开通刷码乘车服务。
4312
+ *
4313
+ * @param request - 开通服务请求参数
4314
+ * @returns 开通结果
4315
+ */
4316
+ async createUserService(request) {
4317
+ return this.client.post("/v3/qrcode/user-services", request);
4318
+ }
4319
+ /**
4320
+ * 查询用户服务状态
4321
+ *
4322
+ * 查询用户是否已开通刷码乘车服务。
4323
+ *
4324
+ * @param outRequestNo - 商户请求号
4325
+ * @param params - 查询参数
4326
+ * @returns 用户服务状态
4327
+ */
4328
+ async queryUserService(outRequestNo, params) {
4329
+ return this.client.get(`/v3/qrcode/user-services/out-request-no/${outRequestNo}`, params);
4330
+ }
4331
+ /**
4332
+ * 扣费受理
4333
+ *
4334
+ * 发起刷码乘车扣费请求。
4335
+ *
4336
+ * @param request - 扣费请求参数
4337
+ * @returns 扣费受理结果
4338
+ */
4339
+ async createTransaction(request) {
4340
+ return this.client.post("/v3/qrcode/transactions", request);
4341
+ }
4342
+ /**
4343
+ * 查询扣费订单
4344
+ *
4345
+ * 根据商户订单号查询扣费订单状态。
4346
+ *
4347
+ * @param outTradeNo - 商户订单号
4348
+ * @param params - 查询参数
4349
+ * @returns 订单信息
4350
+ */
4351
+ async queryTransaction(outTradeNo, params) {
4352
+ return this.client.get(`/v3/qrcode/transactions/out-trade-no/${outTradeNo}`, params);
4353
+ }
4354
+ };
4355
+
4356
+ // src/services/retailstore.ts
4357
+ var RetailStoreService = class {
4358
+ client;
4359
+ constructor(client) {
4360
+ this.client = client;
4361
+ }
4362
+ /**
4363
+ * 创建门店活动
4364
+ *
4365
+ * @param request - 活动创建请求参数
4366
+ * @returns 创建结果
4367
+ */
4368
+ async createActivity(request) {
4369
+ return this.client.post("/v3/marketing/goldplan/retailstore/activities", request);
4370
+ }
4371
+ /**
4372
+ * 查询门店活动详情
4373
+ *
4374
+ * @param activityId - 活动ID
4375
+ * @returns 活动详情
4376
+ */
4377
+ async queryActivity(activityId) {
4378
+ return this.client.get(`/v3/marketing/goldplan/retailstore/activities/${activityId}`);
4379
+ }
4380
+ /**
4381
+ * 更新门店活动
4382
+ *
4383
+ * @param activityId - 活动ID
4384
+ * @param request - 更新请求参数
4385
+ * @returns 更新结果
4386
+ */
4387
+ async updateActivity(activityId, request) {
4388
+ return this.client.patch(
4389
+ `/v3/marketing/goldplan/retailstore/activities/${activityId}`,
4390
+ request
4391
+ );
4392
+ }
4393
+ /**
4394
+ * 创建门店资质
4395
+ *
4396
+ * @param request - 资质创建请求参数
4397
+ * @returns 创建结果
4398
+ */
4399
+ async createQualification(request) {
4400
+ return this.client.post("/v3/marketing/goldplan/retailstore/qualifications", request);
4401
+ }
4402
+ /**
4403
+ * 查询门店资质
4404
+ *
4405
+ * @param qualificationId - 资质ID
4406
+ * @returns 资质详情
4407
+ */
4408
+ async queryQualification(qualificationId) {
4409
+ return this.client.get(`/v3/marketing/goldplan/retailstore/qualifications/${qualificationId}`);
4410
+ }
4411
+ };
4412
+
4413
+ // src/services/goldplan.ts
4414
+ var GoldPlanService = class {
4415
+ client;
4416
+ constructor(client) {
4417
+ this.client = client;
4418
+ }
4419
+ /**
4420
+ * 查询商户零钱余额
4421
+ *
4422
+ * @param mchid - 商户号
4423
+ * @returns 零钱余额信息
4424
+ */
4425
+ async queryBalance(mchid) {
4426
+ return this.client.get(`/v3/merchant/fund/balance/${mchid}`);
4427
+ }
4428
+ /**
4429
+ * 查询商户零钱流水
4430
+ *
4431
+ * @param mchid - 商户号
4432
+ * @param params - 查询参数
4433
+ * @returns 零钱流水列表
4434
+ */
4435
+ async queryFlow(mchid, params) {
4436
+ return this.client.get(`/v3/merchant/fund/flow`, { mchid, ...params });
4437
+ }
4438
+ /**
4439
+ * 查询商家零钱状态
4440
+ *
4441
+ * @param mchid - 商户号
4442
+ * @returns 零钱状态信息
4443
+ */
4444
+ async queryStatus(mchid) {
4445
+ return this.client.get(`/v3/merchant/fund/status/${mchid}`);
4446
+ }
4447
+ };
4448
+
4449
+ // src/services/lovefeast.ts
4450
+ var LoveFeastService = class {
4451
+ client;
4452
+ constructor(client) {
4453
+ this.client = client;
4454
+ }
4455
+ /**
4456
+ * 创建爱心餐品牌
4457
+ *
4458
+ * @param request - 品牌创建请求参数
4459
+ * @returns 创建结果
4460
+ */
4461
+ async createBrand(request) {
4462
+ return this.client.post("/v3/lovefeast/brands", request);
4463
+ }
4464
+ /**
4465
+ * 查询爱心餐品牌
4466
+ *
4467
+ * @param brandId - 品牌ID
4468
+ * @returns 品牌详情
4469
+ */
4470
+ async queryBrand(brandId) {
4471
+ return this.client.get(`/v3/lovefeast/brands/${brandId}`);
4472
+ }
4473
+ /**
4474
+ * 创建爱心餐订单
4475
+ *
4476
+ * @param request - 订单创建请求参数
4477
+ * @returns 订单创建结果
4478
+ */
4479
+ async createOrder(request) {
4480
+ return this.client.post("/v3/lovefeast/orders", request);
4481
+ }
4482
+ /**
4483
+ * 查询爱心餐订单
4484
+ *
4485
+ * @param outTradeNo - 商户订单号
4486
+ * @param params - 查询参数
4487
+ * @returns 订单详情
4488
+ */
4489
+ async queryOrder(outTradeNo, params) {
4490
+ return this.client.get(`/v3/lovefeast/orders/out-trade-no/${outTradeNo}`, params);
4491
+ }
4492
+ };
4493
+
4494
+ // src/services/merchant-exclusive-coupon.ts
4495
+ var MerchantExclusiveCouponService = class {
4496
+ client;
4497
+ constructor(client) {
4498
+ this.client = client;
4499
+ }
4500
+ /**
4501
+ * 创建优惠券批次
4502
+ *
4503
+ * @param request - 批次创建请求参数
4504
+ * @returns 创建结果
4505
+ */
4506
+ async createCouponStock(request) {
4507
+ return this.client.post("/v3/marketing/busifavor/stocks", request);
4508
+ }
4509
+ /**
4510
+ * 查询优惠券批次详情
4511
+ *
4512
+ * @param stockId - 批次ID
4513
+ * @returns 批次详情
4514
+ */
4515
+ async queryCouponStock(stockId) {
4516
+ return this.client.get(`/v3/marketing/busifavor/stocks/${stockId}`);
4517
+ }
4518
+ /**
4519
+ * 发放优惠券
4520
+ *
4521
+ * @param request - 发放请求参数
4522
+ * @returns 发放结果
4523
+ */
4524
+ async sendCoupon(request) {
4525
+ return this.client.post("/v3/marketing/busifavor/coupons", request);
4526
+ }
4527
+ /**
4528
+ * 查询用户优惠券
4529
+ *
4530
+ * @param openid - 用户标识
4531
+ * @param params - 查询参数
4532
+ * @returns 用户优惠券列表
4533
+ */
4534
+ async queryUserCoupons(openid, params) {
4535
+ return this.client.get(`/v3/marketing/busifavor/users/${openid}/coupons`, params);
4536
+ }
4537
+ /**
4538
+ * 查询优惠券详情
4539
+ *
4540
+ * @param couponId - 优惠券ID
4541
+ * @param params - 查询参数
4542
+ * @returns 优惠券详情
4543
+ */
4544
+ async queryCoupon(couponId, params) {
4545
+ return this.client.get(`/v3/marketing/busifavor/users/coupons/${couponId}`, params);
4546
+ }
4547
+ };
3853
4548
  function generateAppPaySign(appId, timeStamp, nonceStr, prepayId, privateKey) {
3854
4549
  const signString = `${appId}
3855
4550
  ${timeStamp}
3856
4551
  ${nonceStr}
3857
4552
  prepay_id=${prepayId}
3858
4553
  `;
3859
- const signer = crypto4__default.default.createSign("RSA-SHA256");
4554
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
3860
4555
  signer.update(signString);
3861
4556
  signer.end();
3862
4557
  return signer.sign(privateKey, "base64");
@@ -3881,13 +4576,13 @@ ${timeStamp}
3881
4576
  ${nonceStr}
3882
4577
  prepay_id=${prepayId}
3883
4578
  `;
3884
- const signer = crypto4__default.default.createSign("RSA-SHA256");
4579
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
3885
4580
  signer.update(signString);
3886
4581
  signer.end();
3887
4582
  return signer.sign(privateKey, "base64");
3888
4583
  }
3889
4584
  function generateNonceStr() {
3890
- return crypto4__default.default.randomUUID().replace(/-/g, "");
4585
+ return crypto2__default.default.randomUUID().replace(/-/g, "");
3891
4586
  }
3892
4587
  function buildJsapiBridgeConfig(appId, prepayId, privateKey) {
3893
4588
  const timeStamp = String(Math.floor(Date.now() / 1e3));
@@ -3921,7 +4616,7 @@ ${timeStamp}
3921
4616
  ${nonceStr}
3922
4617
  ${packageStr}
3923
4618
  `;
3924
- const signer = crypto4__default.default.createSign("RSA-SHA256");
4619
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
3925
4620
  signer.update(signString);
3926
4621
  signer.end();
3927
4622
  return signer.sign(privateKey, "base64");
@@ -4071,7 +4766,7 @@ function buildH5CouponUrl(params, signKey) {
4071
4766
  }
4072
4767
  const sortedKeys = Object.keys(signFields).sort();
4073
4768
  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();
4769
+ const sign2 = crypto2__default.default.createHmac("sha256", signKey).update(signStr).digest("hex").toUpperCase();
4075
4770
  const urlParams = new URLSearchParams({
4076
4771
  stock_id: params.stock_id,
4077
4772
  out_request_no: params.out_request_no,
@@ -4173,7 +4868,7 @@ ${timestamp}
4173
4868
  ${nonceStr}
4174
4869
  ${packageStr}
4175
4870
  `;
4176
- const signer = crypto4__default.default.createSign("RSA-SHA256");
4871
+ const signer = crypto2__default.default.createSign("RSA-SHA256");
4177
4872
  signer.update(signString);
4178
4873
  signer.end();
4179
4874
  const sign2 = signer.sign(privateKey, "base64");
@@ -4193,6 +4888,7 @@ exports.BillService = BillService;
4193
4888
  exports.BusinessCircleService = BusinessCircleService;
4194
4889
  exports.CallbackHandler = CallbackHandler;
4195
4890
  exports.CertificateManager = CertificateManager;
4891
+ exports.CertificateService = CertificateService;
4196
4892
  exports.CombineAppService = CombineAppService;
4197
4893
  exports.CombineH5Service = CombineH5Service;
4198
4894
  exports.CombineMiniProgramService = CombineMiniProgramService;
@@ -4200,19 +4896,30 @@ exports.CombineNativeService = CombineNativeService;
4200
4896
  exports.CombineService = CombineService;
4201
4897
  exports.ComplaintService = ComplaintService;
4202
4898
  exports.CouponService = CouponService;
4899
+ exports.DecryptionException = DecryptionException;
4900
+ exports.GoldPlanService = GoldPlanService;
4203
4901
  exports.H5Service = H5Service;
4902
+ exports.HttpException = HttpException;
4204
4903
  exports.JsapiService = JsapiService;
4904
+ exports.LoveFeastService = LoveFeastService;
4905
+ exports.MalformedMessageException = MalformedMessageException;
4205
4906
  exports.MedInsService = MedInsService;
4206
4907
  exports.MediaService = MediaService;
4908
+ exports.MerchantExclusiveCouponService = MerchantExclusiveCouponService;
4207
4909
  exports.MerchantTransferService = MerchantTransferService;
4208
4910
  exports.NativeService = NativeService;
4209
4911
  exports.ParkingService = ParkingService;
4210
4912
  exports.PartnershipService = PartnershipService;
4211
4913
  exports.PayGiftActivityService = PayGiftActivityService;
4212
4914
  exports.PayScoreService = PayScoreService;
4915
+ exports.PayrollCardService = PayrollCardService;
4213
4916
  exports.ProfitSharingService = ProfitSharingService;
4917
+ exports.RetailStoreService = RetailStoreService;
4918
+ exports.ScanAndRideService = ScanAndRideService;
4214
4919
  exports.SecurityService = SecurityService;
4920
+ exports.ServiceException = ServiceException;
4215
4921
  exports.SmartGuideService = SmartGuideService;
4922
+ exports.ValidationException = ValidationException;
4216
4923
  exports.WxPayClient = WxPayClient;
4217
4924
  exports.WxPayError = WxPayError;
4218
4925
  exports.buildAppBridgeConfig = buildAppBridgeConfig;
@@ -4236,12 +4943,19 @@ exports.buildPayScoreDetailMiniProgramBridgeConfig = buildPayScoreDetailMiniProg
4236
4943
  exports.buildPayScoreJsapiBridgeConfig = buildPayScoreJsapiBridgeConfig;
4237
4944
  exports.buildPayScoreMiniProgramBridgeConfig = buildPayScoreMiniProgramBridgeConfig;
4238
4945
  exports.buildSignString = buildSignString;
4946
+ exports.decryptSensitiveFields = decryptSensitiveFields;
4947
+ exports.decryptSensitiveFieldsInArray = decryptSensitiveFieldsInArray;
4948
+ exports.encryptSensitiveFields = encryptSensitiveFields;
4949
+ exports.encryptSensitiveFieldsInArray = encryptSensitiveFieldsInArray;
4239
4950
  exports.generateAppPaySign = generateAppPaySign;
4240
4951
  exports.generateNonce = generateNonce;
4241
4952
  exports.generateNonceStr = generateNonceStr;
4242
4953
  exports.generatePayScorePaySign = generatePayScorePaySign;
4243
4954
  exports.generatePaySign = generatePaySign;
4955
+ exports.isTimestampValid = isTimestampValid;
4956
+ exports.oaepDecrypt = oaepDecrypt;
4244
4957
  exports.oaepEncrypt = oaepEncrypt;
4958
+ exports.registerSensitiveFields = registerSensitiveFields;
4245
4959
  exports.sign = sign;
4246
4960
  exports.verifySignature = verifySignature;
4247
4961
  //# sourceMappingURL=index.js.map