wxpay-nodejs-sdk 0.1.0

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 ADDED
@@ -0,0 +1,4248 @@
1
+ 'use strict';
2
+
3
+ var fs = require('fs');
4
+ var crypto4 = require('crypto');
5
+
6
+ function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
7
+
8
+ var fs__default = /*#__PURE__*/_interopDefault(fs);
9
+ var crypto4__default = /*#__PURE__*/_interopDefault(crypto4);
10
+
11
+ // src/core/client.ts
12
+ var CertificateManager = class {
13
+ /** 平台证书缓存 Map<序列号, 证书信息> */
14
+ certificates = /* @__PURE__ */ new Map();
15
+ /** 微信支付公钥(PEM 格式),支持公钥模式 */
16
+ wxpayPublicKey = null;
17
+ /** 微信支付公钥ID */
18
+ wxpayPublicKeyId = null;
19
+ /** API V3 密钥 */
20
+ apiV3Key;
21
+ constructor(apiV3Key, certificates) {
22
+ this.apiV3Key = apiV3Key;
23
+ if (certificates) {
24
+ for (const cert of certificates) {
25
+ this.certificates.set(cert.serialNo, cert);
26
+ }
27
+ }
28
+ }
29
+ /**
30
+ * 获取证书序列号列表
31
+ */
32
+ get serialNos() {
33
+ return Array.from(this.certificates.keys());
34
+ }
35
+ /**
36
+ * 设置微信支付公钥(公钥模式)
37
+ *
38
+ * @param publicKeyId - 微信支付公钥ID(从商户平台获取)
39
+ * @param publicKey - PEM 格式的微信支付公钥
40
+ */
41
+ setWxPayPublicKey(publicKeyId, publicKey) {
42
+ this.wxpayPublicKeyId = publicKeyId;
43
+ this.wxpayPublicKey = publicKey;
44
+ }
45
+ /**
46
+ * 获取用于验签的公钥
47
+ *
48
+ * 优先返回微信支付公钥(公钥模式),否则根据证书序列号查找平台证书。
49
+ *
50
+ * @param serialNo - 证书序列号或公钥ID
51
+ * @returns PEM 格式的公钥,不存在则返回 null
52
+ */
53
+ getPublicKey(serialNo) {
54
+ if (this.wxpayPublicKey && this.wxpayPublicKeyId === serialNo) {
55
+ return this.wxpayPublicKey;
56
+ }
57
+ if (this.wxpayPublicKey && serialNo.startsWith("PUB_KEY_ID_")) {
58
+ return this.wxpayPublicKey;
59
+ }
60
+ const cert = this.certificates.get(serialNo);
61
+ if (!cert) return null;
62
+ const { ciphertext, nonce, associatedData, algorithm } = cert.encryptCertificate;
63
+ if (algorithm === "RAW_PUBLIC_KEY") {
64
+ return Buffer.from(ciphertext, "base64").toString("utf-8");
65
+ }
66
+ try {
67
+ const decipher = crypto4__default.default.createDecipheriv(
68
+ "aes-256-gcm",
69
+ Buffer.from(this.apiV3Key, "utf-8"),
70
+ Buffer.from(nonce, "utf-8")
71
+ );
72
+ decipher.setAAD(Buffer.from(associatedData, "utf-8"));
73
+ decipher.setAuthTag(Buffer.from(ciphertext, "base64").subarray(-16));
74
+ const encryptedData = Buffer.from(ciphertext, "base64").subarray(0, -16);
75
+ let decrypted = decipher.update(encryptedData);
76
+ decrypted = Buffer.concat([decrypted, decipher.final()]);
77
+ return decrypted.toString("utf-8");
78
+ } catch {
79
+ return null;
80
+ }
81
+ }
82
+ /**
83
+ * 更新平台证书
84
+ */
85
+ updateCertificates(certificates) {
86
+ for (const cert of certificates) {
87
+ this.certificates.set(cert.serialNo, cert);
88
+ }
89
+ }
90
+ /**
91
+ * 直接设置证书公钥(用于已解密后的证书)
92
+ *
93
+ * @param serialNo - 证书序列号
94
+ * @param publicKey - PEM 格式的公钥
95
+ */
96
+ setPublicKey(serialNo, publicKey) {
97
+ const cert = {
98
+ serialNo,
99
+ effectiveTime: (/* @__PURE__ */ new Date()).toISOString(),
100
+ expireTime: new Date(Date.now() + 365 * 24 * 3600 * 1e3).toISOString(),
101
+ encryptCertificate: {
102
+ algorithm: "RAW_PUBLIC_KEY",
103
+ nonce: "",
104
+ associatedData: "",
105
+ ciphertext: Buffer.from(publicKey, "utf-8").toString("base64")
106
+ }
107
+ };
108
+ this.certificates.set(serialNo, cert);
109
+ }
110
+ /**
111
+ * 清空证书缓存
112
+ */
113
+ clear() {
114
+ this.certificates.clear();
115
+ this.wxpayPublicKey = null;
116
+ this.wxpayPublicKeyId = null;
117
+ }
118
+ };
119
+
120
+ // src/utils/http.ts
121
+ var WxPayError = class extends Error {
122
+ /** HTTP 状态码 */
123
+ status;
124
+ /** 错误响应头 */
125
+ headers;
126
+ /** 错误详情 */
127
+ detail;
128
+ constructor(status, headers, detail) {
129
+ super(`[${detail.code}] ${detail.message}`);
130
+ this.name = "WxPayError";
131
+ this.status = status;
132
+ this.headers = headers;
133
+ this.detail = detail;
134
+ }
135
+ /** 是否为客户端错误 (4xx) */
136
+ get isClientError() {
137
+ return this.status >= 400 && this.status < 500;
138
+ }
139
+ /** 是否为服务端错误 (5xx) */
140
+ get isServerError() {
141
+ return this.status >= 500 && this.status < 600;
142
+ }
143
+ };
144
+ function buildUrl(base, path, params) {
145
+ const url = new URL(path, base);
146
+ if (params) {
147
+ Object.entries(params).forEach(([key, value]) => {
148
+ if (value !== void 0 && value !== null) {
149
+ url.searchParams.append(key, String(value));
150
+ }
151
+ });
152
+ }
153
+ return url.toString();
154
+ }
155
+ function parseResponseHeaders(headers) {
156
+ const result = {};
157
+ const keys = [
158
+ "wechatpay-serial",
159
+ "wechatpay-signature",
160
+ "wechatpay-timestamp",
161
+ "wechatpay-nonce",
162
+ "request-id"
163
+ ];
164
+ for (const key of keys) {
165
+ const value = headers.get(key);
166
+ if (value) {
167
+ result[key] = value;
168
+ }
169
+ }
170
+ return result;
171
+ }
172
+ function createRequestHeaders(options) {
173
+ return {
174
+ Authorization: options.authorization,
175
+ Accept: options.accept ?? "application/json",
176
+ "Content-Type": options.contentType ?? "application/json",
177
+ "User-Agent": "wxpay-nodejs-sdk/0.1.0",
178
+ ...options.additional
179
+ };
180
+ }
181
+ async function parseResponse(response, verify) {
182
+ const headers = parseResponseHeaders(response.headers);
183
+ const rawBody = await response.text();
184
+ if (!response.ok) {
185
+ let errorDetail;
186
+ try {
187
+ const parsed = JSON.parse(rawBody);
188
+ if (parsed && typeof parsed === "object" && "code" in parsed && "message" in parsed) {
189
+ errorDetail = parsed;
190
+ } else {
191
+ errorDetail = {
192
+ code: "HTTP_ERROR",
193
+ message: `HTTP ${response.status}: ${response.statusText}`
194
+ };
195
+ }
196
+ } catch {
197
+ errorDetail = {
198
+ code: "HTTP_ERROR",
199
+ message: `HTTP ${response.status}: ${response.statusText}`
200
+ };
201
+ }
202
+ throw new WxPayError(response.status, headers, errorDetail);
203
+ }
204
+ if (verify) {
205
+ const signature = headers["wechatpay-signature"];
206
+ const timestamp = headers["wechatpay-timestamp"];
207
+ const nonce = headers["wechatpay-nonce"];
208
+ const serial = headers["wechatpay-serial"];
209
+ if (signature && timestamp && nonce && serial) {
210
+ const valid = verify(rawBody, signature, timestamp, nonce, serial);
211
+ if (!valid) {
212
+ throw new WxPayError(response.status, headers, {
213
+ code: "SIGN_ERROR",
214
+ message: "\u5E94\u7B54\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25"
215
+ });
216
+ }
217
+ }
218
+ }
219
+ let data;
220
+ try {
221
+ const parsed = JSON.parse(rawBody);
222
+ if (parsed === null || parsed === void 0 || typeof parsed !== "object") {
223
+ throw new Error("\u54CD\u5E94\u6570\u636E\u683C\u5F0F\u9519\u8BEF");
224
+ }
225
+ data = parsed;
226
+ } 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
+ });
231
+ }
232
+ return {
233
+ status: response.status,
234
+ headers,
235
+ data
236
+ };
237
+ }
238
+ function buildSignString(payload) {
239
+ const { method, path, timestamp, nonce, body } = payload;
240
+ return `${method}
241
+ ${path}
242
+ ${timestamp}
243
+ ${nonce}
244
+ ${body}
245
+ `;
246
+ }
247
+ function sign(signString, privateKey) {
248
+ const signer = crypto4__default.default.createSign("RSA-SHA256");
249
+ signer.update(signString);
250
+ signer.end();
251
+ return signer.sign(privateKey, "base64");
252
+ }
253
+ function buildAuthorization(mchid, serialNo, timestamp, nonce, signature) {
254
+ return `WECHATPAY2-SHA256-RSA2048 mchid="${mchid}",nonce_str="${nonce}",timestamp="${timestamp}",serial_no="${serialNo}",signature="${signature}"`;
255
+ }
256
+ function generateNonce() {
257
+ return crypto4__default.default.randomUUID().replace(/-/g, "");
258
+ }
259
+ function verifySignature(body, signature, timestamp, nonce, publicKey) {
260
+ const signString = `${timestamp}
261
+ ${nonce}
262
+ ${body}
263
+ `;
264
+ const verifier = crypto4__default.default.createVerify("RSA-SHA256");
265
+ verifier.update(signString);
266
+ verifier.end();
267
+ return verifier.verify(publicKey, signature, "base64");
268
+ }
269
+ function oaepEncrypt(plaintext, publicKey) {
270
+ const encrypted = crypto4__default.default.publicEncrypt(
271
+ {
272
+ key: publicKey,
273
+ padding: crypto4__default.default.constants.RSA_PKCS1_OAEP_PADDING,
274
+ oaepHash: "sha256"
275
+ },
276
+ Buffer.from(plaintext, "utf-8")
277
+ );
278
+ return encrypted.toString("base64");
279
+ }
280
+
281
+ // src/core/client.ts
282
+ var WxPayClient = class _WxPayClient {
283
+ /** 生产环境 API 地址 */
284
+ static PRODUCTION_BASE = "https://api.mch.weixin.qq.com";
285
+ /** 沙箱环境 API 地址 */
286
+ static SANDBOX_BASE = "https://api.mch.weixin.qq.com/sandboxnew";
287
+ /** 商户号 */
288
+ mchid;
289
+ apiV3Key;
290
+ serialNo;
291
+ privateKey;
292
+ timeout;
293
+ baseUrl;
294
+ enableResponseVerification;
295
+ /** 平台证书管理器 */
296
+ certificates;
297
+ constructor(options) {
298
+ this.mchid = options.mchid;
299
+ this.apiV3Key = options.apiV3Key;
300
+ this.serialNo = options.serialNo;
301
+ this.privateKey = this.resolvePrivateKey(options.privateKey);
302
+ this.timeout = options.timeout ?? 3e4;
303
+ this.baseUrl = options.sandbox ? _WxPayClient.SANDBOX_BASE : _WxPayClient.PRODUCTION_BASE;
304
+ this.enableResponseVerification = options.enableResponseVerification ?? true;
305
+ this.certificates = new CertificateManager(this.apiV3Key, options.platformCertificates);
306
+ if (options.wxpayPublicKeyId && options.wxpayPublicKey) {
307
+ const publicKey = this.resolvePublicKey(options.wxpayPublicKey);
308
+ this.certificates.setWxPayPublicKey(options.wxpayPublicKeyId, publicKey);
309
+ }
310
+ }
311
+ /**
312
+ * 发起 GET 请求
313
+ */
314
+ async get(path, params) {
315
+ return this.request("GET", path, params);
316
+ }
317
+ /**
318
+ * 发起 POST 请求
319
+ */
320
+ async post(path, body, params, extraHeaders) {
321
+ return this.request("POST", path, params, body, extraHeaders);
322
+ }
323
+ /**
324
+ * 发起 PUT 请求
325
+ */
326
+ async put(path, body, params) {
327
+ return this.request("PUT", path, params, body);
328
+ }
329
+ /**
330
+ * 发起 PATCH 请求
331
+ */
332
+ async patch(path, body, params) {
333
+ return this.request("PATCH", path, params, body);
334
+ }
335
+ /**
336
+ * 发起 DELETE 请求
337
+ */
338
+ async delete(path, params) {
339
+ return this.request("DELETE", path, params);
340
+ }
341
+ /**
342
+ * 下载原始二进制文件(账单下载等场景)
343
+ *
344
+ * 直接请求完整的 URL(非 API 路径),返回原始响应体。
345
+ * 用于下载账单等返回非 JSON 格式数据的场景。
346
+ *
347
+ * @param url - 完整的下载 URL(从申请账单接口返回的 download_url)
348
+ * @returns 包含原始 Buffer 数据和响应头的 WxPayResponse
349
+ */
350
+ async downloadRaw(url) {
351
+ const method = "GET";
352
+ const bodyStr = "";
353
+ const timestamp = Math.floor(Date.now() / 1e3);
354
+ const nonce = generateNonce();
355
+ const urlObj = new URL(url);
356
+ const signPath = urlObj.pathname + urlObj.search;
357
+ const signString = buildSignString({
358
+ method,
359
+ path: signPath,
360
+ timestamp,
361
+ nonce,
362
+ body: bodyStr
363
+ });
364
+ const signature = sign(signString, this.privateKey);
365
+ const authorization = buildAuthorization(
366
+ this.mchid,
367
+ this.serialNo,
368
+ timestamp,
369
+ nonce,
370
+ signature
371
+ );
372
+ const headers = {
373
+ Authorization: authorization,
374
+ Accept: "application/json",
375
+ "User-Agent": "wxpay-nodejs-sdk/0.1.0"
376
+ };
377
+ const controller = new AbortController();
378
+ const timeoutId = setTimeout(() => {
379
+ controller.abort();
380
+ }, this.timeout);
381
+ try {
382
+ const response = await fetch(url, {
383
+ method,
384
+ headers,
385
+ signal: controller.signal
386
+ });
387
+ if (!response.ok) {
388
+ let errorDetail;
389
+ try {
390
+ const data2 = await response.json();
391
+ if (data2 && typeof data2 === "object" && "code" in data2 && "message" in data2) {
392
+ errorDetail = data2;
393
+ } else {
394
+ errorDetail = {
395
+ code: "HTTP_ERROR",
396
+ message: `HTTP ${response.status}: ${response.statusText}`
397
+ };
398
+ }
399
+ } catch {
400
+ errorDetail = {
401
+ code: "HTTP_ERROR",
402
+ message: `HTTP ${response.status}: ${response.statusText}`
403
+ };
404
+ }
405
+ throw new WxPayError(response.status, {}, errorDetail);
406
+ }
407
+ const arrayBuffer = await response.arrayBuffer();
408
+ const data = Buffer.from(arrayBuffer);
409
+ const responseHeaders = {};
410
+ response.headers.forEach((value, key) => {
411
+ responseHeaders[key] = value;
412
+ });
413
+ return {
414
+ status: response.status,
415
+ headers: responseHeaders,
416
+ data
417
+ };
418
+ } catch (error) {
419
+ if (error instanceof WxPayError) {
420
+ throw error;
421
+ }
422
+ if (error instanceof DOMException && error.name === "AbortError") {
423
+ throw new WxPayError(
424
+ 0,
425
+ {},
426
+ {
427
+ code: "REQUEST_TIMEOUT",
428
+ message: `\u8BF7\u6C42\u8D85\u65F6 (${this.timeout}ms)`
429
+ }
430
+ );
431
+ }
432
+ throw new WxPayError(
433
+ 0,
434
+ {},
435
+ {
436
+ code: "NETWORK_ERROR",
437
+ message: error instanceof Error ? error.message : "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"
438
+ }
439
+ );
440
+ } finally {
441
+ clearTimeout(timeoutId);
442
+ }
443
+ }
444
+ /**
445
+ * 上传文件(multipart/form-data)
446
+ *
447
+ * 用于图片上传等需要提交文件的场景。
448
+ * 微信支付文件上传接口要求将 meta(JSON)和 file 分别作为 form-data 的两个 part 提交,
449
+ * 签名计算基于 meta 部分的 JSON 字符串。
450
+ *
451
+ * @param path - API 路径
452
+ * @param file - 文件内容 Buffer
453
+ * @param filename - 文件名
454
+ * @param meta - 业务参数(作为 meta part 的 JSON 内容)
455
+ */
456
+ async upload(path, file, filename, meta) {
457
+ const url = buildUrl(this.baseUrl, path);
458
+ const metaStr = meta ? JSON.stringify(meta) : "{}";
459
+ const timestamp = Math.floor(Date.now() / 1e3);
460
+ const nonce = generateNonce();
461
+ const urlObj = new URL(url);
462
+ const signPath = urlObj.pathname + urlObj.search;
463
+ const signString = buildSignString({
464
+ method: "POST",
465
+ path: signPath,
466
+ timestamp,
467
+ nonce,
468
+ body: metaStr
469
+ });
470
+ const signature = sign(signString, this.privateKey);
471
+ const authorization = buildAuthorization(
472
+ this.mchid,
473
+ this.serialNo,
474
+ timestamp,
475
+ nonce,
476
+ signature
477
+ );
478
+ const boundary = `----WxPayNodeJSSDK${Date.now()}`;
479
+ const crlf = "\r\n";
480
+ const parts = [];
481
+ parts.push(
482
+ Buffer.from(
483
+ `--${boundary}${crlf}Content-Disposition: form-data; name="meta"${crlf}Content-Type: application/json${crlf}${crlf}${metaStr}${crlf}`
484
+ )
485
+ );
486
+ const fileHeader = Buffer.from(
487
+ `--${boundary}${crlf}Content-Disposition: form-data; name="file"; filename="${filename}"${crlf}Content-Type: application/octet-stream${crlf}${crlf}`
488
+ );
489
+ parts.push(fileHeader);
490
+ parts.push(file);
491
+ parts.push(Buffer.from(crlf));
492
+ parts.push(Buffer.from(`--${boundary}--${crlf}`));
493
+ const body = Buffer.concat(parts);
494
+ const headers = {
495
+ Authorization: authorization,
496
+ Accept: "application/json",
497
+ "Content-Type": `multipart/form-data; boundary=${boundary}`,
498
+ "User-Agent": "wxpay-nodejs-sdk/0.1.0"
499
+ };
500
+ const controller = new AbortController();
501
+ const timeoutId = setTimeout(() => {
502
+ controller.abort();
503
+ }, this.timeout);
504
+ try {
505
+ const response = await fetch(url, {
506
+ method: "POST",
507
+ headers,
508
+ body,
509
+ signal: controller.signal
510
+ });
511
+ return await parseResponse(response, this.createVerifier());
512
+ } catch (error) {
513
+ if (error instanceof WxPayError) {
514
+ throw error;
515
+ }
516
+ if (error instanceof DOMException && error.name === "AbortError") {
517
+ throw new WxPayError(
518
+ 0,
519
+ {},
520
+ {
521
+ code: "REQUEST_TIMEOUT",
522
+ message: `\u8BF7\u6C42\u8D85\u65F6 (${this.timeout}ms)`
523
+ }
524
+ );
525
+ }
526
+ throw new WxPayError(
527
+ 0,
528
+ {},
529
+ {
530
+ code: "NETWORK_ERROR",
531
+ message: error instanceof Error ? error.message : "\u7F51\u7EDC\u8BF7\u6C42\u5931\u8D25"
532
+ }
533
+ );
534
+ } finally {
535
+ clearTimeout(timeoutId);
536
+ }
537
+ }
538
+ /**
539
+ * 通用 HTTP 请求方法
540
+ */
541
+ async request(method, path, params, body, extraHeaders) {
542
+ const url = buildUrl(this.baseUrl, path, params);
543
+ const bodyStr = body ? JSON.stringify(body) : "";
544
+ const timestamp = Math.floor(Date.now() / 1e3);
545
+ 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
554
+ });
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
574
+ });
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)`
587
+ }
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"
596
+ }
597
+ );
598
+ } finally {
599
+ clearTimeout(timeoutId);
600
+ }
601
+ }
602
+ /**
603
+ * 解析私钥:支持直接传入内容或文件路径
604
+ */
605
+ resolvePrivateKey(key) {
606
+ if (Buffer.isBuffer(key)) return key;
607
+ if (key.startsWith("-----BEGIN")) return key;
608
+ try {
609
+ return fs__default.default.readFileSync(key, "utf-8");
610
+ } catch {
611
+ return key;
612
+ }
613
+ }
614
+ /**
615
+ * 解析公钥:支持直接传入内容或文件路径
616
+ */
617
+ resolvePublicKey(key) {
618
+ if (Buffer.isBuffer(key)) return key.toString("utf-8");
619
+ if (key.startsWith("-----BEGIN")) return key;
620
+ try {
621
+ return fs__default.default.readFileSync(key, "utf-8");
622
+ } catch {
623
+ return key;
624
+ }
625
+ }
626
+ /**
627
+ * 创建应答验签函数
628
+ */
629
+ createVerifier() {
630
+ if (!this.enableResponseVerification) return void 0;
631
+ return (body, signature, timestamp, nonce, serial) => {
632
+ const publicKey = this.certificates.getPublicKey(serial);
633
+ if (!publicKey) {
634
+ throw new Error(`\u672A\u627E\u5230\u5E8F\u5217\u53F7\u4E3A ${serial} \u7684\u5E73\u53F0\u8BC1\u4E66\u6216\u516C\u94A5\uFF0C\u8BF7\u786E\u4FDD\u5DF2\u914D\u7F6E`);
635
+ }
636
+ return verifySignature(body, signature, timestamp, nonce, publicKey);
637
+ };
638
+ }
639
+ };
640
+
641
+ // src/services/jsapi.ts
642
+ var JsapiService = class {
643
+ client;
644
+ constructor(client) {
645
+ this.client = client;
646
+ }
647
+ /**
648
+ * JSAPI/小程序下单
649
+ *
650
+ * 商户通过此接口生成预付单并获取 prepay_id。
651
+ * prepay_id 有效期为 2 小时,超过 2 小时需重新请求。
652
+ *
653
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791856
654
+ */
655
+ async createOrder(request) {
656
+ return this.client.post("/v3/pay/transactions/jsapi", request);
657
+ }
658
+ /**
659
+ * 查询 JSAPI 支付订单
660
+ *
661
+ * 支持通过微信支付订单号或商户订单号查询订单状态。
662
+ *
663
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791858 (微信支付订单号查询订单)
664
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791859 (商户订单号查询订单)
665
+ */
666
+ async queryOrderById(params) {
667
+ if (params.transactionId) {
668
+ return this.client.get(
669
+ `/v3/pay/transactions/id/${params.transactionId}`,
670
+ { mchid: this.client.mchid }
671
+ );
672
+ }
673
+ if (params.outTradeNo) {
674
+ return this.client.get(
675
+ `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,
676
+ { mchid: this.client.mchid }
677
+ );
678
+ }
679
+ throw new Error("outTradeNo \u6216 transactionId \u5FC5\u987B\u63D0\u4F9B\u5176\u4E2D\u4E00\u4E2A");
680
+ }
681
+ /**
682
+ * 关闭订单
683
+ *
684
+ * 对于未支付的订单,商户可通过此接口关闭订单。
685
+ * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
686
+ *
687
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791860
688
+ */
689
+ async closeOrder(outTradeNo, request) {
690
+ return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);
691
+ }
692
+ /**
693
+ * 申请退款
694
+ *
695
+ * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
696
+ * 仅支持支付成功后 1 年内的订单。
697
+ *
698
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791862
699
+ */
700
+ async createRefund(request) {
701
+ return this.client.post("/v3/refund/domestic/refunds", request);
702
+ }
703
+ /**
704
+ * 查询退款单
705
+ *
706
+ * 通过商户退款单号查询退款状态。
707
+ *
708
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791863
709
+ */
710
+ async queryRefund(params) {
711
+ return this.client.get(
712
+ `/v3/refund/domestic/refunds/${params.outRefundNo}`
713
+ );
714
+ }
715
+ /**
716
+ * 申请交易账单
717
+ *
718
+ * 商户可通过此接口获取交易账单的下载链接。
719
+ *
720
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791866
721
+ */
722
+ async tradeBill(params) {
723
+ return this.client.get("/v3/bill/tradebill", params);
724
+ }
725
+ /**
726
+ * 申请资金账单
727
+ *
728
+ * 商户可通过此接口获取资金账单的下载链接。
729
+ *
730
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791867
731
+ */
732
+ async fundFlowBill(params) {
733
+ return this.client.get("/v3/bill/fundflowbill", params);
734
+ }
735
+ /**
736
+ * 申请异常退款
737
+ *
738
+ * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
739
+ * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
740
+ *
741
+ * @param refundId - 微信支付退款单号
742
+ * @param request - 异常退款请求参数
743
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791864
744
+ */
745
+ async applyAbnormalRefund(refundId, request) {
746
+ return this.client.post(
747
+ `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
748
+ request
749
+ );
750
+ }
751
+ /**
752
+ * 下载账单
753
+ *
754
+ * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
755
+ * 下载地址 5 分钟内有效,请及时下载。
756
+ * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
757
+ *
758
+ * @param downloadUrl - 申请账单返回的 download_url
759
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791868
760
+ */
761
+ async downloadBill(downloadUrl) {
762
+ return this.client.downloadRaw(downloadUrl);
763
+ }
764
+ };
765
+
766
+ // src/services/h5.ts
767
+ var H5Service = class {
768
+ client;
769
+ constructor(client) {
770
+ this.client = client;
771
+ }
772
+ /**
773
+ * H5 支付下单
774
+ *
775
+ * 商户通过此接口生成 H5 支付链接(h5_url),用于在已配置 H5 支付域名的网页中
776
+ * 跳转并调起微信支付收银台。h5_url 有效期为 5 分钟,过期后需重新请求。
777
+ *
778
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791834
779
+ */
780
+ async createOrder(request) {
781
+ return this.client.post("/v3/pay/transactions/h5", request);
782
+ }
783
+ /**
784
+ * 查询订单
785
+ *
786
+ * 支持通过微信支付订单号或商户订单号查询订单状态。
787
+ *
788
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791837 (微信支付订单号查询订单)
789
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791838 (商户订单号查询订单)
790
+ */
791
+ async queryOrderById(params) {
792
+ if (params.transactionId) {
793
+ return this.client.get(
794
+ `/v3/pay/transactions/id/${params.transactionId}`,
795
+ { mchid: this.client.mchid }
796
+ );
797
+ }
798
+ if (params.outTradeNo) {
799
+ return this.client.get(
800
+ `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,
801
+ { mchid: this.client.mchid }
802
+ );
803
+ }
804
+ throw new Error("outTradeNo \u6216 transactionId \u5FC5\u987B\u63D0\u4F9B\u5176\u4E2D\u4E00\u4E2A");
805
+ }
806
+ /**
807
+ * 关闭订单
808
+ *
809
+ * 对于未支付的订单,商户可通过此接口关闭订单。
810
+ * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
811
+ *
812
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791839
813
+ */
814
+ async closeOrder(outTradeNo, request) {
815
+ return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);
816
+ }
817
+ /**
818
+ * 申请退款
819
+ *
820
+ * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
821
+ * 仅支持支付成功后 1 年内的订单。
822
+ *
823
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810597
824
+ */
825
+ async createRefund(request) {
826
+ return this.client.post("/v3/refund/domestic/refunds", request);
827
+ }
828
+ /**
829
+ * 查询退款单
830
+ *
831
+ * 通过商户退款单号查询退款状态。
832
+ *
833
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810601
834
+ */
835
+ async queryRefund(params) {
836
+ return this.client.get(
837
+ `/v3/refund/domestic/refunds/${params.outRefundNo}`
838
+ );
839
+ }
840
+ /**
841
+ * 申请异常退款
842
+ *
843
+ * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
844
+ * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
845
+ *
846
+ * @param refundId - 微信支付退款单号
847
+ * @param request - 异常退款请求参数
848
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810603
849
+ */
850
+ async applyAbnormalRefund(refundId, request) {
851
+ return this.client.post(
852
+ `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
853
+ request
854
+ );
855
+ }
856
+ /**
857
+ * 申请交易账单
858
+ *
859
+ * 商户可通过此接口获取交易账单的下载链接。
860
+ *
861
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810606
862
+ */
863
+ async tradeBill(params) {
864
+ return this.client.get("/v3/bill/tradebill", params);
865
+ }
866
+ /**
867
+ * 申请资金账单
868
+ *
869
+ * 商户可通过此接口获取资金账单的下载链接。
870
+ *
871
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810609
872
+ */
873
+ async fundFlowBill(params) {
874
+ return this.client.get("/v3/bill/fundflowbill", params);
875
+ }
876
+ /**
877
+ * 下载账单
878
+ *
879
+ * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
880
+ * 下载地址 5 分钟内有效,请及时下载。
881
+ * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
882
+ *
883
+ * @param downloadUrl - 申请账单返回的 download_url
884
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810615
885
+ */
886
+ async downloadBill(downloadUrl) {
887
+ return this.client.downloadRaw(downloadUrl);
888
+ }
889
+ };
890
+
891
+ // src/services/app.ts
892
+ var AppService = class {
893
+ client;
894
+ constructor(client) {
895
+ this.client = client;
896
+ }
897
+ /**
898
+ * APP 支付下单
899
+ *
900
+ * 商户通过此接口生成预付单并获取 prepay_id。
901
+ * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。
902
+ *
903
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070347
904
+ */
905
+ async createOrder(request) {
906
+ return this.client.post("/v3/pay/transactions/app", request);
907
+ }
908
+ /**
909
+ * 查询订单
910
+ *
911
+ * 支持通过微信支付订单号或商户订单号查询订单状态。
912
+ *
913
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070354 (微信支付订单号查询订单)
914
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070356 (商户订单号查询订单)
915
+ */
916
+ async queryOrderById(params) {
917
+ if (params.transactionId) {
918
+ return this.client.get(
919
+ `/v3/pay/transactions/id/${params.transactionId}`,
920
+ { mchid: this.client.mchid }
921
+ );
922
+ }
923
+ if (params.outTradeNo) {
924
+ return this.client.get(
925
+ `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,
926
+ { mchid: this.client.mchid }
927
+ );
928
+ }
929
+ throw new Error("outTradeNo \u6216 transactionId \u5FC5\u987B\u63D0\u4F9B\u5176\u4E2D\u4E00\u4E2A");
930
+ }
931
+ /**
932
+ * 关闭订单
933
+ *
934
+ * 对于未支付的订单,商户可通过此接口关闭订单。
935
+ * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
936
+ *
937
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070360
938
+ */
939
+ async closeOrder(outTradeNo, request) {
940
+ return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);
941
+ }
942
+ /**
943
+ * 申请退款
944
+ *
945
+ * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
946
+ * 仅支持支付成功后 1 年内的订单。
947
+ *
948
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070371
949
+ */
950
+ async createRefund(request) {
951
+ return this.client.post("/v3/refund/domestic/refunds", request);
952
+ }
953
+ /**
954
+ * 查询退款单
955
+ *
956
+ * 通过商户退款单号查询退款状态。
957
+ *
958
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070374
959
+ */
960
+ async queryRefund(params) {
961
+ return this.client.get(
962
+ `/v3/refund/domestic/refunds/${params.outRefundNo}`
963
+ );
964
+ }
965
+ /**
966
+ * 申请异常退款
967
+ *
968
+ * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
969
+ * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
970
+ *
971
+ * @param refundId - 微信支付退款单号
972
+ * @param request - 异常退款请求参数
973
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070379
974
+ */
975
+ async applyAbnormalRefund(refundId, request) {
976
+ return this.client.post(
977
+ `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
978
+ request
979
+ );
980
+ }
981
+ /**
982
+ * 申请交易账单
983
+ *
984
+ * 商户可通过此接口获取交易账单的下载链接。
985
+ *
986
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070395
987
+ */
988
+ async tradeBill(params) {
989
+ return this.client.get("/v3/bill/tradebill", params);
990
+ }
991
+ /**
992
+ * 申请资金账单
993
+ *
994
+ * 商户可通过此接口获取资金账单的下载链接。
995
+ *
996
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070400
997
+ */
998
+ async fundFlowBill(params) {
999
+ return this.client.get("/v3/bill/fundflowbill", params);
1000
+ }
1001
+ /**
1002
+ * 下载账单
1003
+ *
1004
+ * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1005
+ * 下载地址 5 分钟内有效,请及时下载。
1006
+ * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
1007
+ *
1008
+ * @param downloadUrl - 申请账单返回的 download_url
1009
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070401
1010
+ */
1011
+ async downloadBill(downloadUrl) {
1012
+ return this.client.downloadRaw(downloadUrl);
1013
+ }
1014
+ };
1015
+
1016
+ // src/services/native.ts
1017
+ var NativeService = class {
1018
+ client;
1019
+ constructor(client) {
1020
+ this.client = client;
1021
+ }
1022
+ /**
1023
+ * Native 支付下单
1024
+ *
1025
+ * 商户通过此接口生成订单并获取二维码链接(code_url)。
1026
+ * code_url 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。
1027
+ *
1028
+ * 商户后端获取 code_url 后传递给前端,前端将其转换为二维码图片展示给用户。
1029
+ * 用户使用微信扫一扫扫描二维码后,将调起微信收银台完成支付。
1030
+ *
1031
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791877
1032
+ */
1033
+ async createOrder(request) {
1034
+ return this.client.post("/v3/pay/transactions/native", request);
1035
+ }
1036
+ /**
1037
+ * 查询订单
1038
+ *
1039
+ * 支持通过微信支付订单号或商户订单号查询订单状态。
1040
+ *
1041
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791879 (微信支付订单号查询订单)
1042
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791880 (商户订单号查询订单)
1043
+ */
1044
+ async queryOrderById(params) {
1045
+ if (params.transactionId) {
1046
+ return this.client.get(
1047
+ `/v3/pay/transactions/id/${params.transactionId}`,
1048
+ { mchid: this.client.mchid }
1049
+ );
1050
+ }
1051
+ if (params.outTradeNo) {
1052
+ return this.client.get(
1053
+ `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,
1054
+ { mchid: this.client.mchid }
1055
+ );
1056
+ }
1057
+ throw new Error("outTradeNo \u6216 transactionId \u5FC5\u987B\u63D0\u4F9B\u5176\u4E2D\u4E00\u4E2A");
1058
+ }
1059
+ /**
1060
+ * 关闭订单
1061
+ *
1062
+ * 对于未支付的订单,商户可通过此接口关闭订单。
1063
+ * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1064
+ *
1065
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791881
1066
+ */
1067
+ async closeOrder(outTradeNo, request) {
1068
+ return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);
1069
+ }
1070
+ /**
1071
+ * 申请退款
1072
+ *
1073
+ * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1074
+ * 仅支持支付成功后 1 年内的订单。
1075
+ *
1076
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791883
1077
+ */
1078
+ async createRefund(request) {
1079
+ return this.client.post("/v3/refund/domestic/refunds", request);
1080
+ }
1081
+ /**
1082
+ * 查询退款单
1083
+ *
1084
+ * 通过商户退款单号查询退款状态。
1085
+ *
1086
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791884
1087
+ */
1088
+ async queryRefund(params) {
1089
+ return this.client.get(
1090
+ `/v3/refund/domestic/refunds/${params.outRefundNo}`
1091
+ );
1092
+ }
1093
+ /**
1094
+ * 申请异常退款
1095
+ *
1096
+ * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1097
+ * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1098
+ *
1099
+ * @param refundId - 微信支付退款单号
1100
+ * @param request - 异常退款请求参数
1101
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791885
1102
+ */
1103
+ async applyAbnormalRefund(refundId, request) {
1104
+ return this.client.post(
1105
+ `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1106
+ request
1107
+ );
1108
+ }
1109
+ /**
1110
+ * 申请交易账单
1111
+ *
1112
+ * 商户可通过此接口获取交易账单的下载链接。
1113
+ *
1114
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791887
1115
+ */
1116
+ async tradeBill(params) {
1117
+ return this.client.get("/v3/bill/tradebill", params);
1118
+ }
1119
+ /**
1120
+ * 申请资金账单
1121
+ *
1122
+ * 商户可通过此接口获取资金账单的下载链接。
1123
+ *
1124
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791888
1125
+ */
1126
+ async fundFlowBill(params) {
1127
+ return this.client.get("/v3/bill/fundflowbill", params);
1128
+ }
1129
+ /**
1130
+ * 下载账单
1131
+ *
1132
+ * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1133
+ * 下载地址 5 分钟内有效,请及时下载。
1134
+ * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
1135
+ *
1136
+ * @param downloadUrl - 申请账单返回的 download_url
1137
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791889
1138
+ */
1139
+ async downloadBill(downloadUrl) {
1140
+ return this.client.downloadRaw(downloadUrl);
1141
+ }
1142
+ };
1143
+
1144
+ // src/services/combine.ts
1145
+ var CombineService = class {
1146
+ client;
1147
+ constructor(client) {
1148
+ this.client = client;
1149
+ }
1150
+ /**
1151
+ * JSAPI 合单下单
1152
+ *
1153
+ * 商户通过此接口生成合单预付单并获取 prepay_id。
1154
+ * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。
1155
+ *
1156
+ * 关键约束:
1157
+ * - combine_mchid 需先申请发起合单支付权限
1158
+ * - sub_orders 中的 mchid 需先申请接收合单支付权限
1159
+ * - 合单发起方和子单参与方需绑定同一个 combine_appid
1160
+ * - 子单数量为 2-10 笔
1161
+ * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天
1162
+ *
1163
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556926
1164
+ */
1165
+ async createOrder(request) {
1166
+ return this.client.post("/v3/combine-transactions/jsapi", request);
1167
+ }
1168
+ /**
1169
+ * 查询合单订单
1170
+ *
1171
+ * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
1172
+ *
1173
+ * 订单状态(sub_orders[].trade_state):
1174
+ * - SUCCESS:支付成功(终态)
1175
+ * - NOTPAY:未支付
1176
+ * - CLOSED:已关闭(终态)
1177
+ *
1178
+ * 注意:请勿使用非合单支付的查单接口查询合单订单。
1179
+ *
1180
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421222
1181
+ */
1182
+ async queryOrderById(params) {
1183
+ return this.client.get(
1184
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
1185
+ );
1186
+ }
1187
+ /**
1188
+ * 关闭合单订单
1189
+ *
1190
+ * 对于未支付的合单订单,商户可通过此接口关闭订单。
1191
+ * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1192
+ *
1193
+ * 关键约束:
1194
+ * - 只能整单关闭,不支持关闭部分子单
1195
+ * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致
1196
+ * - 仅支持未支付状态的订单
1197
+ *
1198
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421225
1199
+ */
1200
+ async closeOrder(params, request) {
1201
+ return this.client.post(
1202
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1203
+ request
1204
+ );
1205
+ }
1206
+ /**
1207
+ * 申请退款
1208
+ *
1209
+ * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口对子单申请退款。
1210
+ * 仅支持支付成功后 1 年内的订单。
1211
+ *
1212
+ * 注意:合单支付的订单无法通过合单总单号 combine_out_trade_no 退款,
1213
+ * 需要传入子单的 transaction_id 或 out_trade_no。
1214
+ *
1215
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421249
1216
+ */
1217
+ async createRefund(request) {
1218
+ return this.client.post("/v3/refund/domestic/refunds", request);
1219
+ }
1220
+ /**
1221
+ * 查询退款单
1222
+ *
1223
+ * 通过商户退款单号查询退款状态。
1224
+ *
1225
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421261
1226
+ */
1227
+ async queryRefund(params) {
1228
+ return this.client.get(
1229
+ `/v3/refund/domestic/refunds/${params.outRefundNo}`
1230
+ );
1231
+ }
1232
+ /**
1233
+ * 申请异常退款
1234
+ *
1235
+ * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1236
+ * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1237
+ *
1238
+ * @param refundId - 微信支付退款单号
1239
+ * @param request - 异常退款请求参数
1240
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421269
1241
+ */
1242
+ async applyAbnormalRefund(refundId, request) {
1243
+ return this.client.post(
1244
+ `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1245
+ request
1246
+ );
1247
+ }
1248
+ };
1249
+
1250
+ // src/services/combine-h5.ts
1251
+ var CombineH5Service = class {
1252
+ client;
1253
+ constructor(client) {
1254
+ this.client = client;
1255
+ }
1256
+ /**
1257
+ * H5 合单下单
1258
+ *
1259
+ * 商户通过此接口生成 H5 合单支付链接(h5_url),用于在已配置 H5 支付域名的
1260
+ * 网页中跳转并唤起微信支付收银台。h5_url 有效期为 5 分钟,过期后需使用
1261
+ * 原下单参数重新请求。
1262
+ *
1263
+ * 关键约束:
1264
+ * - combine_mchid 需先申请发起合单支付权限
1265
+ * - sub_orders 中的 mchid 需先申请接收合单支付权限
1266
+ * - 合单发起方和子单参与方需绑定同一个 combine_appid
1267
+ * - 子单数量为 2-10 笔
1268
+ * - scene_info.payer_client_ip 需传真实的用户端 IP
1269
+ * - scene_info.h5_info 必填,需指定 type 为 Wap/iOS/Android 之一
1270
+ * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天
1271
+ *
1272
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556961
1273
+ */
1274
+ async createOrder(request) {
1275
+ return this.client.post("/v3/combine-transactions/h5", request);
1276
+ }
1277
+ /**
1278
+ * 查询合单订单
1279
+ *
1280
+ * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
1281
+ * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。
1282
+ *
1283
+ * 订单状态(sub_orders[].trade_state):
1284
+ * - SUCCESS:支付成功(终态)
1285
+ * - NOTPAY:未支付
1286
+ * - CLOSED:已关闭(终态)
1287
+ *
1288
+ * 典型使用场景:
1289
+ * - 用户支付后从收银台返回商户页面时,确认订单支付状态
1290
+ * - 未收到支付成功回调通知时,主动查询确认订单状态
1291
+ * - 关单前确认订单仍为未支付状态
1292
+ *
1293
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421126
1294
+ */
1295
+ async queryOrderById(params) {
1296
+ return this.client.get(
1297
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
1298
+ );
1299
+ }
1300
+ /**
1301
+ * 关闭合单订单
1302
+ *
1303
+ * 对于未支付的合单订单,商户可通过此接口关闭订单。
1304
+ * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1305
+ *
1306
+ * 关键约束:
1307
+ * - 只能整单关闭,不支持关闭部分子单
1308
+ * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致
1309
+ * - 仅支持未支付状态的订单
1310
+ * - 关单后订单为失败终态
1311
+ *
1312
+ * 典型使用场景:
1313
+ * - 用户超过商户系统内部规定的支付时间
1314
+ * - 超过下单时设置的 time_expire 时间
1315
+ * - 因特殊原因需在可支付时间范围内关闭订单
1316
+ *
1317
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421130
1318
+ */
1319
+ async closeOrder(params, request) {
1320
+ return this.client.post(
1321
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1322
+ request
1323
+ );
1324
+ }
1325
+ /**
1326
+ * 申请退款(基于子单)
1327
+ *
1328
+ * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,
1329
+ * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。
1330
+ *
1331
+ * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1332
+ * 仅支持支付成功后 1 年内的订单。
1333
+ *
1334
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421148
1335
+ */
1336
+ async createRefund(request) {
1337
+ return this.client.post("/v3/refund/domestic/refunds", request);
1338
+ }
1339
+ /**
1340
+ * 查询退款单
1341
+ *
1342
+ * 通过商户退款单号查询退款状态。
1343
+ * 退款申请成功后,可通过此接口确认退款是否到账。
1344
+ *
1345
+ * 退款状态:
1346
+ * - SUCCESS:退款成功
1347
+ * - CLOSED:退款关闭
1348
+ * - PROCESSING:退款处理中
1349
+ * - ABNORMAL:退款异常
1350
+ *
1351
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421156
1352
+ */
1353
+ async queryRefund(params) {
1354
+ return this.client.get(
1355
+ `/v3/refund/domestic/refunds/${params.outRefundNo}`
1356
+ );
1357
+ }
1358
+ /**
1359
+ * 申请异常退款
1360
+ *
1361
+ * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1362
+ * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1363
+ *
1364
+ * @param refundId - 微信支付退款单号
1365
+ * @param request - 异常退款请求参数
1366
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421164
1367
+ */
1368
+ async applyAbnormalRefund(refundId, request) {
1369
+ return this.client.post(
1370
+ `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1371
+ request
1372
+ );
1373
+ }
1374
+ };
1375
+
1376
+ // src/services/combine-app.ts
1377
+ var CombineAppService = class {
1378
+ client;
1379
+ constructor(client) {
1380
+ this.client = client;
1381
+ }
1382
+ /**
1383
+ * APP 合单下单
1384
+ *
1385
+ * 商户通过此接口生成 APP 合单预付单并获取 prepay_id。
1386
+ * 获取 prepay_id 后,配合 buildAppBridgeConfig 生成调起支付参数,
1387
+ * 通过微信 OpenSDK 的 sendReq 方法在商户 APP 内调起微信支付收银台。
1388
+ *
1389
+ * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。
1390
+ *
1391
+ * 关键约束:
1392
+ * - combine_mchid 需先申请发起合单支付权限
1393
+ * - sub_orders 中的 mchid 需先申请接收合单支付权限
1394
+ * - 合单发起方和子单参与方需绑定同一个 combine_appid
1395
+ * - combine_appid 必须为移动应用 APPID
1396
+ * - 子单数量为 2-10 笔
1397
+ * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天
1398
+ *
1399
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556944
1400
+ */
1401
+ async createOrder(request) {
1402
+ return this.client.post("/v3/combine-transactions/app", request);
1403
+ }
1404
+ /**
1405
+ * 查询合单订单
1406
+ *
1407
+ * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
1408
+ * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。
1409
+ *
1410
+ * 订单状态(sub_orders[].trade_state):
1411
+ * - SUCCESS:支付成功(终态)
1412
+ * - NOTPAY:未支付
1413
+ * - CLOSED:已关闭(终态)
1414
+ *
1415
+ * 典型使用场景:
1416
+ * - 用户支付后从微信收银台返回商户 APP 时,OpenSDK 回调 onResp 后确认订单支付状态
1417
+ * - 未收到支付成功回调通知时,主动查询确认订单状态
1418
+ * - 关单前确认订单仍为未支付状态
1419
+ *
1420
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557006
1421
+ */
1422
+ async queryOrderById(params) {
1423
+ return this.client.get(
1424
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
1425
+ );
1426
+ }
1427
+ /**
1428
+ * 关闭合单订单
1429
+ *
1430
+ * 对于未支付的合单订单,商户可通过此接口关闭订单。
1431
+ * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1432
+ *
1433
+ * 关键约束:
1434
+ * - 只能整单关闭,不支持关闭部分子单
1435
+ * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致
1436
+ * - 仅支持未支付状态的订单
1437
+ * - 关单后订单为失败终态
1438
+ *
1439
+ * 典型使用场景:
1440
+ * - 用户超过商户系统内部规定的支付时间
1441
+ * - 超过下单时设置的 time_expire 时间
1442
+ * - 因特殊原因需在可支付时间范围内关闭订单
1443
+ *
1444
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012577452
1445
+ */
1446
+ async closeOrder(params, request) {
1447
+ return this.client.post(
1448
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1449
+ request
1450
+ );
1451
+ }
1452
+ /**
1453
+ * 申请退款(基于子单)
1454
+ *
1455
+ * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,
1456
+ * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。
1457
+ *
1458
+ * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1459
+ * 仅支持支付成功后 1 年内的订单。
1460
+ *
1461
+ * 注意:
1462
+ * - 一笔订单最多支持 50 次部分退款,间隔至少 1 分钟
1463
+ * - 重试时必须使用原商户退款单号,避免重复退款
1464
+ * - 接口返回成功仅表示受理成功,最终结果以回调通知和查询接口为准
1465
+ *
1466
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556524
1467
+ */
1468
+ async createRefund(request) {
1469
+ return this.client.post("/v3/refund/domestic/refunds", request);
1470
+ }
1471
+ /**
1472
+ * 查询退款单
1473
+ *
1474
+ * 通过商户退款单号查询退款状态。
1475
+ * 退款申请成功后,可通过此接口确认退款是否到账。
1476
+ *
1477
+ * 退款状态:
1478
+ * - SUCCESS:退款成功
1479
+ * - CLOSED:退款关闭
1480
+ * - PROCESSING:退款处理中
1481
+ * - ABNORMAL:退款异常
1482
+ *
1483
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556587
1484
+ */
1485
+ async queryRefund(params) {
1486
+ return this.client.get(
1487
+ `/v3/refund/domestic/refunds/${params.outRefundNo}`
1488
+ );
1489
+ }
1490
+ /**
1491
+ * 申请异常退款
1492
+ *
1493
+ * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1494
+ * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1495
+ *
1496
+ * @param refundId - 微信支付退款单号
1497
+ * @param request - 异常退款请求参数
1498
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013420988
1499
+ */
1500
+ async applyAbnormalRefund(refundId, request) {
1501
+ return this.client.post(
1502
+ `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1503
+ request
1504
+ );
1505
+ }
1506
+ /**
1507
+ * 申请交易账单
1508
+ *
1509
+ * 合单支付的订单账单是以子单为维度,每笔子单都会记录在各个子单商户账单内,
1510
+ * 需要各个子单商户自己进行下载。
1511
+ *
1512
+ * 商户可通过此接口获取交易账单的下载链接,下载地址 5 分钟内有效。
1513
+ *
1514
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556692
1515
+ */
1516
+ async tradeBill(params) {
1517
+ return this.client.get("/v3/bill/tradebill", params);
1518
+ }
1519
+ /**
1520
+ * 申请资金账单
1521
+ *
1522
+ * 商户可通过此接口获取资金账单的下载链接,下载地址 5 分钟内有效。
1523
+ *
1524
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556748
1525
+ */
1526
+ async fundFlowBill(params) {
1527
+ return this.client.get("/v3/bill/fundflowbill", params);
1528
+ }
1529
+ /**
1530
+ * 下载账单
1531
+ *
1532
+ * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1533
+ * 下载地址 5 分钟内有效,请及时下载。
1534
+ * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
1535
+ *
1536
+ * @param downloadUrl - 申请账单返回的 download_url
1537
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012085923
1538
+ */
1539
+ async downloadBill(downloadUrl) {
1540
+ return this.client.downloadRaw(downloadUrl);
1541
+ }
1542
+ };
1543
+
1544
+ // src/services/combine-miniprogram.ts
1545
+ var CombineMiniProgramService = class {
1546
+ client;
1547
+ constructor(client) {
1548
+ this.client = client;
1549
+ }
1550
+ /**
1551
+ * 小程序合单下单
1552
+ *
1553
+ * 商户通过此接口生成小程序合单预付单并获取 prepay_id。
1554
+ * 获取 prepay_id 后,配合 buildMiniProgramBridgeConfig 生成调起支付参数,
1555
+ * 通过小程序 wx.requestPayment() 方法唤起微信支付收银台。
1556
+ *
1557
+ * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。
1558
+ *
1559
+ * 关键约束:
1560
+ * - combine_mchid 需先申请发起合单支付权限
1561
+ * - sub_orders 中的 mchid 需先申请接收合单支付权限
1562
+ * - 合单发起方和子单参与方需绑定同一个 combine_appid
1563
+ * - combine_appid 必须为小程序 AppID
1564
+ * - combine_payer_info.openid 在小程序场景下可选(由运行环境隐式提供)
1565
+ * - 子单数量为 2-10 笔
1566
+ * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天
1567
+ *
1568
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556931
1569
+ */
1570
+ async createOrder(request) {
1571
+ return this.client.post(
1572
+ "/v3/combine-transactions/jsapi",
1573
+ request
1574
+ );
1575
+ }
1576
+ /**
1577
+ * 查询合单订单
1578
+ *
1579
+ * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
1580
+ * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。
1581
+ *
1582
+ * 订单状态(sub_orders[].trade_state):
1583
+ * - SUCCESS:支付成功(终态)
1584
+ * - NOTPAY:未支付
1585
+ * - CLOSED:已关闭(终态)
1586
+ *
1587
+ * 典型使用场景:
1588
+ * - 用户支付后从收银台返回小程序页面时,requestPayment 回调后确认订单支付状态
1589
+ * - 未收到支付成功回调通知时,主动查询确认订单状态
1590
+ * - 关单前确认订单仍为未支付状态
1591
+ *
1592
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421401
1593
+ */
1594
+ async queryOrderById(params) {
1595
+ return this.client.get(
1596
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
1597
+ );
1598
+ }
1599
+ /**
1600
+ * 关闭合单订单
1601
+ *
1602
+ * 对于未支付的合单订单,商户可通过此接口关闭订单。
1603
+ * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1604
+ *
1605
+ * 关键约束:
1606
+ * - 只能整单关闭,不支持关闭部分子单
1607
+ * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致
1608
+ * - 仅支持未支付状态的订单
1609
+ * - 关单后订单为失败终态
1610
+ *
1611
+ * 典型使用场景:
1612
+ * - 用户超过商户系统内部规定的支付时间
1613
+ * - 超过下单时设置的 time_expire 时间
1614
+ * - 因特殊原因需在可支付时间范围内关闭订单
1615
+ *
1616
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421404
1617
+ */
1618
+ async closeOrder(params, request) {
1619
+ return this.client.post(
1620
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1621
+ request
1622
+ );
1623
+ }
1624
+ /**
1625
+ * 申请退款(基于子单)
1626
+ *
1627
+ * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,
1628
+ * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。
1629
+ *
1630
+ * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1631
+ * 仅支持支付成功后 1 年内的订单。
1632
+ *
1633
+ * 注意:
1634
+ * - 一笔订单最多支持 50 次部分退款,间隔至少 1 分钟
1635
+ * - 重试时必须使用原商户退款单号,避免重复退款
1636
+ * - 接口返回成功仅表示受理成功,最终结果以回调通知和查询接口为准
1637
+ *
1638
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421410
1639
+ */
1640
+ async createRefund(request) {
1641
+ return this.client.post("/v3/refund/domestic/refunds", request);
1642
+ }
1643
+ /**
1644
+ * 查询退款单
1645
+ *
1646
+ * 通过商户退款单号查询退款状态。
1647
+ * 退款申请成功后,可通过此接口确认退款是否到账。
1648
+ *
1649
+ * 退款状态:
1650
+ * - SUCCESS:退款成功
1651
+ * - CLOSED:退款关闭
1652
+ * - PROCESSING:退款处理中
1653
+ * - ABNORMAL:退款异常
1654
+ *
1655
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421421
1656
+ */
1657
+ async queryRefund(params) {
1658
+ return this.client.get(
1659
+ `/v3/refund/domestic/refunds/${params.outRefundNo}`
1660
+ );
1661
+ }
1662
+ /**
1663
+ * 申请异常退款
1664
+ *
1665
+ * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1666
+ * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1667
+ *
1668
+ * @param refundId - 微信支付退款单号
1669
+ * @param request - 异常退款请求参数
1670
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421429
1671
+ */
1672
+ async applyAbnormalRefund(refundId, request) {
1673
+ return this.client.post(
1674
+ `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1675
+ request
1676
+ );
1677
+ }
1678
+ /**
1679
+ * 申请交易账单
1680
+ *
1681
+ * 合单支付的订单账单是以子单为维度,每笔子单都会记录在各个子单商户账单内,
1682
+ * 需要各个子单商户自己进行下载。
1683
+ *
1684
+ * 商户可通过此接口获取交易账单的下载链接,下载地址 5 分钟内有效。
1685
+ *
1686
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421450
1687
+ */
1688
+ async tradeBill(params) {
1689
+ return this.client.get("/v3/bill/tradebill", params);
1690
+ }
1691
+ /**
1692
+ * 申请资金账单
1693
+ *
1694
+ * 商户可通过此接口获取资金账单的下载链接,下载地址 5 分钟内有效。
1695
+ *
1696
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421456
1697
+ */
1698
+ async fundFlowBill(params) {
1699
+ return this.client.get("/v3/bill/fundflowbill", params);
1700
+ }
1701
+ /**
1702
+ * 下载账单
1703
+ *
1704
+ * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1705
+ * 下载地址 5 分钟内有效,请及时下载。
1706
+ * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
1707
+ *
1708
+ * @param downloadUrl - 申请账单返回的 download_url
1709
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421461
1710
+ */
1711
+ async downloadBill(downloadUrl) {
1712
+ return this.client.downloadRaw(downloadUrl);
1713
+ }
1714
+ };
1715
+
1716
+ // src/services/combine-native.ts
1717
+ var CombineNativeService = class {
1718
+ client;
1719
+ constructor(client) {
1720
+ this.client = client;
1721
+ }
1722
+ /**
1723
+ * Native 合单下单
1724
+ *
1725
+ * 商户通过此接口生成合单订单并获取二维码链接(code_url)。
1726
+ * 商户后端获取 code_url 后传递给前端,前端将其转换为二维码图片展示给用户。
1727
+ * 用户使用微信扫一扫扫描二维码后,将调起微信收银台完成支付。
1728
+ *
1729
+ * code_url 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求下单接口,
1730
+ * 获取新的 code_url。
1731
+ *
1732
+ * 关键约束:
1733
+ * - combine_mchid 需先申请发起合单支付权限
1734
+ * - sub_orders 中的 mchid 需先申请接收合单支付权限
1735
+ * - 合单发起方和子单参与方需绑定同一个 combine_appid
1736
+ * - 子单数量为 2-10 笔
1737
+ * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天
1738
+ * - 二维码不支持通过相册识别或长按识别二维码的方式完成支付
1739
+ *
1740
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556982
1741
+ */
1742
+ async createOrder(request) {
1743
+ return this.client.post(
1744
+ "/v3/combine-transactions/native",
1745
+ request
1746
+ );
1747
+ }
1748
+ /**
1749
+ * 查询合单订单
1750
+ *
1751
+ * 通过合单商户订单号查询合单订单的支付状态及各子单详情。
1752
+ * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。
1753
+ *
1754
+ * 订单状态(sub_orders[].trade_state):
1755
+ * - SUCCESS:支付成功(终态)
1756
+ * - NOTPAY:未支付
1757
+ * - CLOSED:已关闭(终态)
1758
+ *
1759
+ * 典型使用场景:
1760
+ * - 用户扫码支付后,轮询确认订单支付状态
1761
+ * - 未收到支付成功回调通知时,主动查询确认订单状态
1762
+ * - 关单前确认订单仍为未支付状态
1763
+ *
1764
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421316
1765
+ */
1766
+ async queryOrderById(params) {
1767
+ return this.client.get(
1768
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`
1769
+ );
1770
+ }
1771
+ /**
1772
+ * 关闭合单订单
1773
+ *
1774
+ * 对于未支付的合单订单,商户可通过此接口关闭订单。
1775
+ * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。
1776
+ *
1777
+ * 关键约束:
1778
+ * - 只能整单关闭,不支持关闭部分子单
1779
+ * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致
1780
+ * - 仅支持未支付状态的订单
1781
+ * - 关单后订单为失败终态
1782
+ *
1783
+ * 典型使用场景:
1784
+ * - 用户超过商户系统内部规定的支付时间
1785
+ * - 超过下单时设置的 time_expire 时间
1786
+ * - 因特殊原因需在可支付时间范围内关闭订单
1787
+ *
1788
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421330
1789
+ */
1790
+ async closeOrder(params, request) {
1791
+ return this.client.post(
1792
+ `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,
1793
+ request
1794
+ );
1795
+ }
1796
+ /**
1797
+ * 申请退款(基于子单)
1798
+ *
1799
+ * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,
1800
+ * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。
1801
+ *
1802
+ * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。
1803
+ * 仅支持支付成功后 1 年内的订单。
1804
+ *
1805
+ * 注意:
1806
+ * - 一笔订单最多支持 50 次部分退款,间隔至少 1 分钟
1807
+ * - 重试时必须使用原商户退款单号,避免重复退款
1808
+ * - 接口返回成功仅表示受理成功,最终结果以回调通知和查询接口为准
1809
+ *
1810
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421340
1811
+ */
1812
+ async createRefund(request) {
1813
+ return this.client.post("/v3/refund/domestic/refunds", request);
1814
+ }
1815
+ /**
1816
+ * 查询退款单
1817
+ *
1818
+ * 通过商户退款单号查询退款状态。
1819
+ * 退款申请成功后,可通过此接口确认退款是否到账。
1820
+ *
1821
+ * 退款状态:
1822
+ * - SUCCESS:退款成功
1823
+ * - CLOSED:退款关闭
1824
+ * - PROCESSING:退款处理中
1825
+ * - ABNORMAL:退款异常
1826
+ *
1827
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421346
1828
+ */
1829
+ async queryRefund(params) {
1830
+ return this.client.get(
1831
+ `/v3/refund/domestic/refunds/${params.outRefundNo}`
1832
+ );
1833
+ }
1834
+ /**
1835
+ * 申请异常退款
1836
+ *
1837
+ * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。
1838
+ * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。
1839
+ *
1840
+ * @param refundId - 微信支付退款单号
1841
+ * @param request - 异常退款请求参数
1842
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421352
1843
+ */
1844
+ async applyAbnormalRefund(refundId, request) {
1845
+ return this.client.post(
1846
+ `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,
1847
+ request
1848
+ );
1849
+ }
1850
+ /**
1851
+ * 申请交易账单
1852
+ *
1853
+ * 合单支付的订单账单是以子单为维度,每笔子单都会记录在各个子单商户账单内,
1854
+ * 需要各个子单商户自己进行下载。
1855
+ *
1856
+ * 商户可通过此接口获取交易账单的下载链接,下载地址 5 分钟内有效。
1857
+ *
1858
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421361
1859
+ */
1860
+ async tradeBill(params) {
1861
+ return this.client.get("/v3/bill/tradebill", params);
1862
+ }
1863
+ /**
1864
+ * 申请资金账单
1865
+ *
1866
+ * 商户可通过此接口获取资金账单的下载链接,下载地址 5 分钟内有效。
1867
+ *
1868
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421365
1869
+ */
1870
+ async fundFlowBill(params) {
1871
+ return this.client.get("/v3/bill/fundflowbill", params);
1872
+ }
1873
+ /**
1874
+ * 下载账单
1875
+ *
1876
+ * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。
1877
+ * 下载地址 5 分钟内有效,请及时下载。
1878
+ * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
1879
+ *
1880
+ * @param downloadUrl - 申请账单返回的 download_url
1881
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421368
1882
+ */
1883
+ async downloadBill(downloadUrl) {
1884
+ return this.client.downloadRaw(downloadUrl);
1885
+ }
1886
+ };
1887
+
1888
+ // src/services/profitsharing.ts
1889
+ var ProfitSharingService = class {
1890
+ client;
1891
+ constructor(client) {
1892
+ this.client = client;
1893
+ }
1894
+ /**
1895
+ * 请求分账
1896
+ *
1897
+ * 微信订单支付成功后,商户通过此接口发起分账请求,将订单资金分给指定的接收方。
1898
+ * 此接口采用异步处理模式,受理请求后返回的结果非最终分账结果,
1899
+ * 最终分账结果需要通过查询分账结果接口获取。
1900
+ *
1901
+ * 单笔订单最多支持 50 次分账请求,每次请求最多支持 50 个接收方。
1902
+ *
1903
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012524936
1904
+ */
1905
+ async createOrder(request) {
1906
+ return this.client.post("/v3/profitsharing/orders", request);
1907
+ }
1908
+ /**
1909
+ * 查询分账结果
1910
+ *
1911
+ * 通过商户分账单号查询分账结果。
1912
+ * 发起分账请求后,可通过此接口主动查询分账的最终处理结果。
1913
+ *
1914
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012525210
1915
+ */
1916
+ async queryOrder(params) {
1917
+ return this.client.get(
1918
+ `/v3/profitsharing/orders/${params.outOrderNo}`,
1919
+ { transaction_id: params.transactionId }
1920
+ );
1921
+ }
1922
+ /**
1923
+ * 请求分账回退
1924
+ *
1925
+ * 对已经分账成功的订单,商户可以通过此接口将分账资金从接收方回退给分账方。
1926
+ * 此接口采用同步处理模式,会实时返回处理结果。
1927
+ *
1928
+ * 注意:
1929
+ * - 单笔分账单最多支持 50 次回退
1930
+ * - 回退窗口期为 180 天
1931
+ * - 仅支持对 MERCHANT_ID 类型且分账结果为 SUCCESS 的接收方进行回退
1932
+ * - 不支持对个人接收方的回退
1933
+ *
1934
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012525287
1935
+ */
1936
+ async createReturnOrder(request) {
1937
+ return this.client.post(
1938
+ "/v3/profitsharing/return-orders",
1939
+ request
1940
+ );
1941
+ }
1942
+ /**
1943
+ * 查询分账回退结果
1944
+ *
1945
+ * 通过商户回退单号查询分账回退的处理结果。
1946
+ * 如果回退结果为 PROCESSING,请不要更换商户回退单号重复发起回退,
1947
+ * 否则会出现资金风险。
1948
+ *
1949
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012526279
1950
+ */
1951
+ async queryReturnOrder(params) {
1952
+ return this.client.get(
1953
+ `/v3/profitsharing/return-orders/${params.outReturnNo}`,
1954
+ { out_order_no: params.outOrderNo }
1955
+ );
1956
+ }
1957
+ /**
1958
+ * 解冻剩余资金
1959
+ *
1960
+ * 将订单的金额全部解冻给本商户。
1961
+ * 适用于无需分账或分账完成后需将剩余冻结资金解冻给商户的场景。
1962
+ * 此接口采用异步处理模式。
1963
+ *
1964
+ * 注意:
1965
+ * - 当分账已完成(金额全部分完)时,无需再请求此接口
1966
+ * - 同一分账单号多次请求视为同一请求(幂等)
1967
+ *
1968
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012526374
1969
+ */
1970
+ async unfreeze(request) {
1971
+ return this.client.post(
1972
+ "/v3/profitsharing/orders/unfreeze",
1973
+ request
1974
+ );
1975
+ }
1976
+ /**
1977
+ * 查询剩余待分金额
1978
+ *
1979
+ * 通过微信支付订单号查询该订单的剩余未分账金额。
1980
+ * 可用于判断是否可以继续分账以及剩余可分金额。
1981
+ *
1982
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012457939
1983
+ */
1984
+ async queryAmount(transactionId) {
1985
+ return this.client.get(
1986
+ `/v3/profitsharing/transactions/${transactionId}/amounts`
1987
+ );
1988
+ }
1989
+ /**
1990
+ * 添加分账接收方
1991
+ *
1992
+ * 商户在发起分账前,需要先通过此接口添加分账接收方。
1993
+ * 每个商户号最多添加 2 万个分账接收方。
1994
+ * 接收方全称(name 字段)需使用微信支付公钥进行 RSAES-OAEP 加密。
1995
+ *
1996
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012528995
1997
+ */
1998
+ async addReceiver(request) {
1999
+ return this.client.post(
2000
+ "/v3/profitsharing/receivers/add",
2001
+ request
2002
+ );
2003
+ }
2004
+ /**
2005
+ * 删除分账接收方
2006
+ *
2007
+ * 商户可以通过此接口删除已添加的分账接收方。
2008
+ * 删除后,该接收方将无法参与新的分账。
2009
+ *
2010
+ * 注意:
2011
+ * - 删除接口有频率限制,请勿频繁调用
2012
+ * - 已参与分账的接收方仍可被删除,但不会影响已完成的交易
2013
+ *
2014
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012529590
2015
+ */
2016
+ async deleteReceiver(request) {
2017
+ return this.client.post(
2018
+ "/v3/profitsharing/receivers/delete",
2019
+ request
2020
+ );
2021
+ }
2022
+ /**
2023
+ * 申请分账账单
2024
+ *
2025
+ * 商户可通过此接口获取分账账单的下载链接。
2026
+ * 仅支持最近三个月的账单。
2027
+ *
2028
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012529628
2029
+ */
2030
+ async bill(params) {
2031
+ return this.client.get("/v3/profitsharing/bills", params);
2032
+ }
2033
+ /**
2034
+ * 下载分账账单
2035
+ *
2036
+ * 通过申请分账账单接口返回的 download_url,以 GET 方式下载账单原始文件。
2037
+ * 下载地址 30 秒内有效,请及时下载。
2038
+ * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。
2039
+ *
2040
+ * @param downloadUrl - 申请分账账单返回的 download_url
2041
+ */
2042
+ async downloadBill(downloadUrl) {
2043
+ return this.client.downloadRaw(downloadUrl);
2044
+ }
2045
+ };
2046
+
2047
+ // src/services/payscore.ts
2048
+ var PayScoreService = class {
2049
+ client;
2050
+ constructor(client) {
2051
+ this.client = client;
2052
+ }
2053
+ /**
2054
+ * 创建支付分订单
2055
+ *
2056
+ * 当用户申请使用服务时,商户需调用此接口创建支付分订单。
2057
+ * 创单成功后订单状态 state 为 CREATED(已创建),返回的 package
2058
+ * 参数用于拉起支付分小程序确认订单页面。
2059
+ *
2060
+ * - 需确认模式下,need_user_confirm 必须固定传 true
2061
+ * - risk_fund.name:先免模式可选 DEPOSIT/ADVANCE/CASH_DEPOSIT,先享模式固定 ESTIMATE_ORDER_COST
2062
+ * - risk_fund.amount 不可超过服务ID风险金额上限
2063
+ * - 该接口支持原参重入,相同参数重复调用可以返回成功
2064
+ *
2065
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587900
2066
+ */
2067
+ async createOrder(request) {
2068
+ return this.client.post("/v3/payscore/serviceorder", request);
2069
+ }
2070
+ /**
2071
+ * 查询支付分订单
2072
+ *
2073
+ * 通过商户服务订单号或回跳查询ID查询支付分订单状态和详情。
2074
+ * out_order_no 和 query_id 必须提供其中一个,不可同时提供。
2075
+ *
2076
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587902
2077
+ */
2078
+ async queryOrder(params) {
2079
+ const queryParams = {
2080
+ service_id: params.service_id,
2081
+ appid: params.appid
2082
+ };
2083
+ if (params.out_order_no) {
2084
+ queryParams["out_order_no"] = params.out_order_no;
2085
+ }
2086
+ if (params.query_id) {
2087
+ queryParams["query_id"] = params.query_id;
2088
+ }
2089
+ return this.client.get("/v3/payscore/serviceorder", queryParams);
2090
+ }
2091
+ /**
2092
+ * 取消支付分订单
2093
+ *
2094
+ * 取消已创建、用户已确认或待支付状态的支付分订单。
2095
+ * 可在订单状态为 CREATED、USER_CONFIRM(用户已确认)和 USER_PAYING(待支付)时调用。
2096
+ *
2097
+ * - 若因网络原因未获取到接口返回内容,可使用相同参数重试,该接口支持原参重入
2098
+ * - 待支付订单若用户正主动支付或系统正自动扣款时调用,可能报错,建议等待 3 分钟后重试
2099
+ *
2100
+ * @param outOrderNo - 商户服务订单号
2101
+ * @param request - 取消订单请求参数
2102
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587905
2103
+ */
2104
+ async cancelOrder(outOrderNo, request) {
2105
+ return this.client.post(
2106
+ `/v3/payscore/serviceorder/${outOrderNo}/cancel`,
2107
+ request
2108
+ );
2109
+ }
2110
+ /**
2111
+ * 完结支付分订单
2112
+ *
2113
+ * 服务完成后,商户需调用此接口通知微信支付服务已结束。
2114
+ * 订单完结后,支付分会持续自动扣款,无需重复调用完结接口。
2115
+ *
2116
+ * - total_amount = 后付费项目金额总和 - 优惠项目金额总和
2117
+ * - 先免模式:订单收款总金额 ≤ 创单传的服务风险金额 ≤ 服务ID风险金额上限
2118
+ * - 先享模式:订单收款总金额 ≤ 服务ID风险金额上限
2119
+ * - 调用完结接口后 collection.state 变为 USER_PAYING(待支付状态)
2120
+ *
2121
+ * @param outOrderNo - 商户服务订单号
2122
+ * @param request - 完结订单请求参数
2123
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587955
2124
+ */
2125
+ async completeOrder(outOrderNo, request) {
2126
+ return this.client.post(
2127
+ `/v3/payscore/serviceorder/${outOrderNo}/complete`,
2128
+ request
2129
+ );
2130
+ }
2131
+ /**
2132
+ * 修改订单金额
2133
+ *
2134
+ * 当订单处于 USER_PAYING(待支付)状态时,商户可调用此接口下调收款金额。
2135
+ * 修改成功后微信侧将按新金额发起扣款。
2136
+ *
2137
+ * - 只能下调扣款金额,不能上调
2138
+ * - total_amount = post_payments.amount 总和 - post_discounts.amount 总和
2139
+ *
2140
+ * @param outOrderNo - 商户服务订单号
2141
+ * @param request - 修改订单金额请求参数
2142
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587957
2143
+ */
2144
+ async modifyOrder(outOrderNo, request) {
2145
+ return this.client.post(
2146
+ `/v3/payscore/serviceorder/${outOrderNo}/modify`,
2147
+ request
2148
+ );
2149
+ }
2150
+ /**
2151
+ * 同步订单状态
2152
+ *
2153
+ * 当支付分订单处于 USER_PAYING(待支付)状态,用户通过其他渠道支付后,
2154
+ * 商户可调用此接口将订单改为已完成状态,微信支付将不再发起扣款。
2155
+ *
2156
+ * - type 固定传 Order_Paid
2157
+ * - paid_time 需满足:完结接口时间 < paid_time ≤ 同步接口时间 + 60 秒
2158
+ * - 若用户正在通过支付分收银台支付或自动扣款中,调用可能报错,可等 3 分钟后重试
2159
+ *
2160
+ * @param outOrderNo - 商户服务订单号
2161
+ * @param request - 同步订单状态请求参数
2162
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587962
2163
+ */
2164
+ async syncOrder(outOrderNo, request) {
2165
+ return this.client.post(
2166
+ `/v3/payscore/serviceorder/${outOrderNo}/sync`,
2167
+ request
2168
+ );
2169
+ }
2170
+ /**
2171
+ * 申请退款
2172
+ *
2173
+ * 支付分订单完结扣款后,如需退款可通过此接口发起。
2174
+ * transaction_id 来源于支付成功回调或查询支付分订单中的 collection.details。
2175
+ *
2176
+ * @param request - 退款请求参数
2177
+ * @returns 退款结果
2178
+ *
2179
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587971
2180
+ */
2181
+ async applyRefund(request) {
2182
+ return this.client.post("/v3/refund/domestic/refunds", request);
2183
+ }
2184
+ /**
2185
+ * 查询单笔退款
2186
+ *
2187
+ * 通过商户退款单号查询退款状态和详情。
2188
+ *
2189
+ * @param outRefundNo - 商户退款单号
2190
+ * @returns 退款详情
2191
+ *
2192
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587973
2193
+ */
2194
+ async queryRefund(outRefundNo) {
2195
+ return this.client.get(`/v3/refund/domestic/refunds/${outRefundNo}`);
2196
+ }
2197
+ };
2198
+
2199
+ // src/services/parking.ts
2200
+ var ParkingService = class {
2201
+ client;
2202
+ constructor(client) {
2203
+ this.client = client;
2204
+ }
2205
+ /**
2206
+ * 创建停车入场
2207
+ *
2208
+ * 用户入场时调用此接口创建停车入场信息。
2209
+ * 根据返回的车牌状态判断用户是否开通支付分停车服务:
2210
+ * - state 为 NORMAL:正常,可使用支付分停车服务
2211
+ * - state 为 BLOCKED:不可用,通过 block_reason 获取具体原因
2212
+ *
2213
+ * @param request - 创建停车入场请求参数
2214
+ * @returns 停车入场信息,包含入场ID和车牌状态
2215
+ *
2216
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533937
2217
+ */
2218
+ async createEntry(request) {
2219
+ return this.client.post("/v3/vehicle/parking/parkings", request);
2220
+ }
2221
+ /**
2222
+ * 查询车牌服务开通信息
2223
+ *
2224
+ * 查询用户是否开通微信支付分停车服务。
2225
+ * 用于在用户未收到入场状态变更通知时,主动确认车牌服务开通状态。
2226
+ *
2227
+ * @param params - 查询参数,包含appid、车牌号、用户openid和车牌颜色
2228
+ * @returns 车牌服务开通信息,包含开通状态和开通时间
2229
+ *
2230
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534043
2231
+ */
2232
+ async queryPlateService(params) {
2233
+ return this.client.get("/v3/vehicle/parking/services/find", {
2234
+ appid: params.appid,
2235
+ plate_number: params.plate_number,
2236
+ openid: params.openid,
2237
+ plate_color: params.plate_color
2238
+ });
2239
+ }
2240
+ /**
2241
+ * 扣费受理
2242
+ *
2243
+ * 用户离场时调用此接口完成订单受理,微信支付进行异步扣款。
2244
+ *
2245
+ * **重要**:必须确认接口返回的交易状态为 "ACCEPTED" 才能放行车辆。
2246
+ * 若未接收到该状态而放行车辆离场,造成的资金损失由商户侧自行承担。
2247
+ *
2248
+ * @param request - 扣费受理请求参数
2249
+ * @returns 扣费受理结果,包含交易状态
2250
+ *
2251
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534352
2252
+ */
2253
+ async createTransaction(request) {
2254
+ return this.client.post(
2255
+ "/v3/vehicle/transactions/parking",
2256
+ request
2257
+ );
2258
+ }
2259
+ /**
2260
+ * 查询停车订单
2261
+ *
2262
+ * 通过商户订单号查询停车扣费订单状态和详情。
2263
+ * 如果在所有通知频率后没有收到微信侧回调,商户应调用此接口确认订单状态。
2264
+ *
2265
+ * @param outTradeNo - 商户系统内部订单号
2266
+ * @returns 停车订单信息,包含交易状态和支付详情
2267
+ *
2268
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534308
2269
+ */
2270
+ async queryTransaction(outTradeNo) {
2271
+ return this.client.get(
2272
+ `/v3/vehicle/transactions/out-trade-no/${outTradeNo}`
2273
+ );
2274
+ }
2275
+ /**
2276
+ * 申请停车退款
2277
+ *
2278
+ * 交易时间超过一年的订单无法提交退款。
2279
+ * 微信支付退款支持单笔交易分多次退款(不超过50次),多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。
2280
+ * 申请退款总金额不能超过订单金额。
2281
+ * 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号。
2282
+ *
2283
+ * **注意**:申请退款接口的返回仅代表业务的受理情况,具体退款是否成功,需要通过查询退款接口获取结果。
2284
+ *
2285
+ * @param request - 申请退款请求参数
2286
+ * @returns 退款受理结果
2287
+ *
2288
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557131
2289
+ */
2290
+ async applyRefund(request) {
2291
+ return this.client.post("/v3/refund/domestic/refunds", request);
2292
+ }
2293
+ /**
2294
+ * 查询单笔退款
2295
+ *
2296
+ * 通过商户退款单号查询退款状态和详情。
2297
+ * 提交退款申请后,建议每分钟查询一次退款状态;超过5分钟仍为处理中时,逐步衰减查询频率。
2298
+ *
2299
+ * @param outRefundNo - 商户退款单号
2300
+ * @returns 退款详细信息
2301
+ *
2302
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557161
2303
+ */
2304
+ async queryRefund(outRefundNo) {
2305
+ return this.client.get(
2306
+ `/v3/refund/domestic/refunds/${outRefundNo}`
2307
+ );
2308
+ }
2309
+ };
2310
+
2311
+ // src/services/bill.ts
2312
+ var BillService = class {
2313
+ constructor(client) {
2314
+ this.client = client;
2315
+ }
2316
+ client;
2317
+ /**
2318
+ * 申请交易账单
2319
+ *
2320
+ * 商户调用该接口获取交易账单的下载链接。次日 10:00 后获取前一天账单,
2321
+ * 支持三个月内的账单查询。
2322
+ *
2323
+ * @param params - 账单请求参数
2324
+ * @returns 包含 hash_type、hash_value 和 download_url 的响应
2325
+ *
2326
+ * @example
2327
+ * ```ts
2328
+ * const result = await billService.applyTradeBill({
2329
+ * bill_date: '2024-01-15',
2330
+ * bill_type: 'ALL',
2331
+ * tar_type: 'GZIP',
2332
+ * });
2333
+ * console.log(result.data.download_url);
2334
+ * ```
2335
+ */
2336
+ async applyTradeBill(params) {
2337
+ return this.client.get("/v3/bill/tradebill", {
2338
+ bill_date: params.bill_date,
2339
+ bill_type: params.bill_type,
2340
+ tar_type: params.tar_type
2341
+ });
2342
+ }
2343
+ /**
2344
+ * 申请资金账单
2345
+ *
2346
+ * 商户调用该接口获取资金账单的下载链接。次日 10:00 后获取前一天账单,
2347
+ * 支持三个月内的账单查询。
2348
+ *
2349
+ * @param params - 账单请求参数
2350
+ * @returns 包含 hash_type、hash_value 和 download_url 的响应
2351
+ *
2352
+ * @example
2353
+ * ```ts
2354
+ * const result = await billService.applyFundFlowBill({
2355
+ * bill_date: '2024-01-15',
2356
+ * account_type: 'BASIC',
2357
+ * tar_type: 'GZIP',
2358
+ * });
2359
+ * console.log(result.data.download_url);
2360
+ * ```
2361
+ */
2362
+ async applyFundFlowBill(params) {
2363
+ return this.client.get("/v3/bill/fundflowbill", {
2364
+ bill_date: params.bill_date,
2365
+ account_type: params.account_type,
2366
+ tar_type: params.tar_type
2367
+ });
2368
+ }
2369
+ /**
2370
+ * 申请分账账单
2371
+ *
2372
+ * 商户调用该接口获取分账账单的下载链接。次日 10:00 后获取前一天账单,
2373
+ * 支持三个月内的账单查询。
2374
+ *
2375
+ * @param params - 账单请求参数
2376
+ * @returns 包含 hash_type、hash_value 和 download_url 的响应
2377
+ *
2378
+ * @example
2379
+ * ```ts
2380
+ * const result = await billService.applyProfitSharingBill({
2381
+ * bill_date: '2024-01-15',
2382
+ * tar_type: 'GZIP',
2383
+ * });
2384
+ * console.log(result.data.download_url);
2385
+ * ```
2386
+ */
2387
+ async applyProfitSharingBill(params) {
2388
+ return this.client.get("/v3/bill/profitsharingbill", {
2389
+ bill_date: params.bill_date,
2390
+ tar_type: params.tar_type
2391
+ });
2392
+ }
2393
+ /**
2394
+ * 下载账单文件
2395
+ *
2396
+ * 使用申请账单接口返回的 download_url 下载账单文件。
2397
+ * download_url 有效期为 5 分钟(分账账单为 30 秒),需及时下载。
2398
+ *
2399
+ * 下载完成后建议计算文件的 SHA1 哈希值,与申请账单接口返回的 hash_value
2400
+ * 进行比对,确保账单文件完整性。
2401
+ *
2402
+ * @param downloadUrl - 申请账单接口返回的 download_url
2403
+ * @returns 包含原始账单文件 Buffer 的响应
2404
+ *
2405
+ * @example
2406
+ * ```ts
2407
+ * // 先申请账单获取 download_url
2408
+ * const applyResult = await billService.applyTradeBill({
2409
+ * bill_date: '2024-01-15',
2410
+ * tar_type: 'GZIP',
2411
+ * });
2412
+ *
2413
+ * // 下载账单文件
2414
+ * const downloadResult = await billService.downloadBill(
2415
+ * applyResult.data.download_url,
2416
+ * );
2417
+ *
2418
+ * // 验证哈希值
2419
+ * const crypto = require('crypto');
2420
+ * const fileHash = crypto
2421
+ * .createHash('sha1')
2422
+ * .update(downloadResult.data)
2423
+ * .digest('hex');
2424
+ * console.log(fileHash === applyResult.data.hash_value); // true
2425
+ * ```
2426
+ */
2427
+ async downloadBill(downloadUrl) {
2428
+ return this.client.downloadRaw(downloadUrl);
2429
+ }
2430
+ };
2431
+ var CallbackHandler = class {
2432
+ apiV3Key;
2433
+ certificates;
2434
+ constructor(apiV3Key, certificates) {
2435
+ this.apiV3Key = apiV3Key;
2436
+ this.certificates = certificates;
2437
+ }
2438
+ /**
2439
+ * 验证回调通知签名
2440
+ *
2441
+ * 使用微信支付平台公钥验证回调通知的签名。
2442
+ *
2443
+ * @param headers - 回调请求头
2444
+ * @param body - 回调请求体(原始 JSON 字符串)
2445
+ * @returns 签名验证是否通过
2446
+ */
2447
+ verifySignature(headers, body) {
2448
+ const serialNo = headers["wechatpay-serial"];
2449
+ const publicKey = this.certificates.getPublicKey(serialNo);
2450
+ if (!publicKey) {
2451
+ 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`);
2452
+ }
2453
+ return verifySignature(
2454
+ body,
2455
+ headers["wechatpay-signature"],
2456
+ headers["wechatpay-timestamp"],
2457
+ headers["wechatpay-nonce"],
2458
+ publicKey
2459
+ );
2460
+ }
2461
+ /**
2462
+ * 解密回调通知中的业务数据
2463
+ *
2464
+ * 使用 AES-256-GCM 算法和 API V3 密钥解密 resource.ciphertext。
2465
+ *
2466
+ * @param notification - 回调通知 JSON 对象
2467
+ * @returns 解密后的业务数据
2468
+ * @throws 如果解密后的数据为空或格式无效
2469
+ */
2470
+ decryptNotification(notification) {
2471
+ const { resource } = notification;
2472
+ const plaintext = this.aesGcmDecrypt(
2473
+ resource.ciphertext,
2474
+ resource.associated_data,
2475
+ resource.nonce
2476
+ );
2477
+ let parsed;
2478
+ try {
2479
+ parsed = JSON.parse(plaintext);
2480
+ } catch (error) {
2481
+ throw new Error(
2482
+ `\u56DE\u8C03\u6570\u636E JSON \u89E3\u6790\u5931\u8D25: ${error instanceof Error ? error.message : "\u672A\u77E5\u9519\u8BEF"}`
2483
+ );
2484
+ }
2485
+ if (parsed === null || parsed === void 0 || typeof parsed !== "object") {
2486
+ throw new Error(`\u56DE\u8C03\u6570\u636E\u683C\u5F0F\u65E0\u6548: \u671F\u671B\u5BF9\u8C61\uFF0C\u5B9E\u9645\u4E3A ${typeof parsed}`);
2487
+ }
2488
+ const data = parsed;
2489
+ return {
2490
+ id: notification.id,
2491
+ create_time: notification.create_time,
2492
+ event_type: notification.event_type,
2493
+ resource_type: notification.resource_type,
2494
+ summary: notification.summary,
2495
+ data
2496
+ };
2497
+ }
2498
+ /**
2499
+ * 处理回调通知(验证签名 + 解密数据)
2500
+ *
2501
+ * @param headers - 回调请求头
2502
+ * @param body - 回调请求体(原始 JSON 字符串)
2503
+ * @returns 解密后的回调数据
2504
+ */
2505
+ process(headers, body) {
2506
+ const valid = this.verifySignature(headers, body);
2507
+ if (!valid) {
2508
+ throw new Error("\u56DE\u8C03\u901A\u77E5\u7B7E\u540D\u9A8C\u8BC1\u5931\u8D25");
2509
+ }
2510
+ const notification = JSON.parse(body);
2511
+ return this.decryptNotification(notification);
2512
+ }
2513
+ /**
2514
+ * 处理支付成功回调通知
2515
+ */
2516
+ processTransactionCallback(headers, body) {
2517
+ return this.process(headers, body);
2518
+ }
2519
+ /**
2520
+ * 处理退款回调通知
2521
+ */
2522
+ processRefundCallback(headers, body) {
2523
+ return this.process(headers, body);
2524
+ }
2525
+ /**
2526
+ * 处理分账动账回调通知
2527
+ *
2528
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012289679
2529
+ */
2530
+ processProfitSharingCallback(headers, body) {
2531
+ return this.process(headers, body);
2532
+ }
2533
+ /**
2534
+ * 处理支付分用户确认订单回调通知
2535
+ *
2536
+ * 用户确认支付分订单后,微信支付会向商户发送此回调通知。
2537
+ * event_type 为 PAYSCORE.USER_CONFIRM。
2538
+ *
2539
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587953
2540
+ */
2541
+ processPayScoreUserConfirmCallback(headers, body) {
2542
+ return this.process(headers, body);
2543
+ }
2544
+ /**
2545
+ * 处理支付分支付成功回调通知
2546
+ *
2547
+ * 支付分订单扣款成功后,微信支付会向商户发送此回调通知。
2548
+ * event_type 为 PAYSCORE.USER_PAID。
2549
+ *
2550
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587960
2551
+ */
2552
+ processPayScoreUserPaidCallback(headers, body) {
2553
+ return this.process(headers, body);
2554
+ }
2555
+ /**
2556
+ * 处理停车入场状态变更回调通知
2557
+ *
2558
+ * 场内车牌状态发生变化后,微信支付通过此回调通知商户。
2559
+ * 例如用户开通/暂停支付分停车服务、用户移除车牌等。
2560
+ *
2561
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284177
2562
+ */
2563
+ processParkingEntryStatusCallback(headers, body) {
2564
+ return this.process(headers, body);
2565
+ }
2566
+ /**
2567
+ * 处理停车订单支付结果回调通知
2568
+ *
2569
+ * 扣费受理后,微信支付异步扣款完成时会发送此回调通知。
2570
+ * event_type 为 TRANSACTION.SUCCESS(支付成功)、TRANSACTION.FAIL(支付失败)
2571
+ * 或 TRANSACTION.PAY_BACK(还款)。
2572
+ *
2573
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284311
2574
+ */
2575
+ processParkingTransactionCallback(headers, body) {
2576
+ return this.process(headers, body);
2577
+ }
2578
+ /**
2579
+ * 处理停车退款结果回调通知
2580
+ *
2581
+ * 退款完成后,微信支付会向商户发送此回调通知。
2582
+ * event_type 为 REFUND.SUCCESS(退款成功)、REFUND.ABNORMAL(退款异常)
2583
+ * 或 REFUND.CLOSED(退款关闭)。
2584
+ *
2585
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012083103
2586
+ */
2587
+ processParkingRefundCallback(headers, body) {
2588
+ return this.process(headers, body);
2589
+ }
2590
+ /**
2591
+ * 处理代金券核销事件回调通知
2592
+ *
2593
+ * 用户使用券后,微信会把相关核销券信息发送给商户。
2594
+ * event_type 为 COUPON.USE。
2595
+ *
2596
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285250
2597
+ */
2598
+ processCouponUseCallback(headers, body) {
2599
+ return this.process(headers, body);
2600
+ }
2601
+ /**
2602
+ * 处理合单支付成功回调通知
2603
+ *
2604
+ * 合单支付成功后,微信支付会向商户发送此回调通知。
2605
+ * event_type 为 TRANSACTION.SUCCESS。
2606
+ *
2607
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421231
2608
+ */
2609
+ processCombineTransactionCallback(headers, body) {
2610
+ return this.process(headers, body);
2611
+ }
2612
+ /**
2613
+ * 处理商家转账状态变更回调通知
2614
+ *
2615
+ * 转账单据状态变更后,微信支付会向商户发送此回调通知。
2616
+ * 包括转账成功、转账失败、已撤销等状态变更。
2617
+ *
2618
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012712115
2619
+ */
2620
+ processMerchantTransferCallback(headers, body) {
2621
+ return this.process(headers, body);
2622
+ }
2623
+ /**
2624
+ * 处理免确认收款授权变更回调通知
2625
+ *
2626
+ * 用户确认授权或解除授权后,微信支付会向商户发送此回调通知。
2627
+ * 包括授权生效(TAKING_EFFECT)和授权关闭(CLOSED)等状态变更。
2628
+ *
2629
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4014512908
2630
+ */
2631
+ processMerchantTransferAuthorizationCallback(headers, body) {
2632
+ return this.process(headers, body);
2633
+ }
2634
+ /**
2635
+ * 处理支付分退款结果回调通知
2636
+ *
2637
+ * 支付分订单退款完成后,微信支付会向商户发送此回调通知。
2638
+ * event_type 为 REFUND.SUCCESS(退款成功)、REFUND.ABNORMAL(退款异常)
2639
+ * 或 REFUND.CLOSED(退款关闭)。
2640
+ *
2641
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587976
2642
+ */
2643
+ processPayScoreRefundCallback(headers, body) {
2644
+ return this.process(headers, body);
2645
+ }
2646
+ /**
2647
+ * 处理消费者投诉通知回调
2648
+ *
2649
+ * 用户提交投诉、用户撤诉、用户确认投诉已处理完成时,
2650
+ * 微信支付会通过此回调通知商户。
2651
+ *
2652
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012289719
2653
+ */
2654
+ processComplaintCallback(headers, body) {
2655
+ return this.process(headers, body);
2656
+ }
2657
+ /**
2658
+ * 处理医保支付成功回调通知
2659
+ *
2660
+ * 医保自费混合订单支付成功后,微信支付会向商户发送此回调通知。
2661
+ * event_type 为 MED_INS.SUCCESS。
2662
+ *
2663
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781502
2664
+ */
2665
+ processMedInsSuccessCallback(headers, body) {
2666
+ return this.process(headers, body);
2667
+ }
2668
+ /**
2669
+ * 处理医保退款回调通知
2670
+ *
2671
+ * 医保订单退款完成后,微信支付会向商户发送此回调通知。
2672
+ * event_type 为 MED_INS.REFUND.SUCCESS、MED_INS.REFUND.ABNORMAL 或 MED_INS.REFUND.CLOSED。
2673
+ *
2674
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781502
2675
+ */
2676
+ processMedInsRefundCallback(headers, body) {
2677
+ return this.process(headers, body);
2678
+ }
2679
+ /**
2680
+ * 处理商圈会员积分服务授权结果回调通知
2681
+ *
2682
+ * 用户在小程序内授权/解除授权商圈积分服务后,微信支付会向商户发送此回调通知。
2683
+ * event_type 为 BUSINESS_CIRCLE.USER_AUTHORIZE 或 BUSINESS_CIRCLE.USER_DEAUTHORIZE。
2684
+ *
2685
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285836
2686
+ */
2687
+ processBusinessCircleAuthorizeCallback(headers, body) {
2688
+ return this.process(headers, body);
2689
+ }
2690
+ /**
2691
+ * 处理商圈会员场内支付结果回调通知
2692
+ *
2693
+ * 用户在商圈内支付成功后,微信支付会向商户发送此回调通知。
2694
+ * event_type 为 TRANSACTION.SUCCESS。
2695
+ *
2696
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285856
2697
+ */
2698
+ processBusinessCircleTransactionCallback(headers, body) {
2699
+ return this.process(headers, body);
2700
+ }
2701
+ /**
2702
+ * 处理商圈会员场内退款结果回调通知
2703
+ *
2704
+ * 商圈内交易退款完成后,微信支付会向商户发送此回调通知。
2705
+ * event_type 为 REFUND.SUCCESS、REFUND.ABNORMAL 或 REFUND.CLOSED。
2706
+ *
2707
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285869
2708
+ */
2709
+ processBusinessCircleRefundCallback(headers, body) {
2710
+ return this.process(headers, body);
2711
+ }
2712
+ /**
2713
+ * AES-256-GCM 解密
2714
+ *
2715
+ * @param ciphertext - Base64 编码的密文
2716
+ * @param associatedData - 附加数据(用于 AEAD 认证)
2717
+ * @param nonce - 随机串
2718
+ * @returns 解密后的明文字符串
2719
+ */
2720
+ aesGcmDecrypt(ciphertext, associatedData, nonce) {
2721
+ const key = Buffer.from(this.apiV3Key, "utf-8");
2722
+ const ciphertextBuffer = Buffer.from(ciphertext, "base64");
2723
+ const authTag = ciphertextBuffer.subarray(-16);
2724
+ const encryptedData = ciphertextBuffer.subarray(0, -16);
2725
+ const decipher = crypto4__default.default.createDecipheriv("aes-256-gcm", key, Buffer.from(nonce, "utf-8"));
2726
+ decipher.setAuthTag(authTag);
2727
+ decipher.setAAD(Buffer.from(associatedData, "utf-8"));
2728
+ const decrypted = Buffer.concat([decipher.update(encryptedData), decipher.final()]);
2729
+ return decrypted.toString("utf-8");
2730
+ }
2731
+ };
2732
+
2733
+ // src/services/merchant-transfer.ts
2734
+ var MerchantTransferService = class {
2735
+ client;
2736
+ constructor(client) {
2737
+ this.client = client;
2738
+ }
2739
+ // ============= 用户确认收款模式 =============
2740
+ /**
2741
+ * 发起转账
2742
+ *
2743
+ * 商户调用此接口发起转账申请,用户需确认收款。
2744
+ * 成功时返回 package_info 用于拉起用户确认收款页。
2745
+ *
2746
+ * 注意:
2747
+ * - 转账金额≥2000元时,user_name 必传
2748
+ * - 返回 ACCEPTED 时,需检查运营账户资金是否足够
2749
+ * - 遇到错误不要换单重试,需先查询原订单结果
2750
+ *
2751
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716434
2752
+ */
2753
+ async createTransfer(request) {
2754
+ return this.client.post(
2755
+ "/v3/fund-app/mch-transfer/transfer-bills",
2756
+ request
2757
+ );
2758
+ }
2759
+ /**
2760
+ * 商户单号查询转账单
2761
+ *
2762
+ * 通过商户单号查询转账单详情,仅支持查询最近30天内的转账单。
2763
+ *
2764
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716437
2765
+ */
2766
+ async queryTransferByOutBillNo(outBillNo) {
2767
+ return this.client.get(
2768
+ `/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/${outBillNo}`
2769
+ );
2770
+ }
2771
+ /**
2772
+ * 微信单号查询转账单
2773
+ *
2774
+ * 通过微信转账单号查询转账单详情,仅支持查询最近30天内的转账单。
2775
+ *
2776
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716457
2777
+ */
2778
+ async queryTransferByTransferBillNo(transferBillNo) {
2779
+ return this.client.get(
2780
+ `/v3/fund-app/mch-transfer/transfer-bills/transfer-bill-no/${transferBillNo}`
2781
+ );
2782
+ }
2783
+ /**
2784
+ * 撤销转账
2785
+ *
2786
+ * 在用户确认收款前,商户可通过此接口撤销转账。
2787
+ * 返回成功仅表示撤销请求已受理,系统会异步处理退款等操作,
2788
+ * 需以最终查询转账单返回的状态为准。
2789
+ *
2790
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716458
2791
+ */
2792
+ async cancelTransfer(outBillNo) {
2793
+ return this.client.post(
2794
+ `/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/${outBillNo}/cancel`
2795
+ );
2796
+ }
2797
+ // ============= 电子回单 =============
2798
+ /**
2799
+ * 商户单号申请电子回单
2800
+ *
2801
+ * 申请条件:
2802
+ * - 转账单据状态为 SUCCESS
2803
+ * - 传入了收款用户姓名
2804
+ * - 六个月内的转账单据
2805
+ *
2806
+ * 回单有效期为90天,过期需重新申请。
2807
+ *
2808
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716452
2809
+ */
2810
+ async applyElecSignByOutBillNo(request) {
2811
+ return this.client.post(
2812
+ "/v3/fund-app/mch-transfer/elecsign/out-bill-no",
2813
+ request
2814
+ );
2815
+ }
2816
+ /**
2817
+ * 商户单号查询电子回单
2818
+ *
2819
+ * 当申请单状态为 FINISHED 时,返回回单文件的下载地址和摘要信息。
2820
+ * 下载地址有效期为10分钟,过期后需重新调用此接口获取。
2821
+ *
2822
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716436
2823
+ */
2824
+ async queryElecSignByOutBillNo(outBillNo) {
2825
+ return this.client.get(
2826
+ `/v3/fund-app/mch-transfer/elecsign/out-bill-no/${outBillNo}`
2827
+ );
2828
+ }
2829
+ /**
2830
+ * 微信单号申请电子回单
2831
+ *
2832
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716456
2833
+ */
2834
+ async applyElecSignByTransferBillNo(request) {
2835
+ return this.client.post(
2836
+ "/v3/fund-app/mch-transfer/elecsign/transfer-bill-no",
2837
+ request
2838
+ );
2839
+ }
2840
+ /**
2841
+ * 微信单号查询电子回单
2842
+ *
2843
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716455
2844
+ */
2845
+ async queryElecSignByTransferBillNo(transferBillNo) {
2846
+ return this.client.get(
2847
+ `/v3/fund-app/mch-transfer/elecsign/transfer-bill-no/${transferBillNo}`
2848
+ );
2849
+ }
2850
+ // ============= 用户授权免确认模式 =============
2851
+ /**
2852
+ * 发起转账并完成免确认收款授权
2853
+ *
2854
+ * 在发起转账的同时申请免确认收款授权,用户确认收款时可同时完成授权。
2855
+ * 授权成功后,后续转账无需用户逐笔确认。
2856
+ *
2857
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4014399293
2858
+ */
2859
+ async createTransferWithAuthorization(request) {
2860
+ return this.client.post(
2861
+ "/v3/fund-app/mch-transfer/transfer-bills/pre-transfer-with-authorization",
2862
+ request
2863
+ );
2864
+ }
2865
+ /**
2866
+ * 发起免确认收款授权
2867
+ *
2868
+ * 直接申请免确认收款授权,不发起转账。
2869
+ * 用户需在24小时内完成授权,未确认记录保留30天。
2870
+ * 同一微信号在同商户下待确认+已授权状态的授权单最多5个。
2871
+ *
2872
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4015901167
2873
+ */
2874
+ async createAuthorization(request) {
2875
+ return this.client.post(
2876
+ "/v3/fund-app/mch-transfer/user-confirm-authorization",
2877
+ request
2878
+ );
2879
+ }
2880
+ /**
2881
+ * 商户单号查询授权结果
2882
+ *
2883
+ * @param outAuthorizationNo - 商户侧授权单号
2884
+ * @param options - 可选参数,is_display_authorization 控制是否返回 package_info
2885
+ *
2886
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4014399423
2887
+ */
2888
+ async queryAuthorizationByOutAuthorizationNo(outAuthorizationNo, options) {
2889
+ return this.client.get(
2890
+ `/v3/fund-app/mch-transfer/user-confirm-authorization/out-authorization-no/${outAuthorizationNo}`,
2891
+ options
2892
+ );
2893
+ }
2894
+ /**
2895
+ * 用户授权后转账
2896
+ *
2897
+ * 用户完成授权后,商户可直接发起转账,无需用户逐笔确认收款。
2898
+ * 需要提供 authorization_id 或 out_authorization_no(二选一)。
2899
+ *
2900
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4014399371
2901
+ */
2902
+ async createTransferAfterAuthorization(request) {
2903
+ return this.client.post(
2904
+ "/v3/fund-app/mch-transfer/transfer-bills/transfer",
2905
+ request
2906
+ );
2907
+ }
2908
+ /**
2909
+ * 解除免确认收款授权
2910
+ *
2911
+ * 商户可调用此接口帮助用户发起解除授权。
2912
+ * 用户也可通过微信支付入账消息的收款设置操作关闭授权。
2913
+ *
2914
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4015653811
2915
+ */
2916
+ async closeAuthorization(outAuthorizationNo) {
2917
+ return this.client.post(
2918
+ `/v3/fund-app/mch-transfer/user-confirm-authorization/out-authorization-no/${outAuthorizationNo}/close`
2919
+ );
2920
+ }
2921
+ // ============= 电子回单下载 =============
2922
+ /**
2923
+ * 下载电子回单
2924
+ *
2925
+ * 通过申请电子回单接口返回的 download_url,以 GET 方式下载回单原始文件。
2926
+ * 下载地址有效期为 10 分钟,过期后需重新调用查询接口获取。
2927
+ * 返回的 data 为 PDF 文件的 Buffer。
2928
+ *
2929
+ * @param downloadUrl - 查询电子回单返回的 download_url
2930
+ * @returns 电子回单文件 Buffer
2931
+ *
2932
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013866774
2933
+ */
2934
+ async downloadElecSign(downloadUrl) {
2935
+ return this.client.downloadRaw(downloadUrl);
2936
+ }
2937
+ };
2938
+
2939
+ // src/services/coupon.ts
2940
+ var CouponService = class {
2941
+ client;
2942
+ constructor(client) {
2943
+ this.client = client;
2944
+ }
2945
+ // ============= 批次管理 =============
2946
+ /**
2947
+ * 创建代金券批次
2948
+ *
2949
+ * 通过此接口可创建代金券批次,包括预充值和免充值两种类型。
2950
+ * 预充值代金券适用于第三方出资策划的活动,免充值适用于商户策划的活动。
2951
+ *
2952
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534633
2953
+ */
2954
+ async createStock(request) {
2955
+ return this.client.post(
2956
+ "/v3/marketing/favor/coupon-stocks",
2957
+ request
2958
+ );
2959
+ }
2960
+ /**
2961
+ * 激活代金券批次
2962
+ *
2963
+ * 制券成功后,通过调用激活接口激活代金券批次。
2964
+ * 如果是预充值代金券,激活时从商户账户余额中锁定本批次的营销资金。
2965
+ *
2966
+ * @param stockId - 微信为每个代金券批次分配的唯一ID
2967
+ * @param request - 请求参数
2968
+ *
2969
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460137
2970
+ */
2971
+ async activateStock(stockId, request) {
2972
+ return this.client.post(
2973
+ `/v3/marketing/favor/stocks/${stockId}/start`,
2974
+ request
2975
+ );
2976
+ }
2977
+ /**
2978
+ * 暂停代金券批次
2979
+ *
2980
+ * 通过此接口可暂停指定代金券批次。暂停后,该批次暂停发放,
2981
+ * 用户无法通过任何渠道再领取该批次的券。前提条件是批次处于激活状态。
2982
+ *
2983
+ * @param stockId - 微信为每个代金券批次分配的唯一ID
2984
+ * @param request - 请求参数
2985
+ *
2986
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460305
2987
+ */
2988
+ async pauseStock(stockId, request) {
2989
+ return this.client.post(
2990
+ `/v3/marketing/favor/stocks/${stockId}/pause`,
2991
+ request
2992
+ );
2993
+ }
2994
+ /**
2995
+ * 重启代金券批次
2996
+ *
2997
+ * 通过此接口可重启指定代金券批次。重启后,该批次可以再次发放。
2998
+ * 前提条件是批次处于暂停状态。
2999
+ *
3000
+ * @param stockId - 微信为每个代金券批次分配的唯一ID
3001
+ * @param request - 请求参数
3002
+ *
3003
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460411
3004
+ */
3005
+ async restartStock(stockId, request) {
3006
+ return this.client.post(
3007
+ `/v3/marketing/favor/stocks/${stockId}/restart`,
3008
+ request
3009
+ );
3010
+ }
3011
+ // ============= 发放 =============
3012
+ /**
3013
+ * 发放代金券
3014
+ *
3015
+ * 通过调用此接口可发放指定批次给指定用户,发券场景可以是小程序、H5、App等。
3016
+ * 批次状态必须为"运营中"。
3017
+ *
3018
+ * @param openid - 用户在appid下的唯一标识
3019
+ * @param request - 请求参数
3020
+ *
3021
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012463767
3022
+ */
3023
+ async sendCoupon(openid, request) {
3024
+ return this.client.post(
3025
+ `/v3/marketing/favor/users/${openid}/coupons`,
3026
+ request
3027
+ );
3028
+ }
3029
+ // ============= 查询 =============
3030
+ /**
3031
+ * 条件查询批次列表
3032
+ *
3033
+ * 通过此接口可查询多个批次的信息,包括批次的配置信息以及批次概况数据。
3034
+ *
3035
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460489
3036
+ */
3037
+ async queryStocks(params) {
3038
+ return this.client.get("/v3/marketing/favor/stocks", params);
3039
+ }
3040
+ /**
3041
+ * 查询批次详情
3042
+ *
3043
+ * 通过此接口可查询单个批次的信息,包括批次的配置信息以及批次概况数据。
3044
+ *
3045
+ * @param stockId - 微信为每个代金券批次分配的唯一ID
3046
+ * @param params - 查询参数,需包含 stock_creator_mchid
3047
+ *
3048
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460564
3049
+ */
3050
+ async queryStockDetail(stockId, params) {
3051
+ return this.client.get(`/v3/marketing/favor/stocks/${stockId}`, params);
3052
+ }
3053
+ /**
3054
+ * 查询代金券详情
3055
+ *
3056
+ * 通过此接口可查询代金券信息,包括代金券的基础信息、状态。
3057
+ * 如代金券已核销,会包括代金券核销的订单信息。
3058
+ *
3059
+ * @param openid - 用户在appid下的唯一标识
3060
+ * @param couponId - 微信为代金券唯一分配的ID
3061
+ * @param params - 查询参数,需包含 appid
3062
+ *
3063
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012486942
3064
+ */
3065
+ async queryCouponDetail(openid, couponId, params) {
3066
+ return this.client.get(
3067
+ `/v3/marketing/favor/users/${openid}/coupons/${couponId}`,
3068
+ params
3069
+ );
3070
+ }
3071
+ /**
3072
+ * 查询代金券可用商户
3073
+ *
3074
+ * 通过调用此接口可查询批次的可用商户号,判断券是否在某商户号可用,来决定是否展示。
3075
+ *
3076
+ * @param stockId - 微信为每个代金券批次分配的唯一ID
3077
+ * @param params - 查询参数
3078
+ *
3079
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012463358
3080
+ */
3081
+ async queryStockMerchants(stockId, params) {
3082
+ return this.client.get(
3083
+ `/v3/marketing/favor/stocks/${stockId}/merchants`,
3084
+ params
3085
+ );
3086
+ }
3087
+ /**
3088
+ * 查询代金券可用单品
3089
+ *
3090
+ * 通过此接口可查询批次的可用商品编码,判断券是否可用于某些商品,来决定是否展示。
3091
+ *
3092
+ * @param stockId - 微信为每个代金券批次分配的唯一ID
3093
+ * @param params - 查询参数
3094
+ *
3095
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012463442
3096
+ */
3097
+ async queryStockItems(stockId, params) {
3098
+ return this.client.get(
3099
+ `/v3/marketing/favor/stocks/${stockId}/items`,
3100
+ params
3101
+ );
3102
+ }
3103
+ /**
3104
+ * 根据商户号查用户的券
3105
+ *
3106
+ * 可通过该接口查询用户在某商户号可用的全部券,可用于商户的小程序/H5中,
3107
+ * 用户"我的代金券"或"提交订单页"展示优惠信息。
3108
+ *
3109
+ * 注意:无法查询到微信支付立减金(全平台通用券)。
3110
+ *
3111
+ * @param openid - 用户在商户appid下的唯一标识
3112
+ * @param params - 查询参数
3113
+ *
3114
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534690
3115
+ */
3116
+ async queryUserCoupons(openid, params) {
3117
+ return this.client.get(
3118
+ `/v3/marketing/favor/users/${openid}/coupons`,
3119
+ params
3120
+ );
3121
+ }
3122
+ // ============= 明细下载 =============
3123
+ /**
3124
+ * 下载批次核销明细
3125
+ *
3126
+ * 可获取到某批次的核销明细数据,包括订单号、单品信息、银行流水号等,用于对账/数据分析。
3127
+ * 需要活动结束后次日10点才可下载。下载链接30秒内有效。
3128
+ *
3129
+ * @param stockId - 代金券批次唯一ID
3130
+ *
3131
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012463585
3132
+ */
3133
+ async downloadUseFlow(stockId) {
3134
+ return this.client.get(
3135
+ `/v3/marketing/favor/stocks/${stockId}/use-flow`
3136
+ );
3137
+ }
3138
+ /**
3139
+ * 下载批次退款明细
3140
+ *
3141
+ * 可获取到某批次的退款明细数据,包括订单号、单品信息、银行流水号等,用于对账/数据分析。
3142
+ * 需要活动结束后次日10点才可下载。下载链接30秒内有效。
3143
+ *
3144
+ * @param stockId - 代金券批次唯一ID
3145
+ *
3146
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012463523
3147
+ */
3148
+ async downloadRefundFlow(stockId) {
3149
+ return this.client.get(
3150
+ `/v3/marketing/favor/stocks/${stockId}/refund-flow`
3151
+ );
3152
+ }
3153
+ // ============= 通知设置 =============
3154
+ /**
3155
+ * 设置代金券消息通知地址
3156
+ *
3157
+ * 用于设置接收营销事件通知的URL,可接收营销相关的事件通知,包括核销、发放、退款等。
3158
+ * 通知URL必须为HTTPS协议、可直接访问、不能携带参数。
3159
+ *
3160
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012464198
3161
+ */
3162
+ async setCallback(request) {
3163
+ return this.client.post("/v3/marketing/favor/callbacks", request);
3164
+ }
3165
+ /**
3166
+ * 查询代金券消息通知地址
3167
+ *
3168
+ * 查询已设置的代金券核销事件通知地址。
3169
+ *
3170
+ * @param mchid - 商户号
3171
+ * @returns 通知地址信息
3172
+ *
3173
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012464070
3174
+ */
3175
+ async queryCallback(mchid) {
3176
+ return this.client.get("/v3/marketing/favor/callbacks", { mchid });
3177
+ }
3178
+ };
3179
+
3180
+ // src/services/complaint.ts
3181
+ var ComplaintService = class {
3182
+ client;
3183
+ constructor(client) {
3184
+ this.client = client;
3185
+ }
3186
+ // ============= 主动查询投诉信息 =============
3187
+ /**
3188
+ * 查询投诉单列表
3189
+ *
3190
+ * 商户可通过此接口查询近期的用户投诉单列表。
3191
+ * 支持按投诉时间、投诉状态筛选,支持分页查询。
3192
+ *
3193
+ * @param params - 查询参数
3194
+ * @returns 投诉单列表及分页信息
3195
+ *
3196
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533431
3197
+ */
3198
+ async queryComplaints(params) {
3199
+ const queryParams = {
3200
+ begin_date: params.begin_date,
3201
+ end_date: params.end_date
3202
+ };
3203
+ if (params.complaint_state) {
3204
+ queryParams["complaint_state"] = params.complaint_state;
3205
+ }
3206
+ if (params.mchid) {
3207
+ queryParams["mchid"] = params.mchid;
3208
+ }
3209
+ if (params.offset !== void 0) {
3210
+ queryParams["offset"] = params.offset;
3211
+ }
3212
+ if (params.limit !== void 0) {
3213
+ queryParams["limit"] = params.limit;
3214
+ }
3215
+ return this.client.get(
3216
+ "/v3/merchant-service/complaints-v2",
3217
+ queryParams
3218
+ );
3219
+ }
3220
+ /**
3221
+ * 查询投诉单详情
3222
+ *
3223
+ * 通过投诉单号查询投诉单的详细信息,包括投诉人信息、
3224
+ * 投诉订单信息、投诉图片等。
3225
+ *
3226
+ * @param complaintId - 投诉单号
3227
+ * @returns 投诉单详细信息
3228
+ *
3229
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533436
3230
+ */
3231
+ async queryComplaint(complaintId) {
3232
+ return this.client.get(
3233
+ `/v3/merchant-service/complaints-v2/${complaintId}`
3234
+ );
3235
+ }
3236
+ /**
3237
+ * 查询投诉单协商历史
3238
+ *
3239
+ * 查询指定投诉单的协商历史记录,包括商户回复和用户反馈。
3240
+ *
3241
+ * @param complaintId - 投诉单号
3242
+ * @returns 协商历史记录列表
3243
+ *
3244
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533439
3245
+ */
3246
+ async queryNegotiationHistory(complaintId) {
3247
+ return this.client.get(
3248
+ `/v3/merchant-service/complaints-v2/${complaintId}/negotiation-historys`
3249
+ );
3250
+ }
3251
+ // ============= 商户处理用户投诉 =============
3252
+ /**
3253
+ * 回复用户
3254
+ *
3255
+ * 商户可通过此接口回复用户的投诉,回复内容会展示在协商历史中。
3256
+ *
3257
+ * @param request - 回复请求参数
3258
+ * @returns 空响应表示成功
3259
+ *
3260
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012467254
3261
+ */
3262
+ async replyComplaint(request) {
3263
+ const { complaint_id, ...body } = request;
3264
+ return this.client.post(`/v3/merchant-service/complaints-v2/${complaint_id}/replies`, body);
3265
+ }
3266
+ /**
3267
+ * 反馈处理完成
3268
+ *
3269
+ * 商户处理完投诉后,可通过此接口通知微信支付处理结果。
3270
+ * 调用成功后,投诉单状态变为 PROCESSED。
3271
+ *
3272
+ * @param request - 处理完成请求参数
3273
+ * @returns 空响应表示成功
3274
+ *
3275
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012467255
3276
+ */
3277
+ async completeComplaint(request) {
3278
+ const { complaint_id, ...body } = request;
3279
+ return this.client.post(`/v3/merchant-service/complaints-v2/${complaint_id}/complete`, body);
3280
+ }
3281
+ /**
3282
+ * 更新退款审批结果
3283
+ *
3284
+ * 当用户投诉涉及退款时,商户可通过此接口通知微信支付退款审批结果。
3285
+ * 退款审批通过后,微信支付会自动发起退款。
3286
+ *
3287
+ * @param request - 更新退款审批结果请求参数
3288
+ * @returns 空响应表示成功
3289
+ *
3290
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012467256
3291
+ */
3292
+ async updateRefundResult(request) {
3293
+ const { complaint_id, ...body } = request;
3294
+ return this.client.post(
3295
+ `/v3/merchant-service/complaints-v2/${complaint_id}/update-refund`,
3296
+ body
3297
+ );
3298
+ }
3299
+ /**
3300
+ * 回复需要即时服务的投诉单
3301
+ *
3302
+ * 对于需要即时服务的投诉(如投诉涉及订单退款),
3303
+ * 商户需在 2 小时内回复用户,否则平台可能介入。
3304
+ *
3305
+ * @param request - 即时服务回复请求参数
3306
+ * @returns 空响应表示成功
3307
+ *
3308
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4017151596
3309
+ */
3310
+ async replyImmediateService(request) {
3311
+ const { complaint_id, ...body } = request;
3312
+ return this.client.post(`/v3/merchant-service/complaints-v2/${complaint_id}/replies`, body);
3313
+ }
3314
+ // ============= 商户反馈图片 =============
3315
+ /**
3316
+ * 图片上传接口
3317
+ *
3318
+ * 上传投诉处理相关的图片文件,获取 media_id 用于回复投诉。
3319
+ * 图片大小限制:≤ 2MB,格式:JPG、BMP、PNG。
3320
+ * 上传时需提供图片文件的 SHA256 哈希值。
3321
+ *
3322
+ * @param file - 图片文件 Buffer
3323
+ * @param filename - 文件名
3324
+ * @returns 上传成功后的 media_id
3325
+ *
3326
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012467250
3327
+ */
3328
+ async uploadImage(file, filename) {
3329
+ return this.client.upload(
3330
+ "/v3/merchant-service/complaints-v2/images/upload",
3331
+ file,
3332
+ filename
3333
+ );
3334
+ }
3335
+ /**
3336
+ * 图片请求接口
3337
+ *
3338
+ * 通过 media_id 获取投诉相关的图片文件。
3339
+ * 返回的 data 为图片文件的 Buffer。
3340
+ *
3341
+ * @param mediaId - 图片媒体文件标识
3342
+ * @returns 图片文件 Buffer
3343
+ *
3344
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012467251
3345
+ */
3346
+ async getImage(mediaId) {
3347
+ return this.client.downloadRaw(`/v3/merchant-service/complaints-v2/images/${mediaId}`);
3348
+ }
3349
+ // ============= 投诉通知回调地址管理 =============
3350
+ /**
3351
+ * 创建投诉通知回调地址
3352
+ *
3353
+ * 设置接收投诉通知的回调 URL。用户提交投诉、撤诉、确认处理完成时,
3354
+ * 微信支付会向此 URL 发送通知。
3355
+ *
3356
+ * @param request - 创建回调地址请求参数
3357
+ * @returns 空响应表示成功
3358
+ *
3359
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012458679
3360
+ */
3361
+ async createCallbackUrl(request) {
3362
+ return this.client.post("/v3/merchant-service/complaint-notifications", request);
3363
+ }
3364
+ /**
3365
+ * 查询投诉通知回调地址
3366
+ *
3367
+ * 查询当前设置的投诉通知回调 URL。
3368
+ *
3369
+ * @returns 回调地址信息
3370
+ *
3371
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012459014
3372
+ */
3373
+ async queryCallbackUrl() {
3374
+ return this.client.get(
3375
+ "/v3/merchant-service/complaint-notifications"
3376
+ );
3377
+ }
3378
+ /**
3379
+ * 更新投诉通知回调地址
3380
+ *
3381
+ * 更新已设置的投诉通知回调 URL。
3382
+ *
3383
+ * @param request - 更新回调地址请求参数
3384
+ * @returns 空响应表示成功
3385
+ *
3386
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012459282
3387
+ */
3388
+ async updateCallbackUrl(request) {
3389
+ return this.client.put("/v3/merchant-service/complaint-notifications", request);
3390
+ }
3391
+ /**
3392
+ * 删除投诉通知回调地址
3393
+ *
3394
+ * 删除已设置的投诉通知回调 URL。删除后将不再接收投诉通知。
3395
+ *
3396
+ * @returns 空响应表示成功
3397
+ *
3398
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460452
3399
+ */
3400
+ async deleteCallbackUrl() {
3401
+ return this.client.delete("/v3/merchant-service/complaint-notifications");
3402
+ }
3403
+ };
3404
+
3405
+ // src/services/partnership.ts
3406
+ var PartnershipService = class {
3407
+ client;
3408
+ constructor(client) {
3409
+ this.client = client;
3410
+ }
3411
+ /**
3412
+ * 建立合作关系
3413
+ *
3414
+ * 商户可通过此接口与合作方建立委托营销合作关系。
3415
+ * 支持与 AppID 或商户号建立合作关系,授权代金券批次或商家券批次。
3416
+ *
3417
+ * @param request - 建立合作关系请求参数
3418
+ * @param idempotencyKey - 幂等键,需保持唯一性
3419
+ * @returns 合作关系详情
3420
+ *
3421
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012380498
3422
+ */
3423
+ async build(request, idempotencyKey) {
3424
+ return this.client.post(
3425
+ "/v3/marketing/partnerships/build",
3426
+ request,
3427
+ void 0,
3428
+ { "Idempotency-Key": idempotencyKey }
3429
+ );
3430
+ }
3431
+ /**
3432
+ * 查询合作关系列表
3433
+ *
3434
+ * 查询已建立的委托营销合作关系列表,支持分页。
3435
+ *
3436
+ * @param params - 查询参数
3437
+ * @returns 合作关系列表
3438
+ *
3439
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012380536
3440
+ */
3441
+ async list(params) {
3442
+ const queryParams = {
3443
+ "authorized_data.business_type": params.authorized_data.business_type
3444
+ };
3445
+ if (params.authorized_data.stock_id) {
3446
+ queryParams["authorized_data.stock_id"] = params.authorized_data.stock_id;
3447
+ }
3448
+ if (params.partner) {
3449
+ queryParams["partner.type"] = params.partner.type;
3450
+ if (params.partner.appid) {
3451
+ queryParams["partner.appid"] = params.partner.appid;
3452
+ }
3453
+ if (params.partner.merchant_id) {
3454
+ queryParams["partner.merchant_id"] = params.partner.merchant_id;
3455
+ }
3456
+ }
3457
+ if (params.limit !== void 0) {
3458
+ queryParams["limit"] = params.limit;
3459
+ }
3460
+ if (params.offset !== void 0) {
3461
+ queryParams["offset"] = params.offset;
3462
+ }
3463
+ return this.client.get("/v3/marketing/partnerships", queryParams);
3464
+ }
3465
+ };
3466
+
3467
+ // src/services/smartguide.ts
3468
+ var SmartGuideService = class {
3469
+ client;
3470
+ constructor(client) {
3471
+ this.client = client;
3472
+ }
3473
+ /**
3474
+ * 服务人员查询
3475
+ *
3476
+ * 查询门店下的服务人员列表。支持按企业微信员工ID、手机号码、工号筛选。
3477
+ *
3478
+ * @param params - 查询参数
3479
+ * @returns 服务人员列表
3480
+ *
3481
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535123
3482
+ */
3483
+ async query(params) {
3484
+ const queryParams = {
3485
+ store_id: params.store_id
3486
+ };
3487
+ if (params.userid) {
3488
+ queryParams["userid"] = params.userid;
3489
+ }
3490
+ if (params.mobile) {
3491
+ queryParams["mobile"] = params.mobile;
3492
+ }
3493
+ if (params.work_id) {
3494
+ queryParams["work_id"] = params.work_id;
3495
+ }
3496
+ if (params.limit !== void 0) {
3497
+ queryParams["limit"] = params.limit;
3498
+ }
3499
+ if (params.offset !== void 0) {
3500
+ queryParams["offset"] = params.offset;
3501
+ }
3502
+ return this.client.get("/v3/smartguide/guides", queryParams);
3503
+ }
3504
+ /**
3505
+ * 服务人员注册
3506
+ *
3507
+ * 注册门店的服务人员。name 和 mobile 字段需使用微信支付公钥加密。
3508
+ * 注册成功后返回 guide_id,用于后续更新和分配操作。
3509
+ *
3510
+ * @param request - 注册请求参数
3511
+ * @returns 注册成功后的服务人员ID
3512
+ *
3513
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535138
3514
+ */
3515
+ async register(request) {
3516
+ return this.client.post("/v3/smartguide/guides", request);
3517
+ }
3518
+ /**
3519
+ * 服务人员更新
3520
+ *
3521
+ * 更新已注册的服务人员信息。仅需传入需要更新的字段。
3522
+ * name 和 mobile 属于敏感字段,需使用微信支付公钥加密。
3523
+ *
3524
+ * @param guideId - 服务人员ID
3525
+ * @param request - 更新请求参数
3526
+ *
3527
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535160
3528
+ */
3529
+ async update(guideId, request) {
3530
+ return this.client.patch(`/v3/smartguide/guides/${guideId}`, request);
3531
+ }
3532
+ /**
3533
+ * 服务人员分配
3534
+ *
3535
+ * 将服务人员与订单关联。必须在支付完成之前调用,
3536
+ * 否则将无法在支付凭证上出现服务人员名片入口。
3537
+ *
3538
+ * @param guideId - 服务人员ID
3539
+ * @param request - 分配请求参数
3540
+ *
3541
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535161
3542
+ */
3543
+ async assign(guideId, request) {
3544
+ return this.client.post(`/v3/smartguide/guides/${guideId}/assign`, request);
3545
+ }
3546
+ };
3547
+
3548
+ // src/services/businesscircle.ts
3549
+ var BusinessCircleService = class {
3550
+ client;
3551
+ constructor(client) {
3552
+ this.client = client;
3553
+ }
3554
+ /**
3555
+ * 商圈会员积分同步
3556
+ *
3557
+ * 商户完成积分发放或扣除后,通过此接口通知微信支付积分变更情况。
3558
+ * 成功返回 204 No Content。
3559
+ *
3560
+ * @param request - 积分同步请求参数
3561
+ *
3562
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534698
3563
+ */
3564
+ async syncPoints(request) {
3565
+ return this.client.post("/v3/businesscircle/points/notify", request);
3566
+ }
3567
+ /**
3568
+ * 商圈会员积分服务授权查询
3569
+ *
3570
+ * 查询用户是否已授权商圈进行支付即积分。
3571
+ *
3572
+ * @param openid - 顾客授权时使用的小程序上的OpenID
3573
+ * @param appid - 顾客授权积分时使用的小程序的AppID
3574
+ * @returns 授权状态信息
3575
+ *
3576
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534848
3577
+ */
3578
+ async queryAuthorization(openid, appid) {
3579
+ return this.client.get(
3580
+ `/v3/businesscircle/user-authorizations/${openid}`,
3581
+ { appid }
3582
+ );
3583
+ }
3584
+ /**
3585
+ * 商圈会员待积分状态查询
3586
+ *
3587
+ * 查询用户的交易是否有待积分。
3588
+ *
3589
+ * @param params - 查询参数
3590
+ * @returns 待积分状态
3591
+ *
3592
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534994
3593
+ */
3594
+ async queryPendingPoints(params) {
3595
+ return this.client.get(
3596
+ "/v3/businesscircle/users/pending-points",
3597
+ {
3598
+ openid: params.openid,
3599
+ appid: params.appid,
3600
+ transaction_id: params.transaction_id
3601
+ }
3602
+ );
3603
+ }
3604
+ /**
3605
+ * 商圈会员停车状态同步
3606
+ *
3607
+ * 用户停车入场时,商户通过此接口通知微信支付。
3608
+ *
3609
+ * @param request - 停车状态同步请求参数
3610
+ *
3611
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535502
3612
+ */
3613
+ async syncParkingStatus(request) {
3614
+ return this.client.post("/v3/businesscircle/parkings", request);
3615
+ }
3616
+ };
3617
+
3618
+ // src/services/paygiftactivity.ts
3619
+ var PayGiftActivityService = class {
3620
+ client;
3621
+ constructor(client) {
3622
+ this.client = client;
3623
+ }
3624
+ /**
3625
+ * 创建全场满额送活动
3626
+ *
3627
+ * 创建支付有礼全场满额送活动,用户支付满额后自动发放商家券。
3628
+ *
3629
+ * @param request - 创建活动请求参数
3630
+ * @returns 活动ID和创建时间
3631
+ *
3632
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012487898
3633
+ */
3634
+ async create(request) {
3635
+ return this.client.post(
3636
+ "/v3/marketing/paygiftactivity/unique-threshold-activity",
3637
+ request
3638
+ );
3639
+ }
3640
+ /**
3641
+ * 获取活动详情
3642
+ *
3643
+ * 通过活动ID查询支付有礼活动的详细信息。
3644
+ *
3645
+ * @param activityId - 活动ID
3646
+ * @returns 活动详情
3647
+ *
3648
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012487971
3649
+ */
3650
+ async get(activityId) {
3651
+ return this.client.get(
3652
+ `/v3/marketing/paygiftactivity/activities/${activityId}`
3653
+ );
3654
+ }
3655
+ /**
3656
+ * 获取支付有礼活动列表
3657
+ *
3658
+ * 查询商户的支付有礼活动列表,支持按状态筛选和分页。
3659
+ *
3660
+ * @param params - 查询参数
3661
+ * @returns 活动列表
3662
+ *
3663
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012489126
3664
+ */
3665
+ async list(params) {
3666
+ const queryParams = {};
3667
+ if (params?.activity_state) {
3668
+ queryParams["activity_state"] = params.activity_state;
3669
+ }
3670
+ if (params?.limit !== void 0) {
3671
+ queryParams["limit"] = params.limit;
3672
+ }
3673
+ if (params?.offset !== void 0) {
3674
+ queryParams["offset"] = params.offset;
3675
+ }
3676
+ return this.client.get(
3677
+ "/v3/marketing/paygiftactivity/activities",
3678
+ queryParams
3679
+ );
3680
+ }
3681
+ /**
3682
+ * 终止活动
3683
+ *
3684
+ * 终止进行中的支付有礼活动。
3685
+ *
3686
+ * @param activityId - 活动ID
3687
+ *
3688
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012466523
3689
+ */
3690
+ async terminate(activityId) {
3691
+ return this.client.post(`/v3/marketing/paygiftactivity/activities/${activityId}/terminate`);
3692
+ }
3693
+ /**
3694
+ * 获取活动发券商户号
3695
+ *
3696
+ * 查询活动的发券商户号列表。
3697
+ *
3698
+ * @param activityId - 活动ID
3699
+ * @returns 发券商户号列表
3700
+ *
3701
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012466149
3702
+ */
3703
+ async getMerchants(activityId) {
3704
+ return this.client.get(
3705
+ `/v3/marketing/paygiftactivity/activities/${activityId}/merchant`
3706
+ );
3707
+ }
3708
+ /**
3709
+ * 新增活动发券商户号
3710
+ *
3711
+ * 向活动中添加新的发券商户号。
3712
+ *
3713
+ * @param activityId - 活动ID
3714
+ * @param merchantIdList - 商户号列表
3715
+ *
3716
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012466671
3717
+ */
3718
+ async addMerchant(activityId, merchantIdList) {
3719
+ return this.client.post(`/v3/marketing/paygiftactivity/activities/${activityId}/merchant`, {
3720
+ merchant_id_list: merchantIdList
3721
+ });
3722
+ }
3723
+ /**
3724
+ * 删除活动发券商户号
3725
+ *
3726
+ * 从活动中删除指定的发券商户号。
3727
+ *
3728
+ * @param activityId - 活动ID
3729
+ * @param merchantId - 商户号
3730
+ *
3731
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012466787
3732
+ */
3733
+ async deleteMerchant(activityId, merchantId) {
3734
+ return this.client.delete(
3735
+ `/v3/marketing/paygiftactivity/activities/${activityId}/merchant/${merchantId}`
3736
+ );
3737
+ }
3738
+ /**
3739
+ * 获取活动指定商品列表
3740
+ *
3741
+ * 查询活动中指定的商品列表。
3742
+ *
3743
+ * @param activityId - 活动ID
3744
+ * @returns 商品列表
3745
+ *
3746
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012466448
3747
+ */
3748
+ async getGoods(activityId) {
3749
+ return this.client.get(
3750
+ `/v3/marketing/paygiftactivity/activities/${activityId}/goods`
3751
+ );
3752
+ }
3753
+ };
3754
+
3755
+ // src/services/medins.ts
3756
+ var MedInsService = class {
3757
+ client;
3758
+ constructor(client) {
3759
+ this.client = client;
3760
+ }
3761
+ /**
3762
+ * 医保自费混合收款下单
3763
+ *
3764
+ * 创建医保自费混合支付订单。支持纯自费、纯医保、医保+自费混合支付。
3765
+ * 支持代亲属支付,需传入 relative 字段。
3766
+ *
3767
+ * @param request - 下单请求参数
3768
+ * @returns 混合订单信息
3769
+ *
3770
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781466
3771
+ */
3772
+ async createOrder(request) {
3773
+ return this.client.post("/v3/med-ins/orders", request);
3774
+ }
3775
+ /**
3776
+ * 使用医保自费混合订单号查看下单结果
3777
+ *
3778
+ * 通过混合订单号查询订单状态和详情。
3779
+ *
3780
+ * @param mixTradeNo - 医保自费混合订单号
3781
+ * @returns 订单信息
3782
+ *
3783
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781479
3784
+ */
3785
+ async queryByMixTradeNo(mixTradeNo) {
3786
+ return this.client.get(`/v3/med-ins/orders/${mixTradeNo}`);
3787
+ }
3788
+ /**
3789
+ * 使用商户订单号查看下单结果
3790
+ *
3791
+ * 通过商户订单号查询订单状态和详情。
3792
+ *
3793
+ * @param outTradeNo - 商户订单号
3794
+ * @returns 订单信息
3795
+ *
3796
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781490
3797
+ */
3798
+ async queryByOutTradeNo(outTradeNo) {
3799
+ return this.client.get(`/v3/med-ins/orders/out-trade-no/${outTradeNo}`);
3800
+ }
3801
+ };
3802
+
3803
+ // src/services/media.ts
3804
+ var MediaService = class {
3805
+ client;
3806
+ constructor(client) {
3807
+ this.client = client;
3808
+ }
3809
+ /**
3810
+ * 营销专用图片上传
3811
+ *
3812
+ * 上传图片文件至微信支付,获取 media_id 用于营销活动(如支付有礼、代金券等)。
3813
+ * 图片大小限制:≤ 2MB,格式:JPG、BMP、PNG、JPEG。
3814
+ *
3815
+ * @param file - 图片文件 Buffer
3816
+ * @param filename - 文件名(需包含扩展名,如 image.jpg)
3817
+ * @returns 上传成功后的 media_id
3818
+ *
3819
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012286130
3820
+ */
3821
+ async uploadImage(file, filename) {
3822
+ return this.client.upload(
3823
+ "/v3/merchant/media/upload",
3824
+ file,
3825
+ filename,
3826
+ { type: "image" }
3827
+ );
3828
+ }
3829
+ };
3830
+
3831
+ // src/services/security.ts
3832
+ var SecurityService = class {
3833
+ client;
3834
+ constructor(client) {
3835
+ this.client = client;
3836
+ }
3837
+ /**
3838
+ * 签名验签/加解密测试
3839
+ *
3840
+ * 用于测试商户的签名、验签、加密、解密能力。
3841
+ * 请求中 echo_message 会原样返回,encrypted_echo_message 经加密后返回。
3842
+ * 如传入 notify_url,微信支付会在测试成功后向该地址发送回调通知。
3843
+ *
3844
+ * @param request - 测试请求参数
3845
+ * @returns 测试结果,包含回显信息
3846
+ *
3847
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4014551946
3848
+ */
3849
+ async echoTest(request) {
3850
+ return this.client.post("/v3/security/echo", request);
3851
+ }
3852
+ };
3853
+ function generateAppPaySign(appId, timeStamp, nonceStr, prepayId, privateKey) {
3854
+ const signString = `${appId}
3855
+ ${timeStamp}
3856
+ ${nonceStr}
3857
+ prepay_id=${prepayId}
3858
+ `;
3859
+ const signer = crypto4__default.default.createSign("RSA-SHA256");
3860
+ signer.update(signString);
3861
+ signer.end();
3862
+ return signer.sign(privateKey, "base64");
3863
+ }
3864
+ function buildAppBridgeConfig(appId, partnerId, prepayId, privateKey) {
3865
+ const timeStamp = String(Math.floor(Date.now() / 1e3));
3866
+ const nonceStr = generateNonceStr();
3867
+ const sign2 = generateAppPaySign(appId, timeStamp, nonceStr, prepayId, privateKey);
3868
+ return {
3869
+ appId,
3870
+ partnerId,
3871
+ prepayId,
3872
+ packageValue: "Sign=WXPay",
3873
+ nonceStr,
3874
+ timeStamp,
3875
+ sign: sign2
3876
+ };
3877
+ }
3878
+ function generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey) {
3879
+ const signString = `${appId}
3880
+ ${timeStamp}
3881
+ ${nonceStr}
3882
+ prepay_id=${prepayId}
3883
+ `;
3884
+ const signer = crypto4__default.default.createSign("RSA-SHA256");
3885
+ signer.update(signString);
3886
+ signer.end();
3887
+ return signer.sign(privateKey, "base64");
3888
+ }
3889
+ function generateNonceStr() {
3890
+ return crypto4__default.default.randomUUID().replace(/-/g, "");
3891
+ }
3892
+ function buildJsapiBridgeConfig(appId, prepayId, privateKey) {
3893
+ const timeStamp = String(Math.floor(Date.now() / 1e3));
3894
+ const nonceStr = generateNonceStr();
3895
+ const paySign = generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey);
3896
+ return {
3897
+ appId,
3898
+ timeStamp,
3899
+ nonceStr,
3900
+ package: `prepay_id=${prepayId}`,
3901
+ signType: "RSA",
3902
+ paySign
3903
+ };
3904
+ }
3905
+ function buildMiniProgramBridgeConfig(appId, prepayId, privateKey) {
3906
+ const timeStamp = String(Math.floor(Date.now() / 1e3));
3907
+ const nonceStr = generateNonceStr();
3908
+ const paySign = generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey);
3909
+ return {
3910
+ timeStamp,
3911
+ nonceStr,
3912
+ package: `prepay_id=${prepayId}`,
3913
+ signType: "RSA",
3914
+ paySign
3915
+ };
3916
+ }
3917
+ function generatePayScorePaySign(appId, timeStamp, nonceStr, serviceId, outOrderNo, privateKey) {
3918
+ const packageStr = `service_id=${serviceId}&out_order_no=${outOrderNo}&need_sign_type=RSA`;
3919
+ const signString = `${appId}
3920
+ ${timeStamp}
3921
+ ${nonceStr}
3922
+ ${packageStr}
3923
+ `;
3924
+ const signer = crypto4__default.default.createSign("RSA-SHA256");
3925
+ signer.update(signString);
3926
+ signer.end();
3927
+ return signer.sign(privateKey, "base64");
3928
+ }
3929
+ function buildPayScoreJsapiBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
3930
+ const timestamp = String(Math.floor(Date.now() / 1e3));
3931
+ const nonceStr = generateNonceStr();
3932
+ const sign2 = generatePayScorePaySign(
3933
+ appId,
3934
+ timestamp,
3935
+ nonceStr,
3936
+ serviceId,
3937
+ outOrderNo,
3938
+ privateKey
3939
+ );
3940
+ return {
3941
+ appid: appId,
3942
+ mchid: mchId,
3943
+ service_id: serviceId,
3944
+ out_order_no: outOrderNo,
3945
+ timestamp,
3946
+ nonce_str: nonceStr,
3947
+ sign_type: "RSA",
3948
+ sign: sign2
3949
+ };
3950
+ }
3951
+ function buildPayScoreMiniProgramBridgeConfig(mchId, serviceId, outOrderNo, appId, privateKey) {
3952
+ const timestamp = String(Math.floor(Date.now() / 1e3));
3953
+ const nonceStr = generateNonceStr();
3954
+ const sign2 = generatePayScorePaySign(
3955
+ appId,
3956
+ timestamp,
3957
+ nonceStr,
3958
+ serviceId,
3959
+ outOrderNo,
3960
+ privateKey
3961
+ );
3962
+ return {
3963
+ mchid: mchId,
3964
+ service_id: serviceId,
3965
+ out_order_no: outOrderNo,
3966
+ timestamp,
3967
+ nonce_str: nonceStr,
3968
+ sign_type: "RSA",
3969
+ sign: sign2
3970
+ };
3971
+ }
3972
+ function buildPayScoreAppBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
3973
+ const timestamp = String(Math.floor(Date.now() / 1e3));
3974
+ const nonceStr = generateNonceStr();
3975
+ const sign2 = generatePayScorePaySign(
3976
+ appId,
3977
+ timestamp,
3978
+ nonceStr,
3979
+ serviceId,
3980
+ outOrderNo,
3981
+ privateKey
3982
+ );
3983
+ return {
3984
+ appid: appId,
3985
+ mchid: mchId,
3986
+ service_id: serviceId,
3987
+ out_order_no: outOrderNo,
3988
+ timestamp,
3989
+ nonce_str: nonceStr,
3990
+ sign_type: "RSA",
3991
+ sign: sign2
3992
+ };
3993
+ }
3994
+ function buildMerchantTransferJsapiBridgeConfig(mchId, appId, packageInfo) {
3995
+ return {
3996
+ mchId,
3997
+ appId,
3998
+ package: packageInfo
3999
+ };
4000
+ }
4001
+ function buildMerchantTransferMiniProgramBridgeConfig(mchId, appId, packageInfo) {
4002
+ return {
4003
+ mchId,
4004
+ appId,
4005
+ package: packageInfo
4006
+ };
4007
+ }
4008
+ function buildMerchantTransferAuthorizationJsapiBridgeConfig(mchId, appId, packageInfo) {
4009
+ return {
4010
+ mchId,
4011
+ appId,
4012
+ package: packageInfo
4013
+ };
4014
+ }
4015
+ var PARKING_SERVICE_APPID = "wxbcad394b3d99dac9";
4016
+ var PARKING_SERVICE_PATH = "/pages/auth-creditpay/auth-creditpay";
4017
+ var PARKING_REPAY_APPID = "wx5e73c65404eee268";
4018
+ var PARKING_REPAY_PATH = "pages/invest_list/invest_list";
4019
+ function buildParkingQueryString(mchid, openid, plateNumber, plateColor) {
4020
+ const params = new URLSearchParams({
4021
+ mchid,
4022
+ openid,
4023
+ plate_number: plateNumber,
4024
+ plate_color: plateColor,
4025
+ trade_scene: "PARKING"
4026
+ });
4027
+ return params.toString();
4028
+ }
4029
+ function buildParkingMiniProgramBridgeConfig(mchid, openid, plateNumber, plateColor) {
4030
+ return {
4031
+ appId: PARKING_SERVICE_APPID,
4032
+ path: PARKING_SERVICE_PATH,
4033
+ extraData: {
4034
+ mchid,
4035
+ openid,
4036
+ plate_number: plateNumber,
4037
+ plate_color: plateColor,
4038
+ trade_scene: "PARKING"
4039
+ }
4040
+ };
4041
+ }
4042
+ function buildParkingH5BridgeUrl(mchid, openid, plateNumber, plateColor) {
4043
+ const queryString = buildParkingQueryString(mchid, openid, plateNumber, plateColor);
4044
+ return `${PARKING_SERVICE_PATH}?${queryString}`;
4045
+ }
4046
+ function buildParkingAppBridgePath(mchid, openid, plateNumber, plateColor) {
4047
+ const queryString = buildParkingQueryString(mchid, openid, plateNumber, plateColor);
4048
+ return `${PARKING_SERVICE_PATH}?${queryString}`;
4049
+ }
4050
+ function buildParkingRepayBridgeConfig(mchid, openid) {
4051
+ return {
4052
+ appId: PARKING_REPAY_APPID,
4053
+ path: PARKING_REPAY_PATH,
4054
+ extraData: {
4055
+ mchid,
4056
+ nonce_str: generateNonceStr(),
4057
+ openid
4058
+ }
4059
+ };
4060
+ }
4061
+ var H5_COUPON_URL = "https://action.weixin.qq.com/busifavor/getcouponinfo";
4062
+ function buildH5CouponUrl(params, signKey) {
4063
+ const signFields = {
4064
+ stock_id: params.stock_id,
4065
+ out_request_no: params.out_request_no,
4066
+ send_coupon_merchant: params.send_coupon_merchant,
4067
+ open_id: params.open_id
4068
+ };
4069
+ if (params.coupon_code) {
4070
+ signFields["coupon_code"] = params.coupon_code;
4071
+ }
4072
+ const sortedKeys = Object.keys(signFields).sort();
4073
+ 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();
4075
+ const urlParams = new URLSearchParams({
4076
+ stock_id: params.stock_id,
4077
+ out_request_no: params.out_request_no,
4078
+ sign: sign2,
4079
+ send_coupon_merchant: params.send_coupon_merchant,
4080
+ open_id: params.open_id
4081
+ });
4082
+ if (params.coupon_code) {
4083
+ urlParams.set("coupon_code", params.coupon_code);
4084
+ }
4085
+ if (params.customize_send_time) {
4086
+ urlParams.set("customize_send_time", params.customize_send_time);
4087
+ }
4088
+ return `${H5_COUPON_URL}?${urlParams.toString()}#wechat_pay&wechat_redirect`;
4089
+ }
4090
+ function buildPayScoreDetailJsapiBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
4091
+ const timestamp = String(Math.floor(Date.now() / 1e3));
4092
+ const nonceStr = generateNonceStr();
4093
+ const sign2 = generatePayScorePaySign(
4094
+ appId,
4095
+ timestamp,
4096
+ nonceStr,
4097
+ serviceId,
4098
+ outOrderNo,
4099
+ privateKey
4100
+ );
4101
+ return {
4102
+ appid: appId,
4103
+ mchid: mchId,
4104
+ service_id: serviceId,
4105
+ out_order_no: outOrderNo,
4106
+ timestamp,
4107
+ nonce_str: nonceStr,
4108
+ sign_type: "RSA",
4109
+ sign: sign2
4110
+ };
4111
+ }
4112
+ function buildPayScoreDetailMiniProgramBridgeConfig(mchId, serviceId, outOrderNo, appId, privateKey) {
4113
+ const timestamp = String(Math.floor(Date.now() / 1e3));
4114
+ const nonceStr = generateNonceStr();
4115
+ const sign2 = generatePayScorePaySign(
4116
+ appId,
4117
+ timestamp,
4118
+ nonceStr,
4119
+ serviceId,
4120
+ outOrderNo,
4121
+ privateKey
4122
+ );
4123
+ return {
4124
+ mchid: mchId,
4125
+ service_id: serviceId,
4126
+ out_order_no: outOrderNo,
4127
+ timestamp,
4128
+ nonce_str: nonceStr,
4129
+ sign_type: "RSA",
4130
+ sign: sign2
4131
+ };
4132
+ }
4133
+ function buildPayScoreDetailAppBridgeConfig(appId, mchId, serviceId, outOrderNo, privateKey) {
4134
+ const timestamp = String(Math.floor(Date.now() / 1e3));
4135
+ const nonceStr = generateNonceStr();
4136
+ const sign2 = generatePayScorePaySign(
4137
+ appId,
4138
+ timestamp,
4139
+ nonceStr,
4140
+ serviceId,
4141
+ outOrderNo,
4142
+ privateKey
4143
+ );
4144
+ return {
4145
+ appid: appId,
4146
+ mchid: mchId,
4147
+ service_id: serviceId,
4148
+ out_order_no: outOrderNo,
4149
+ timestamp,
4150
+ nonce_str: nonceStr,
4151
+ sign_type: "RSA",
4152
+ sign: sign2
4153
+ };
4154
+ }
4155
+ var MED_INS_APPID = "wxbcad394b3d99dac9";
4156
+ var MED_INS_PATH = "/pages/med-ins/pay/pay";
4157
+ function buildMedInsMiniProgramBridgeConfig(mchid, mixTradeNo) {
4158
+ return {
4159
+ appId: MED_INS_APPID,
4160
+ path: MED_INS_PATH,
4161
+ extraData: {
4162
+ mchid,
4163
+ mix_trade_no: mixTradeNo
4164
+ }
4165
+ };
4166
+ }
4167
+ function buildMedInsJsapiBridgeConfig(appId, mchId, mixTradeNo, privateKey) {
4168
+ const timestamp = String(Math.floor(Date.now() / 1e3));
4169
+ const nonceStr = generateNonceStr();
4170
+ const packageStr = `mchid=${mchId}&mix_trade_no=${mixTradeNo}`;
4171
+ const signString = `${appId}
4172
+ ${timestamp}
4173
+ ${nonceStr}
4174
+ ${packageStr}
4175
+ `;
4176
+ const signer = crypto4__default.default.createSign("RSA-SHA256");
4177
+ signer.update(signString);
4178
+ signer.end();
4179
+ const sign2 = signer.sign(privateKey, "base64");
4180
+ return {
4181
+ appid: appId,
4182
+ mchid: mchId,
4183
+ mix_trade_no: mixTradeNo,
4184
+ timestamp,
4185
+ nonce_str: nonceStr,
4186
+ sign_type: "RSA",
4187
+ sign: sign2
4188
+ };
4189
+ }
4190
+
4191
+ exports.AppService = AppService;
4192
+ exports.BillService = BillService;
4193
+ exports.BusinessCircleService = BusinessCircleService;
4194
+ exports.CallbackHandler = CallbackHandler;
4195
+ exports.CertificateManager = CertificateManager;
4196
+ exports.CombineAppService = CombineAppService;
4197
+ exports.CombineH5Service = CombineH5Service;
4198
+ exports.CombineMiniProgramService = CombineMiniProgramService;
4199
+ exports.CombineNativeService = CombineNativeService;
4200
+ exports.CombineService = CombineService;
4201
+ exports.ComplaintService = ComplaintService;
4202
+ exports.CouponService = CouponService;
4203
+ exports.H5Service = H5Service;
4204
+ exports.JsapiService = JsapiService;
4205
+ exports.MedInsService = MedInsService;
4206
+ exports.MediaService = MediaService;
4207
+ exports.MerchantTransferService = MerchantTransferService;
4208
+ exports.NativeService = NativeService;
4209
+ exports.ParkingService = ParkingService;
4210
+ exports.PartnershipService = PartnershipService;
4211
+ exports.PayGiftActivityService = PayGiftActivityService;
4212
+ exports.PayScoreService = PayScoreService;
4213
+ exports.ProfitSharingService = ProfitSharingService;
4214
+ exports.SecurityService = SecurityService;
4215
+ exports.SmartGuideService = SmartGuideService;
4216
+ exports.WxPayClient = WxPayClient;
4217
+ exports.WxPayError = WxPayError;
4218
+ exports.buildAppBridgeConfig = buildAppBridgeConfig;
4219
+ exports.buildAuthorization = buildAuthorization;
4220
+ exports.buildH5CouponUrl = buildH5CouponUrl;
4221
+ exports.buildJsapiBridgeConfig = buildJsapiBridgeConfig;
4222
+ exports.buildMedInsJsapiBridgeConfig = buildMedInsJsapiBridgeConfig;
4223
+ exports.buildMedInsMiniProgramBridgeConfig = buildMedInsMiniProgramBridgeConfig;
4224
+ exports.buildMerchantTransferAuthorizationJsapiBridgeConfig = buildMerchantTransferAuthorizationJsapiBridgeConfig;
4225
+ exports.buildMerchantTransferJsapiBridgeConfig = buildMerchantTransferJsapiBridgeConfig;
4226
+ exports.buildMerchantTransferMiniProgramBridgeConfig = buildMerchantTransferMiniProgramBridgeConfig;
4227
+ exports.buildMiniProgramBridgeConfig = buildMiniProgramBridgeConfig;
4228
+ exports.buildParkingAppBridgePath = buildParkingAppBridgePath;
4229
+ exports.buildParkingH5BridgeUrl = buildParkingH5BridgeUrl;
4230
+ exports.buildParkingMiniProgramBridgeConfig = buildParkingMiniProgramBridgeConfig;
4231
+ exports.buildParkingRepayBridgeConfig = buildParkingRepayBridgeConfig;
4232
+ exports.buildPayScoreAppBridgeConfig = buildPayScoreAppBridgeConfig;
4233
+ exports.buildPayScoreDetailAppBridgeConfig = buildPayScoreDetailAppBridgeConfig;
4234
+ exports.buildPayScoreDetailJsapiBridgeConfig = buildPayScoreDetailJsapiBridgeConfig;
4235
+ exports.buildPayScoreDetailMiniProgramBridgeConfig = buildPayScoreDetailMiniProgramBridgeConfig;
4236
+ exports.buildPayScoreJsapiBridgeConfig = buildPayScoreJsapiBridgeConfig;
4237
+ exports.buildPayScoreMiniProgramBridgeConfig = buildPayScoreMiniProgramBridgeConfig;
4238
+ exports.buildSignString = buildSignString;
4239
+ exports.generateAppPaySign = generateAppPaySign;
4240
+ exports.generateNonce = generateNonce;
4241
+ exports.generateNonceStr = generateNonceStr;
4242
+ exports.generatePayScorePaySign = generatePayScorePaySign;
4243
+ exports.generatePaySign = generatePaySign;
4244
+ exports.oaepEncrypt = oaepEncrypt;
4245
+ exports.sign = sign;
4246
+ exports.verifySignature = verifySignature;
4247
+ //# sourceMappingURL=index.js.map
4248
+ //# sourceMappingURL=index.js.map