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/LICENSE +21 -0
- package/README.md +118 -0
- package/dist/index.d.mts +7874 -0
- package/dist/index.d.ts +7874 -0
- package/dist/index.js +4248 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +4186 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +92 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/certificate.ts","../src/utils/http.ts","../src/utils/sign.ts","../src/core/client.ts","../src/services/jsapi.ts","../src/services/h5.ts","../src/services/app.ts","../src/services/native.ts","../src/services/combine.ts","../src/services/combine-h5.ts","../src/services/combine-app.ts","../src/services/combine-miniprogram.ts","../src/services/combine-native.ts","../src/services/profitsharing.ts","../src/services/payscore.ts","../src/services/parking.ts","../src/services/bill.ts","../src/services/callback.ts","../src/services/merchant-transfer.ts","../src/services/coupon.ts","../src/services/complaint.ts","../src/services/partnership.ts","../src/services/smartguide.ts","../src/services/businesscircle.ts","../src/services/paygiftactivity.ts","../src/services/medins.ts","../src/services/media.ts","../src/services/security.ts","../src/services/bridge.ts"],"names":["crypto","data","fs","sign"],"mappings":"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","file":"index.js","sourcesContent":["import crypto from 'node:crypto';\nimport type { PlatformCertificate } from '../types/index.js';\n\n/**\n * 微信支付平台证书管理器\n *\n * 支持两种验签模式:\n * - 微信支付公钥模式(推荐):通过 wxpayPublicKey 配置微信支付公钥\n * - 平台证书模式:通过 platformCertificates 配置平台证书\n *\n * 负责平台证书的解密、缓存和获取公钥\n */\nexport class CertificateManager {\n /** 平台证书缓存 Map<序列号, 证书信息> */\n private certificates = new Map<string, PlatformCertificate>();\n\n /** 微信支付公钥(PEM 格式),支持公钥模式 */\n private wxpayPublicKey: string | null = null;\n\n /** 微信支付公钥ID */\n private wxpayPublicKeyId: string | null = null;\n\n /** API V3 密钥 */\n private readonly apiV3Key: string;\n\n constructor(apiV3Key: string, certificates?: PlatformCertificate[]) {\n this.apiV3Key = apiV3Key;\n if (certificates) {\n for (const cert of certificates) {\n this.certificates.set(cert.serialNo, cert);\n }\n }\n }\n\n /**\n * 获取证书序列号列表\n */\n get serialNos(): string[] {\n return Array.from(this.certificates.keys());\n }\n\n /**\n * 设置微信支付公钥(公钥模式)\n *\n * @param publicKeyId - 微信支付公钥ID(从商户平台获取)\n * @param publicKey - PEM 格式的微信支付公钥\n */\n setWxPayPublicKey(publicKeyId: string, publicKey: string): void {\n this.wxpayPublicKeyId = publicKeyId;\n this.wxpayPublicKey = publicKey;\n }\n\n /**\n * 获取用于验签的公钥\n *\n * 优先返回微信支付公钥(公钥模式),否则根据证书序列号查找平台证书。\n *\n * @param serialNo - 证书序列号或公钥ID\n * @returns PEM 格式的公钥,不存在则返回 null\n */\n getPublicKey(serialNo: string): string | null {\n // 公钥模式:如果配置了微信支付公钥且序列号匹配\n if (this.wxpayPublicKey && this.wxpayPublicKeyId === serialNo) {\n return this.wxpayPublicKey;\n }\n\n // 公钥模式:如果配置了微信支付公钥且序列号以 PUB_KEY_ID_ 开头\n if (this.wxpayPublicKey && serialNo.startsWith('PUB_KEY_ID_')) {\n return this.wxpayPublicKey;\n }\n\n const cert = this.certificates.get(serialNo);\n if (!cert) return null;\n\n const { ciphertext, nonce, associatedData, algorithm } = cert.encryptCertificate;\n\n // 如果直接传入了公钥(非加密格式),直接返回\n if (algorithm === 'RAW_PUBLIC_KEY') {\n return Buffer.from(ciphertext, 'base64').toString('utf-8');\n }\n\n try {\n const decipher = crypto.createDecipheriv(\n 'aes-256-gcm',\n Buffer.from(this.apiV3Key, 'utf-8'),\n Buffer.from(nonce, 'utf-8'),\n );\n\n decipher.setAAD(Buffer.from(associatedData, 'utf-8'));\n decipher.setAuthTag(Buffer.from(ciphertext, 'base64').subarray(-16));\n\n const encryptedData = Buffer.from(ciphertext, 'base64').subarray(0, -16);\n let decrypted = decipher.update(encryptedData);\n decrypted = Buffer.concat([decrypted, decipher.final()]);\n\n return decrypted.toString('utf-8');\n } catch {\n return null;\n }\n }\n\n /**\n * 更新平台证书\n */\n updateCertificates(certificates: PlatformCertificate[]): void {\n for (const cert of certificates) {\n this.certificates.set(cert.serialNo, cert);\n }\n }\n\n /**\n * 直接设置证书公钥(用于已解密后的证书)\n *\n * @param serialNo - 证书序列号\n * @param publicKey - PEM 格式的公钥\n */\n setPublicKey(serialNo: string, publicKey: string): void {\n // 将公钥以加密证书的形式存储,解密时直接返回\n // 这里使用一个特殊的标记,让 getPublicKey 识别\n const cert: PlatformCertificate = {\n serialNo,\n effectiveTime: new Date().toISOString(),\n expireTime: new Date(Date.now() + 365 * 24 * 3600 * 1000).toISOString(),\n encryptCertificate: {\n algorithm: 'RAW_PUBLIC_KEY',\n nonce: '',\n associatedData: '',\n ciphertext: Buffer.from(publicKey, 'utf-8').toString('base64'),\n },\n };\n this.certificates.set(serialNo, cert);\n }\n\n /**\n * 清空证书缓存\n */\n clear(): void {\n this.certificates.clear();\n this.wxpayPublicKey = null;\n this.wxpayPublicKeyId = null;\n }\n}\n","import type { WxPayResponse, WxPayErrorDetail } from '../types/index.js';\n\n/**\n * 微信支付 API V3 自定义错误类\n */\nexport class WxPayError extends Error {\n /** HTTP 状态码 */\n public readonly status: number;\n /** 错误响应头 */\n public readonly headers: Record<string, string>;\n /** 错误详情 */\n public readonly detail: WxPayErrorDetail;\n\n constructor(status: number, headers: Record<string, string>, detail: WxPayErrorDetail) {\n super(`[${detail.code}] ${detail.message}`);\n this.name = 'WxPayError';\n this.status = status;\n this.headers = headers;\n this.detail = detail;\n }\n\n /** 是否为客户端错误 (4xx) */\n get isClientError(): boolean {\n return this.status >= 400 && this.status < 500;\n }\n\n /** 是否为服务端错误 (5xx) */\n get isServerError(): boolean {\n return this.status >= 500 && this.status < 600;\n }\n}\n\n/**\n * 构建完整的请求 URL\n */\nexport function buildUrl(base: string, path: string, params?: Record<string, unknown>): string {\n const url = new URL(path, base);\n\n if (params) {\n Object.entries(params).forEach(([key, value]) => {\n if (value !== undefined && value !== null) {\n // searchParams.append 内部会调用 toString,此处显式转换是安全的\n // eslint-disable-next-line @typescript-eslint/no-base-to-string\n url.searchParams.append(key, String(value));\n }\n });\n }\n\n return url.toString();\n}\n\n/**\n * 从微信支付响应头中提取关键信息\n */\nexport function parseResponseHeaders(headers: Headers): Record<string, string> {\n const result: Record<string, string> = {};\n const keys = [\n 'wechatpay-serial',\n 'wechatpay-signature',\n 'wechatpay-timestamp',\n 'wechatpay-nonce',\n 'request-id',\n ];\n\n for (const key of keys) {\n const value = headers.get(key);\n if (value) {\n result[key] = value;\n }\n }\n\n return result;\n}\n\n/**\n * 创建 HTTP 请求头\n */\nexport function createRequestHeaders(options: {\n authorization: string;\n accept?: string;\n contentType?: string;\n additional?: Record<string, string>;\n}): Record<string, string> {\n return {\n Authorization: options.authorization,\n Accept: options.accept ?? 'application/json',\n 'Content-Type': options.contentType ?? 'application/json',\n 'User-Agent': 'wxpay-nodejs-sdk/0.1.0',\n ...options.additional,\n };\n}\n\n/**\n * 将 JSON 对象转换为微信支付 API 所需的格式\n */\nexport function toWxPayBody(data: Record<string, unknown>): string {\n return JSON.stringify(data);\n}\n\n/**\n * 微信支付应答验签函数类型\n *\n * @param body - 原始响应体字符串\n * @param signature - Wechatpay-Signature 头的值\n * @param timestamp - Wechatpay-Timestamp 头的值\n * @param nonce - Wechatpay-Nonce 头的值\n * @param serial - Wechatpay-Serial 头的值(证书序列号或公钥ID)\n * @returns 验签是否通过\n */\nexport type ResponseVerifier = (\n body: string,\n signature: string,\n timestamp: string,\n nonce: string,\n serial: string,\n) => boolean;\n\n/**\n * 解析微信支付 API 的 JSON 响应\n *\n * @param response - Fetch Response 对象\n * @param verify - 可选的验签函数,传入时将验证应答签名\n */\nexport async function parseResponse<T>(\n response: Response,\n verify?: ResponseVerifier,\n): Promise<WxPayResponse<T>> {\n const headers = parseResponseHeaders(response.headers);\n\n const rawBody = await response.text();\n\n if (!response.ok) {\n let errorDetail: WxPayErrorDetail;\n try {\n const parsed: unknown = JSON.parse(rawBody);\n if (parsed && typeof parsed === 'object' && 'code' in parsed && 'message' in parsed) {\n errorDetail = parsed as WxPayErrorDetail;\n } else {\n errorDetail = {\n code: 'HTTP_ERROR',\n message: `HTTP ${response.status}: ${response.statusText}`,\n };\n }\n } catch {\n errorDetail = {\n code: 'HTTP_ERROR',\n message: `HTTP ${response.status}: ${response.statusText}`,\n };\n }\n throw new WxPayError(response.status, headers, errorDetail);\n }\n\n if (verify) {\n const signature = headers['wechatpay-signature'];\n const timestamp = headers['wechatpay-timestamp'];\n const nonce = headers['wechatpay-nonce'];\n const serial = headers['wechatpay-serial'];\n\n if (signature && timestamp && nonce && serial) {\n const valid = verify(rawBody, signature, timestamp, nonce, serial);\n if (!valid) {\n throw new WxPayError(response.status, headers, {\n code: 'SIGN_ERROR',\n message: '应答签名验证失败',\n });\n }\n }\n }\n\n let data: T;\n try {\n const parsed: unknown = JSON.parse(rawBody);\n if (parsed === null || parsed === undefined || typeof parsed !== 'object') {\n throw new Error('响应数据格式错误');\n }\n data = parsed as T;\n } catch (error) {\n throw new WxPayError(response.status, headers, {\n code: 'PARSE_ERROR',\n message: error instanceof Error ? error.message : '响应数据解析失败',\n });\n }\n\n return {\n status: response.status,\n headers,\n data,\n };\n}\n","import crypto from 'node:crypto';\n\n/**\n * 微信支付 API V3 签名工具\n *\n * 签名算法: 使用商户私钥对签名串进行 RSA-SHA256 签名\n * 签名串格式: HTTP方法\\nURL路径\\n时间戳\\n随机数\\n请求体\\n\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012365342\n */\n\n/** 签名串的组成部分 */\nexport interface SignPayload {\n /** HTTP 请求方法 (GET/POST/PUT/DELETE) */\n method: string;\n /** 请求 URL 路径(含查询参数,不含域名),如 /v3/pay/transactions/jsapi?mchid=123 */\n path: string;\n /** Unix 时间戳(秒) */\n timestamp: number;\n /** 随机字符串 */\n nonce: string;\n /** 请求体(GET 请求为空字符串) */\n body: string;\n}\n\n/**\n * 构建签名串\n */\nexport function buildSignString(payload: SignPayload): string {\n const { method, path, timestamp, nonce, body } = payload;\n return `${method}\\n${path}\\n${timestamp}\\n${nonce}\\n${body}\\n`;\n}\n\n/**\n * 使用 RSA-SHA256 对签名串进行签名\n *\n * @param signString - 待签名字符串\n * @param privateKey - PEM 格式的商户 API 私钥\n * @returns Base64 编码的签名值\n */\nexport function sign(signString: string, privateKey: string | Buffer): string {\n const signer = crypto.createSign('RSA-SHA256');\n signer.update(signString);\n signer.end();\n return signer.sign(privateKey, 'base64');\n}\n\n/**\n * 生成 WECHATPAY2-SHA256-RSA2048 格式的 Authorization 头\n *\n * @param mchid - 商户号\n * @param serialNo - 商户证书序列号\n * @param timestamp - Unix 时间戳\n * @param nonce - 随机字符串\n * @param signature - Base64 编码的签名\n */\nexport function buildAuthorization(\n mchid: string,\n serialNo: string,\n timestamp: number,\n nonce: string,\n signature: string,\n): string {\n return (\n `WECHATPAY2-SHA256-RSA2048 ` +\n `mchid=\"${mchid}\",` +\n `nonce_str=\"${nonce}\",` +\n `timestamp=\"${timestamp}\",` +\n `serial_no=\"${serialNo}\",` +\n `signature=\"${signature}\"`\n );\n}\n\n/**\n * 生成随机 nonce 字符串\n */\nexport function generateNonce(): string {\n return crypto.randomUUID().replace(/-/g, '');\n}\n\n/**\n * 验证微信支付应答或回调通知签名\n *\n * 签名串格式:应答时间戳\\n应答随机串\\n应答报文主体\\n\n *\n * @param body - 应答或回调的请求体\n * @param signature - HTTP 头 Wechatpay-Signature\n * @param timestamp - HTTP 头 Wechatpay-Timestamp\n * @param nonce - HTTP 头 Wechatpay-Nonce\n * @param publicKey - 微信支付公钥或平台证书公钥(PEM 格式)\n */\nexport function verifySignature(\n body: string,\n signature: string,\n timestamp: string,\n nonce: string,\n publicKey: string | Buffer,\n): boolean {\n const signString = `${timestamp}\\n${nonce}\\n${body}\\n`;\n const verifier = crypto.createVerify('RSA-SHA256');\n verifier.update(signString);\n verifier.end();\n return verifier.verify(publicKey, signature, 'base64');\n}\n\n/**\n * 使用 RSAES-OAEP(SHA-256)算法加密敏感字段\n *\n * 用于分账接口等需要加密接收方姓名等敏感信息的场景。\n *\n * @param plaintext - 待加密的明文\n * @param publicKey - 微信支付公钥或平台证书公钥(PEM 格式)\n * @returns Base64 编码的密文\n */\nexport function oaepEncrypt(plaintext: string, publicKey: string | Buffer): string {\n const encrypted = crypto.publicEncrypt(\n {\n key: publicKey,\n padding: crypto.constants.RSA_PKCS1_OAEP_PADDING,\n oaepHash: 'sha256',\n },\n Buffer.from(plaintext, 'utf-8'),\n );\n return encrypted.toString('base64');\n}\n","import fs from 'node:fs';\nimport type { WxPayOptions, WxPayResponse, WxPayErrorDetail } from '../types/index.js';\nimport { CertificateManager } from './certificate.js';\nimport {\n WxPayError,\n buildUrl,\n createRequestHeaders,\n parseResponse,\n type ResponseVerifier,\n} from '../utils/http.js';\nimport {\n buildSignString,\n sign,\n generateNonce,\n buildAuthorization,\n verifySignature,\n} from '../utils/sign.js';\n\n/**\n * 微信支付 API V3 客户端\n *\n * @example\n * ```ts\n * const wxpay = new WxPayClient({\n * mchid: '1900000100',\n * apiV3Key: 'your-api-v3-key',\n * serialNo: 'your-certificate-serial-number',\n * privateKey: fs.readFileSync('/path/to/apiclient_key.pem'),\n * });\n * ```\n */\nexport class WxPayClient {\n /** 生产环境 API 地址 */\n private static readonly PRODUCTION_BASE = 'https://api.mch.weixin.qq.com';\n\n /** 沙箱环境 API 地址 */\n private static readonly SANDBOX_BASE = 'https://api.mch.weixin.qq.com/sandboxnew';\n\n /** 商户号 */\n public readonly mchid: string;\n private readonly apiV3Key: string;\n private readonly serialNo: string;\n private readonly privateKey: string | Buffer;\n private readonly timeout: number;\n private readonly baseUrl: string;\n private readonly enableResponseVerification: boolean;\n\n /** 平台证书管理器 */\n public readonly certificates: CertificateManager;\n\n constructor(options: WxPayOptions) {\n this.mchid = options.mchid;\n this.apiV3Key = options.apiV3Key;\n this.serialNo = options.serialNo;\n this.privateKey = this.resolvePrivateKey(options.privateKey);\n this.timeout = options.timeout ?? 30000;\n this.baseUrl = options.sandbox ? WxPayClient.SANDBOX_BASE : WxPayClient.PRODUCTION_BASE;\n this.enableResponseVerification = options.enableResponseVerification ?? true;\n\n this.certificates = new CertificateManager(this.apiV3Key, options.platformCertificates);\n\n // 配置微信支付公钥(推荐模式)\n if (options.wxpayPublicKeyId && options.wxpayPublicKey) {\n const publicKey = this.resolvePublicKey(options.wxpayPublicKey);\n this.certificates.setWxPayPublicKey(options.wxpayPublicKeyId, publicKey);\n }\n }\n\n /**\n * 发起 GET 请求\n */\n async get<T = unknown>(\n path: string,\n params?: Record<string, unknown>,\n ): Promise<WxPayResponse<T>> {\n return this.request<T>('GET', path, params);\n }\n\n /**\n * 发起 POST 请求\n */\n async post<T = unknown>(\n path: string,\n body?: object,\n params?: Record<string, unknown>,\n extraHeaders?: Record<string, string>,\n ): Promise<WxPayResponse<T>> {\n return this.request<T>('POST', path, params, body, extraHeaders);\n }\n\n /**\n * 发起 PUT 请求\n */\n async put<T = unknown>(\n path: string,\n body?: object,\n params?: Record<string, unknown>,\n ): Promise<WxPayResponse<T>> {\n return this.request<T>('PUT', path, params, body);\n }\n\n /**\n * 发起 PATCH 请求\n */\n async patch<T = unknown>(\n path: string,\n body?: object,\n params?: Record<string, unknown>,\n ): Promise<WxPayResponse<T>> {\n return this.request<T>('PATCH', path, params, body);\n }\n\n /**\n * 发起 DELETE 请求\n */\n async delete<T = unknown>(\n path: string,\n params?: Record<string, unknown>,\n ): Promise<WxPayResponse<T>> {\n return this.request<T>('DELETE', path, params);\n }\n\n /**\n * 下载原始二进制文件(账单下载等场景)\n *\n * 直接请求完整的 URL(非 API 路径),返回原始响应体。\n * 用于下载账单等返回非 JSON 格式数据的场景。\n *\n * @param url - 完整的下载 URL(从申请账单接口返回的 download_url)\n * @returns 包含原始 Buffer 数据和响应头的 WxPayResponse\n */\n async downloadRaw(url: string): Promise<WxPayResponse<Buffer>> {\n const method = 'GET';\n const bodyStr = '';\n const timestamp = Math.floor(Date.now() / 1000);\n const nonce = generateNonce();\n\n const urlObj = new URL(url);\n const signPath = urlObj.pathname + urlObj.search;\n\n const signString = buildSignString({\n method,\n path: signPath,\n timestamp,\n nonce,\n body: bodyStr,\n });\n\n const signature = sign(signString, this.privateKey);\n const authorization = buildAuthorization(\n this.mchid,\n this.serialNo,\n timestamp,\n nonce,\n signature,\n );\n\n const headers: Record<string, string> = {\n Authorization: authorization,\n Accept: 'application/json',\n 'User-Agent': 'wxpay-nodejs-sdk/0.1.0',\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, this.timeout);\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n signal: controller.signal,\n });\n\n // 下载账单的响应不包含签名,无需验签\n // 但需要处理错误响应\n if (!response.ok) {\n let errorDetail: WxPayErrorDetail;\n try {\n const data: unknown = await response.json();\n if (data && typeof data === 'object' && 'code' in data && 'message' in data) {\n errorDetail = data as WxPayErrorDetail;\n } else {\n errorDetail = {\n code: 'HTTP_ERROR',\n message: `HTTP ${response.status}: ${response.statusText}`,\n };\n }\n } catch {\n errorDetail = {\n code: 'HTTP_ERROR',\n message: `HTTP ${response.status}: ${response.statusText}`,\n };\n }\n throw new WxPayError(response.status, {}, errorDetail);\n }\n\n const arrayBuffer = await response.arrayBuffer();\n const data = Buffer.from(arrayBuffer);\n\n const responseHeaders: Record<string, string> = {};\n response.headers.forEach((value, key) => {\n responseHeaders[key] = value;\n });\n\n return {\n status: response.status,\n headers: responseHeaders,\n data,\n };\n } catch (error) {\n if (error instanceof WxPayError) {\n throw error;\n }\n if (error instanceof DOMException && error.name === 'AbortError') {\n throw new WxPayError(\n 0,\n {},\n {\n code: 'REQUEST_TIMEOUT',\n message: `请求超时 (${this.timeout}ms)`,\n },\n );\n }\n throw new WxPayError(\n 0,\n {},\n {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : '网络请求失败',\n },\n );\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * 上传文件(multipart/form-data)\n *\n * 用于图片上传等需要提交文件的场景。\n * 微信支付文件上传接口要求将 meta(JSON)和 file 分别作为 form-data 的两个 part 提交,\n * 签名计算基于 meta 部分的 JSON 字符串。\n *\n * @param path - API 路径\n * @param file - 文件内容 Buffer\n * @param filename - 文件名\n * @param meta - 业务参数(作为 meta part 的 JSON 内容)\n */\n async upload<T = unknown>(\n path: string,\n file: Buffer,\n filename: string,\n meta?: Record<string, unknown>,\n ): Promise<WxPayResponse<T>> {\n const url = buildUrl(this.baseUrl, path);\n const metaStr = meta ? JSON.stringify(meta) : '{}';\n const timestamp = Math.floor(Date.now() / 1000);\n const nonce = generateNonce();\n\n const urlObj = new URL(url);\n const signPath = urlObj.pathname + urlObj.search;\n\n const signString = buildSignString({\n method: 'POST',\n path: signPath,\n timestamp,\n nonce,\n body: metaStr,\n });\n\n const signature = sign(signString, this.privateKey);\n const authorization = buildAuthorization(\n this.mchid,\n this.serialNo,\n timestamp,\n nonce,\n signature,\n );\n\n const boundary = `----WxPayNodeJSSDK${Date.now()}`;\n const crlf = '\\r\\n';\n\n const parts: Buffer[] = [];\n\n // meta part\n parts.push(\n Buffer.from(\n `--${boundary}${crlf}Content-Disposition: form-data; name=\"meta\"${crlf}Content-Type: application/json${crlf}${crlf}${metaStr}${crlf}`,\n ),\n );\n\n // file part\n const fileHeader = Buffer.from(\n `--${boundary}${crlf}Content-Disposition: form-data; name=\"file\"; filename=\"${filename}\"${crlf}Content-Type: application/octet-stream${crlf}${crlf}`,\n );\n parts.push(fileHeader);\n parts.push(file);\n parts.push(Buffer.from(crlf));\n\n // closing boundary\n parts.push(Buffer.from(`--${boundary}--${crlf}`));\n\n const body = Buffer.concat(parts);\n\n const headers: Record<string, string> = {\n Authorization: authorization,\n Accept: 'application/json',\n 'Content-Type': `multipart/form-data; boundary=${boundary}`,\n 'User-Agent': 'wxpay-nodejs-sdk/0.1.0',\n };\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, this.timeout);\n\n try {\n const response = await fetch(url, {\n method: 'POST',\n headers,\n body,\n signal: controller.signal,\n });\n\n return await parseResponse<T>(response, this.createVerifier());\n } catch (error) {\n if (error instanceof WxPayError) {\n throw error;\n }\n if (error instanceof DOMException && error.name === 'AbortError') {\n throw new WxPayError(\n 0,\n {},\n {\n code: 'REQUEST_TIMEOUT',\n message: `请求超时 (${this.timeout}ms)`,\n },\n );\n }\n throw new WxPayError(\n 0,\n {},\n {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : '网络请求失败',\n },\n );\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * 通用 HTTP 请求方法\n */\n private async request<T = unknown>(\n method: string,\n path: string,\n params?: Record<string, unknown>,\n body?: object,\n extraHeaders?: Record<string, string>,\n ): Promise<WxPayResponse<T>> {\n const url = buildUrl(this.baseUrl, path, params);\n const bodyStr = body ? JSON.stringify(body) : '';\n const timestamp = Math.floor(Date.now() / 1000);\n const nonce = generateNonce();\n\n // 提取 URL 路径部分用于签名\n const urlObj = new URL(url);\n const signPath = urlObj.pathname + urlObj.search;\n\n // 构建签名\n const signString = buildSignString({\n method: method.toUpperCase(),\n path: signPath,\n timestamp,\n nonce,\n body: bodyStr,\n });\n\n const signature = sign(signString, this.privateKey);\n\n // 构建 Authorization 头\n const authorization = buildAuthorization(\n this.mchid,\n this.serialNo,\n timestamp,\n nonce,\n signature,\n );\n\n const headers = createRequestHeaders({ authorization, additional: extraHeaders });\n\n const controller = new AbortController();\n const timeoutId = setTimeout(() => {\n controller.abort();\n }, this.timeout);\n\n try {\n const response = await fetch(url, {\n method,\n headers,\n body: bodyStr || undefined,\n signal: controller.signal,\n });\n\n return await parseResponse<T>(response, this.createVerifier());\n } catch (error) {\n if (error instanceof WxPayError) {\n throw error;\n }\n if (error instanceof DOMException && error.name === 'AbortError') {\n throw new WxPayError(\n 0,\n {},\n {\n code: 'REQUEST_TIMEOUT',\n message: `请求超时 (${this.timeout}ms)`,\n },\n );\n }\n throw new WxPayError(\n 0,\n {},\n {\n code: 'NETWORK_ERROR',\n message: error instanceof Error ? error.message : '网络请求失败',\n },\n );\n } finally {\n clearTimeout(timeoutId);\n }\n }\n\n /**\n * 解析私钥:支持直接传入内容或文件路径\n */\n private resolvePrivateKey(key: string | Buffer): string | Buffer {\n if (Buffer.isBuffer(key)) return key;\n\n // 以 PEM 格式开头,直接返回\n if (key.startsWith('-----BEGIN')) return key;\n\n // 否则认为是文件路径\n try {\n return fs.readFileSync(key, 'utf-8');\n } catch {\n // 如果读取失败,假定是密钥内容\n return key;\n }\n }\n\n /**\n * 解析公钥:支持直接传入内容或文件路径\n */\n private resolvePublicKey(key: string | Buffer): string {\n if (Buffer.isBuffer(key)) return key.toString('utf-8');\n\n // 以 PEM 格式开头,直接返回\n if (key.startsWith('-----BEGIN')) return key;\n\n // 否则认为是文件路径\n try {\n return fs.readFileSync(key, 'utf-8');\n } catch {\n return key;\n }\n }\n\n /**\n * 创建应答验签函数\n */\n private createVerifier(): ResponseVerifier | undefined {\n if (!this.enableResponseVerification) return undefined;\n\n return (\n body: string,\n signature: string,\n timestamp: string,\n nonce: string,\n serial: string,\n ): boolean => {\n const publicKey = this.certificates.getPublicKey(serial);\n if (!publicKey) {\n throw new Error(`未找到序列号为 ${serial} 的平台证书或公钥,请确保已配置`);\n }\n return verifySignature(body, signature, timestamp, nonce, publicKey);\n };\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateJsapiOrderRequest,\n CreateJsapiOrderResponse,\n QueryOrderParams,\n QueryOrderResponse,\n CloseOrderRequest,\n CreateRefundRequest,\n CreateRefundResponse,\n ApplyAbnormalRefundRequest,\n ApplyAbnormalRefundResponse,\n QueryRefundParams,\n QueryRefundResponse,\n TradeBillParams,\n TradeBillResponse,\n FundFlowBillParams,\n FundFlowBillResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * JSAPI 支付 / 小程序支付 服务\n *\n * 提供 JSAPI 支付全流程相关的 API 封装,包括:\n * - JSAPI/小程序下单\n * - 查询订单\n * - 关闭订单\n * - 申请退款\n * - 查询退款\n * - 申请异常退款\n * - 申请交易账单\n * - 申请资金账单\n * - 下载账单\n */\nexport class JsapiService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * JSAPI/小程序下单\n *\n * 商户通过此接口生成预付单并获取 prepay_id。\n * prepay_id 有效期为 2 小时,超过 2 小时需重新请求。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791856\n */\n async createOrder(\n request: CreateJsapiOrderRequest,\n ): Promise<WxPayResponse<CreateJsapiOrderResponse>> {\n return this.client.post<CreateJsapiOrderResponse>('/v3/pay/transactions/jsapi', request);\n }\n\n /**\n * 查询 JSAPI 支付订单\n *\n * 支持通过微信支付订单号或商户订单号查询订单状态。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791858 (微信支付订单号查询订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791859 (商户订单号查询订单)\n */\n async queryOrderById(params: QueryOrderParams): Promise<WxPayResponse<QueryOrderResponse>> {\n if (params.transactionId) {\n return this.client.get<QueryOrderResponse>(\n `/v3/pay/transactions/id/${params.transactionId}`,\n { mchid: this.client.mchid },\n );\n }\n if (params.outTradeNo) {\n return this.client.get<QueryOrderResponse>(\n `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,\n { mchid: this.client.mchid },\n );\n }\n throw new Error('outTradeNo 或 transactionId 必须提供其中一个');\n }\n\n /**\n * 关闭订单\n *\n * 对于未支付的订单,商户可通过此接口关闭订单。\n * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791860\n */\n async closeOrder(outTradeNo: string, request: CloseOrderRequest): Promise<WxPayResponse> {\n return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);\n }\n\n /**\n * 申请退款\n *\n * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。\n * 仅支持支付成功后 1 年内的订单。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791862\n */\n async createRefund(request: CreateRefundRequest): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.post<CreateRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询退款单\n *\n * 通过商户退款单号查询退款状态。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791863\n */\n async queryRefund(params: QueryRefundParams): Promise<WxPayResponse<QueryRefundResponse>> {\n return this.client.get<QueryRefundResponse>(\n `/v3/refund/domestic/refunds/${params.outRefundNo}`,\n );\n }\n\n /**\n * 申请交易账单\n *\n * 商户可通过此接口获取交易账单的下载链接。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791866\n */\n async tradeBill(params: TradeBillParams): Promise<WxPayResponse<TradeBillResponse>> {\n return this.client.get<TradeBillResponse>('/v3/bill/tradebill', params);\n }\n\n /**\n * 申请资金账单\n *\n * 商户可通过此接口获取资金账单的下载链接。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791867\n */\n async fundFlowBill(params: FundFlowBillParams): Promise<WxPayResponse<FundFlowBillResponse>> {\n return this.client.get<FundFlowBillResponse>('/v3/bill/fundflowbill', params);\n }\n\n /**\n * 申请异常退款\n *\n * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。\n * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。\n *\n * @param refundId - 微信支付退款单号\n * @param request - 异常退款请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791864\n */\n async applyAbnormalRefund(\n refundId: string,\n request: ApplyAbnormalRefundRequest,\n ): Promise<WxPayResponse<ApplyAbnormalRefundResponse>> {\n return this.client.post<ApplyAbnormalRefundResponse>(\n `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,\n request,\n );\n }\n\n /**\n * 下载账单\n *\n * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。\n * 下载地址 5 分钟内有效,请及时下载。\n * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。\n *\n * @param downloadUrl - 申请账单返回的 download_url\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791868\n */\n async downloadBill(downloadUrl: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(downloadUrl);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateH5OrderRequest,\n CreateH5OrderResponse,\n QueryOrderParams,\n QueryOrderResponse,\n CloseOrderRequest,\n CreateRefundRequest,\n CreateRefundResponse,\n ApplyAbnormalRefundRequest,\n ApplyAbnormalRefundResponse,\n QueryRefundParams,\n QueryRefundResponse,\n TradeBillParams,\n TradeBillResponse,\n FundFlowBillParams,\n FundFlowBillResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * H5 支付服务\n *\n * 提供 H5 支付全流程相关的 API 封装,包括:\n * - H5 下单\n * - 查询订单\n * - 关闭订单\n * - 申请退款\n * - 查询退款\n * - 申请异常退款\n * - 申请交易账单\n * - 申请资金账单\n * - 下载账单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791834\n */\nexport class H5Service {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * H5 支付下单\n *\n * 商户通过此接口生成 H5 支付链接(h5_url),用于在已配置 H5 支付域名的网页中\n * 跳转并调起微信支付收银台。h5_url 有效期为 5 分钟,过期后需重新请求。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791834\n */\n async createOrder(request: CreateH5OrderRequest): Promise<WxPayResponse<CreateH5OrderResponse>> {\n return this.client.post<CreateH5OrderResponse>('/v3/pay/transactions/h5', request);\n }\n\n /**\n * 查询订单\n *\n * 支持通过微信支付订单号或商户订单号查询订单状态。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791837 (微信支付订单号查询订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791838 (商户订单号查询订单)\n */\n async queryOrderById(params: QueryOrderParams): Promise<WxPayResponse<QueryOrderResponse>> {\n if (params.transactionId) {\n return this.client.get<QueryOrderResponse>(\n `/v3/pay/transactions/id/${params.transactionId}`,\n { mchid: this.client.mchid },\n );\n }\n if (params.outTradeNo) {\n return this.client.get<QueryOrderResponse>(\n `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,\n { mchid: this.client.mchid },\n );\n }\n throw new Error('outTradeNo 或 transactionId 必须提供其中一个');\n }\n\n /**\n * 关闭订单\n *\n * 对于未支付的订单,商户可通过此接口关闭订单。\n * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791839\n */\n async closeOrder(outTradeNo: string, request: CloseOrderRequest): Promise<WxPayResponse> {\n return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);\n }\n\n /**\n * 申请退款\n *\n * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。\n * 仅支持支付成功后 1 年内的订单。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810597\n */\n async createRefund(request: CreateRefundRequest): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.post<CreateRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询退款单\n *\n * 通过商户退款单号查询退款状态。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810601\n */\n async queryRefund(params: QueryRefundParams): Promise<WxPayResponse<QueryRefundResponse>> {\n return this.client.get<QueryRefundResponse>(\n `/v3/refund/domestic/refunds/${params.outRefundNo}`,\n );\n }\n\n /**\n * 申请异常退款\n *\n * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。\n * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。\n *\n * @param refundId - 微信支付退款单号\n * @param request - 异常退款请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810603\n */\n async applyAbnormalRefund(\n refundId: string,\n request: ApplyAbnormalRefundRequest,\n ): Promise<WxPayResponse<ApplyAbnormalRefundResponse>> {\n return this.client.post<ApplyAbnormalRefundResponse>(\n `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,\n request,\n );\n }\n\n /**\n * 申请交易账单\n *\n * 商户可通过此接口获取交易账单的下载链接。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810606\n */\n async tradeBill(params: TradeBillParams): Promise<WxPayResponse<TradeBillResponse>> {\n return this.client.get<TradeBillResponse>('/v3/bill/tradebill', params);\n }\n\n /**\n * 申请资金账单\n *\n * 商户可通过此接口获取资金账单的下载链接。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810609\n */\n async fundFlowBill(params: FundFlowBillParams): Promise<WxPayResponse<FundFlowBillResponse>> {\n return this.client.get<FundFlowBillResponse>('/v3/bill/fundflowbill', params);\n }\n\n /**\n * 下载账单\n *\n * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。\n * 下载地址 5 分钟内有效,请及时下载。\n * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。\n *\n * @param downloadUrl - 申请账单返回的 download_url\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012810615\n */\n async downloadBill(downloadUrl: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(downloadUrl);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateAppOrderRequest,\n CreateAppOrderResponse,\n QueryOrderParams,\n QueryOrderResponse,\n CloseOrderRequest,\n CreateRefundRequest,\n CreateRefundResponse,\n ApplyAbnormalRefundRequest,\n ApplyAbnormalRefundResponse,\n QueryRefundParams,\n QueryRefundResponse,\n TradeBillParams,\n TradeBillResponse,\n FundFlowBillParams,\n FundFlowBillResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * APP 支付服务\n *\n * 提供 APP 支付全流程相关的 API 封装,包括:\n * - APP 下单\n * - 查询订单\n * - 关闭订单\n * - 申请退款\n * - 查询退款\n * - 申请异常退款\n * - 申请交易账单\n * - 申请资金账单\n * - 下载账单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070347\n */\nexport class AppService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * APP 支付下单\n *\n * 商户通过此接口生成预付单并获取 prepay_id。\n * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070347\n */\n async createOrder(\n request: CreateAppOrderRequest,\n ): Promise<WxPayResponse<CreateAppOrderResponse>> {\n return this.client.post<CreateAppOrderResponse>('/v3/pay/transactions/app', request);\n }\n\n /**\n * 查询订单\n *\n * 支持通过微信支付订单号或商户订单号查询订单状态。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070354 (微信支付订单号查询订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070356 (商户订单号查询订单)\n */\n async queryOrderById(params: QueryOrderParams): Promise<WxPayResponse<QueryOrderResponse>> {\n if (params.transactionId) {\n return this.client.get<QueryOrderResponse>(\n `/v3/pay/transactions/id/${params.transactionId}`,\n { mchid: this.client.mchid },\n );\n }\n if (params.outTradeNo) {\n return this.client.get<QueryOrderResponse>(\n `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,\n { mchid: this.client.mchid },\n );\n }\n throw new Error('outTradeNo 或 transactionId 必须提供其中一个');\n }\n\n /**\n * 关闭订单\n *\n * 对于未支付的订单,商户可通过此接口关闭订单。\n * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070360\n */\n async closeOrder(outTradeNo: string, request: CloseOrderRequest): Promise<WxPayResponse> {\n return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);\n }\n\n /**\n * 申请退款\n *\n * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。\n * 仅支持支付成功后 1 年内的订单。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070371\n */\n async createRefund(request: CreateRefundRequest): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.post<CreateRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询退款单\n *\n * 通过商户退款单号查询退款状态。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070374\n */\n async queryRefund(params: QueryRefundParams): Promise<WxPayResponse<QueryRefundResponse>> {\n return this.client.get<QueryRefundResponse>(\n `/v3/refund/domestic/refunds/${params.outRefundNo}`,\n );\n }\n\n /**\n * 申请异常退款\n *\n * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。\n * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。\n *\n * @param refundId - 微信支付退款单号\n * @param request - 异常退款请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070379\n */\n async applyAbnormalRefund(\n refundId: string,\n request: ApplyAbnormalRefundRequest,\n ): Promise<WxPayResponse<ApplyAbnormalRefundResponse>> {\n return this.client.post<ApplyAbnormalRefundResponse>(\n `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,\n request,\n );\n }\n\n /**\n * 申请交易账单\n *\n * 商户可通过此接口获取交易账单的下载链接。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070395\n */\n async tradeBill(params: TradeBillParams): Promise<WxPayResponse<TradeBillResponse>> {\n return this.client.get<TradeBillResponse>('/v3/bill/tradebill', params);\n }\n\n /**\n * 申请资金账单\n *\n * 商户可通过此接口获取资金账单的下载链接。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070400\n */\n async fundFlowBill(params: FundFlowBillParams): Promise<WxPayResponse<FundFlowBillResponse>> {\n return this.client.get<FundFlowBillResponse>('/v3/bill/fundflowbill', params);\n }\n\n /**\n * 下载账单\n *\n * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。\n * 下载地址 5 分钟内有效,请及时下载。\n * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。\n *\n * @param downloadUrl - 申请账单返回的 download_url\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070401\n */\n async downloadBill(downloadUrl: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(downloadUrl);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateNativeOrderRequest,\n CreateNativeOrderResponse,\n QueryOrderParams,\n QueryOrderResponse,\n CloseOrderRequest,\n CreateRefundRequest,\n CreateRefundResponse,\n ApplyAbnormalRefundRequest,\n ApplyAbnormalRefundResponse,\n QueryRefundParams,\n QueryRefundResponse,\n TradeBillParams,\n TradeBillResponse,\n FundFlowBillParams,\n FundFlowBillResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * Native 支付服务\n *\n * 提供 Native 支付(二维码支付)全流程相关的 API 封装,包括:\n * - Native 下单(获取 code_url 用于生成二维码)\n * - 查询订单\n * - 关闭订单\n * - 申请退款\n * - 查询退款\n * - 申请异常退款\n * - 申请交易账单\n * - 申请资金账单\n * - 下载账单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791877\n */\nexport class NativeService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * Native 支付下单\n *\n * 商户通过此接口生成订单并获取二维码链接(code_url)。\n * code_url 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。\n *\n * 商户后端获取 code_url 后传递给前端,前端将其转换为二维码图片展示给用户。\n * 用户使用微信扫一扫扫描二维码后,将调起微信收银台完成支付。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791877\n */\n async createOrder(\n request: CreateNativeOrderRequest,\n ): Promise<WxPayResponse<CreateNativeOrderResponse>> {\n return this.client.post<CreateNativeOrderResponse>('/v3/pay/transactions/native', request);\n }\n\n /**\n * 查询订单\n *\n * 支持通过微信支付订单号或商户订单号查询订单状态。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791879 (微信支付订单号查询订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791880 (商户订单号查询订单)\n */\n async queryOrderById(params: QueryOrderParams): Promise<WxPayResponse<QueryOrderResponse>> {\n if (params.transactionId) {\n return this.client.get<QueryOrderResponse>(\n `/v3/pay/transactions/id/${params.transactionId}`,\n { mchid: this.client.mchid },\n );\n }\n if (params.outTradeNo) {\n return this.client.get<QueryOrderResponse>(\n `/v3/pay/transactions/out-trade-no/${params.outTradeNo}`,\n { mchid: this.client.mchid },\n );\n }\n throw new Error('outTradeNo 或 transactionId 必须提供其中一个');\n }\n\n /**\n * 关闭订单\n *\n * 对于未支付的订单,商户可通过此接口关闭订单。\n * 关单后,订单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791881\n */\n async closeOrder(outTradeNo: string, request: CloseOrderRequest): Promise<WxPayResponse> {\n return this.client.post(`/v3/pay/transactions/out-trade-no/${outTradeNo}/close`, request);\n }\n\n /**\n * 申请退款\n *\n * 当订单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。\n * 仅支持支付成功后 1 年内的订单。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791883\n */\n async createRefund(request: CreateRefundRequest): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.post<CreateRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询退款单\n *\n * 通过商户退款单号查询退款状态。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791884\n */\n async queryRefund(params: QueryRefundParams): Promise<WxPayResponse<QueryRefundResponse>> {\n return this.client.get<QueryRefundResponse>(\n `/v3/refund/domestic/refunds/${params.outRefundNo}`,\n );\n }\n\n /**\n * 申请异常退款\n *\n * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。\n * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。\n *\n * @param refundId - 微信支付退款单号\n * @param request - 异常退款请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791885\n */\n async applyAbnormalRefund(\n refundId: string,\n request: ApplyAbnormalRefundRequest,\n ): Promise<WxPayResponse<ApplyAbnormalRefundResponse>> {\n return this.client.post<ApplyAbnormalRefundResponse>(\n `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,\n request,\n );\n }\n\n /**\n * 申请交易账单\n *\n * 商户可通过此接口获取交易账单的下载链接。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791887\n */\n async tradeBill(params: TradeBillParams): Promise<WxPayResponse<TradeBillResponse>> {\n return this.client.get<TradeBillResponse>('/v3/bill/tradebill', params);\n }\n\n /**\n * 申请资金账单\n *\n * 商户可通过此接口获取资金账单的下载链接。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791888\n */\n async fundFlowBill(params: FundFlowBillParams): Promise<WxPayResponse<FundFlowBillResponse>> {\n return this.client.get<FundFlowBillResponse>('/v3/bill/fundflowbill', params);\n }\n\n /**\n * 下载账单\n *\n * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。\n * 下载地址 5 分钟内有效,请及时下载。\n * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。\n *\n * @param downloadUrl - 申请账单返回的 download_url\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791889\n */\n async downloadBill(downloadUrl: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(downloadUrl);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateCombineOrderRequest,\n CreateCombineOrderResponse,\n QueryCombineOrderParams,\n QueryCombineOrderResponse,\n CloseCombineOrderParams,\n CloseCombineOrderRequest,\n CreateRefundRequest,\n CreateRefundResponse,\n ApplyAbnormalRefundRequest,\n ApplyAbnormalRefundResponse,\n QueryRefundParams,\n QueryRefundResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 合单支付服务\n *\n * 提供 JSAPI 合单支付全流程相关的 API 封装,包括:\n * - JSAPI 合单下单(获取 prepay_id)\n * - 查询合单订单\n * - 关闭合单订单\n * - 申请退款\n * - 查询退款\n * - 申请异常退款\n *\n * 合单支付允许一笔支付中包含 2-10 个子单,适用于多商户场景。\n * 各子单商户号需与合单发起方 APPID 绑定。\n *\n * 注意:对于合单支付的订单,无法通过合单支付总单号 combine_out_trade_no 退款,\n * 只能根据单个子单的 transaction_id 或 out_trade_no 进行退款。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556926 (合单下单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421222 (查询合单订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421225 (关闭合单订单)\n */\nexport class CombineService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * JSAPI 合单下单\n *\n * 商户通过此接口生成合单预付单并获取 prepay_id。\n * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。\n *\n * 关键约束:\n * - combine_mchid 需先申请发起合单支付权限\n * - sub_orders 中的 mchid 需先申请接收合单支付权限\n * - 合单发起方和子单参与方需绑定同一个 combine_appid\n * - 子单数量为 2-10 笔\n * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556926\n */\n async createOrder(\n request: CreateCombineOrderRequest,\n ): Promise<WxPayResponse<CreateCombineOrderResponse>> {\n return this.client.post<CreateCombineOrderResponse>('/v3/combine-transactions/jsapi', request);\n }\n\n /**\n * 查询合单订单\n *\n * 通过合单商户订单号查询合单订单的支付状态及各子单详情。\n *\n * 订单状态(sub_orders[].trade_state):\n * - SUCCESS:支付成功(终态)\n * - NOTPAY:未支付\n * - CLOSED:已关闭(终态)\n *\n * 注意:请勿使用非合单支付的查单接口查询合单订单。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421222\n */\n async queryOrderById(\n params: QueryCombineOrderParams,\n ): Promise<WxPayResponse<QueryCombineOrderResponse>> {\n return this.client.get<QueryCombineOrderResponse>(\n `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`,\n );\n }\n\n /**\n * 关闭合单订单\n *\n * 对于未支付的合单订单,商户可通过此接口关闭订单。\n * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。\n *\n * 关键约束:\n * - 只能整单关闭,不支持关闭部分子单\n * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致\n * - 仅支持未支付状态的订单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421225\n */\n async closeOrder(\n params: CloseCombineOrderParams,\n request: CloseCombineOrderRequest,\n ): Promise<WxPayResponse> {\n return this.client.post(\n `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,\n request,\n );\n }\n\n /**\n * 申请退款\n *\n * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口对子单申请退款。\n * 仅支持支付成功后 1 年内的订单。\n *\n * 注意:合单支付的订单无法通过合单总单号 combine_out_trade_no 退款,\n * 需要传入子单的 transaction_id 或 out_trade_no。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421249\n */\n async createRefund(request: CreateRefundRequest): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.post<CreateRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询退款单\n *\n * 通过商户退款单号查询退款状态。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421261\n */\n async queryRefund(params: QueryRefundParams): Promise<WxPayResponse<QueryRefundResponse>> {\n return this.client.get<QueryRefundResponse>(\n `/v3/refund/domestic/refunds/${params.outRefundNo}`,\n );\n }\n\n /**\n * 申请异常退款\n *\n * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。\n * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。\n *\n * @param refundId - 微信支付退款单号\n * @param request - 异常退款请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421269\n */\n async applyAbnormalRefund(\n refundId: string,\n request: ApplyAbnormalRefundRequest,\n ): Promise<WxPayResponse<ApplyAbnormalRefundResponse>> {\n return this.client.post<ApplyAbnormalRefundResponse>(\n `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,\n request,\n );\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateH5CombineOrderRequest,\n CreateH5CombineOrderResponse,\n QueryCombineOrderParams,\n QueryCombineOrderResponse,\n CloseCombineOrderParams,\n CloseCombineOrderRequest,\n CreateRefundRequest,\n CreateRefundResponse,\n ApplyAbnormalRefundRequest,\n ApplyAbnormalRefundResponse,\n QueryRefundParams,\n QueryRefundResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * H5 合单支付服务\n *\n * 提供 H5 合单支付全流程相关的 API 封装,包括:\n * - H5 合单下单(获取 h5_url 用于跳转支付中间页)\n * - 查询合单订单\n * - 关闭合单订单\n * - 申请退款(基于子单)\n * - 查询退款单\n * - 申请异常退款\n *\n * 合单支付允许一笔支付中包含 2-10 个子单,适用于多商户场景。\n * 各子单商户号需与合单发起方 APPID 绑定。\n *\n * H5 合单支付流程:\n * 1. 调用 createOrder 获取 h5_url\n * 2. 在已配置 H5 支付域名的网页中跳转 h5_url 唤起微信支付收银台\n * 3. 用户支付完成后,通过回调通知或主动查询确认订单状态\n * 4. 退款时需基于子单进行退款,无法通过合单商户订单号退款\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556961 (H5 合单下单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421126 (查询合单订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421130 (关闭合单订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421148 (合单退款)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421156 (查询退款单)\n */\nexport class CombineH5Service {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * H5 合单下单\n *\n * 商户通过此接口生成 H5 合单支付链接(h5_url),用于在已配置 H5 支付域名的\n * 网页中跳转并唤起微信支付收银台。h5_url 有效期为 5 分钟,过期后需使用\n * 原下单参数重新请求。\n *\n * 关键约束:\n * - combine_mchid 需先申请发起合单支付权限\n * - sub_orders 中的 mchid 需先申请接收合单支付权限\n * - 合单发起方和子单参与方需绑定同一个 combine_appid\n * - 子单数量为 2-10 笔\n * - scene_info.payer_client_ip 需传真实的用户端 IP\n * - scene_info.h5_info 必填,需指定 type 为 Wap/iOS/Android 之一\n * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556961\n */\n async createOrder(\n request: CreateH5CombineOrderRequest,\n ): Promise<WxPayResponse<CreateH5CombineOrderResponse>> {\n return this.client.post<CreateH5CombineOrderResponse>('/v3/combine-transactions/h5', request);\n }\n\n /**\n * 查询合单订单\n *\n * 通过合单商户订单号查询合单订单的支付状态及各子单详情。\n * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。\n *\n * 订单状态(sub_orders[].trade_state):\n * - SUCCESS:支付成功(终态)\n * - NOTPAY:未支付\n * - CLOSED:已关闭(终态)\n *\n * 典型使用场景:\n * - 用户支付后从收银台返回商户页面时,确认订单支付状态\n * - 未收到支付成功回调通知时,主动查询确认订单状态\n * - 关单前确认订单仍为未支付状态\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421126\n */\n async queryOrderById(\n params: QueryCombineOrderParams,\n ): Promise<WxPayResponse<QueryCombineOrderResponse>> {\n return this.client.get<QueryCombineOrderResponse>(\n `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`,\n );\n }\n\n /**\n * 关闭合单订单\n *\n * 对于未支付的合单订单,商户可通过此接口关闭订单。\n * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。\n *\n * 关键约束:\n * - 只能整单关闭,不支持关闭部分子单\n * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致\n * - 仅支持未支付状态的订单\n * - 关单后订单为失败终态\n *\n * 典型使用场景:\n * - 用户超过商户系统内部规定的支付时间\n * - 超过下单时设置的 time_expire 时间\n * - 因特殊原因需在可支付时间范围内关闭订单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421130\n */\n async closeOrder(\n params: CloseCombineOrderParams,\n request: CloseCombineOrderRequest,\n ): Promise<WxPayResponse> {\n return this.client.post(\n `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,\n request,\n );\n }\n\n /**\n * 申请退款(基于子单)\n *\n * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,\n * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。\n *\n * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。\n * 仅支持支付成功后 1 年内的订单。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421148\n */\n async createRefund(request: CreateRefundRequest): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.post<CreateRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询退款单\n *\n * 通过商户退款单号查询退款状态。\n * 退款申请成功后,可通过此接口确认退款是否到账。\n *\n * 退款状态:\n * - SUCCESS:退款成功\n * - CLOSED:退款关闭\n * - PROCESSING:退款处理中\n * - ABNORMAL:退款异常\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421156\n */\n async queryRefund(params: QueryRefundParams): Promise<WxPayResponse<QueryRefundResponse>> {\n return this.client.get<QueryRefundResponse>(\n `/v3/refund/domestic/refunds/${params.outRefundNo}`,\n );\n }\n\n /**\n * 申请异常退款\n *\n * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。\n * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。\n *\n * @param refundId - 微信支付退款单号\n * @param request - 异常退款请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421164\n */\n async applyAbnormalRefund(\n refundId: string,\n request: ApplyAbnormalRefundRequest,\n ): Promise<WxPayResponse<ApplyAbnormalRefundResponse>> {\n return this.client.post<ApplyAbnormalRefundResponse>(\n `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,\n request,\n );\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateAppCombineOrderRequest,\n CreateAppCombineOrderResponse,\n QueryCombineOrderParams,\n QueryCombineOrderResponse,\n CloseCombineOrderParams,\n CloseCombineOrderRequest,\n CreateRefundRequest,\n CreateRefundResponse,\n ApplyAbnormalRefundRequest,\n ApplyAbnormalRefundResponse,\n QueryRefundParams,\n QueryRefundResponse,\n TradeBillParams,\n TradeBillResponse,\n FundFlowBillParams,\n FundFlowBillResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * APP 合单支付服务\n *\n * 提供 APP 合单支付全流程相关的 API 封装,包括:\n * - APP 合单下单(获取 prepay_id,用于通过 OpenSDK 调起支付)\n * - 查询合单订单\n * - 关闭合单订单\n * - 申请退款(基于子单)\n * - 查询退款单\n * - 申请异常退款\n * - 申请交易账单\n * - 申请资金账单\n * - 下载账单\n *\n * 合单支付允许一笔支付中包含 2-10 个子单,适用于多商户场景。\n * 各子单商户号需与合单发起方 APPID 绑定。\n *\n * APP 合单支付流程:\n * 1. 调用 createOrder 获取 prepay_id\n * 2. 使用 buildAppBridgeConfig 生成调起支付参数,通过 OpenSDK 的 sendReq 调起微信支付\n * 3. 用户支付完成后,通过回调通知或主动查询确认订单状态\n * 4. 退款时需基于子单进行退款,无法通过合单商户订单号退款\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556944 (APP 合单下单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557006 (查询合单订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012577452 (关闭合单订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556524 (申请退款)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556587 (查询退款单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556692 (下载交易账单)\n */\nexport class CombineAppService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * APP 合单下单\n *\n * 商户通过此接口生成 APP 合单预付单并获取 prepay_id。\n * 获取 prepay_id 后,配合 buildAppBridgeConfig 生成调起支付参数,\n * 通过微信 OpenSDK 的 sendReq 方法在商户 APP 内调起微信支付收银台。\n *\n * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。\n *\n * 关键约束:\n * - combine_mchid 需先申请发起合单支付权限\n * - sub_orders 中的 mchid 需先申请接收合单支付权限\n * - 合单发起方和子单参与方需绑定同一个 combine_appid\n * - combine_appid 必须为移动应用 APPID\n * - 子单数量为 2-10 笔\n * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556944\n */\n async createOrder(\n request: CreateAppCombineOrderRequest,\n ): Promise<WxPayResponse<CreateAppCombineOrderResponse>> {\n return this.client.post<CreateAppCombineOrderResponse>('/v3/combine-transactions/app', request);\n }\n\n /**\n * 查询合单订单\n *\n * 通过合单商户订单号查询合单订单的支付状态及各子单详情。\n * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。\n *\n * 订单状态(sub_orders[].trade_state):\n * - SUCCESS:支付成功(终态)\n * - NOTPAY:未支付\n * - CLOSED:已关闭(终态)\n *\n * 典型使用场景:\n * - 用户支付后从微信收银台返回商户 APP 时,OpenSDK 回调 onResp 后确认订单支付状态\n * - 未收到支付成功回调通知时,主动查询确认订单状态\n * - 关单前确认订单仍为未支付状态\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557006\n */\n async queryOrderById(\n params: QueryCombineOrderParams,\n ): Promise<WxPayResponse<QueryCombineOrderResponse>> {\n return this.client.get<QueryCombineOrderResponse>(\n `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`,\n );\n }\n\n /**\n * 关闭合单订单\n *\n * 对于未支付的合单订单,商户可通过此接口关闭订单。\n * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。\n *\n * 关键约束:\n * - 只能整单关闭,不支持关闭部分子单\n * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致\n * - 仅支持未支付状态的订单\n * - 关单后订单为失败终态\n *\n * 典型使用场景:\n * - 用户超过商户系统内部规定的支付时间\n * - 超过下单时设置的 time_expire 时间\n * - 因特殊原因需在可支付时间范围内关闭订单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012577452\n */\n async closeOrder(\n params: CloseCombineOrderParams,\n request: CloseCombineOrderRequest,\n ): Promise<WxPayResponse> {\n return this.client.post(\n `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,\n request,\n );\n }\n\n /**\n * 申请退款(基于子单)\n *\n * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,\n * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。\n *\n * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。\n * 仅支持支付成功后 1 年内的订单。\n *\n * 注意:\n * - 一笔订单最多支持 50 次部分退款,间隔至少 1 分钟\n * - 重试时必须使用原商户退款单号,避免重复退款\n * - 接口返回成功仅表示受理成功,最终结果以回调通知和查询接口为准\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556524\n */\n async createRefund(request: CreateRefundRequest): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.post<CreateRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询退款单\n *\n * 通过商户退款单号查询退款状态。\n * 退款申请成功后,可通过此接口确认退款是否到账。\n *\n * 退款状态:\n * - SUCCESS:退款成功\n * - CLOSED:退款关闭\n * - PROCESSING:退款处理中\n * - ABNORMAL:退款异常\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556587\n */\n async queryRefund(params: QueryRefundParams): Promise<WxPayResponse<QueryRefundResponse>> {\n return this.client.get<QueryRefundResponse>(\n `/v3/refund/domestic/refunds/${params.outRefundNo}`,\n );\n }\n\n /**\n * 申请异常退款\n *\n * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。\n * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。\n *\n * @param refundId - 微信支付退款单号\n * @param request - 异常退款请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013420988\n */\n async applyAbnormalRefund(\n refundId: string,\n request: ApplyAbnormalRefundRequest,\n ): Promise<WxPayResponse<ApplyAbnormalRefundResponse>> {\n return this.client.post<ApplyAbnormalRefundResponse>(\n `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,\n request,\n );\n }\n\n /**\n * 申请交易账单\n *\n * 合单支付的订单账单是以子单为维度,每笔子单都会记录在各个子单商户账单内,\n * 需要各个子单商户自己进行下载。\n *\n * 商户可通过此接口获取交易账单的下载链接,下载地址 5 分钟内有效。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556692\n */\n async tradeBill(params: TradeBillParams): Promise<WxPayResponse<TradeBillResponse>> {\n return this.client.get<TradeBillResponse>('/v3/bill/tradebill', params);\n }\n\n /**\n * 申请资金账单\n *\n * 商户可通过此接口获取资金账单的下载链接,下载地址 5 分钟内有效。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556748\n */\n async fundFlowBill(params: FundFlowBillParams): Promise<WxPayResponse<FundFlowBillResponse>> {\n return this.client.get<FundFlowBillResponse>('/v3/bill/fundflowbill', params);\n }\n\n /**\n * 下载账单\n *\n * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。\n * 下载地址 5 分钟内有效,请及时下载。\n * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。\n *\n * @param downloadUrl - 申请账单返回的 download_url\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012085923\n */\n async downloadBill(downloadUrl: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(downloadUrl);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateMiniProgramCombineOrderRequest,\n CreateMiniProgramCombineOrderResponse,\n QueryCombineOrderParams,\n QueryCombineOrderResponse,\n CloseCombineOrderParams,\n CloseCombineOrderRequest,\n CreateRefundRequest,\n CreateRefundResponse,\n ApplyAbnormalRefundRequest,\n ApplyAbnormalRefundResponse,\n QueryRefundParams,\n QueryRefundResponse,\n TradeBillParams,\n TradeBillResponse,\n FundFlowBillParams,\n FundFlowBillResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 小程序合单支付服务\n *\n * 提供小程序合单支付全流程相关的 API 封装,包括:\n * - 小程序合单下单(获取 prepay_id)\n * - 查询合单订单\n * - 关闭合单订单\n * - 申请退款(基于子单)\n * - 查询退款单\n * - 申请异常退款\n * - 申请交易账单\n * - 申请资金账单\n * - 下载账单\n *\n * 合单支付允许一笔支付中包含 2-10 个子单,适用于多商户场景。\n * 各子单商户号需与合单发起方 APPID 绑定。\n *\n * 小程序合单支付流程:\n * 1. 调用 createOrder 获取 prepay_id\n * 2. 使用 buildMiniProgramBridgeConfig 生成 wx.requestPayment 调起参数\n * 3. 用户支付完成后,通过 requestPayment 回调、支付成功通知或主动查询确认订单状态\n * 4. 退款时需基于子单进行退款,无法通过合单商户订单号退款\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556931 (小程序合单下单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421401 (查询合单订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421404 (关闭合单订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421410 (申请退款)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421421 (查询退款单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421450 (下载交易账单)\n */\nexport class CombineMiniProgramService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 小程序合单下单\n *\n * 商户通过此接口生成小程序合单预付单并获取 prepay_id。\n * 获取 prepay_id 后,配合 buildMiniProgramBridgeConfig 生成调起支付参数,\n * 通过小程序 wx.requestPayment() 方法唤起微信支付收银台。\n *\n * prepay_id 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求。\n *\n * 关键约束:\n * - combine_mchid 需先申请发起合单支付权限\n * - sub_orders 中的 mchid 需先申请接收合单支付权限\n * - 合单发起方和子单参与方需绑定同一个 combine_appid\n * - combine_appid 必须为小程序 AppID\n * - combine_payer_info.openid 在小程序场景下可选(由运行环境隐式提供)\n * - 子单数量为 2-10 笔\n * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556931\n */\n async createOrder(\n request: CreateMiniProgramCombineOrderRequest,\n ): Promise<WxPayResponse<CreateMiniProgramCombineOrderResponse>> {\n return this.client.post<CreateMiniProgramCombineOrderResponse>(\n '/v3/combine-transactions/jsapi',\n request,\n );\n }\n\n /**\n * 查询合单订单\n *\n * 通过合单商户订单号查询合单订单的支付状态及各子单详情。\n * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。\n *\n * 订单状态(sub_orders[].trade_state):\n * - SUCCESS:支付成功(终态)\n * - NOTPAY:未支付\n * - CLOSED:已关闭(终态)\n *\n * 典型使用场景:\n * - 用户支付后从收银台返回小程序页面时,requestPayment 回调后确认订单支付状态\n * - 未收到支付成功回调通知时,主动查询确认订单状态\n * - 关单前确认订单仍为未支付状态\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421401\n */\n async queryOrderById(\n params: QueryCombineOrderParams,\n ): Promise<WxPayResponse<QueryCombineOrderResponse>> {\n return this.client.get<QueryCombineOrderResponse>(\n `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`,\n );\n }\n\n /**\n * 关闭合单订单\n *\n * 对于未支付的合单订单,商户可通过此接口关闭订单。\n * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。\n *\n * 关键约束:\n * - 只能整单关闭,不支持关闭部分子单\n * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致\n * - 仅支持未支付状态的订单\n * - 关单后订单为失败终态\n *\n * 典型使用场景:\n * - 用户超过商户系统内部规定的支付时间\n * - 超过下单时设置的 time_expire 时间\n * - 因特殊原因需在可支付时间范围内关闭订单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421404\n */\n async closeOrder(\n params: CloseCombineOrderParams,\n request: CloseCombineOrderRequest,\n ): Promise<WxPayResponse> {\n return this.client.post(\n `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,\n request,\n );\n }\n\n /**\n * 申请退款(基于子单)\n *\n * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,\n * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。\n *\n * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。\n * 仅支持支付成功后 1 年内的订单。\n *\n * 注意:\n * - 一笔订单最多支持 50 次部分退款,间隔至少 1 分钟\n * - 重试时必须使用原商户退款单号,避免重复退款\n * - 接口返回成功仅表示受理成功,最终结果以回调通知和查询接口为准\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421410\n */\n async createRefund(request: CreateRefundRequest): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.post<CreateRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询退款单\n *\n * 通过商户退款单号查询退款状态。\n * 退款申请成功后,可通过此接口确认退款是否到账。\n *\n * 退款状态:\n * - SUCCESS:退款成功\n * - CLOSED:退款关闭\n * - PROCESSING:退款处理中\n * - ABNORMAL:退款异常\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421421\n */\n async queryRefund(params: QueryRefundParams): Promise<WxPayResponse<QueryRefundResponse>> {\n return this.client.get<QueryRefundResponse>(\n `/v3/refund/domestic/refunds/${params.outRefundNo}`,\n );\n }\n\n /**\n * 申请异常退款\n *\n * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。\n * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。\n *\n * @param refundId - 微信支付退款单号\n * @param request - 异常退款请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421429\n */\n async applyAbnormalRefund(\n refundId: string,\n request: ApplyAbnormalRefundRequest,\n ): Promise<WxPayResponse<ApplyAbnormalRefundResponse>> {\n return this.client.post<ApplyAbnormalRefundResponse>(\n `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,\n request,\n );\n }\n\n /**\n * 申请交易账单\n *\n * 合单支付的订单账单是以子单为维度,每笔子单都会记录在各个子单商户账单内,\n * 需要各个子单商户自己进行下载。\n *\n * 商户可通过此接口获取交易账单的下载链接,下载地址 5 分钟内有效。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421450\n */\n async tradeBill(params: TradeBillParams): Promise<WxPayResponse<TradeBillResponse>> {\n return this.client.get<TradeBillResponse>('/v3/bill/tradebill', params);\n }\n\n /**\n * 申请资金账单\n *\n * 商户可通过此接口获取资金账单的下载链接,下载地址 5 分钟内有效。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421456\n */\n async fundFlowBill(params: FundFlowBillParams): Promise<WxPayResponse<FundFlowBillResponse>> {\n return this.client.get<FundFlowBillResponse>('/v3/bill/fundflowbill', params);\n }\n\n /**\n * 下载账单\n *\n * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。\n * 下载地址 5 分钟内有效,请及时下载。\n * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。\n *\n * @param downloadUrl - 申请账单返回的 download_url\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421461\n */\n async downloadBill(downloadUrl: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(downloadUrl);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateNativeCombineOrderRequest,\n CreateNativeCombineOrderResponse,\n QueryCombineOrderParams,\n QueryCombineOrderResponse,\n CloseCombineOrderParams,\n CloseCombineOrderRequest,\n CreateRefundRequest,\n CreateRefundResponse,\n ApplyAbnormalRefundRequest,\n ApplyAbnormalRefundResponse,\n QueryRefundParams,\n QueryRefundResponse,\n TradeBillParams,\n TradeBillResponse,\n FundFlowBillParams,\n FundFlowBillResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * Native 合单支付服务\n *\n * 提供 Native 合单支付(二维码支付)全流程相关的 API 封装,包括:\n * - Native 合单下单(获取 code_url 用于生成二维码)\n * - 查询合单订单\n * - 关闭合单订单\n * - 申请退款(基于子单)\n * - 查询退款单\n * - 申请异常退款\n * - 申请交易账单\n * - 申请资金账单\n * - 下载账单\n *\n * 合单支付允许一笔支付中包含 2-10 个子单,适用于多商户场景。\n * 各子单商户号需与合单发起方 APPID 绑定。\n *\n * Native 合单支付流程:\n * 1. 调用 createOrder 获取 code_url\n * 2. 商户前端将 code_url 转换为二维码图片展示给用户\n * 3. 用户使用微信扫一扫扫描二维码,调起微信收银台完成支付\n * 4. 用户支付完成后,通过回调通知或主动查询确认订单状态\n * 5. 退款时需基于子单进行退款,无法通过合单商户订单号退款\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556982 (Native 合单下单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421316 (查询合单订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421330 (关闭合单订单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421340 (申请退款)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421346 (查询退款单)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421361 (下载交易账单)\n */\nexport class CombineNativeService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * Native 合单下单\n *\n * 商户通过此接口生成合单订单并获取二维码链接(code_url)。\n * 商户后端获取 code_url 后传递给前端,前端将其转换为二维码图片展示给用户。\n * 用户使用微信扫一扫扫描二维码后,将调起微信收银台完成支付。\n *\n * code_url 有效期为 2 小时,超过 2 小时需使用原下单参数重新请求下单接口,\n * 获取新的 code_url。\n *\n * 关键约束:\n * - combine_mchid 需先申请发起合单支付权限\n * - sub_orders 中的 mchid 需先申请接收合单支付权限\n * - 合单发起方和子单参与方需绑定同一个 combine_appid\n * - 子单数量为 2-10 笔\n * - time_expire 不能早于下单时间后 1 分钟,不能超过下单时间后 7 天\n * - 二维码不支持通过相册识别或长按识别二维码的方式完成支付\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012556982\n */\n async createOrder(\n request: CreateNativeCombineOrderRequest,\n ): Promise<WxPayResponse<CreateNativeCombineOrderResponse>> {\n return this.client.post<CreateNativeCombineOrderResponse>(\n '/v3/combine-transactions/native',\n request,\n );\n }\n\n /**\n * 查询合单订单\n *\n * 通过合单商户订单号查询合单订单的支付状态及各子单详情。\n * 合单支付订单需使用合单查单接口,不可使用非合单支付的查单接口。\n *\n * 订单状态(sub_orders[].trade_state):\n * - SUCCESS:支付成功(终态)\n * - NOTPAY:未支付\n * - CLOSED:已关闭(终态)\n *\n * 典型使用场景:\n * - 用户扫码支付后,轮询确认订单支付状态\n * - 未收到支付成功回调通知时,主动查询确认订单状态\n * - 关单前确认订单仍为未支付状态\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421316\n */\n async queryOrderById(\n params: QueryCombineOrderParams,\n ): Promise<WxPayResponse<QueryCombineOrderResponse>> {\n return this.client.get<QueryCombineOrderResponse>(\n `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}`,\n );\n }\n\n /**\n * 关闭合单订单\n *\n * 对于未支付的合单订单,商户可通过此接口关闭订单。\n * 关单后,所有子单状态从未支付(NOTPAY)流转为已关闭(CLOSED)。\n *\n * 关键约束:\n * - 只能整单关闭,不支持关闭部分子单\n * - combine_appid、sub_orders 中的 mchid 和 out_trade_no 必须与下单时完全一致\n * - 仅支持未支付状态的订单\n * - 关单后订单为失败终态\n *\n * 典型使用场景:\n * - 用户超过商户系统内部规定的支付时间\n * - 超过下单时设置的 time_expire 时间\n * - 因特殊原因需在可支付时间范围内关闭订单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421330\n */\n async closeOrder(\n params: CloseCombineOrderParams,\n request: CloseCombineOrderRequest,\n ): Promise<WxPayResponse> {\n return this.client.post(\n `/v3/combine-transactions/out-trade-no/${params.combineOutTradeNo}/close`,\n request,\n );\n }\n\n /**\n * 申请退款(基于子单)\n *\n * 合单支付的订单退款,无法通过合单商户订单号(combine_out_trade_no)退款,\n * 只能根据单个子单进行退款。传入子单的 out_trade_no 或 transaction_id。\n *\n * 当子单状态为支付成功(SUCCESS)时,商户可通过此接口申请退款。\n * 仅支持支付成功后 1 年内的订单。\n *\n * 注意:\n * - 一笔订单最多支持 50 次部分退款,间隔至少 1 分钟\n * - 重试时必须使用原商户退款单号,避免重复退款\n * - 接口返回成功仅表示受理成功,最终结果以回调通知和查询接口为准\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421340\n */\n async createRefund(request: CreateRefundRequest): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.post<CreateRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询退款单\n *\n * 通过商户退款单号查询退款状态。\n * 退款申请成功后,可通过此接口确认退款是否到账。\n *\n * 退款状态:\n * - SUCCESS:退款成功\n * - CLOSED:退款关闭\n * - PROCESSING:退款处理中\n * - ABNORMAL:退款异常\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421346\n */\n async queryRefund(params: QueryRefundParams): Promise<WxPayResponse<QueryRefundResponse>> {\n return this.client.get<QueryRefundResponse>(\n `/v3/refund/domestic/refunds/${params.outRefundNo}`,\n );\n }\n\n /**\n * 申请异常退款\n *\n * 当退款状态为 ABNORMAL 时,可通过此接口发起异常退款处理。\n * 支持退款至用户银行卡或退款至交易商户银行账户两种方式。\n *\n * @param refundId - 微信支付退款单号\n * @param request - 异常退款请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421352\n */\n async applyAbnormalRefund(\n refundId: string,\n request: ApplyAbnormalRefundRequest,\n ): Promise<WxPayResponse<ApplyAbnormalRefundResponse>> {\n return this.client.post<ApplyAbnormalRefundResponse>(\n `/v3/refund/domestic/refunds/${refundId}/apply-abnormal-refund`,\n request,\n );\n }\n\n /**\n * 申请交易账单\n *\n * 合单支付的订单账单是以子单为维度,每笔子单都会记录在各个子单商户账单内,\n * 需要各个子单商户自己进行下载。\n *\n * 商户可通过此接口获取交易账单的下载链接,下载地址 5 分钟内有效。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421361\n */\n async tradeBill(params: TradeBillParams): Promise<WxPayResponse<TradeBillResponse>> {\n return this.client.get<TradeBillResponse>('/v3/bill/tradebill', params);\n }\n\n /**\n * 申请资金账单\n *\n * 商户可通过此接口获取资金账单的下载链接,下载地址 5 分钟内有效。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421365\n */\n async fundFlowBill(params: FundFlowBillParams): Promise<WxPayResponse<FundFlowBillResponse>> {\n return this.client.get<FundFlowBillResponse>('/v3/bill/fundflowbill', params);\n }\n\n /**\n * 下载账单\n *\n * 通过申请账单接口返回的 download_url,以 GET 方式下载账单原始文件。\n * 下载地址 5 分钟内有效,请及时下载。\n * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。\n *\n * @param downloadUrl - 申请账单返回的 download_url\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421368\n */\n async downloadBill(downloadUrl: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(downloadUrl);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateProfitSharingOrderRequest,\n CreateProfitSharingOrderResponse,\n QueryProfitSharingOrderParams,\n QueryProfitSharingOrderResponse,\n CreateProfitSharingReturnOrderRequest,\n CreateProfitSharingReturnOrderResponse,\n QueryProfitSharingReturnOrderParams,\n QueryProfitSharingReturnOrderResponse,\n UnfreezeProfitSharingRequest,\n UnfreezeProfitSharingResponse,\n QueryProfitSharingAmountResponse,\n AddProfitSharingReceiverRequest,\n AddProfitSharingReceiverResponse,\n DeleteProfitSharingReceiverRequest,\n DeleteProfitSharingReceiverResponse,\n ProfitSharingBillParams,\n ProfitSharingBillResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 分账服务\n *\n * 提供微信支付分账全流程相关的 API 封装,包括:\n * - 请求分账\n * - 查询分账结果\n * - 请求分账回退\n * - 查询分账回退结果\n * - 解冻剩余资金\n * - 查询剩余待分金额\n * - 添加分账接收方\n * - 删除分账接收方\n * - 申请分账账单\n * - 下载分账账单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012081606\n */\nexport class ProfitSharingService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 请求分账\n *\n * 微信订单支付成功后,商户通过此接口发起分账请求,将订单资金分给指定的接收方。\n * 此接口采用异步处理模式,受理请求后返回的结果非最终分账结果,\n * 最终分账结果需要通过查询分账结果接口获取。\n *\n * 单笔订单最多支持 50 次分账请求,每次请求最多支持 50 个接收方。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012524936\n */\n async createOrder(\n request: CreateProfitSharingOrderRequest,\n ): Promise<WxPayResponse<CreateProfitSharingOrderResponse>> {\n return this.client.post<CreateProfitSharingOrderResponse>('/v3/profitsharing/orders', request);\n }\n\n /**\n * 查询分账结果\n *\n * 通过商户分账单号查询分账结果。\n * 发起分账请求后,可通过此接口主动查询分账的最终处理结果。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012525210\n */\n async queryOrder(\n params: QueryProfitSharingOrderParams,\n ): Promise<WxPayResponse<QueryProfitSharingOrderResponse>> {\n return this.client.get<QueryProfitSharingOrderResponse>(\n `/v3/profitsharing/orders/${params.outOrderNo}`,\n { transaction_id: params.transactionId },\n );\n }\n\n /**\n * 请求分账回退\n *\n * 对已经分账成功的订单,商户可以通过此接口将分账资金从接收方回退给分账方。\n * 此接口采用同步处理模式,会实时返回处理结果。\n *\n * 注意:\n * - 单笔分账单最多支持 50 次回退\n * - 回退窗口期为 180 天\n * - 仅支持对 MERCHANT_ID 类型且分账结果为 SUCCESS 的接收方进行回退\n * - 不支持对个人接收方的回退\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012525287\n */\n async createReturnOrder(\n request: CreateProfitSharingReturnOrderRequest,\n ): Promise<WxPayResponse<CreateProfitSharingReturnOrderResponse>> {\n return this.client.post<CreateProfitSharingReturnOrderResponse>(\n '/v3/profitsharing/return-orders',\n request,\n );\n }\n\n /**\n * 查询分账回退结果\n *\n * 通过商户回退单号查询分账回退的处理结果。\n * 如果回退结果为 PROCESSING,请不要更换商户回退单号重复发起回退,\n * 否则会出现资金风险。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012526279\n */\n async queryReturnOrder(\n params: QueryProfitSharingReturnOrderParams,\n ): Promise<WxPayResponse<QueryProfitSharingReturnOrderResponse>> {\n return this.client.get<QueryProfitSharingReturnOrderResponse>(\n `/v3/profitsharing/return-orders/${params.outReturnNo}`,\n { out_order_no: params.outOrderNo },\n );\n }\n\n /**\n * 解冻剩余资金\n *\n * 将订单的金额全部解冻给本商户。\n * 适用于无需分账或分账完成后需将剩余冻结资金解冻给商户的场景。\n * 此接口采用异步处理模式。\n *\n * 注意:\n * - 当分账已完成(金额全部分完)时,无需再请求此接口\n * - 同一分账单号多次请求视为同一请求(幂等)\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012526374\n */\n async unfreeze(\n request: UnfreezeProfitSharingRequest,\n ): Promise<WxPayResponse<UnfreezeProfitSharingResponse>> {\n return this.client.post<UnfreezeProfitSharingResponse>(\n '/v3/profitsharing/orders/unfreeze',\n request,\n );\n }\n\n /**\n * 查询剩余待分金额\n *\n * 通过微信支付订单号查询该订单的剩余未分账金额。\n * 可用于判断是否可以继续分账以及剩余可分金额。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012457939\n */\n async queryAmount(\n transactionId: string,\n ): Promise<WxPayResponse<QueryProfitSharingAmountResponse>> {\n return this.client.get<QueryProfitSharingAmountResponse>(\n `/v3/profitsharing/transactions/${transactionId}/amounts`,\n );\n }\n\n /**\n * 添加分账接收方\n *\n * 商户在发起分账前,需要先通过此接口添加分账接收方。\n * 每个商户号最多添加 2 万个分账接收方。\n * 接收方全称(name 字段)需使用微信支付公钥进行 RSAES-OAEP 加密。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012528995\n */\n async addReceiver(\n request: AddProfitSharingReceiverRequest,\n ): Promise<WxPayResponse<AddProfitSharingReceiverResponse>> {\n return this.client.post<AddProfitSharingReceiverResponse>(\n '/v3/profitsharing/receivers/add',\n request,\n );\n }\n\n /**\n * 删除分账接收方\n *\n * 商户可以通过此接口删除已添加的分账接收方。\n * 删除后,该接收方将无法参与新的分账。\n *\n * 注意:\n * - 删除接口有频率限制,请勿频繁调用\n * - 已参与分账的接收方仍可被删除,但不会影响已完成的交易\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012529590\n */\n async deleteReceiver(\n request: DeleteProfitSharingReceiverRequest,\n ): Promise<WxPayResponse<DeleteProfitSharingReceiverResponse>> {\n return this.client.post<DeleteProfitSharingReceiverResponse>(\n '/v3/profitsharing/receivers/delete',\n request,\n );\n }\n\n /**\n * 申请分账账单\n *\n * 商户可通过此接口获取分账账单的下载链接。\n * 仅支持最近三个月的账单。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012529628\n */\n async bill(params: ProfitSharingBillParams): Promise<WxPayResponse<ProfitSharingBillResponse>> {\n return this.client.get<ProfitSharingBillResponse>('/v3/profitsharing/bills', params);\n }\n\n /**\n * 下载分账账单\n *\n * 通过申请分账账单接口返回的 download_url,以 GET 方式下载账单原始文件。\n * 下载地址 30 秒内有效,请及时下载。\n * 返回的 data 为 Buffer,可能为 GZIP 压缩格式,需要自行解压。\n *\n * @param downloadUrl - 申请分账账单返回的 download_url\n */\n async downloadBill(downloadUrl: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(downloadUrl);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreatePayScoreOrderRequest,\n CreatePayScoreOrderResponse,\n QueryPayScoreOrderParams,\n QueryPayScoreOrderResponse,\n CancelPayScoreOrderRequest,\n CancelPayScoreOrderResponse,\n CompletePayScoreOrderRequest,\n CompletePayScoreOrderResponse,\n ModifyPayScoreOrderRequest,\n ModifyPayScoreOrderResponse,\n SyncPayScoreOrderRequest,\n SyncPayScoreOrderResponse,\n CreateRefundRequest,\n CreateRefundResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 微信支付分 服务\n *\n * 提供微信支付分全流程相关的 API 封装,包括:\n * - 创建支付分订单\n * - 查询支付分订单\n * - 取消支付分订单\n * - 完结支付分订单\n * - 修改订单金额\n * - 同步订单状态\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587900\n */\nexport class PayScoreService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 创建支付分订单\n *\n * 当用户申请使用服务时,商户需调用此接口创建支付分订单。\n * 创单成功后订单状态 state 为 CREATED(已创建),返回的 package\n * 参数用于拉起支付分小程序确认订单页面。\n *\n * - 需确认模式下,need_user_confirm 必须固定传 true\n * - risk_fund.name:先免模式可选 DEPOSIT/ADVANCE/CASH_DEPOSIT,先享模式固定 ESTIMATE_ORDER_COST\n * - risk_fund.amount 不可超过服务ID风险金额上限\n * - 该接口支持原参重入,相同参数重复调用可以返回成功\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587900\n */\n async createOrder(\n request: CreatePayScoreOrderRequest,\n ): Promise<WxPayResponse<CreatePayScoreOrderResponse>> {\n return this.client.post<CreatePayScoreOrderResponse>('/v3/payscore/serviceorder', request);\n }\n\n /**\n * 查询支付分订单\n *\n * 通过商户服务订单号或回跳查询ID查询支付分订单状态和详情。\n * out_order_no 和 query_id 必须提供其中一个,不可同时提供。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587902\n */\n async queryOrder(\n params: QueryPayScoreOrderParams,\n ): Promise<WxPayResponse<QueryPayScoreOrderResponse>> {\n const queryParams: Record<string, string> = {\n service_id: params.service_id,\n appid: params.appid,\n };\n if (params.out_order_no) {\n queryParams['out_order_no'] = params.out_order_no;\n }\n if (params.query_id) {\n queryParams['query_id'] = params.query_id;\n }\n return this.client.get<QueryPayScoreOrderResponse>('/v3/payscore/serviceorder', queryParams);\n }\n\n /**\n * 取消支付分订单\n *\n * 取消已创建、用户已确认或待支付状态的支付分订单。\n * 可在订单状态为 CREATED、USER_CONFIRM(用户已确认)和 USER_PAYING(待支付)时调用。\n *\n * - 若因网络原因未获取到接口返回内容,可使用相同参数重试,该接口支持原参重入\n * - 待支付订单若用户正主动支付或系统正自动扣款时调用,可能报错,建议等待 3 分钟后重试\n *\n * @param outOrderNo - 商户服务订单号\n * @param request - 取消订单请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587905\n */\n async cancelOrder(\n outOrderNo: string,\n request: CancelPayScoreOrderRequest,\n ): Promise<WxPayResponse<CancelPayScoreOrderResponse>> {\n return this.client.post<CancelPayScoreOrderResponse>(\n `/v3/payscore/serviceorder/${outOrderNo}/cancel`,\n request,\n );\n }\n\n /**\n * 完结支付分订单\n *\n * 服务完成后,商户需调用此接口通知微信支付服务已结束。\n * 订单完结后,支付分会持续自动扣款,无需重复调用完结接口。\n *\n * - total_amount = 后付费项目金额总和 - 优惠项目金额总和\n * - 先免模式:订单收款总金额 ≤ 创单传的服务风险金额 ≤ 服务ID风险金额上限\n * - 先享模式:订单收款总金额 ≤ 服务ID风险金额上限\n * - 调用完结接口后 collection.state 变为 USER_PAYING(待支付状态)\n *\n * @param outOrderNo - 商户服务订单号\n * @param request - 完结订单请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587955\n */\n async completeOrder(\n outOrderNo: string,\n request: CompletePayScoreOrderRequest,\n ): Promise<WxPayResponse<CompletePayScoreOrderResponse>> {\n return this.client.post<CompletePayScoreOrderResponse>(\n `/v3/payscore/serviceorder/${outOrderNo}/complete`,\n request,\n );\n }\n\n /**\n * 修改订单金额\n *\n * 当订单处于 USER_PAYING(待支付)状态时,商户可调用此接口下调收款金额。\n * 修改成功后微信侧将按新金额发起扣款。\n *\n * - 只能下调扣款金额,不能上调\n * - total_amount = post_payments.amount 总和 - post_discounts.amount 总和\n *\n * @param outOrderNo - 商户服务订单号\n * @param request - 修改订单金额请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587957\n */\n async modifyOrder(\n outOrderNo: string,\n request: ModifyPayScoreOrderRequest,\n ): Promise<WxPayResponse<ModifyPayScoreOrderResponse>> {\n return this.client.post<ModifyPayScoreOrderResponse>(\n `/v3/payscore/serviceorder/${outOrderNo}/modify`,\n request,\n );\n }\n\n /**\n * 同步订单状态\n *\n * 当支付分订单处于 USER_PAYING(待支付)状态,用户通过其他渠道支付后,\n * 商户可调用此接口将订单改为已完成状态,微信支付将不再发起扣款。\n *\n * - type 固定传 Order_Paid\n * - paid_time 需满足:完结接口时间 < paid_time ≤ 同步接口时间 + 60 秒\n * - 若用户正在通过支付分收银台支付或自动扣款中,调用可能报错,可等 3 分钟后重试\n *\n * @param outOrderNo - 商户服务订单号\n * @param request - 同步订单状态请求参数\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587962\n */\n async syncOrder(\n outOrderNo: string,\n request: SyncPayScoreOrderRequest,\n ): Promise<WxPayResponse<SyncPayScoreOrderResponse>> {\n return this.client.post<SyncPayScoreOrderResponse>(\n `/v3/payscore/serviceorder/${outOrderNo}/sync`,\n request,\n );\n }\n\n /**\n * 申请退款\n *\n * 支付分订单完结扣款后,如需退款可通过此接口发起。\n * transaction_id 来源于支付成功回调或查询支付分订单中的 collection.details。\n *\n * @param request - 退款请求参数\n * @returns 退款结果\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587971\n */\n async applyRefund(request: CreateRefundRequest): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.post<CreateRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询单笔退款\n *\n * 通过商户退款单号查询退款状态和详情。\n *\n * @param outRefundNo - 商户退款单号\n * @returns 退款详情\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587973\n */\n async queryRefund(outRefundNo: string): Promise<WxPayResponse<CreateRefundResponse>> {\n return this.client.get<CreateRefundResponse>(`/v3/refund/domestic/refunds/${outRefundNo}`);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateParkingRequest,\n CreateParkingResponse,\n QueryPlateServiceParams,\n QueryPlateServiceResponse,\n CreateParkingTransactionRequest,\n CreateParkingTransactionResponse,\n QueryParkingOrderResponse,\n ApplyParkingRefundRequest,\n ApplyParkingRefundResponse,\n QueryParkingRefundResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 微信支付分停车服务\n *\n * 提供微信支付分停车服务全流程相关的 API 封装,包括:\n * - 创建停车入场\n * - 查询车牌服务开通信息\n * - 扣费受理\n * - 查询停车订单\n * - 申请退款\n * - 查询退款\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012077223\n */\nexport class ParkingService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 创建停车入场\n *\n * 用户入场时调用此接口创建停车入场信息。\n * 根据返回的车牌状态判断用户是否开通支付分停车服务:\n * - state 为 NORMAL:正常,可使用支付分停车服务\n * - state 为 BLOCKED:不可用,通过 block_reason 获取具体原因\n *\n * @param request - 创建停车入场请求参数\n * @returns 停车入场信息,包含入场ID和车牌状态\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533937\n */\n async createEntry(request: CreateParkingRequest): Promise<WxPayResponse<CreateParkingResponse>> {\n return this.client.post<CreateParkingResponse>('/v3/vehicle/parking/parkings', request);\n }\n\n /**\n * 查询车牌服务开通信息\n *\n * 查询用户是否开通微信支付分停车服务。\n * 用于在用户未收到入场状态变更通知时,主动确认车牌服务开通状态。\n *\n * @param params - 查询参数,包含appid、车牌号、用户openid和车牌颜色\n * @returns 车牌服务开通信息,包含开通状态和开通时间\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534043\n */\n async queryPlateService(\n params: QueryPlateServiceParams,\n ): Promise<WxPayResponse<QueryPlateServiceResponse>> {\n return this.client.get<QueryPlateServiceResponse>('/v3/vehicle/parking/services/find', {\n appid: params.appid,\n plate_number: params.plate_number,\n openid: params.openid,\n plate_color: params.plate_color,\n });\n }\n\n /**\n * 扣费受理\n *\n * 用户离场时调用此接口完成订单受理,微信支付进行异步扣款。\n *\n * **重要**:必须确认接口返回的交易状态为 \"ACCEPTED\" 才能放行车辆。\n * 若未接收到该状态而放行车辆离场,造成的资金损失由商户侧自行承担。\n *\n * @param request - 扣费受理请求参数\n * @returns 扣费受理结果,包含交易状态\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534352\n */\n async createTransaction(\n request: CreateParkingTransactionRequest,\n ): Promise<WxPayResponse<CreateParkingTransactionResponse>> {\n return this.client.post<CreateParkingTransactionResponse>(\n '/v3/vehicle/transactions/parking',\n request,\n );\n }\n\n /**\n * 查询停车订单\n *\n * 通过商户订单号查询停车扣费订单状态和详情。\n * 如果在所有通知频率后没有收到微信侧回调,商户应调用此接口确认订单状态。\n *\n * @param outTradeNo - 商户系统内部订单号\n * @returns 停车订单信息,包含交易状态和支付详情\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534308\n */\n async queryTransaction(outTradeNo: string): Promise<WxPayResponse<QueryParkingOrderResponse>> {\n return this.client.get<QueryParkingOrderResponse>(\n `/v3/vehicle/transactions/out-trade-no/${outTradeNo}`,\n );\n }\n\n /**\n * 申请停车退款\n *\n * 交易时间超过一年的订单无法提交退款。\n * 微信支付退款支持单笔交易分多次退款(不超过50次),多次退款需要提交原支付订单的商户订单号和设置不同的退款单号。\n * 申请退款总金额不能超过订单金额。\n * 一笔退款失败后重新提交,请不要更换退款单号,请使用原商户退款单号。\n *\n * **注意**:申请退款接口的返回仅代表业务的受理情况,具体退款是否成功,需要通过查询退款接口获取结果。\n *\n * @param request - 申请退款请求参数\n * @returns 退款受理结果\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557131\n */\n async applyRefund(\n request: ApplyParkingRefundRequest,\n ): Promise<WxPayResponse<ApplyParkingRefundResponse>> {\n return this.client.post<ApplyParkingRefundResponse>('/v3/refund/domestic/refunds', request);\n }\n\n /**\n * 查询单笔退款\n *\n * 通过商户退款单号查询退款状态和详情。\n * 提交退款申请后,建议每分钟查询一次退款状态;超过5分钟仍为处理中时,逐步衰减查询频率。\n *\n * @param outRefundNo - 商户退款单号\n * @returns 退款详细信息\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012557161\n */\n async queryRefund(outRefundNo: string): Promise<WxPayResponse<QueryParkingRefundResponse>> {\n return this.client.get<QueryParkingRefundResponse>(\n `/v3/refund/domestic/refunds/${outRefundNo}`,\n );\n }\n}\n","import type { WxPayClient } from '../core/client.js';\nimport type {\n WxPayResponse,\n TradeBillParams,\n TradeBillResponse,\n FundFlowBillParams,\n FundFlowBillResponse,\n ProfitSharingBillParams,\n ProfitSharingBillResponse,\n} from '../types/index.js';\n\n/**\n * 账单下载服务\n *\n * 提供交易账单、资金账单和分账账单的申请与下载功能。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013071227 申请交易账单\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013071235 申请资金账单\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013071238 下载账单\n */\nexport class BillService {\n constructor(private readonly client: WxPayClient) {}\n\n /**\n * 申请交易账单\n *\n * 商户调用该接口获取交易账单的下载链接。次日 10:00 后获取前一天账单,\n * 支持三个月内的账单查询。\n *\n * @param params - 账单请求参数\n * @returns 包含 hash_type、hash_value 和 download_url 的响应\n *\n * @example\n * ```ts\n * const result = await billService.applyTradeBill({\n * bill_date: '2024-01-15',\n * bill_type: 'ALL',\n * tar_type: 'GZIP',\n * });\n * console.log(result.data.download_url);\n * ```\n */\n async applyTradeBill(params: TradeBillParams): Promise<WxPayResponse<TradeBillResponse>> {\n return this.client.get<TradeBillResponse>('/v3/bill/tradebill', {\n bill_date: params.bill_date,\n bill_type: params.bill_type,\n tar_type: params.tar_type,\n });\n }\n\n /**\n * 申请资金账单\n *\n * 商户调用该接口获取资金账单的下载链接。次日 10:00 后获取前一天账单,\n * 支持三个月内的账单查询。\n *\n * @param params - 账单请求参数\n * @returns 包含 hash_type、hash_value 和 download_url 的响应\n *\n * @example\n * ```ts\n * const result = await billService.applyFundFlowBill({\n * bill_date: '2024-01-15',\n * account_type: 'BASIC',\n * tar_type: 'GZIP',\n * });\n * console.log(result.data.download_url);\n * ```\n */\n async applyFundFlowBill(\n params: FundFlowBillParams,\n ): Promise<WxPayResponse<FundFlowBillResponse>> {\n return this.client.get<FundFlowBillResponse>('/v3/bill/fundflowbill', {\n bill_date: params.bill_date,\n account_type: params.account_type,\n tar_type: params.tar_type,\n });\n }\n\n /**\n * 申请分账账单\n *\n * 商户调用该接口获取分账账单的下载链接。次日 10:00 后获取前一天账单,\n * 支持三个月内的账单查询。\n *\n * @param params - 账单请求参数\n * @returns 包含 hash_type、hash_value 和 download_url 的响应\n *\n * @example\n * ```ts\n * const result = await billService.applyProfitSharingBill({\n * bill_date: '2024-01-15',\n * tar_type: 'GZIP',\n * });\n * console.log(result.data.download_url);\n * ```\n */\n async applyProfitSharingBill(\n params: ProfitSharingBillParams,\n ): Promise<WxPayResponse<ProfitSharingBillResponse>> {\n return this.client.get<ProfitSharingBillResponse>('/v3/bill/profitsharingbill', {\n bill_date: params.bill_date,\n tar_type: params.tar_type,\n });\n }\n\n /**\n * 下载账单文件\n *\n * 使用申请账单接口返回的 download_url 下载账单文件。\n * download_url 有效期为 5 分钟(分账账单为 30 秒),需及时下载。\n *\n * 下载完成后建议计算文件的 SHA1 哈希值,与申请账单接口返回的 hash_value\n * 进行比对,确保账单文件完整性。\n *\n * @param downloadUrl - 申请账单接口返回的 download_url\n * @returns 包含原始账单文件 Buffer 的响应\n *\n * @example\n * ```ts\n * // 先申请账单获取 download_url\n * const applyResult = await billService.applyTradeBill({\n * bill_date: '2024-01-15',\n * tar_type: 'GZIP',\n * });\n *\n * // 下载账单文件\n * const downloadResult = await billService.downloadBill(\n * applyResult.data.download_url,\n * );\n *\n * // 验证哈希值\n * const crypto = require('crypto');\n * const fileHash = crypto\n * .createHash('sha1')\n * .update(downloadResult.data)\n * .digest('hex');\n * console.log(fileHash === applyResult.data.hash_value); // true\n * ```\n */\n async downloadBill(downloadUrl: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(downloadUrl);\n }\n}\n","import crypto from 'node:crypto';\nimport { verifySignature } from '../utils/sign.js';\nimport type {\n CallbackNotification,\n CallbackHeaders,\n TransactionCallbackData,\n CombineTransactionCallbackData,\n RefundCallbackData,\n ProfitSharingCallbackData,\n PayScoreUserConfirmCallbackData,\n PayScoreUserPaidCallbackData,\n PayScoreRefundCallbackData,\n ParkingEntryStatusCallbackData,\n ParkingTransactionCallbackData,\n MerchantTransferCallbackData,\n MerchantTransferAuthorizationCallbackData,\n CouponUseCallbackData,\n ComplaintCallbackData,\n MedInsSuccessCallbackData,\n MedInsRefundCallbackData,\n BusinessCircleAuthorizeCallbackData,\n BusinessCircleTransactionCallbackData,\n BusinessCircleRefundCallbackData,\n} from '../types/index.js';\nimport { CertificateManager } from '../core/certificate.js';\n\n/**\n * 回调通知解密后的结果\n */\nexport interface DecryptedCallback<T = unknown> {\n /** 通知ID */\n id: string;\n /** 通知创建时间 */\n create_time: string;\n /** 通知类型 */\n event_type: string;\n /** 通知数据类型 */\n resource_type: string;\n /** 回调摘要 */\n summary: string;\n /** 解密后的业务数据 */\n data: T;\n}\n\n/**\n * 微信支付回调通知处理器\n *\n * 负责验证回调签名并解密回调通知中的业务数据。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791861\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012075249\n */\nexport class CallbackHandler {\n private readonly apiV3Key: string;\n private readonly certificates: CertificateManager;\n\n constructor(apiV3Key: string, certificates: CertificateManager) {\n this.apiV3Key = apiV3Key;\n this.certificates = certificates;\n }\n\n /**\n * 验证回调通知签名\n *\n * 使用微信支付平台公钥验证回调通知的签名。\n *\n * @param headers - 回调请求头\n * @param body - 回调请求体(原始 JSON 字符串)\n * @returns 签名验证是否通过\n */\n verifySignature(headers: CallbackHeaders, body: string): boolean {\n const serialNo = headers['wechatpay-serial'];\n const publicKey = this.certificates.getPublicKey(serialNo);\n\n if (!publicKey) {\n throw new Error(`未找到序列号为 ${serialNo} 的平台证书,请确保已配置平台证书`);\n }\n\n return verifySignature(\n body,\n headers['wechatpay-signature'],\n headers['wechatpay-timestamp'],\n headers['wechatpay-nonce'],\n publicKey,\n );\n }\n\n /**\n * 解密回调通知中的业务数据\n *\n * 使用 AES-256-GCM 算法和 API V3 密钥解密 resource.ciphertext。\n *\n * @param notification - 回调通知 JSON 对象\n * @returns 解密后的业务数据\n * @throws 如果解密后的数据为空或格式无效\n */\n decryptNotification<T = unknown>(notification: CallbackNotification): DecryptedCallback<T> {\n const { resource } = notification;\n\n const plaintext = this.aesGcmDecrypt(\n resource.ciphertext,\n resource.associated_data,\n resource.nonce,\n );\n\n // 安全解析 JSON 并验证结果\n let parsed: unknown;\n try {\n parsed = JSON.parse(plaintext);\n } catch (error) {\n throw new Error(\n `回调数据 JSON 解析失败: ${error instanceof Error ? error.message : '未知错误'}`,\n );\n }\n\n if (parsed === null || parsed === undefined || typeof parsed !== 'object') {\n throw new Error(`回调数据格式无效: 期望对象,实际为 ${typeof parsed}`);\n }\n\n const data = parsed as T;\n\n return {\n id: notification.id,\n create_time: notification.create_time,\n event_type: notification.event_type,\n resource_type: notification.resource_type,\n summary: notification.summary,\n data,\n };\n }\n\n /**\n * 处理回调通知(验证签名 + 解密数据)\n *\n * @param headers - 回调请求头\n * @param body - 回调请求体(原始 JSON 字符串)\n * @returns 解密后的回调数据\n */\n process<T = unknown>(headers: CallbackHeaders, body: string): DecryptedCallback<T> {\n // 1. 验证签名\n const valid = this.verifySignature(headers, body);\n if (!valid) {\n throw new Error('回调通知签名验证失败');\n }\n\n // 2. 解析通知\n const notification = JSON.parse(body) as CallbackNotification;\n\n // 3. 解密数据\n return this.decryptNotification<T>(notification);\n }\n\n /**\n * 处理支付成功回调通知\n */\n processTransactionCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<TransactionCallbackData> {\n return this.process<TransactionCallbackData>(headers, body);\n }\n\n /**\n * 处理退款回调通知\n */\n processRefundCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<RefundCallbackData> {\n return this.process<RefundCallbackData>(headers, body);\n }\n\n /**\n * 处理分账动账回调通知\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012289679\n */\n processProfitSharingCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<ProfitSharingCallbackData> {\n return this.process<ProfitSharingCallbackData>(headers, body);\n }\n\n /**\n * 处理支付分用户确认订单回调通知\n *\n * 用户确认支付分订单后,微信支付会向商户发送此回调通知。\n * event_type 为 PAYSCORE.USER_CONFIRM。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587953\n */\n processPayScoreUserConfirmCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<PayScoreUserConfirmCallbackData> {\n return this.process<PayScoreUserConfirmCallbackData>(headers, body);\n }\n\n /**\n * 处理支付分支付成功回调通知\n *\n * 支付分订单扣款成功后,微信支付会向商户发送此回调通知。\n * event_type 为 PAYSCORE.USER_PAID。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587960\n */\n processPayScoreUserPaidCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<PayScoreUserPaidCallbackData> {\n return this.process<PayScoreUserPaidCallbackData>(headers, body);\n }\n\n /**\n * 处理停车入场状态变更回调通知\n *\n * 场内车牌状态发生变化后,微信支付通过此回调通知商户。\n * 例如用户开通/暂停支付分停车服务、用户移除车牌等。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284177\n */\n processParkingEntryStatusCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<ParkingEntryStatusCallbackData> {\n return this.process<ParkingEntryStatusCallbackData>(headers, body);\n }\n\n /**\n * 处理停车订单支付结果回调通知\n *\n * 扣费受理后,微信支付异步扣款完成时会发送此回调通知。\n * event_type 为 TRANSACTION.SUCCESS(支付成功)、TRANSACTION.FAIL(支付失败)\n * 或 TRANSACTION.PAY_BACK(还款)。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284311\n */\n processParkingTransactionCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<ParkingTransactionCallbackData> {\n return this.process<ParkingTransactionCallbackData>(headers, body);\n }\n\n /**\n * 处理停车退款结果回调通知\n *\n * 退款完成后,微信支付会向商户发送此回调通知。\n * event_type 为 REFUND.SUCCESS(退款成功)、REFUND.ABNORMAL(退款异常)\n * 或 REFUND.CLOSED(退款关闭)。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012083103\n */\n processParkingRefundCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<RefundCallbackData> {\n return this.process<RefundCallbackData>(headers, body);\n }\n\n /**\n * 处理代金券核销事件回调通知\n *\n * 用户使用券后,微信会把相关核销券信息发送给商户。\n * event_type 为 COUPON.USE。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285250\n */\n processCouponUseCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<CouponUseCallbackData> {\n return this.process<CouponUseCallbackData>(headers, body);\n }\n\n /**\n * 处理合单支付成功回调通知\n *\n * 合单支付成功后,微信支付会向商户发送此回调通知。\n * event_type 为 TRANSACTION.SUCCESS。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013421231\n */\n processCombineTransactionCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<CombineTransactionCallbackData> {\n return this.process<CombineTransactionCallbackData>(headers, body);\n }\n\n /**\n * 处理商家转账状态变更回调通知\n *\n * 转账单据状态变更后,微信支付会向商户发送此回调通知。\n * 包括转账成功、转账失败、已撤销等状态变更。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012712115\n */\n processMerchantTransferCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<MerchantTransferCallbackData> {\n return this.process<MerchantTransferCallbackData>(headers, body);\n }\n\n /**\n * 处理免确认收款授权变更回调通知\n *\n * 用户确认授权或解除授权后,微信支付会向商户发送此回调通知。\n * 包括授权生效(TAKING_EFFECT)和授权关闭(CLOSED)等状态变更。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4014512908\n */\n processMerchantTransferAuthorizationCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<MerchantTransferAuthorizationCallbackData> {\n return this.process<MerchantTransferAuthorizationCallbackData>(headers, body);\n }\n\n /**\n * 处理支付分退款结果回调通知\n *\n * 支付分订单退款完成后,微信支付会向商户发送此回调通知。\n * event_type 为 REFUND.SUCCESS(退款成功)、REFUND.ABNORMAL(退款异常)\n * 或 REFUND.CLOSED(退款关闭)。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587976\n */\n processPayScoreRefundCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<PayScoreRefundCallbackData> {\n return this.process<PayScoreRefundCallbackData>(headers, body);\n }\n\n /**\n * 处理消费者投诉通知回调\n *\n * 用户提交投诉、用户撤诉、用户确认投诉已处理完成时,\n * 微信支付会通过此回调通知商户。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012289719\n */\n processComplaintCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<ComplaintCallbackData> {\n return this.process<ComplaintCallbackData>(headers, body);\n }\n\n /**\n * 处理医保支付成功回调通知\n *\n * 医保自费混合订单支付成功后,微信支付会向商户发送此回调通知。\n * event_type 为 MED_INS.SUCCESS。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781502\n */\n processMedInsSuccessCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<MedInsSuccessCallbackData> {\n return this.process<MedInsSuccessCallbackData>(headers, body);\n }\n\n /**\n * 处理医保退款回调通知\n *\n * 医保订单退款完成后,微信支付会向商户发送此回调通知。\n * event_type 为 MED_INS.REFUND.SUCCESS、MED_INS.REFUND.ABNORMAL 或 MED_INS.REFUND.CLOSED。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781502\n */\n processMedInsRefundCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<MedInsRefundCallbackData> {\n return this.process<MedInsRefundCallbackData>(headers, body);\n }\n\n /**\n * 处理商圈会员积分服务授权结果回调通知\n *\n * 用户在小程序内授权/解除授权商圈积分服务后,微信支付会向商户发送此回调通知。\n * event_type 为 BUSINESS_CIRCLE.USER_AUTHORIZE 或 BUSINESS_CIRCLE.USER_DEAUTHORIZE。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285836\n */\n processBusinessCircleAuthorizeCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<BusinessCircleAuthorizeCallbackData> {\n return this.process<BusinessCircleAuthorizeCallbackData>(headers, body);\n }\n\n /**\n * 处理商圈会员场内支付结果回调通知\n *\n * 用户在商圈内支付成功后,微信支付会向商户发送此回调通知。\n * event_type 为 TRANSACTION.SUCCESS。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285856\n */\n processBusinessCircleTransactionCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<BusinessCircleTransactionCallbackData> {\n return this.process<BusinessCircleTransactionCallbackData>(headers, body);\n }\n\n /**\n * 处理商圈会员场内退款结果回调通知\n *\n * 商圈内交易退款完成后,微信支付会向商户发送此回调通知。\n * event_type 为 REFUND.SUCCESS、REFUND.ABNORMAL 或 REFUND.CLOSED。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285869\n */\n processBusinessCircleRefundCallback(\n headers: CallbackHeaders,\n body: string,\n ): DecryptedCallback<BusinessCircleRefundCallbackData> {\n return this.process<BusinessCircleRefundCallbackData>(headers, body);\n }\n\n /**\n * AES-256-GCM 解密\n *\n * @param ciphertext - Base64 编码的密文\n * @param associatedData - 附加数据(用于 AEAD 认证)\n * @param nonce - 随机串\n * @returns 解密后的明文字符串\n */\n private aesGcmDecrypt(ciphertext: string, associatedData: string, nonce: string): string {\n const key = Buffer.from(this.apiV3Key, 'utf-8');\n const ciphertextBuffer = Buffer.from(ciphertext, 'base64');\n const authTag = ciphertextBuffer.subarray(-16);\n const encryptedData = ciphertextBuffer.subarray(0, -16);\n\n const decipher = crypto.createDecipheriv('aes-256-gcm', key, Buffer.from(nonce, 'utf-8'));\n\n decipher.setAuthTag(authTag);\n decipher.setAAD(Buffer.from(associatedData, 'utf-8'));\n\n const decrypted = Buffer.concat([decipher.update(encryptedData), decipher.final()]);\n\n return decrypted.toString('utf-8');\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateMerchantTransferRequest,\n CreateMerchantTransferResponse,\n QueryMerchantTransferResponse,\n CancelMerchantTransferResponse,\n ApplyMerchantTransferElecSignByOutBillNoRequest,\n ApplyMerchantTransferElecSignByTransferBillNoRequest,\n ApplyMerchantTransferElecSignResponse,\n QueryMerchantTransferElecSignResponse,\n CreateTransferWithAuthorizationRequest,\n CreateTransferWithAuthorizationResponse,\n CreateMerchantTransferAuthorizationRequest,\n CreateMerchantTransferAuthorizationResponse,\n QueryMerchantTransferAuthorizationResponse,\n CreateTransferAfterAuthorizationRequest,\n CreateTransferAfterAuthorizationResponse,\n CloseMerchantTransferAuthorizationResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 商家转账服务\n *\n * 提供微信支付商家转账全流程相关的 API 封装,包括:\n * - 用户确认收款模式:发起转账、撤销转账、查询转账单\n * - 电子回单:申请和查询电子回单\n * - 用户授权免确认模式:发起授权、查询授权、授权后转账、解除授权\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716434\n */\nexport class MerchantTransferService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n // ============= 用户确认收款模式 =============\n\n /**\n * 发起转账\n *\n * 商户调用此接口发起转账申请,用户需确认收款。\n * 成功时返回 package_info 用于拉起用户确认收款页。\n *\n * 注意:\n * - 转账金额≥2000元时,user_name 必传\n * - 返回 ACCEPTED 时,需检查运营账户资金是否足够\n * - 遇到错误不要换单重试,需先查询原订单结果\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716434\n */\n async createTransfer(\n request: CreateMerchantTransferRequest,\n ): Promise<WxPayResponse<CreateMerchantTransferResponse>> {\n return this.client.post<CreateMerchantTransferResponse>(\n '/v3/fund-app/mch-transfer/transfer-bills',\n request,\n );\n }\n\n /**\n * 商户单号查询转账单\n *\n * 通过商户单号查询转账单详情,仅支持查询最近30天内的转账单。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716437\n */\n async queryTransferByOutBillNo(\n outBillNo: string,\n ): Promise<WxPayResponse<QueryMerchantTransferResponse>> {\n return this.client.get<QueryMerchantTransferResponse>(\n `/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/${outBillNo}`,\n );\n }\n\n /**\n * 微信单号查询转账单\n *\n * 通过微信转账单号查询转账单详情,仅支持查询最近30天内的转账单。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716457\n */\n async queryTransferByTransferBillNo(\n transferBillNo: string,\n ): Promise<WxPayResponse<QueryMerchantTransferResponse>> {\n return this.client.get<QueryMerchantTransferResponse>(\n `/v3/fund-app/mch-transfer/transfer-bills/transfer-bill-no/${transferBillNo}`,\n );\n }\n\n /**\n * 撤销转账\n *\n * 在用户确认收款前,商户可通过此接口撤销转账。\n * 返回成功仅表示撤销请求已受理,系统会异步处理退款等操作,\n * 需以最终查询转账单返回的状态为准。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716458\n */\n async cancelTransfer(outBillNo: string): Promise<WxPayResponse<CancelMerchantTransferResponse>> {\n return this.client.post<CancelMerchantTransferResponse>(\n `/v3/fund-app/mch-transfer/transfer-bills/out-bill-no/${outBillNo}/cancel`,\n );\n }\n\n // ============= 电子回单 =============\n\n /**\n * 商户单号申请电子回单\n *\n * 申请条件:\n * - 转账单据状态为 SUCCESS\n * - 传入了收款用户姓名\n * - 六个月内的转账单据\n *\n * 回单有效期为90天,过期需重新申请。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716452\n */\n async applyElecSignByOutBillNo(\n request: ApplyMerchantTransferElecSignByOutBillNoRequest,\n ): Promise<WxPayResponse<ApplyMerchantTransferElecSignResponse>> {\n return this.client.post<ApplyMerchantTransferElecSignResponse>(\n '/v3/fund-app/mch-transfer/elecsign/out-bill-no',\n request,\n );\n }\n\n /**\n * 商户单号查询电子回单\n *\n * 当申请单状态为 FINISHED 时,返回回单文件的下载地址和摘要信息。\n * 下载地址有效期为10分钟,过期后需重新调用此接口获取。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716436\n */\n async queryElecSignByOutBillNo(\n outBillNo: string,\n ): Promise<WxPayResponse<QueryMerchantTransferElecSignResponse>> {\n return this.client.get<QueryMerchantTransferElecSignResponse>(\n `/v3/fund-app/mch-transfer/elecsign/out-bill-no/${outBillNo}`,\n );\n }\n\n /**\n * 微信单号申请电子回单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716456\n */\n async applyElecSignByTransferBillNo(\n request: ApplyMerchantTransferElecSignByTransferBillNoRequest,\n ): Promise<WxPayResponse<ApplyMerchantTransferElecSignResponse>> {\n return this.client.post<ApplyMerchantTransferElecSignResponse>(\n '/v3/fund-app/mch-transfer/elecsign/transfer-bill-no',\n request,\n );\n }\n\n /**\n * 微信单号查询电子回单\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716455\n */\n async queryElecSignByTransferBillNo(\n transferBillNo: string,\n ): Promise<WxPayResponse<QueryMerchantTransferElecSignResponse>> {\n return this.client.get<QueryMerchantTransferElecSignResponse>(\n `/v3/fund-app/mch-transfer/elecsign/transfer-bill-no/${transferBillNo}`,\n );\n }\n\n // ============= 用户授权免确认模式 =============\n\n /**\n * 发起转账并完成免确认收款授权\n *\n * 在发起转账的同时申请免确认收款授权,用户确认收款时可同时完成授权。\n * 授权成功后,后续转账无需用户逐笔确认。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4014399293\n */\n async createTransferWithAuthorization(\n request: CreateTransferWithAuthorizationRequest,\n ): Promise<WxPayResponse<CreateTransferWithAuthorizationResponse>> {\n return this.client.post<CreateTransferWithAuthorizationResponse>(\n '/v3/fund-app/mch-transfer/transfer-bills/pre-transfer-with-authorization',\n request,\n );\n }\n\n /**\n * 发起免确认收款授权\n *\n * 直接申请免确认收款授权,不发起转账。\n * 用户需在24小时内完成授权,未确认记录保留30天。\n * 同一微信号在同商户下待确认+已授权状态的授权单最多5个。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4015901167\n */\n async createAuthorization(\n request: CreateMerchantTransferAuthorizationRequest,\n ): Promise<WxPayResponse<CreateMerchantTransferAuthorizationResponse>> {\n return this.client.post<CreateMerchantTransferAuthorizationResponse>(\n '/v3/fund-app/mch-transfer/user-confirm-authorization',\n request,\n );\n }\n\n /**\n * 商户单号查询授权结果\n *\n * @param outAuthorizationNo - 商户侧授权单号\n * @param options - 可选参数,is_display_authorization 控制是否返回 package_info\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4014399423\n */\n async queryAuthorizationByOutAuthorizationNo(\n outAuthorizationNo: string,\n options?: { is_display_authorization?: boolean },\n ): Promise<WxPayResponse<QueryMerchantTransferAuthorizationResponse>> {\n return this.client.get<QueryMerchantTransferAuthorizationResponse>(\n `/v3/fund-app/mch-transfer/user-confirm-authorization/out-authorization-no/${outAuthorizationNo}`,\n options,\n );\n }\n\n /**\n * 用户授权后转账\n *\n * 用户完成授权后,商户可直接发起转账,无需用户逐笔确认收款。\n * 需要提供 authorization_id 或 out_authorization_no(二选一)。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4014399371\n */\n async createTransferAfterAuthorization(\n request: CreateTransferAfterAuthorizationRequest,\n ): Promise<WxPayResponse<CreateTransferAfterAuthorizationResponse>> {\n return this.client.post<CreateTransferAfterAuthorizationResponse>(\n '/v3/fund-app/mch-transfer/transfer-bills/transfer',\n request,\n );\n }\n\n /**\n * 解除免确认收款授权\n *\n * 商户可调用此接口帮助用户发起解除授权。\n * 用户也可通过微信支付入账消息的收款设置操作关闭授权。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4015653811\n */\n async closeAuthorization(\n outAuthorizationNo: string,\n ): Promise<WxPayResponse<CloseMerchantTransferAuthorizationResponse>> {\n return this.client.post<CloseMerchantTransferAuthorizationResponse>(\n `/v3/fund-app/mch-transfer/user-confirm-authorization/out-authorization-no/${outAuthorizationNo}/close`,\n );\n }\n\n // ============= 电子回单下载 =============\n\n /**\n * 下载电子回单\n *\n * 通过申请电子回单接口返回的 download_url,以 GET 方式下载回单原始文件。\n * 下载地址有效期为 10 分钟,过期后需重新调用查询接口获取。\n * 返回的 data 为 PDF 文件的 Buffer。\n *\n * @param downloadUrl - 查询电子回单返回的 download_url\n * @returns 电子回单文件 Buffer\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013866774\n */\n async downloadElecSign(downloadUrl: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(downloadUrl);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreateCouponStockRequest,\n CreateCouponStockResponse,\n ActivateCouponStockRequest,\n ActivateCouponStockResponse,\n SendCouponRequest,\n SendCouponResponse,\n PauseCouponStockRequest,\n PauseCouponStockResponse,\n RestartCouponStockRequest,\n RestartCouponStockResponse,\n QueryCouponStocksParams,\n QueryCouponStocksResponse,\n CouponStockItem,\n QueryCouponDetailParams,\n QueryCouponDetailResponse,\n QueryCouponStockMerchantsParams,\n QueryCouponStockMerchantsResponse,\n QueryCouponStockItemsParams,\n QueryCouponStockItemsResponse,\n QueryUserCouponsParams,\n QueryUserCouponsResponse,\n DownloadCouponStockFlowResponse,\n SetCouponCallbackRequest,\n SetCouponCallbackResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 代金券服务\n *\n * 提供微信支付代金券全流程相关的 API 封装,包括:\n * - 批次管理:创建、激活、暂停、重启代金券批次\n * - 发放:发放指定批次的代金券给用户\n * - 查询:批次列表、批次详情、券详情、可用商户、可用单品、用户券列表\n * - 明细下载:核销明细、退款明细\n * - 通知设置:设置代金券消息通知地址\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012081606\n */\nexport class CouponService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n // ============= 批次管理 =============\n\n /**\n * 创建代金券批次\n *\n * 通过此接口可创建代金券批次,包括预充值和免充值两种类型。\n * 预充值代金券适用于第三方出资策划的活动,免充值适用于商户策划的活动。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534633\n */\n async createStock(\n request: CreateCouponStockRequest,\n ): Promise<WxPayResponse<CreateCouponStockResponse>> {\n return this.client.post<CreateCouponStockResponse>(\n '/v3/marketing/favor/coupon-stocks',\n request,\n );\n }\n\n /**\n * 激活代金券批次\n *\n * 制券成功后,通过调用激活接口激活代金券批次。\n * 如果是预充值代金券,激活时从商户账户余额中锁定本批次的营销资金。\n *\n * @param stockId - 微信为每个代金券批次分配的唯一ID\n * @param request - 请求参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460137\n */\n async activateStock(\n stockId: string,\n request: ActivateCouponStockRequest,\n ): Promise<WxPayResponse<ActivateCouponStockResponse>> {\n return this.client.post<ActivateCouponStockResponse>(\n `/v3/marketing/favor/stocks/${stockId}/start`,\n request,\n );\n }\n\n /**\n * 暂停代金券批次\n *\n * 通过此接口可暂停指定代金券批次。暂停后,该批次暂停发放,\n * 用户无法通过任何渠道再领取该批次的券。前提条件是批次处于激活状态。\n *\n * @param stockId - 微信为每个代金券批次分配的唯一ID\n * @param request - 请求参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460305\n */\n async pauseStock(\n stockId: string,\n request: PauseCouponStockRequest,\n ): Promise<WxPayResponse<PauseCouponStockResponse>> {\n return this.client.post<PauseCouponStockResponse>(\n `/v3/marketing/favor/stocks/${stockId}/pause`,\n request,\n );\n }\n\n /**\n * 重启代金券批次\n *\n * 通过此接口可重启指定代金券批次。重启后,该批次可以再次发放。\n * 前提条件是批次处于暂停状态。\n *\n * @param stockId - 微信为每个代金券批次分配的唯一ID\n * @param request - 请求参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460411\n */\n async restartStock(\n stockId: string,\n request: RestartCouponStockRequest,\n ): Promise<WxPayResponse<RestartCouponStockResponse>> {\n return this.client.post<RestartCouponStockResponse>(\n `/v3/marketing/favor/stocks/${stockId}/restart`,\n request,\n );\n }\n\n // ============= 发放 =============\n\n /**\n * 发放代金券\n *\n * 通过调用此接口可发放指定批次给指定用户,发券场景可以是小程序、H5、App等。\n * 批次状态必须为\"运营中\"。\n *\n * @param openid - 用户在appid下的唯一标识\n * @param request - 请求参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012463767\n */\n async sendCoupon(\n openid: string,\n request: SendCouponRequest,\n ): Promise<WxPayResponse<SendCouponResponse>> {\n return this.client.post<SendCouponResponse>(\n `/v3/marketing/favor/users/${openid}/coupons`,\n request,\n );\n }\n\n // ============= 查询 =============\n\n /**\n * 条件查询批次列表\n *\n * 通过此接口可查询多个批次的信息,包括批次的配置信息以及批次概况数据。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460489\n */\n async queryStocks(\n params: QueryCouponStocksParams,\n ): Promise<WxPayResponse<QueryCouponStocksResponse>> {\n return this.client.get<QueryCouponStocksResponse>('/v3/marketing/favor/stocks', params);\n }\n\n /**\n * 查询批次详情\n *\n * 通过此接口可查询单个批次的信息,包括批次的配置信息以及批次概况数据。\n *\n * @param stockId - 微信为每个代金券批次分配的唯一ID\n * @param params - 查询参数,需包含 stock_creator_mchid\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460564\n */\n async queryStockDetail(\n stockId: string,\n params: { stock_creator_mchid: string },\n ): Promise<WxPayResponse<CouponStockItem>> {\n return this.client.get<CouponStockItem>(`/v3/marketing/favor/stocks/${stockId}`, params);\n }\n\n /**\n * 查询代金券详情\n *\n * 通过此接口可查询代金券信息,包括代金券的基础信息、状态。\n * 如代金券已核销,会包括代金券核销的订单信息。\n *\n * @param openid - 用户在appid下的唯一标识\n * @param couponId - 微信为代金券唯一分配的ID\n * @param params - 查询参数,需包含 appid\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012486942\n */\n async queryCouponDetail(\n openid: string,\n couponId: string,\n params: QueryCouponDetailParams,\n ): Promise<WxPayResponse<QueryCouponDetailResponse>> {\n return this.client.get<QueryCouponDetailResponse>(\n `/v3/marketing/favor/users/${openid}/coupons/${couponId}`,\n params,\n );\n }\n\n /**\n * 查询代金券可用商户\n *\n * 通过调用此接口可查询批次的可用商户号,判断券是否在某商户号可用,来决定是否展示。\n *\n * @param stockId - 微信为每个代金券批次分配的唯一ID\n * @param params - 查询参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012463358\n */\n async queryStockMerchants(\n stockId: string,\n params: QueryCouponStockMerchantsParams,\n ): Promise<WxPayResponse<QueryCouponStockMerchantsResponse>> {\n return this.client.get<QueryCouponStockMerchantsResponse>(\n `/v3/marketing/favor/stocks/${stockId}/merchants`,\n params,\n );\n }\n\n /**\n * 查询代金券可用单品\n *\n * 通过此接口可查询批次的可用商品编码,判断券是否可用于某些商品,来决定是否展示。\n *\n * @param stockId - 微信为每个代金券批次分配的唯一ID\n * @param params - 查询参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012463442\n */\n async queryStockItems(\n stockId: string,\n params: QueryCouponStockItemsParams,\n ): Promise<WxPayResponse<QueryCouponStockItemsResponse>> {\n return this.client.get<QueryCouponStockItemsResponse>(\n `/v3/marketing/favor/stocks/${stockId}/items`,\n params,\n );\n }\n\n /**\n * 根据商户号查用户的券\n *\n * 可通过该接口查询用户在某商户号可用的全部券,可用于商户的小程序/H5中,\n * 用户\"我的代金券\"或\"提交订单页\"展示优惠信息。\n *\n * 注意:无法查询到微信支付立减金(全平台通用券)。\n *\n * @param openid - 用户在商户appid下的唯一标识\n * @param params - 查询参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534690\n */\n async queryUserCoupons(\n openid: string,\n params: QueryUserCouponsParams,\n ): Promise<WxPayResponse<QueryUserCouponsResponse>> {\n return this.client.get<QueryUserCouponsResponse>(\n `/v3/marketing/favor/users/${openid}/coupons`,\n params,\n );\n }\n\n // ============= 明细下载 =============\n\n /**\n * 下载批次核销明细\n *\n * 可获取到某批次的核销明细数据,包括订单号、单品信息、银行流水号等,用于对账/数据分析。\n * 需要活动结束后次日10点才可下载。下载链接30秒内有效。\n *\n * @param stockId - 代金券批次唯一ID\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012463585\n */\n async downloadUseFlow(stockId: string): Promise<WxPayResponse<DownloadCouponStockFlowResponse>> {\n return this.client.get<DownloadCouponStockFlowResponse>(\n `/v3/marketing/favor/stocks/${stockId}/use-flow`,\n );\n }\n\n /**\n * 下载批次退款明细\n *\n * 可获取到某批次的退款明细数据,包括订单号、单品信息、银行流水号等,用于对账/数据分析。\n * 需要活动结束后次日10点才可下载。下载链接30秒内有效。\n *\n * @param stockId - 代金券批次唯一ID\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012463523\n */\n async downloadRefundFlow(\n stockId: string,\n ): Promise<WxPayResponse<DownloadCouponStockFlowResponse>> {\n return this.client.get<DownloadCouponStockFlowResponse>(\n `/v3/marketing/favor/stocks/${stockId}/refund-flow`,\n );\n }\n\n // ============= 通知设置 =============\n\n /**\n * 设置代金券消息通知地址\n *\n * 用于设置接收营销事件通知的URL,可接收营销相关的事件通知,包括核销、发放、退款等。\n * 通知URL必须为HTTPS协议、可直接访问、不能携带参数。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012464198\n */\n async setCallback(\n request: SetCouponCallbackRequest,\n ): Promise<WxPayResponse<SetCouponCallbackResponse>> {\n return this.client.post<SetCouponCallbackResponse>('/v3/marketing/favor/callbacks', request);\n }\n\n /**\n * 查询代金券消息通知地址\n *\n * 查询已设置的代金券核销事件通知地址。\n *\n * @param mchid - 商户号\n * @returns 通知地址信息\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012464070\n */\n async queryCallback(mchid: string): Promise<WxPayResponse<SetCouponCallbackResponse>> {\n return this.client.get<SetCouponCallbackResponse>('/v3/marketing/favor/callbacks', { mchid });\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n QueryComplaintsParams,\n QueryComplaintsResponse,\n QueryComplaintResponse,\n ComplaintNegotiationHistoryResponse,\n ReplyComplaintRequest,\n CompleteComplaintRequest,\n UpdateComplaintRefundRequest,\n ReplyImmediateServiceRequest,\n UploadComplaintImageResponse,\n ComplaintCallbackUrlRequest,\n ComplaintCallbackUrlResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 消费者投诉2.0 服务\n *\n * 提供微信支付消费者投诉处理全流程相关的 API 封装,包括:\n * - 主动查询:投诉单列表、投诉单详情、协商历史\n * - 商户处理:回复用户、处理完成、更新退款审批结果、即时服务回复\n * - 图片上传:上传反馈图片、获取投诉图片\n * - 回调管理:创建、查询、更新、删除投诉通知回调地址\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533431\n */\nexport class ComplaintService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n // ============= 主动查询投诉信息 =============\n\n /**\n * 查询投诉单列表\n *\n * 商户可通过此接口查询近期的用户投诉单列表。\n * 支持按投诉时间、投诉状态筛选,支持分页查询。\n *\n * @param params - 查询参数\n * @returns 投诉单列表及分页信息\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533431\n */\n async queryComplaints(\n params: QueryComplaintsParams,\n ): Promise<WxPayResponse<QueryComplaintsResponse>> {\n const queryParams: Record<string, string | number | boolean | undefined> = {\n begin_date: params.begin_date,\n end_date: params.end_date,\n };\n if (params.complaint_state) {\n queryParams['complaint_state'] = params.complaint_state;\n }\n if (params.mchid) {\n queryParams['mchid'] = params.mchid;\n }\n if (params.offset !== undefined) {\n queryParams['offset'] = params.offset;\n }\n if (params.limit !== undefined) {\n queryParams['limit'] = params.limit;\n }\n return this.client.get<QueryComplaintsResponse>(\n '/v3/merchant-service/complaints-v2',\n queryParams,\n );\n }\n\n /**\n * 查询投诉单详情\n *\n * 通过投诉单号查询投诉单的详细信息,包括投诉人信息、\n * 投诉订单信息、投诉图片等。\n *\n * @param complaintId - 投诉单号\n * @returns 投诉单详细信息\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533436\n */\n async queryComplaint(complaintId: string): Promise<WxPayResponse<QueryComplaintResponse>> {\n return this.client.get<QueryComplaintResponse>(\n `/v3/merchant-service/complaints-v2/${complaintId}`,\n );\n }\n\n /**\n * 查询投诉单协商历史\n *\n * 查询指定投诉单的协商历史记录,包括商户回复和用户反馈。\n *\n * @param complaintId - 投诉单号\n * @returns 协商历史记录列表\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012533439\n */\n async queryNegotiationHistory(\n complaintId: string,\n ): Promise<WxPayResponse<ComplaintNegotiationHistoryResponse>> {\n return this.client.get<ComplaintNegotiationHistoryResponse>(\n `/v3/merchant-service/complaints-v2/${complaintId}/negotiation-historys`,\n );\n }\n\n // ============= 商户处理用户投诉 =============\n\n /**\n * 回复用户\n *\n * 商户可通过此接口回复用户的投诉,回复内容会展示在协商历史中。\n *\n * @param request - 回复请求参数\n * @returns 空响应表示成功\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012467254\n */\n async replyComplaint(request: ReplyComplaintRequest): Promise<WxPayResponse> {\n const { complaint_id, ...body } = request;\n return this.client.post(`/v3/merchant-service/complaints-v2/${complaint_id}/replies`, body);\n }\n\n /**\n * 反馈处理完成\n *\n * 商户处理完投诉后,可通过此接口通知微信支付处理结果。\n * 调用成功后,投诉单状态变为 PROCESSED。\n *\n * @param request - 处理完成请求参数\n * @returns 空响应表示成功\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012467255\n */\n async completeComplaint(request: CompleteComplaintRequest): Promise<WxPayResponse> {\n const { complaint_id, ...body } = request;\n return this.client.post(`/v3/merchant-service/complaints-v2/${complaint_id}/complete`, body);\n }\n\n /**\n * 更新退款审批结果\n *\n * 当用户投诉涉及退款时,商户可通过此接口通知微信支付退款审批结果。\n * 退款审批通过后,微信支付会自动发起退款。\n *\n * @param request - 更新退款审批结果请求参数\n * @returns 空响应表示成功\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012467256\n */\n async updateRefundResult(request: UpdateComplaintRefundRequest): Promise<WxPayResponse> {\n const { complaint_id, ...body } = request;\n return this.client.post(\n `/v3/merchant-service/complaints-v2/${complaint_id}/update-refund`,\n body,\n );\n }\n\n /**\n * 回复需要即时服务的投诉单\n *\n * 对于需要即时服务的投诉(如投诉涉及订单退款),\n * 商户需在 2 小时内回复用户,否则平台可能介入。\n *\n * @param request - 即时服务回复请求参数\n * @returns 空响应表示成功\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4017151596\n */\n async replyImmediateService(request: ReplyImmediateServiceRequest): Promise<WxPayResponse> {\n const { complaint_id, ...body } = request;\n return this.client.post(`/v3/merchant-service/complaints-v2/${complaint_id}/replies`, body);\n }\n\n // ============= 商户反馈图片 =============\n\n /**\n * 图片上传接口\n *\n * 上传投诉处理相关的图片文件,获取 media_id 用于回复投诉。\n * 图片大小限制:≤ 2MB,格式:JPG、BMP、PNG。\n * 上传时需提供图片文件的 SHA256 哈希值。\n *\n * @param file - 图片文件 Buffer\n * @param filename - 文件名\n * @returns 上传成功后的 media_id\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012467250\n */\n async uploadImage(\n file: Buffer,\n filename: string,\n ): Promise<WxPayResponse<UploadComplaintImageResponse>> {\n return this.client.upload<UploadComplaintImageResponse>(\n '/v3/merchant-service/complaints-v2/images/upload',\n file,\n filename,\n );\n }\n\n /**\n * 图片请求接口\n *\n * 通过 media_id 获取投诉相关的图片文件。\n * 返回的 data 为图片文件的 Buffer。\n *\n * @param mediaId - 图片媒体文件标识\n * @returns 图片文件 Buffer\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012467251\n */\n async getImage(mediaId: string): Promise<WxPayResponse<Buffer>> {\n return this.client.downloadRaw(`/v3/merchant-service/complaints-v2/images/${mediaId}`);\n }\n\n // ============= 投诉通知回调地址管理 =============\n\n /**\n * 创建投诉通知回调地址\n *\n * 设置接收投诉通知的回调 URL。用户提交投诉、撤诉、确认处理完成时,\n * 微信支付会向此 URL 发送通知。\n *\n * @param request - 创建回调地址请求参数\n * @returns 空响应表示成功\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012458679\n */\n async createCallbackUrl(request: ComplaintCallbackUrlRequest): Promise<WxPayResponse> {\n return this.client.post('/v3/merchant-service/complaint-notifications', request);\n }\n\n /**\n * 查询投诉通知回调地址\n *\n * 查询当前设置的投诉通知回调 URL。\n *\n * @returns 回调地址信息\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012459014\n */\n async queryCallbackUrl(): Promise<WxPayResponse<ComplaintCallbackUrlResponse>> {\n return this.client.get<ComplaintCallbackUrlResponse>(\n '/v3/merchant-service/complaint-notifications',\n );\n }\n\n /**\n * 更新投诉通知回调地址\n *\n * 更新已设置的投诉通知回调 URL。\n *\n * @param request - 更新回调地址请求参数\n * @returns 空响应表示成功\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012459282\n */\n async updateCallbackUrl(request: ComplaintCallbackUrlRequest): Promise<WxPayResponse> {\n return this.client.put('/v3/merchant-service/complaint-notifications', request);\n }\n\n /**\n * 删除投诉通知回调地址\n *\n * 删除已设置的投诉通知回调 URL。删除后将不再接收投诉通知。\n *\n * @returns 空响应表示成功\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012460452\n */\n async deleteCallbackUrl(): Promise<WxPayResponse> {\n return this.client.delete('/v3/merchant-service/complaint-notifications');\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n BuildPartnershipRequest,\n BuildPartnershipResponse,\n QueryPartnershipsParams,\n QueryPartnershipsResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 委托营销服务\n *\n * 提供商户间委托营销合作关系管理的 API 封装,包括:\n * - 建立合作关系\n * - 查询合作关系列表\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012380498\n */\nexport class PartnershipService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 建立合作关系\n *\n * 商户可通过此接口与合作方建立委托营销合作关系。\n * 支持与 AppID 或商户号建立合作关系,授权代金券批次或商家券批次。\n *\n * @param request - 建立合作关系请求参数\n * @param idempotencyKey - 幂等键,需保持唯一性\n * @returns 合作关系详情\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012380498\n */\n async build(\n request: BuildPartnershipRequest,\n idempotencyKey: string,\n ): Promise<WxPayResponse<BuildPartnershipResponse>> {\n return this.client.post<BuildPartnershipResponse>(\n '/v3/marketing/partnerships/build',\n request,\n undefined,\n { 'Idempotency-Key': idempotencyKey },\n );\n }\n\n /**\n * 查询合作关系列表\n *\n * 查询已建立的委托营销合作关系列表,支持分页。\n *\n * @param params - 查询参数\n * @returns 合作关系列表\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012380536\n */\n async list(params: QueryPartnershipsParams): Promise<WxPayResponse<QueryPartnershipsResponse>> {\n const queryParams: Record<string, string | number | boolean | undefined> = {\n 'authorized_data.business_type': params.authorized_data.business_type,\n };\n if (params.authorized_data.stock_id) {\n queryParams['authorized_data.stock_id'] = params.authorized_data.stock_id;\n }\n if (params.partner) {\n queryParams['partner.type'] = params.partner.type;\n if (params.partner.appid) {\n queryParams['partner.appid'] = params.partner.appid;\n }\n if (params.partner.merchant_id) {\n queryParams['partner.merchant_id'] = params.partner.merchant_id;\n }\n }\n if (params.limit !== undefined) {\n queryParams['limit'] = params.limit;\n }\n if (params.offset !== undefined) {\n queryParams['offset'] = params.offset;\n }\n return this.client.get<QueryPartnershipsResponse>('/v3/marketing/partnerships', queryParams);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n QuerySmartGuidesParams,\n QuerySmartGuidesResponse,\n RegisterSmartGuideRequest,\n RegisterSmartGuideResponse,\n UpdateSmartGuideRequest,\n AssignSmartGuideRequest,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 支付即服务(服务人员)服务\n *\n * 提供支付即服务相关 API 封装,包括:\n * - 服务人员查询\n * - 服务人员注册\n * - 服务人员更新\n * - 服务人员分配\n *\n * 服务人员信息中的 name、mobile 等敏感字段需使用微信支付公钥或平台证书加密。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535123\n */\nexport class SmartGuideService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 服务人员查询\n *\n * 查询门店下的服务人员列表。支持按企业微信员工ID、手机号码、工号筛选。\n *\n * @param params - 查询参数\n * @returns 服务人员列表\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535123\n */\n async query(params: QuerySmartGuidesParams): Promise<WxPayResponse<QuerySmartGuidesResponse>> {\n const queryParams: Record<string, string | number | boolean | undefined> = {\n store_id: params.store_id,\n };\n if (params.userid) {\n queryParams['userid'] = params.userid;\n }\n if (params.mobile) {\n queryParams['mobile'] = params.mobile;\n }\n if (params.work_id) {\n queryParams['work_id'] = params.work_id;\n }\n if (params.limit !== undefined) {\n queryParams['limit'] = params.limit;\n }\n if (params.offset !== undefined) {\n queryParams['offset'] = params.offset;\n }\n return this.client.get<QuerySmartGuidesResponse>('/v3/smartguide/guides', queryParams);\n }\n\n /**\n * 服务人员注册\n *\n * 注册门店的服务人员。name 和 mobile 字段需使用微信支付公钥加密。\n * 注册成功后返回 guide_id,用于后续更新和分配操作。\n *\n * @param request - 注册请求参数\n * @returns 注册成功后的服务人员ID\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535138\n */\n async register(\n request: RegisterSmartGuideRequest,\n ): Promise<WxPayResponse<RegisterSmartGuideResponse>> {\n return this.client.post<RegisterSmartGuideResponse>('/v3/smartguide/guides', request);\n }\n\n /**\n * 服务人员更新\n *\n * 更新已注册的服务人员信息。仅需传入需要更新的字段。\n * name 和 mobile 属于敏感字段,需使用微信支付公钥加密。\n *\n * @param guideId - 服务人员ID\n * @param request - 更新请求参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535160\n */\n async update(guideId: string, request: UpdateSmartGuideRequest): Promise<WxPayResponse> {\n return this.client.patch(`/v3/smartguide/guides/${guideId}`, request);\n }\n\n /**\n * 服务人员分配\n *\n * 将服务人员与订单关联。必须在支付完成之前调用,\n * 否则将无法在支付凭证上出现服务人员名片入口。\n *\n * @param guideId - 服务人员ID\n * @param request - 分配请求参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535161\n */\n async assign(guideId: string, request: AssignSmartGuideRequest): Promise<WxPayResponse> {\n return this.client.post(`/v3/smartguide/guides/${guideId}/assign`, request);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n SyncBusinessCirclePointsRequest,\n QueryBusinessCircleAuthorizationResponse,\n QueryBusinessCirclePendingPointsParams,\n QueryBusinessCirclePendingPointsResponse,\n SyncBusinessCircleParkingStatusRequest,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 智慧商圈服务\n *\n * 提供微信支付智慧商圈相关 API 封装,包括:\n * - 商圈会员积分同步\n * - 商圈会员积分服务授权查询\n * - 商圈会员待积分状态查询\n * - 商圈会员停车状态同步\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534698\n */\nexport class BusinessCircleService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 商圈会员积分同步\n *\n * 商户完成积分发放或扣除后,通过此接口通知微信支付积分变更情况。\n * 成功返回 204 No Content。\n *\n * @param request - 积分同步请求参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534698\n */\n async syncPoints(request: SyncBusinessCirclePointsRequest): Promise<WxPayResponse> {\n return this.client.post('/v3/businesscircle/points/notify', request);\n }\n\n /**\n * 商圈会员积分服务授权查询\n *\n * 查询用户是否已授权商圈进行支付即积分。\n *\n * @param openid - 顾客授权时使用的小程序上的OpenID\n * @param appid - 顾客授权积分时使用的小程序的AppID\n * @returns 授权状态信息\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534848\n */\n async queryAuthorization(\n openid: string,\n appid: string,\n ): Promise<WxPayResponse<QueryBusinessCircleAuthorizationResponse>> {\n return this.client.get<QueryBusinessCircleAuthorizationResponse>(\n `/v3/businesscircle/user-authorizations/${openid}`,\n { appid },\n );\n }\n\n /**\n * 商圈会员待积分状态查询\n *\n * 查询用户的交易是否有待积分。\n *\n * @param params - 查询参数\n * @returns 待积分状态\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012534994\n */\n async queryPendingPoints(\n params: QueryBusinessCirclePendingPointsParams,\n ): Promise<WxPayResponse<QueryBusinessCirclePendingPointsResponse>> {\n return this.client.get<QueryBusinessCirclePendingPointsResponse>(\n '/v3/businesscircle/users/pending-points',\n {\n openid: params.openid,\n appid: params.appid,\n transaction_id: params.transaction_id,\n },\n );\n }\n\n /**\n * 商圈会员停车状态同步\n *\n * 用户停车入场时,商户通过此接口通知微信支付。\n *\n * @param request - 停车状态同步请求参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012535502\n */\n async syncParkingStatus(request: SyncBusinessCircleParkingStatusRequest): Promise<WxPayResponse> {\n return this.client.post('/v3/businesscircle/parkings', request);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type {\n CreatePayGiftActivityRequest,\n CreatePayGiftActivityResponse,\n QueryPayGiftActivitiesParams,\n QueryPayGiftActivitiesResponse,\n QueryPayGiftActivityResponse,\n GetPayGiftActivityMerchantsResponse,\n GetPayGiftActivityGoodsResponse,\n} from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 支付有礼服务\n *\n * 提供微信支付支付有礼活动管理的 API 封装,包括:\n * - 创建全场满额送活动\n * - 获取活动详情\n * - 获取活动列表\n * - 终止活动\n * - 活动发券商户号管理\n * - 活动商品列表查询\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012487898\n */\nexport class PayGiftActivityService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 创建全场满额送活动\n *\n * 创建支付有礼全场满额送活动,用户支付满额后自动发放商家券。\n *\n * @param request - 创建活动请求参数\n * @returns 活动ID和创建时间\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012487898\n */\n async create(\n request: CreatePayGiftActivityRequest,\n ): Promise<WxPayResponse<CreatePayGiftActivityResponse>> {\n return this.client.post<CreatePayGiftActivityResponse>(\n '/v3/marketing/paygiftactivity/unique-threshold-activity',\n request,\n );\n }\n\n /**\n * 获取活动详情\n *\n * 通过活动ID查询支付有礼活动的详细信息。\n *\n * @param activityId - 活动ID\n * @returns 活动详情\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012487971\n */\n async get(activityId: string): Promise<WxPayResponse<QueryPayGiftActivityResponse>> {\n return this.client.get<QueryPayGiftActivityResponse>(\n `/v3/marketing/paygiftactivity/activities/${activityId}`,\n );\n }\n\n /**\n * 获取支付有礼活动列表\n *\n * 查询商户的支付有礼活动列表,支持按状态筛选和分页。\n *\n * @param params - 查询参数\n * @returns 活动列表\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012489126\n */\n async list(\n params?: QueryPayGiftActivitiesParams,\n ): Promise<WxPayResponse<QueryPayGiftActivitiesResponse>> {\n const queryParams: Record<string, string | number | boolean | undefined> = {};\n if (params?.activity_state) {\n queryParams['activity_state'] = params.activity_state;\n }\n if (params?.limit !== undefined) {\n queryParams['limit'] = params.limit;\n }\n if (params?.offset !== undefined) {\n queryParams['offset'] = params.offset;\n }\n return this.client.get<QueryPayGiftActivitiesResponse>(\n '/v3/marketing/paygiftactivity/activities',\n queryParams,\n );\n }\n\n /**\n * 终止活动\n *\n * 终止进行中的支付有礼活动。\n *\n * @param activityId - 活动ID\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012466523\n */\n async terminate(activityId: string): Promise<WxPayResponse> {\n return this.client.post(`/v3/marketing/paygiftactivity/activities/${activityId}/terminate`);\n }\n\n /**\n * 获取活动发券商户号\n *\n * 查询活动的发券商户号列表。\n *\n * @param activityId - 活动ID\n * @returns 发券商户号列表\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012466149\n */\n async getMerchants(\n activityId: string,\n ): Promise<WxPayResponse<GetPayGiftActivityMerchantsResponse>> {\n return this.client.get<GetPayGiftActivityMerchantsResponse>(\n `/v3/marketing/paygiftactivity/activities/${activityId}/merchant`,\n );\n }\n\n /**\n * 新增活动发券商户号\n *\n * 向活动中添加新的发券商户号。\n *\n * @param activityId - 活动ID\n * @param merchantIdList - 商户号列表\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012466671\n */\n async addMerchant(activityId: string, merchantIdList: string[]): Promise<WxPayResponse> {\n return this.client.post(`/v3/marketing/paygiftactivity/activities/${activityId}/merchant`, {\n merchant_id_list: merchantIdList,\n });\n }\n\n /**\n * 删除活动发券商户号\n *\n * 从活动中删除指定的发券商户号。\n *\n * @param activityId - 活动ID\n * @param merchantId - 商户号\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012466787\n */\n async deleteMerchant(activityId: string, merchantId: string): Promise<WxPayResponse> {\n return this.client.delete(\n `/v3/marketing/paygiftactivity/activities/${activityId}/merchant/${merchantId}`,\n );\n }\n\n /**\n * 获取活动指定商品列表\n *\n * 查询活动中指定的商品列表。\n *\n * @param activityId - 活动ID\n * @returns 商品列表\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012466448\n */\n async getGoods(activityId: string): Promise<WxPayResponse<GetPayGiftActivityGoodsResponse>> {\n return this.client.get<GetPayGiftActivityGoodsResponse>(\n `/v3/marketing/paygiftactivity/activities/${activityId}/goods`,\n );\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type { CreateMedInsOrderRequest, MedInsOrderResponse } from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 医保支付服务\n *\n * 提供医保自费混合支付全流程相关的 API 封装,包括:\n * - 医保自费混合收款下单\n * - 使用混合订单号查看下单结果\n * - 使用商户订单号查看下单结果\n *\n * 注意:payer 和 relative 中的 name、id_digest 字段需使用微信支付公钥加密。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781466\n */\nexport class MedInsService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 医保自费混合收款下单\n *\n * 创建医保自费混合支付订单。支持纯自费、纯医保、医保+自费混合支付。\n * 支持代亲属支付,需传入 relative 字段。\n *\n * @param request - 下单请求参数\n * @returns 混合订单信息\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781466\n */\n async createOrder(\n request: CreateMedInsOrderRequest,\n ): Promise<WxPayResponse<MedInsOrderResponse>> {\n return this.client.post<MedInsOrderResponse>('/v3/med-ins/orders', request);\n }\n\n /**\n * 使用医保自费混合订单号查看下单结果\n *\n * 通过混合订单号查询订单状态和详情。\n *\n * @param mixTradeNo - 医保自费混合订单号\n * @returns 订单信息\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781479\n */\n async queryByMixTradeNo(mixTradeNo: string): Promise<WxPayResponse<MedInsOrderResponse>> {\n return this.client.get<MedInsOrderResponse>(`/v3/med-ins/orders/${mixTradeNo}`);\n }\n\n /**\n * 使用商户订单号查看下单结果\n *\n * 通过商户订单号查询订单状态和详情。\n *\n * @param outTradeNo - 商户订单号\n * @returns 订单信息\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781490\n */\n async queryByOutTradeNo(outTradeNo: string): Promise<WxPayResponse<MedInsOrderResponse>> {\n return this.client.get<MedInsOrderResponse>(`/v3/med-ins/orders/out-trade-no/${outTradeNo}`);\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type { UploadMarketingImageResponse } from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 媒体文件上传服务\n *\n * 提供营销专用图片上传 API 封装。\n * 上传的图片可用于支付有礼、代金券等营销活动。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012286130\n */\nexport class MediaService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 营销专用图片上传\n *\n * 上传图片文件至微信支付,获取 media_id 用于营销活动(如支付有礼、代金券等)。\n * 图片大小限制:≤ 2MB,格式:JPG、BMP、PNG、JPEG。\n *\n * @param file - 图片文件 Buffer\n * @param filename - 文件名(需包含扩展名,如 image.jpg)\n * @returns 上传成功后的 media_id\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012286130\n */\n async uploadImage(\n file: Buffer,\n filename: string,\n ): Promise<WxPayResponse<UploadMarketingImageResponse>> {\n return this.client.upload<UploadMarketingImageResponse>(\n '/v3/merchant/media/upload',\n file,\n filename,\n { type: 'image' },\n );\n }\n}\n","import type { WxPayResponse } from '../types/index.js';\nimport type { EchoTestRequest, EchoTestResponse } from '../types/index.js';\nimport { WxPayClient } from '../core/client.js';\n\n/**\n * 微信支付安全服务\n *\n * 提供微信支付公钥签名验签/加解密测试接口封装。\n * 用于验证商户与微信支付之间的签名验签和加解密能力是否正常。\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4014551946\n */\nexport class SecurityService {\n private readonly client: WxPayClient;\n\n constructor(client: WxPayClient) {\n this.client = client;\n }\n\n /**\n * 签名验签/加解密测试\n *\n * 用于测试商户的签名、验签、加密、解密能力。\n * 请求中 echo_message 会原样返回,encrypted_echo_message 经加密后返回。\n * 如传入 notify_url,微信支付会在测试成功后向该地址发送回调通知。\n *\n * @param request - 测试请求参数\n * @returns 测试结果,包含回显信息\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4014551946\n */\n async echoTest(request: EchoTestRequest): Promise<WxPayResponse<EchoTestResponse>> {\n return this.client.post<EchoTestResponse>('/v3/security/echo', request);\n }\n}\n","import crypto from 'node:crypto';\nimport type {\n AppBridgeConfig,\n JsapiBridgeConfig,\n MiniProgramBridgeConfig,\n PayScoreJsapiBridgeConfig,\n PayScoreMiniProgramBridgeConfig,\n PayScoreAppBridgeConfig,\n PayScoreDetailJsapiBridgeConfig,\n PayScoreDetailMiniProgramBridgeConfig,\n PayScoreDetailAppBridgeConfig,\n MerchantTransferJsapiBridgeConfig,\n MerchantTransferAuthorizationJsapiBridgeConfig,\n PlateColor,\n ParkingMiniProgramBridgeConfig,\n ParkingRepayBridgeConfig,\n MedInsMiniProgramBridgeConfig,\n MedInsJsapiBridgeConfig,\n} from '../types/index.js';\n\n/**\n * 调起支付参数生成工具\n *\n * 用于生成各场景下调起微信支付所需的参数,包括签名计算:\n * - APP 支付:生成 PayReq 对象参数(通过 OpenSDK 的 sendReq 调起)\n * - JSAPI 支付:生成 WeixinJSBridge.invoke() 参数\n * - 小程序支付:生成 wx.requestPayment() 参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070351 (APP 调起支付)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012365340 (APP 调起支付签名)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791857 (JSAPI 调起支付)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791898 (小程序调起支付)\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012365341 (小程序调起支付签名)\n */\n\n/**\n * 生成 APP 调起支付的 sign\n *\n * 签名算法:使用商户私钥对签名串进行 RSA-SHA256 签名\n * 签名串格式:appId\\ntimeStamp\\nnonceStr\\nprepay_id\\n\n *\n * @param appId - 应用ID\n * @param timeStamp - 时间戳(秒)\n * @param nonceStr - 随机字符串\n * @param prepayId - 预支付ID\n * @param privateKey - 商户私钥\n * @returns Base64 编码的签名\n */\nexport function generateAppPaySign(\n appId: string,\n timeStamp: string,\n nonceStr: string,\n prepayId: string,\n privateKey: string | Buffer,\n): string {\n const signString = `${appId}\\n${timeStamp}\\n${nonceStr}\\nprepay_id=${prepayId}\\n`;\n const signer = crypto.createSign('RSA-SHA256');\n signer.update(signString);\n signer.end();\n return signer.sign(privateKey, 'base64');\n}\n\n/**\n * 生成 APP 调起支付所需的完整配置\n *\n * 用于生成 OpenSDK sendReq 方法中 PayReq 对象所需的全部参数。\n * sign 使用商户 API 证书私钥进行 RSA-SHA256 签名。\n *\n * @param appId - 应用ID(下单时传入的 appid)\n * @param partnerId - 商户号(下单时传入的 mchid)\n * @param prepayId - 预支付ID(从 APP 下单接口获取)\n * @param privateKey - 商户私钥\n * @returns PayReq 对象所需的参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4013070351\n */\nexport function buildAppBridgeConfig(\n appId: string,\n partnerId: string,\n prepayId: string,\n privateKey: string | Buffer,\n): AppBridgeConfig {\n const timeStamp = String(Math.floor(Date.now() / 1000));\n const nonceStr = generateNonceStr();\n const sign = generateAppPaySign(appId, timeStamp, nonceStr, prepayId, privateKey);\n\n return {\n appId,\n partnerId,\n prepayId,\n packageValue: 'Sign=WXPay',\n nonceStr,\n timeStamp,\n sign,\n };\n}\n\n/**\n * 生成 JSAPI 调起支付的 paySign\n *\n * 签名算法:使用商户私钥对签名串进行 RSA-SHA256 签名\n * 签名串格式:appId\\ntimeStamp\\nnonceStr\\nprepay_id\\n\n *\n * @param appId - 应用ID\n * @param timeStamp - 时间戳(秒)\n * @param nonceStr - 随机字符串\n * @param prepayId - 预支付ID(package 参数为 prepay_id=xxx)\n * @param privateKey - 商户私钥\n * @returns Base64 编码的签名\n */\nexport function generatePaySign(\n appId: string,\n timeStamp: string,\n nonceStr: string,\n prepayId: string,\n privateKey: string | Buffer,\n): string {\n const signString = `${appId}\\n${timeStamp}\\n${nonceStr}\\nprepay_id=${prepayId}\\n`;\n const signer = crypto.createSign('RSA-SHA256');\n signer.update(signString);\n signer.end();\n return signer.sign(privateKey, 'base64');\n}\n\n/**\n * 生成随机 nonce 字符串(用于 JSAPI 调起支付)\n */\nexport function generateNonceStr(): string {\n return crypto.randomUUID().replace(/-/g, '');\n}\n\n/**\n * 生成 JSAPI 调起支付所需的完整配置\n *\n * @param appId - 应用ID\n * @param prepayId - 预支付ID(从下单接口获取)\n * @param privateKey - 商户私钥\n * @returns WeixinJSBridge.invoke() 所需的参数对象\n */\nexport function buildJsapiBridgeConfig(\n appId: string,\n prepayId: string,\n privateKey: string | Buffer,\n): JsapiBridgeConfig {\n const timeStamp = String(Math.floor(Date.now() / 1000));\n const nonceStr = generateNonceStr();\n const paySign = generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey);\n\n return {\n appId,\n timeStamp,\n nonceStr,\n package: `prepay_id=${prepayId}`,\n signType: 'RSA',\n paySign,\n };\n}\n\n/**\n * 生成小程序调起支付所需的完整配置\n *\n * 与 JSAPI 支付不同的是,小程序通过 wx.requestPayment() 调起支付,\n * 不需要传递 appId 字段(由小程序运行环境隐式提供)。\n * 但签名时仍然需要使用 appId 参与计算。\n *\n * @param appId - 小程序 AppID\n * @param prepayId - 预支付ID(从下单接口获取)\n * @param privateKey - 商户私钥\n * @returns wx.requestPayment() 所需的参数对象\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012791898\n */\nexport function buildMiniProgramBridgeConfig(\n appId: string,\n prepayId: string,\n privateKey: string | Buffer,\n): MiniProgramBridgeConfig {\n const timeStamp = String(Math.floor(Date.now() / 1000));\n const nonceStr = generateNonceStr();\n const paySign = generatePaySign(appId, timeStamp, nonceStr, prepayId, privateKey);\n\n return {\n timeStamp,\n nonceStr,\n package: `prepay_id=${prepayId}`,\n signType: 'RSA',\n paySign,\n };\n}\n\n/**\n * 生成支付分调起确认订单页的签名\n *\n * 签名算法:使用商户私钥对签名串进行 RSA-SHA256 签名\n * 签名串格式:appId\\ntimeStamp\\nnonceStr\\npackage\\n\n * 其中 package 为 service_id={service_id}&out_order_no={out_order_no}&need_sign_type=RSA\n *\n * @param appId - 应用ID\n * @param timeStamp - 时间戳(秒)\n * @param nonceStr - 随机字符串\n * @param serviceId - 服务ID\n * @param outOrderNo - 商户服务订单号\n * @param privateKey - 商户私钥\n * @returns Base64 编码的签名\n */\nexport function generatePayScorePaySign(\n appId: string,\n timeStamp: string,\n nonceStr: string,\n serviceId: string,\n outOrderNo: string,\n privateKey: string | Buffer,\n): string {\n const packageStr = `service_id=${serviceId}&out_order_no=${outOrderNo}&need_sign_type=RSA`;\n const signString = `${appId}\\n${timeStamp}\\n${nonceStr}\\n${packageStr}\\n`;\n const signer = crypto.createSign('RSA-SHA256');\n signer.update(signString);\n signer.end();\n return signer.sign(privateKey, 'base64');\n}\n\n/**\n * 生成支付分 JSAPI 调起确认订单页所需参数\n *\n * 用于 WeixinJSBridge.invoke('openBusinessView', config) 调起支付分确认订单页。\n * businessType 需传入 'wxpayScoreUse',queryString 需传入返回的 config 参数。\n *\n * @param appId - 公众号 AppID\n * @param mchId - 商户号\n * @param serviceId - 服务ID\n * @param outOrderNo - 商户服务订单号\n * @param privateKey - 商户私钥\n * @returns JSAPI 调起支付分确认订单页所需参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587945\n */\nexport function buildPayScoreJsapiBridgeConfig(\n appId: string,\n mchId: string,\n serviceId: string,\n outOrderNo: string,\n privateKey: string | Buffer,\n): PayScoreJsapiBridgeConfig {\n const timestamp = String(Math.floor(Date.now() / 1000));\n const nonceStr = generateNonceStr();\n const sign = generatePayScorePaySign(\n appId,\n timestamp,\n nonceStr,\n serviceId,\n outOrderNo,\n privateKey,\n );\n\n return {\n appid: appId,\n mchid: mchId,\n service_id: serviceId,\n out_order_no: outOrderNo,\n timestamp,\n nonce_str: nonceStr,\n sign_type: 'RSA',\n sign,\n };\n}\n\n/**\n * 生成支付分小程序调起确认订单页所需参数\n *\n * 用于 wx.openBusinessView({ businessType: 'wxpayScoreUse' }) 调起支付分确认订单页。\n * 小程序场景下不需要传入 appid 字段(由小程序运行环境隐式提供),\n * 但签名计算时仍需使用 appId。\n *\n * @param mchId - 商户号\n * @param serviceId - 服务ID\n * @param outOrderNo - 商户服务订单号\n * @param appId - 小程序 AppID(仅用于签名计算)\n * @param privateKey - 商户私钥\n * @returns 小程序调起支付分确认订单页所需参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587949\n */\nexport function buildPayScoreMiniProgramBridgeConfig(\n mchId: string,\n serviceId: string,\n outOrderNo: string,\n appId: string,\n privateKey: string | Buffer,\n): PayScoreMiniProgramBridgeConfig {\n const timestamp = String(Math.floor(Date.now() / 1000));\n const nonceStr = generateNonceStr();\n const sign = generatePayScorePaySign(\n appId,\n timestamp,\n nonceStr,\n serviceId,\n outOrderNo,\n privateKey,\n );\n\n return {\n mchid: mchId,\n service_id: serviceId,\n out_order_no: outOrderNo,\n timestamp,\n nonce_str: nonceStr,\n sign_type: 'RSA',\n sign,\n };\n}\n\n/**\n * 生成支付分 APP 调起确认订单页所需参数\n *\n * 用于 APP 端通过 OpenSDK 调起支付分确认订单页。\n *\n * @param appId - 应用 AppID\n * @param mchId - 商户号\n * @param serviceId - 服务ID\n * @param outOrderNo - 商户服务订单号\n * @param privateKey - 商户私钥\n * @returns APP 调起支付分确认订单页所需参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587909\n */\nexport function buildPayScoreAppBridgeConfig(\n appId: string,\n mchId: string,\n serviceId: string,\n outOrderNo: string,\n privateKey: string | Buffer,\n): PayScoreAppBridgeConfig {\n const timestamp = String(Math.floor(Date.now() / 1000));\n const nonceStr = generateNonceStr();\n const sign = generatePayScorePaySign(\n appId,\n timestamp,\n nonceStr,\n serviceId,\n outOrderNo,\n privateKey,\n );\n\n return {\n appid: appId,\n mchid: mchId,\n service_id: serviceId,\n out_order_no: outOrderNo,\n timestamp,\n nonce_str: nonceStr,\n sign_type: 'RSA',\n sign,\n };\n}\n\n// ============= 商家转账 =============\n\n/**\n * 生成商家转账 JSAPI 调起用户确认收款所需配置\n *\n * 用于 WeixinJSBridge.invoke('requestMerchantTransfer', config) 调起确认收款页。\n * 仅当转账单状态为 WAIT_USER_CONFIRM 时,发起转账接口才会返回 package_info。\n *\n * @param mchId - 商户号\n * @param appId - 商户AppID\n * @param packageInfo - 发起转账接口返回的 package_info\n * @returns JSAPI 调起用户确认收款所需参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716430\n */\nexport function buildMerchantTransferJsapiBridgeConfig(\n mchId: string,\n appId: string,\n packageInfo: string,\n): MerchantTransferJsapiBridgeConfig {\n return {\n mchId,\n appId,\n package: packageInfo,\n };\n}\n\n/**\n * 生成商家转账小程序调起用户确认收款所需配置\n *\n * 用于 wx.requestMerchantTransfer(config) 调起确认收款页。\n *\n * @param mchId - 商户号\n * @param appId - 商户AppID\n * @param packageInfo - 发起转账接口返回的 package_info\n * @returns 小程序调起用户确认收款所需参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012716430\n */\nexport function buildMerchantTransferMiniProgramBridgeConfig(\n mchId: string,\n appId: string,\n packageInfo: string,\n): MerchantTransferJsapiBridgeConfig {\n return {\n mchId,\n appId,\n package: packageInfo,\n };\n}\n\n/**\n * 生成 JSAPI 调起免确认收款授权页面所需配置\n *\n * 用于 WeixinJSBridge.invoke('requestMerchantTransfer', config) 调起授权确认页。\n * 仅当授权单状态为 WAIT_USER_CONFIRM 时,发起授权接口才会返回 package_info。\n *\n * @param mchId - 商户号\n * @param appId - 商户AppID\n * @param packageInfo - 发起授权接口返回的 package_info\n * @returns JSAPI 调起授权页面所需参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4015930512\n */\nexport function buildMerchantTransferAuthorizationJsapiBridgeConfig(\n mchId: string,\n appId: string,\n packageInfo: string,\n): MerchantTransferAuthorizationJsapiBridgeConfig {\n return {\n mchId,\n appId,\n package: packageInfo,\n };\n}\n\n// ============= 支付分停车服务 =============\n\n/** 支付分停车服务开通页目标小程序 AppID */\nconst PARKING_SERVICE_APPID = 'wxbcad394b3d99dac9';\n\n/** 支付分停车服务开通页目标小程序路径 */\nconst PARKING_SERVICE_PATH = '/pages/auth-creditpay/auth-creditpay';\n\n/** 微信垫资还款小程序 AppID */\nconst PARKING_REPAY_APPID = 'wx5e73c65404eee268';\n\n/** 微信垫资还款小程序路径 */\nconst PARKING_REPAY_PATH = 'pages/invest_list/invest_list';\n\n/**\n * 构建停车服务开通页查询参数字符串\n *\n * @param mchid - 商户号\n * @param openid - 用户在商户对应AppID下的唯一标识\n * @param plateNumber - 待开通车牌号\n * @param plateColor - 待开通车牌颜色\n * @returns URL 查询参数字符串(不含 ? 前缀)\n */\nfunction buildParkingQueryString(\n mchid: string,\n openid: string,\n plateNumber: string,\n plateColor: PlateColor,\n): string {\n const params = new URLSearchParams({\n mchid,\n openid,\n plate_number: plateNumber,\n plate_color: plateColor,\n trade_scene: 'PARKING',\n });\n return params.toString();\n}\n\n/**\n * 生成小程序调起支付分停车服务开通页配置\n *\n * 通过 wx.navigateToMiniProgram 跳转到车主服务小程序,引导用户开通支付分停车服务。\n * 用户完成授权后会跳转回商户小程序,商户需调用查询车牌服务开通信息接口确认最终结果。\n *\n * @param mchid - 商户号\n * @param openid - 用户在商户对应AppID下的唯一标识\n * @param plateNumber - 待开通车牌号\n * @param plateColor - 待开通车牌颜色\n * @returns wx.navigateToMiniProgram 所需的参数对象\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284186\n */\nexport function buildParkingMiniProgramBridgeConfig(\n mchid: string,\n openid: string,\n plateNumber: string,\n plateColor: PlateColor,\n): ParkingMiniProgramBridgeConfig {\n return {\n appId: PARKING_SERVICE_APPID,\n path: PARKING_SERVICE_PATH,\n extraData: {\n mchid,\n openid,\n plate_number: plateNumber,\n plate_color: plateColor,\n trade_scene: 'PARKING',\n },\n };\n}\n\n/**\n * 生成 H5 调起支付分停车服务开通页 URL\n *\n * 通过微信 H5 开放标签(wx-open-launch-weapp)拉起微信支付分停车服务小程序,\n * 引导用户进行服务开通。用户完成授权后跳转回商户 H5 页面,\n * 商户需调用查询车牌服务开通信息接口确认最终结果。\n *\n * @param mchid - 商户号\n * @param openid - 用户在商户对应AppID下的唯一标识\n * @param plateNumber - 待开通车牌号\n * @param plateColor - 待开通车牌颜色\n * @returns H5 开放标签所需的 path 属性值(含查询参数的完整路径)\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284235\n */\nexport function buildParkingH5BridgeUrl(\n mchid: string,\n openid: string,\n plateNumber: string,\n plateColor: PlateColor,\n): string {\n const queryString = buildParkingQueryString(mchid, openid, plateNumber, plateColor);\n return `${PARKING_SERVICE_PATH}?${queryString}`;\n}\n\n/**\n * 生成 App 拉起支付分停车服务开通页路径\n *\n * 通过微信 OpenSDK 的 WXLaunchMiniProgram 拉起微信支付分停车服务小程序,\n * 引导用户进行服务开通。用户完成授权后跳转回商户 App,\n * 商户需调用查询车牌服务开通信息接口确认最终结果。\n *\n * @param mchid - 商户号\n * @param openid - 用户在商户对应AppID下的唯一标识\n * @param plateNumber - 待开通车牌号\n * @param plateColor - 待开通车牌颜色\n * @returns App 拉起小程序所需的 path 参数(含查询参数的完整路径)\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284257\n */\nexport function buildParkingAppBridgePath(\n mchid: string,\n openid: string,\n plateNumber: string,\n plateColor: PlateColor,\n): string {\n const queryString = buildParkingQueryString(mchid, openid, plateNumber, plateColor);\n return `${PARKING_SERVICE_PATH}?${queryString}`;\n}\n\n/**\n * 生成微信垫资还款小程序跳转配置\n *\n * 通过小程序 navigator 组件或 App OpenSDK 拉起还款小程序,\n * 引导用户进行微信垫资还款操作。\n *\n * @param mchid - 商户号\n * @param openid - 用户在商户AppID下的唯一标识(可选)\n * @returns 还款小程序跳转配置\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012284369\n */\nexport function buildParkingRepayBridgeConfig(\n mchid: string,\n openid?: string,\n): ParkingRepayBridgeConfig {\n return {\n appId: PARKING_REPAY_APPID,\n path: PARKING_REPAY_PATH,\n extraData: {\n mchid,\n nonce_str: generateNonceStr(),\n openid,\n },\n };\n}\n\n// ============= H5 发券 =============\n\n/** H5 发券目标 URL */\nconst H5_COUPON_URL = 'https://action.weixin.qq.com/busifavor/getcouponinfo';\n\n/**\n * 生成 H5 发券跳转 URL\n *\n * 通过 URL 重定向方式在 H5 页面向用户发放商家券。\n * 商户将用户重定向至该 URL,用户在页面点击领券完成发券。\n *\n * 签名方式为 HMAC-SHA256(V2 签名规则),\n * 参与签名的字段:stock_id、out_request_no、send_coupon_merchant、open_id,\n * 以及可选的 coupon_code。\n *\n * @param params - H5 发券参数\n * @param signKey - V2 签名密钥(APIv2 signkey)\n * @returns 完整的 H5 发券跳转 URL\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012285783\n */\nexport function buildH5CouponUrl(\n params: {\n stock_id: string;\n out_request_no: string;\n send_coupon_merchant: string;\n open_id: string;\n coupon_code?: string;\n customize_send_time?: string;\n },\n signKey: string,\n): string {\n const signFields: Record<string, string> = {\n stock_id: params.stock_id,\n out_request_no: params.out_request_no,\n send_coupon_merchant: params.send_coupon_merchant,\n open_id: params.open_id,\n };\n if (params.coupon_code) {\n signFields['coupon_code'] = params.coupon_code;\n }\n\n // 按字典序拼接签名字符串\n const sortedKeys = Object.keys(signFields).sort();\n const signStr = sortedKeys.map((k) => `${k}=${signFields[k]}`).join('&') + `&key=${signKey}`;\n\n const sign = crypto.createHmac('sha256', signKey).update(signStr).digest('hex').toUpperCase();\n\n const urlParams = new URLSearchParams({\n stock_id: params.stock_id,\n out_request_no: params.out_request_no,\n sign,\n send_coupon_merchant: params.send_coupon_merchant,\n open_id: params.open_id,\n });\n if (params.coupon_code) {\n urlParams.set('coupon_code', params.coupon_code);\n }\n if (params.customize_send_time) {\n urlParams.set('customize_send_time', params.customize_send_time);\n }\n\n return `${H5_COUPON_URL}?${urlParams.toString()}#wechat_pay&wechat_redirect`;\n}\n\n// ============= 支付分 - 订单详情页 =============\n\n/**\n * 生成支付分 JSAPI 调起订单详情页所需参数\n *\n * 用于 WeixinJSBridge.invoke('openBusinessView', config) 调起支付分订单详情页。\n * businessType 需传入 'wxpayScoreDetail',queryString 需传入返回的 config 参数。\n *\n * @param appId - 公众号 AppID\n * @param mchId - 商户号\n * @param serviceId - 服务ID\n * @param outOrderNo - 商户服务订单号\n * @param privateKey - 商户私钥\n * @returns JSAPI 调起支付分订单详情页所需参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587945\n */\nexport function buildPayScoreDetailJsapiBridgeConfig(\n appId: string,\n mchId: string,\n serviceId: string,\n outOrderNo: string,\n privateKey: string | Buffer,\n): PayScoreDetailJsapiBridgeConfig {\n const timestamp = String(Math.floor(Date.now() / 1000));\n const nonceStr = generateNonceStr();\n const sign = generatePayScorePaySign(\n appId,\n timestamp,\n nonceStr,\n serviceId,\n outOrderNo,\n privateKey,\n );\n\n return {\n appid: appId,\n mchid: mchId,\n service_id: serviceId,\n out_order_no: outOrderNo,\n timestamp,\n nonce_str: nonceStr,\n sign_type: 'RSA',\n sign,\n };\n}\n\n/**\n * 生成支付分小程序调起订单详情页所需参数\n *\n * 用于 wx.openBusinessView({ businessType: 'wxpayScoreDetail' }) 调起支付分订单详情页。\n * 小程序场景下不需要传入 appid 字段(由小程序运行环境隐式提供),\n * 但签名计算时仍需使用 appId。\n *\n * @param mchId - 商户号\n * @param serviceId - 服务ID\n * @param outOrderNo - 商户服务订单号\n * @param appId - 小程序 AppID(仅用于签名计算)\n * @param privateKey - 商户私钥\n * @returns 小程序调起支付分订单详情页所需参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587949\n */\nexport function buildPayScoreDetailMiniProgramBridgeConfig(\n mchId: string,\n serviceId: string,\n outOrderNo: string,\n appId: string,\n privateKey: string | Buffer,\n): PayScoreDetailMiniProgramBridgeConfig {\n const timestamp = String(Math.floor(Date.now() / 1000));\n const nonceStr = generateNonceStr();\n const sign = generatePayScorePaySign(\n appId,\n timestamp,\n nonceStr,\n serviceId,\n outOrderNo,\n privateKey,\n );\n\n return {\n mchid: mchId,\n service_id: serviceId,\n out_order_no: outOrderNo,\n timestamp,\n nonce_str: nonceStr,\n sign_type: 'RSA',\n sign,\n };\n}\n\n/**\n * 生成支付分 APP 调起订单详情页所需参数\n *\n * 用于 APP 端通过 OpenSDK 调起支付分订单详情页。\n *\n * @param appId - 应用 AppID\n * @param mchId - 商户号\n * @param serviceId - 服务ID\n * @param outOrderNo - 商户服务订单号\n * @param privateKey - 商户私钥\n * @returns APP 调起支付分订单详情页所需参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4012587909\n */\nexport function buildPayScoreDetailAppBridgeConfig(\n appId: string,\n mchId: string,\n serviceId: string,\n outOrderNo: string,\n privateKey: string | Buffer,\n): PayScoreDetailAppBridgeConfig {\n const timestamp = String(Math.floor(Date.now() / 1000));\n const nonceStr = generateNonceStr();\n const sign = generatePayScorePaySign(\n appId,\n timestamp,\n nonceStr,\n serviceId,\n outOrderNo,\n privateKey,\n );\n\n return {\n appid: appId,\n mchid: mchId,\n service_id: serviceId,\n out_order_no: outOrderNo,\n timestamp,\n nonce_str: nonceStr,\n sign_type: 'RSA',\n sign,\n };\n}\n\n// ============= 医保支付 =============\n\n/** 医保支付小程序目标 AppID */\nconst MED_INS_APPID = 'wxbcad394b3d99dac9';\n\n/** 医保支付小程序目标路径 */\nconst MED_INS_PATH = '/pages/med-ins/pay/pay';\n\n/**\n * 生成小程序调起医保支付配置\n *\n * 通过 wx.navigateToMiniProgram 跳转到医保支付小程序,引导用户完成医保自费混合支付。\n * 用户完成支付后会跳转回商户小程序,商户需调用查询订单接口确认最终结果。\n *\n * @param mchid - 商户号\n * @param mixTradeNo - 医保自费混合订单号\n * @returns wx.navigateToMiniProgram 所需的参数对象\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781466\n */\nexport function buildMedInsMiniProgramBridgeConfig(\n mchid: string,\n mixTradeNo: string,\n): MedInsMiniProgramBridgeConfig {\n return {\n appId: MED_INS_APPID,\n path: MED_INS_PATH,\n extraData: {\n mchid,\n mix_trade_no: mixTradeNo,\n },\n };\n}\n\n/**\n * 生成医保支付 JSAPI 调起配置\n *\n * 用于 WeixinJSBridge.invoke('openBusinessView', config) 调起医保支付。\n * businessType 需传入 'medInsPay'。\n *\n * @param appId - 公众号 AppID\n * @param mchId - 商户号\n * @param mixTradeNo - 医保自费混合订单号\n * @param privateKey - 商户私钥\n * @returns JSAPI 调起医保支付所需参数\n *\n * @see https://pay.weixin.qq.com/doc/v3/merchant/4016781466\n */\nexport function buildMedInsJsapiBridgeConfig(\n appId: string,\n mchId: string,\n mixTradeNo: string,\n privateKey: string | Buffer,\n): MedInsJsapiBridgeConfig {\n const timestamp = String(Math.floor(Date.now() / 1000));\n const nonceStr = generateNonceStr();\n const packageStr = `mchid=${mchId}&mix_trade_no=${mixTradeNo}`;\n const signString = `${appId}\\n${timestamp}\\n${nonceStr}\\n${packageStr}\\n`;\n const signer = crypto.createSign('RSA-SHA256');\n signer.update(signString);\n signer.end();\n const sign = signer.sign(privateKey, 'base64');\n\n return {\n appid: appId,\n mchid: mchId,\n mix_trade_no: mixTradeNo,\n timestamp,\n nonce_str: nonceStr,\n sign_type: 'RSA',\n sign,\n };\n}\n"]}
|