better-wechatpay 1.0.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.
Files changed (87) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +391 -0
  3. package/dist/app/app.d.ts +23 -0
  4. package/dist/app/app.d.ts.map +1 -0
  5. package/dist/app/app.js +89 -0
  6. package/dist/app/app.js.map +1 -0
  7. package/dist/config/loader.d.ts +3 -0
  8. package/dist/config/loader.d.ts.map +1 -0
  9. package/dist/config/loader.js +30 -0
  10. package/dist/config/loader.js.map +1 -0
  11. package/dist/core/base-payment.d.ts +70 -0
  12. package/dist/core/base-payment.d.ts.map +1 -0
  13. package/dist/core/base-payment.js +245 -0
  14. package/dist/core/base-payment.js.map +1 -0
  15. package/dist/core/cert-manager.d.ts +13 -0
  16. package/dist/core/cert-manager.d.ts.map +1 -0
  17. package/dist/core/cert-manager.js +32 -0
  18. package/dist/core/cert-manager.js.map +1 -0
  19. package/dist/core/client.d.ts +18 -0
  20. package/dist/core/client.d.ts.map +1 -0
  21. package/dist/core/client.js +105 -0
  22. package/dist/core/client.js.map +1 -0
  23. package/dist/core/crypto.d.ts +7 -0
  24. package/dist/core/crypto.d.ts.map +1 -0
  25. package/dist/core/crypto.js +26 -0
  26. package/dist/core/crypto.js.map +1 -0
  27. package/dist/core/debug.d.ts +7 -0
  28. package/dist/core/debug.d.ts.map +1 -0
  29. package/dist/core/debug.js +22 -0
  30. package/dist/core/debug.js.map +1 -0
  31. package/dist/core/sign.d.ts +9 -0
  32. package/dist/core/sign.d.ts.map +1 -0
  33. package/dist/core/sign.js +22 -0
  34. package/dist/core/sign.js.map +1 -0
  35. package/dist/core/verify.d.ts +16 -0
  36. package/dist/core/verify.d.ts.map +1 -0
  37. package/dist/core/verify.js +66 -0
  38. package/dist/core/verify.js.map +1 -0
  39. package/dist/h5/h5.d.ts +22 -0
  40. package/dist/h5/h5.d.ts.map +1 -0
  41. package/dist/h5/h5.js +117 -0
  42. package/dist/h5/h5.js.map +1 -0
  43. package/dist/index.d.ts +30 -0
  44. package/dist/index.d.ts.map +1 -0
  45. package/dist/index.js +63 -0
  46. package/dist/index.js.map +1 -0
  47. package/dist/jsapi/jsapi.d.ts +26 -0
  48. package/dist/jsapi/jsapi.d.ts.map +1 -0
  49. package/dist/jsapi/jsapi.js +132 -0
  50. package/dist/jsapi/jsapi.js.map +1 -0
  51. package/dist/native/index.d.ts +2 -0
  52. package/dist/native/index.d.ts.map +1 -0
  53. package/dist/native/index.js +2 -0
  54. package/dist/native/index.js.map +1 -0
  55. package/dist/native/native.d.ts +22 -0
  56. package/dist/native/native.d.ts.map +1 -0
  57. package/dist/native/native.js +88 -0
  58. package/dist/native/native.js.map +1 -0
  59. package/dist/types/api.d.ts +166 -0
  60. package/dist/types/api.d.ts.map +1 -0
  61. package/dist/types/api.js +3 -0
  62. package/dist/types/api.js.map +1 -0
  63. package/dist/types/config.d.ts +17 -0
  64. package/dist/types/config.d.ts.map +1 -0
  65. package/dist/types/config.js +2 -0
  66. package/dist/types/config.js.map +1 -0
  67. package/dist/types/index.d.ts +6 -0
  68. package/dist/types/index.d.ts.map +1 -0
  69. package/dist/types/index.js +5 -0
  70. package/dist/types/index.js.map +1 -0
  71. package/dist/types/payment.d.ts +353 -0
  72. package/dist/types/payment.d.ts.map +1 -0
  73. package/dist/types/payment.js +3 -0
  74. package/dist/types/payment.js.map +1 -0
  75. package/dist/types/webhook.d.ts +16 -0
  76. package/dist/types/webhook.d.ts.map +1 -0
  77. package/dist/types/webhook.js +2 -0
  78. package/dist/types/webhook.js.map +1 -0
  79. package/dist/webhook/index.d.ts +2 -0
  80. package/dist/webhook/index.d.ts.map +1 -0
  81. package/dist/webhook/index.js +2 -0
  82. package/dist/webhook/index.js.map +1 -0
  83. package/dist/webhook/webhook.d.ts +11 -0
  84. package/dist/webhook/webhook.d.ts.map +1 -0
  85. package/dist/webhook/webhook.js +35 -0
  86. package/dist/webhook/webhook.js.map +1 -0
  87. package/package.json +49 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Better WeChat Pay
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF, OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,391 @@
1
+ # Better WeChat Pay
2
+
3
+ 现代化的微信支付 Node.js SDK - ESM、TypeScript、全支付方式支持
4
+
5
+ ## 目录
6
+
7
+ - [特性](#特性)
8
+ - [安装](#安装)
9
+ - [快速开始](#快速开始)
10
+ - [环境变量](#环境变量)
11
+ - [支付方式](#支付方式)
12
+ - [Native 支付(扫码支付)](#native-支付扫码支付)
13
+ - [APP 支付](#app-支付)
14
+ - [JSAPI / 小程序支付](#jsapi--小程序支付)
15
+ - [H5 支付](#h5-支付)
16
+ - [合单支付](#合单支付)
17
+ - [订单管理](#订单管理)
18
+ - [退款管理](#退款管理)
19
+ - [账单下载](#账单下载)
20
+ - [Webhook 处理](#webhook-处理)
21
+ - [自定义 API 调用](#自定义-api-调用)
22
+ - [调试模式](#调试模式)
23
+ - [示例项目](#示例项目)
24
+ - [文档](#文档)
25
+ - [许可证](#许可证)
26
+
27
+ ## 特性
28
+
29
+ - ✅ 纯 ESM(ES Modules)
30
+ - ✅ 完整的 TypeScript 类型支持
31
+ - ✅ 支持所有支付方式(Native/APP/JSAPI/小程序/H5)
32
+ - ✅ 双签名验证(新公钥 + 平台证书)
33
+ - ✅ 内置调试模式
34
+ - ✅ 最小依赖(@peculiar/x509、ofetch)
35
+ - ✅ 自动金额格式化(元转分)
36
+ - ✅ 完善的测试覆盖
37
+
38
+ ## 安装
39
+
40
+ ```bash
41
+ npm install better-wechatpay
42
+ ```
43
+
44
+ ## 快速开始
45
+
46
+ ```typescript
47
+ import WeChatPay from 'better-wechatpay';
48
+
49
+ const wechat = new WeChatPay({
50
+ config: {
51
+ appId: process.env.WECHAT_PAY_APP_ID,
52
+ mchId: process.env.WECHAT_PAY_MCH_ID,
53
+ apiKey: process.env.WECHAT_PAY_API_KEY,
54
+ privateKey: process.env.WECHAT_PAY_PRIVATE_KEY,
55
+ publicKey: process.env.WECHAT_PAY_PUBLIC_KEY,
56
+ notifyUrl: 'https://your-domain.com/webhook/wechat'
57
+ }
58
+ });
59
+
60
+ // 创建 Native 支付(扫码支付)
61
+ const payment = await wechat.native.create({
62
+ out_trade_no: 'order-123',
63
+ description: '会员订阅',
64
+ amount: 99.00 // 自动转换为分(9900)
65
+ });
66
+
67
+ console.log('二维码链接:', payment.code_url);
68
+ ```
69
+
70
+ ## 环境变量
71
+
72
+ 必需的环境变量:
73
+
74
+ ```bash
75
+ # 微信支付凭证
76
+ WECHAT_PAY_APP_ID="your_app_id"
77
+ WECHAT_PAY_MCH_ID="your_mch_id"
78
+ WECHAT_PAY_API_KEY="32_character_api_key"
79
+
80
+ # 证书(PEM 格式,单行)
81
+ WECHAT_PAY_PRIVATE_KEY="-----BEGIN PRIVATE KEY-----
82
+ MIIEvQIBADANBgkq...
83
+ -----END PRIVATE KEY-----"
84
+
85
+ WECHAT_PAY_PUBLIC_KEY="-----BEGIN CERTIFICATE-----
86
+ MIID8zCCAtugAwIB...
87
+ -----END CERTIFICATE-----"
88
+
89
+ # 可选:微信支付公钥(推荐)
90
+ WECHAT_PAY_PAYMENT_PUBLIC_KEY="-----BEGIN PUBLIC KEY-----
91
+ MIIEvgIBADAN...
92
+ -----END PUBLIC KEY-----"
93
+
94
+ WECHAT_PAY_PUBLIC_KEY_ID="public_key_id"
95
+ ```
96
+
97
+ ## 支付方式
98
+
99
+ ### Native 支付(扫码支付)
100
+
101
+ ```typescript
102
+ const payment = await wechat.native.create({
103
+ out_trade_no: 'order-123',
104
+ description: '会员订阅',
105
+ amount: 99.00
106
+ });
107
+ // 返回: { code_url: 'weixin://...', out_trade_no: 'order-123' }
108
+ ```
109
+
110
+ ### APP 支付
111
+
112
+ ```typescript
113
+ const payment = await wechat.app.create({
114
+ out_trade_no: 'order-123',
115
+ description: '会员订阅',
116
+ amount: 99.00
117
+ });
118
+ // 返回: { prepay_id: '...', out_trade_no: 'order-123' }
119
+ ```
120
+
121
+ ### JSAPI / 小程序支付
122
+
123
+ ```typescript
124
+ const payment = await wechat.jsapi.create({
125
+ out_trade_no: 'order-123',
126
+ description: '会员订阅',
127
+ amount: 99.00,
128
+ openid: 'user_openid' // 必填
129
+ });
130
+ // 返回: { prepay_id: '...', out_trade_no: 'order-123' }
131
+ ```
132
+
133
+ ### H5 支付
134
+
135
+ ```typescript
136
+ const payment = await wechat.h5.create({
137
+ out_trade_no: 'order-123',
138
+ description: '会员订阅',
139
+ amount: 99.00,
140
+ payer_client_ip: '1.2.3.4',
141
+ h5_info: {
142
+ type: 'Wap',
143
+ app_name: '我的应用',
144
+ app_url: 'https://example.com'
145
+ }
146
+ });
147
+ // 返回: { h5_url: 'https://wx.tenpay.com/...', out_trade_no: 'order-123' }
148
+ ```
149
+
150
+ ## 通用操作
151
+
152
+ 所有支付方式都支持以下操作:
153
+
154
+ ### 查询订单
155
+
156
+ ```typescript
157
+ // 通过商户订单号查询
158
+ const order = await wechat.native.query({ out_trade_no: 'order-123' });
159
+
160
+ // 通过微信订单号查询
161
+ const order = await wechat.native.queryByTransactionId({ transaction_id: 'txn-123' });
162
+
163
+ console.log('订单状态:', order.trade_state);
164
+ console.log('微信订单号:', order.transaction_id);
165
+ console.log('金额:', order.amount.total);
166
+ ```
167
+
168
+ ### 关闭订单
169
+
170
+ ```typescript
171
+ await wechat.native.close('order-123');
172
+ ```
173
+
174
+ ### 申请退款
175
+
176
+ ```typescript
177
+ const refund = await wechat.native.refund({
178
+ out_trade_no: 'order-123',
179
+ out_refund_no: 'refund-123',
180
+ refund: 99.00,
181
+ total: 99.00,
182
+ reason: '商品售后'
183
+ });
184
+ ```
185
+
186
+ ### 查询退款
187
+
188
+ ```typescript
189
+ const refund = await wechat.native.queryRefund({ out_refund_no: 'refund-123' });
190
+ ```
191
+
192
+ ### 申请账单
193
+
194
+ ```typescript
195
+ // 交易账单
196
+ const tradeBill = await wechat.native.applyTradeBill({
197
+ bill_date: '2025-01-01',
198
+ bill_type: 'ALL'
199
+ });
200
+
201
+ // 资金账单
202
+ const fundBill = await wechat.native.applyFundFlowBill({
203
+ bill_date: '2025-01-01',
204
+ account_type: 'BASIC'
205
+ });
206
+ ```
207
+
208
+ ## 自定义 API 调用
209
+
210
+ SDK 暴露了底层 HTTP 客户端,可用于调用未实现的微信支付 API:
211
+
212
+ ```typescript
213
+ const result = await wechat.request<CustomResponse>(
214
+ 'POST',
215
+ '/v3/custom/endpoint',
216
+ { custom_param: 'value' }
217
+ );
218
+ ```
219
+
220
+ 这对于调用新推出的微信支付 API 或特殊业务场景非常有用。
221
+
222
+ ## Webhook 处理
223
+
224
+ ```typescript
225
+ import { createServer } from 'http';
226
+
227
+ const server = createServer(async (req, res) => {
228
+ if (req.url === '/webhook/wechat') {
229
+ let body = '';
230
+ req.on('data', chunk => body += chunk);
231
+ req.on('end', async () => {
232
+ const result = await wechat.webhook.verify({
233
+ headers: req.headers as any,
234
+ body
235
+ });
236
+
237
+ if (result.success) {
238
+ console.log('Webhook 验证成功:', result.eventType);
239
+ console.log('解密数据:', result.decryptedData);
240
+ res.writeHead(200);
241
+ res.end('OK');
242
+ } else {
243
+ console.error('Webhook 签名无效');
244
+ res.writeHead(400);
245
+ res.end('Invalid signature');
246
+ }
247
+ });
248
+ }
249
+ });
250
+
251
+ server.listen(3000);
252
+ ```
253
+
254
+ ## 调试模式
255
+
256
+ 启用调试日志:
257
+
258
+ ```typescript
259
+ const wechat = new WeChatPay({
260
+ config: {
261
+ /* ... 配置 ... */
262
+ debug: true
263
+ }
264
+ });
265
+
266
+ // 或通过环境变量
267
+ WECHAT_PAY_DEBUG=true node app.js
268
+ ```
269
+
270
+ 调试输出包含:
271
+ - 请求详情(URL、方法、请求头、请求体)
272
+ - 响应详情(状态码、响应头、响应体)
273
+ - 签名验证结果
274
+ - 错误详情
275
+
276
+ ## 配置选项
277
+
278
+ ```typescript
279
+ interface WeChatPayConfig {
280
+ appId: string; // 应用 ID
281
+ mchId: string; // 商户号
282
+ apiKey: string; // API 密钥(32位)
283
+ privateKey: Buffer | string; // 商户私钥
284
+ publicKey: Buffer | string; // 商户证书
285
+ paymentPublicKey?: Buffer | string; // 微信支付公钥(可选,推荐)
286
+ publicKeyId?: string; // 公钥 ID(使用 paymentPublicKey 时必填)
287
+ notifyUrl?: string; // 回调通知地址
288
+ baseUrl?: string; // API 基础 URL(默认生产环境)
289
+ debug?: boolean; // 调试模式
290
+ }
291
+ ```
292
+
293
+ ## 安全注意事项
294
+
295
+ 1. **永远不要将证书或密钥提交到版本控制**
296
+ 2. **将敏感凭证存储在环境变量中**
297
+ 3. **始终验证 Webhook 签名**
298
+ 4. **Webhook URL 必须使用 HTTPS**
299
+ 5. **定期轮换证书**
300
+
301
+ 详见 [安全指南](docs/security.md)。
302
+
303
+ ## 文档
304
+
305
+ ### 快速入门
306
+ - [快速开始](docs/getting-started.md)
307
+ - [API 参考](docs/api-reference.md)
308
+ - [调试模式](docs/debug-mode.md)
309
+ - [安全指南](docs/security.md)
310
+ - [错误码](docs/error-codes.md)
311
+
312
+ ### 支付方式
313
+ - [Native 支付(扫码支付)](docs/native-payment.md)
314
+ - [APP 支付](docs/app-payment.md)
315
+ - [JSAPI 支付](docs/jsapi-payment.md)
316
+ - [H5 支付](docs/h5-payment.md)
317
+ - [合单支付](docs/combine-payment.md)
318
+
319
+ ## 示例服务器
320
+
321
+ 想要测试完整的支付流程?查看 [示例服务器](examples/demo/QUICKSTART.md) - 一个功能完整的测试服务器:
322
+
323
+ - ✅ 创建真实支付和二维码
324
+ - ✅ 使用微信扫码完成支付
325
+ - ✅ 处理真实的 Webhook
326
+ - ✅ 查询和管理订单
327
+ - ✅ 测试所有支付状态
328
+
329
+ **快速启动:**
330
+ ```bash
331
+ # 1. 配置环境变量
332
+ cd examples/demo
333
+ cp .env.example .env
334
+ # 编辑 .env,填入你的微信支付凭证
335
+
336
+ # 2. 启动示例服务器
337
+ npm install
338
+ npm run dev
339
+
340
+ # 3. 打开 http://localhost:3000
341
+ # 创建支付,扫描二维码,完成支付!
342
+ ```
343
+
344
+ 详见 [示例服务器文档](examples/demo/QUICKSTART.md)。
345
+
346
+ ## 框架集成
347
+
348
+ 查看框架集成示例:
349
+
350
+ ### [Next.js](examples/nextjs/)
351
+ 现代 React 框架,支持 App Router
352
+
353
+ ```bash
354
+ cd examples/nextjs
355
+ npm install
356
+ npm run dev
357
+ ```
358
+
359
+ ### [Nuxt](examples/nuxt/)
360
+ 直观的 Vue 全栈开发框架
361
+
362
+ ```bash
363
+ cd examples/nuxt
364
+ npm install
365
+ npm run dev
366
+ ```
367
+
368
+ 详见 [所有示例](examples/INDEX.md)。
369
+
370
+ ## 开发
371
+
372
+ ```bash
373
+ # 安装依赖
374
+ npm install
375
+
376
+ # 构建 TypeScript
377
+ npm run build
378
+
379
+ # 运行单元测试
380
+ npm test
381
+
382
+ # 运行示例服务器(需要微信支付凭证)
383
+ npm run dev
384
+
385
+ # 类型检查
386
+ npm run typecheck
387
+ ```
388
+
389
+ ## 许可证
390
+
391
+ MIT
@@ -0,0 +1,23 @@
1
+ import type { HttpClient } from '../core/client';
2
+ import type { CreateAppPaymentParams, CreateAppPaymentResult, CreateCombineAppPaymentParams, CreateCombineAppPaymentResult } from '../types';
3
+ import { BasePayment } from '../core/base-payment';
4
+ /**
5
+ * APP支付
6
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070158
7
+ */
8
+ export declare class AppPayment extends BasePayment {
9
+ constructor(client: HttpClient, instance: object);
10
+ /**
11
+ * APP下单
12
+ * 商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易会话标识后,
13
+ * 再按照APP调起支付的规范调起支付。
14
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070164
15
+ */
16
+ create(params: CreateAppPaymentParams): Promise<CreateAppPaymentResult>;
17
+ /**
18
+ * APP合单下单
19
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556944
20
+ */
21
+ createCombine(params: CreateCombineAppPaymentParams): Promise<CreateCombineAppPaymentResult>;
22
+ }
23
+ //# sourceMappingURL=app.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.d.ts","sourceRoot":"","sources":["../../src/app/app.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,KAAK,EACV,sBAAsB,EACtB,sBAAsB,EAEtB,6BAA6B,EAC7B,6BAA6B,EAE9B,MAAM,UAAU,CAAC;AAClB,OAAO,EAAE,WAAW,EAAE,MAAM,sBAAsB,CAAC;AAGnD;;;GAGG;AACH,qBAAa,UAAW,SAAQ,WAAW;gBAC7B,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM;IAIhD;;;;;OAKG;IACG,MAAM,CAAC,MAAM,EAAE,sBAAsB,GAAG,OAAO,CAAC,sBAAsB,CAAC;IA0C7E;;;OAGG;IACG,aAAa,CAAC,MAAM,EAAE,6BAA6B,GAAG,OAAO,CAAC,6BAA6B,CAAC;CAwCnG"}
@@ -0,0 +1,89 @@
1
+ import { BasePayment } from '../core/base-payment';
2
+ import { logger } from '../core/debug';
3
+ /**
4
+ * APP支付
5
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070158
6
+ */
7
+ export class AppPayment extends BasePayment {
8
+ constructor(client, instance) {
9
+ super(client, instance);
10
+ }
11
+ /**
12
+ * APP下单
13
+ * 商户系统先调用该接口在微信支付服务后台生成预支付交易单,返回正确的预支付交易会话标识后,
14
+ * 再按照APP调起支付的规范调起支付。
15
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070164
16
+ */
17
+ async create(params) {
18
+ logger.log(this.instance, 'Creating APP payment:', params);
19
+ const data = this.removeUndefined({
20
+ appid: this.client.getAppId(),
21
+ mchid: this.client.getMerchantId(),
22
+ description: params.description,
23
+ out_trade_no: params.out_trade_no,
24
+ time_expire: params.time_expire,
25
+ attach: params.attach,
26
+ notify_url: this.client.getNotifyUrl(),
27
+ goods_tag: params.goods_tag,
28
+ support_fapiao: params.support_fapiao,
29
+ amount: {
30
+ total: this.formatAmount(params.amount),
31
+ currency: params.currency || 'CNY'
32
+ },
33
+ detail: params.detail ? {
34
+ cost_price: params.detail.cost_price,
35
+ invoice_id: params.detail.invoice_id,
36
+ goods_detail: params.detail.goods_detail
37
+ } : undefined,
38
+ scene_info: {
39
+ payer_client_ip: params.payer_client_ip || params.scene_info?.payer_client_ip || '127.0.0.1',
40
+ device_id: params.scene_info?.device_id,
41
+ store_info: params.scene_info?.store_info
42
+ },
43
+ settle_info: params.settle_info
44
+ });
45
+ const result = await this.client.request('POST', '/v3/pay/transactions/app', data);
46
+ return {
47
+ prepay_id: result.prepay_id,
48
+ out_trade_no: params.out_trade_no
49
+ };
50
+ }
51
+ /**
52
+ * APP合单下单
53
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556944
54
+ */
55
+ async createCombine(params) {
56
+ logger.log(this.instance, 'Creating APP combine payment:', params);
57
+ const data = this.removeUndefined({
58
+ combine_appid: this.client.getAppId(),
59
+ combine_mchid: this.client.getMerchantId(),
60
+ combine_out_trade_no: params.combine_out_trade_no,
61
+ time_expire: params.time_expire,
62
+ notify_url: params.notify_url || this.client.getNotifyUrl(),
63
+ scene_info: params.payer_client_ip || params.scene_info ? {
64
+ payer_client_ip: params.payer_client_ip || params.scene_info?.payer_client_ip || '127.0.0.1',
65
+ device_id: params.scene_info?.device_id,
66
+ store_info: params.scene_info?.store_info
67
+ } : undefined,
68
+ sub_orders: params.sub_orders.map((order) => ({
69
+ mchid: order.mchid,
70
+ attach: order.attach,
71
+ out_trade_no: order.out_trade_no,
72
+ description: order.description,
73
+ amount: {
74
+ total_amount: this.formatAmount(order.amount.total_amount),
75
+ currency: order.amount.currency || 'CNY'
76
+ },
77
+ detail: order.detail,
78
+ goods_tag: order.goods_tag,
79
+ settle_info: order.settle_info
80
+ }))
81
+ });
82
+ const result = await this.client.request('POST', '/v3/combine-transactions/app', data);
83
+ return {
84
+ prepay_id: result.prepay_id,
85
+ combine_out_trade_no: params.combine_out_trade_no
86
+ };
87
+ }
88
+ }
89
+ //# sourceMappingURL=app.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"app.js","sourceRoot":"","sources":["../../src/app/app.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import { WeChatPayConfig, WeChatPayOptions } from '../types/index';
2
+ export declare function loadConfig(options: WeChatPayOptions | WeChatPayConfig): WeChatPayConfig;
3
+ //# sourceMappingURL=loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,gBAAgB,EAAE,MAAM,gBAAgB,CAAC;AAEnE,wBAAgB,UAAU,CAAC,OAAO,EAAE,gBAAgB,GAAG,eAAe,GAAG,eAAe,CA4BvF"}
@@ -0,0 +1,30 @@
1
+ export function loadConfig(options) {
2
+ if (options.configPath) {
3
+ throw new Error('Loading config from file is not yet implemented');
4
+ }
5
+ let config;
6
+ if (options.config) {
7
+ config = options.config;
8
+ }
9
+ else {
10
+ config = options;
11
+ }
12
+ if (!config.appId)
13
+ throw new Error('appId is required');
14
+ if (!config.mchId)
15
+ throw new Error('mchId is required');
16
+ if (!config.apiKey)
17
+ throw new Error('apiKey is required');
18
+ if (!config.privateKey)
19
+ throw new Error('privateKey is required');
20
+ if (!config.publicKey)
21
+ throw new Error('publicKey is required');
22
+ if (config.debug === undefined) {
23
+ config.debug = process.env.WECHAT_PAY_DEBUG === 'true';
24
+ }
25
+ if (!config.baseUrl) {
26
+ config.baseUrl = 'https://api.mch.weixin.qq.com';
27
+ }
28
+ return config;
29
+ }
30
+ //# sourceMappingURL=loader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loader.js","sourceRoot":"","sources":["../../src/config/loader.ts"],"names":[],"mappings":"AAEA,MAAM,UAAU,UAAU,CAAC,OAA2C;IACpE,IAAK,OAA4B,CAAC,UAAU,EAAE,CAAC;QAC7C,MAAM,IAAI,KAAK,CAAC,iDAAiD,CAAC,CAAC;IACrE,CAAC;IAED,IAAI,MAAuB,CAAC;IAE5B,IAAK,OAA4B,CAAC,MAAM,EAAE,CAAC;QACzC,MAAM,GAAI,OAA4B,CAAC,MAAO,CAAC;IACjD,CAAC;SAAM,CAAC;QACN,MAAM,GAAG,OAA0B,CAAC;IACtC,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,mBAAmB,CAAC,CAAC;IACxD,IAAI,CAAC,MAAM,CAAC,MAAM;QAAE,MAAM,IAAI,KAAK,CAAC,oBAAoB,CAAC,CAAC;IAC1D,IAAI,CAAC,MAAM,CAAC,UAAU;QAAE,MAAM,IAAI,KAAK,CAAC,wBAAwB,CAAC,CAAC;IAClE,IAAI,CAAC,MAAM,CAAC,SAAS;QAAE,MAAM,IAAI,KAAK,CAAC,uBAAuB,CAAC,CAAC;IAEhE,IAAI,MAAM,CAAC,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,MAAM,CAAC,KAAK,GAAG,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,MAAM,CAAC;IACzD,CAAC;IAED,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,CAAC,OAAO,GAAG,+BAA+B,CAAC;IACnD,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,70 @@
1
+ import type { HttpClient } from './client';
2
+ import type { QueryOrderParams, QueryOrderResult, QueryOrderByTransactionIdParams, QueryCombineOrderParams, QueryCombineOrderResult, CloseCombineOrderParams, RefundParams, RefundResult, QueryRefundParams, AbnormalRefundParams, ApplyTradeBillParams, BillResult, ApplyFundFlowBillParams } from '../types';
3
+ /**
4
+ * 支付基类
5
+ * 包含所有支付方式共用的方法:查询、关闭、退款、账单等
6
+ */
7
+ export declare abstract class BasePayment {
8
+ protected client: HttpClient;
9
+ protected instance: object;
10
+ protected constructor(client: HttpClient, instance: object);
11
+ /**
12
+ * 通过商户订单号查询订单
13
+ */
14
+ query(params: QueryOrderParams): Promise<QueryOrderResult>;
15
+ /**
16
+ * 关闭订单
17
+ */
18
+ close(out_trade_no: string): Promise<void>;
19
+ /**
20
+ * 查询合单订单
21
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557006
22
+ */
23
+ queryCombineOrder(params: QueryCombineOrderParams): Promise<QueryCombineOrderResult>;
24
+ /**
25
+ * 关闭合单订单
26
+ * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557007
27
+ */
28
+ closeCombineOrder(params: CloseCombineOrderParams): Promise<void>;
29
+ /**
30
+ * 通过微信支付订单号查询订单
31
+ */
32
+ queryByTransactionId(params: QueryOrderByTransactionIdParams): Promise<QueryOrderResult>;
33
+ /**
34
+ * 申请退款
35
+ */
36
+ refund(params: RefundParams): Promise<RefundResult>;
37
+ /**
38
+ * 查询单笔退款
39
+ */
40
+ queryRefund(params: QueryRefundParams): Promise<RefundResult>;
41
+ /**
42
+ * 发起异常退款
43
+ */
44
+ applyAbnormalRefund(params: AbnormalRefundParams): Promise<RefundResult>;
45
+ /**
46
+ * 申请交易账单
47
+ */
48
+ applyTradeBill(params: ApplyTradeBillParams): Promise<BillResult>;
49
+ /**
50
+ * 申请资金账单
51
+ */
52
+ applyFundFlowBill(params: ApplyFundFlowBillParams): Promise<BillResult>;
53
+ /**
54
+ * 解析退款结果
55
+ */
56
+ protected parseRefundResult(result: any): RefundResult;
57
+ /**
58
+ * 金额转换:元 → 分
59
+ */
60
+ protected formatAmount(amount: number): number;
61
+ /**
62
+ * 递归移除对象中的 undefined 值
63
+ */
64
+ protected removeUndefined<T extends object>(obj: T): T;
65
+ /**
66
+ * 构建 URL 查询字符串,自动过滤 undefined 值
67
+ */
68
+ protected buildQueryString(params: Record<string, string | undefined>): string;
69
+ }
70
+ //# sourceMappingURL=base-payment.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-payment.d.ts","sourceRoot":"","sources":["../../src/core/base-payment.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC3C,OAAO,KAAK,EACV,gBAAgB,EAChB,gBAAgB,EAEhB,+BAA+B,EAC/B,uBAAuB,EACvB,uBAAuB,EACvB,uBAAuB,EACvB,YAAY,EACZ,YAAY,EACZ,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,UAAU,EACV,uBAAuB,EACxB,MAAM,UAAU,CAAC;AAGlB;;;GAGG;AACH,8BAAsB,WAAW;IAE7B,SAAS,CAAC,MAAM,EAAE,UAAU;IAC5B,SAAS,CAAC,QAAQ,EAAE,MAAM;IAF5B,SAAS,aACG,MAAM,EAAE,UAAU,EAClB,QAAQ,EAAE,MAAM;IAG5B;;OAEG;IACG,KAAK,CAAC,MAAM,EAAE,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAuBhE;;OAEG;IACG,KAAK,CAAC,YAAY,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAUhD;;;OAGG;IACG,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,uBAAuB,CAAC;IAkB1F;;;OAGG;IACG,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,IAAI,CAAC;IAevE;;OAEG;IACG,oBAAoB,CAAC,MAAM,EAAE,+BAA+B,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAuB9F;;OAEG;IACG,MAAM,CAAC,MAAM,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAwBzD;;OAEG;IACG,WAAW,CAAC,MAAM,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC;IAWnE;;OAEG;IACG,mBAAmB,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC;IAoB9E;;OAEG;IACG,cAAc,CAAC,MAAM,EAAE,oBAAoB,GAAG,OAAO,CAAC,UAAU,CAAC;IAqBvE;;OAEG;IACG,iBAAiB,CAAC,MAAM,EAAE,uBAAuB,GAAG,OAAO,CAAC,UAAU,CAAC;IAuB7E;;OAEG;IACH,SAAS,CAAC,iBAAiB,CAAC,MAAM,EAAE,GAAG,GAAG,YAAY;IA6BtD;;OAEG;IACH,SAAS,CAAC,YAAY,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM;IAI9C;;OAEG;IACH,SAAS,CAAC,eAAe,CAAC,CAAC,SAAS,MAAM,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC;IA2BtD;;OAEG;IACH,SAAS,CAAC,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,GAAG,MAAM;CAW/E"}