UNPKG

koishi-plugin-pay-tool

Version:

适用于Koishi框架的易支付工具插件,支持订单创建、查询、退款、分配等功能

182 lines (181 loc) 7.75 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.EpayClient = void 0; const axios_1 = __importDefault(require("axios")); const utils_1 = require("./utils"); class EpayClient { constructor(config, logger) { this.config = config; this.logger = logger; this.axios = axios_1.default.create({ timeout: 30000, headers: { 'Content-Type': 'application/x-www-form-urlencoded' } }); // 添加响应拦截器,处理API返回字符串的情况 this.axios.interceptors.response.use(response => { // 如果响应数据是字符串,尝试解析为JSON if (typeof response.data === 'string') { try { response.data = JSON.parse(response.data); } catch (e) { // 如果解析失败,保持原样 this.logger.warn('无法解析API响应为JSON:', response.data); } } return response; }); } /** * 创建订单 * @param amount 金额 * @param paymentType 支付方式 * @param outTradeNo 商户订单号 * @param notifyUrl 回调地址 * @param returnUrl 跳转地址(可选) * @returns 订单创建结果 */ async createOrder(amount, paymentType, outTradeNo, notifyUrl, returnUrl) { const params = { pid: this.config.merchantPid, type: paymentType, out_trade_no: outTradeNo, notify_url: notifyUrl, name: this.config.productName, money: (0, utils_1.formatAmount)(amount), clientip: (0, utils_1.getClientIp)(), device: 'pc', sign: '', sign_type: 'MD5' }; // 添加跳转地址(如果配置了) if (returnUrl && returnUrl.trim()) { params.return_url = returnUrl; } // 生成签名 params.sign = (0, utils_1.generateSign)(params, this.config.merchantKey); try { const response = await this.axios.post(`${this.config.apiUrl}/mapi.php`, params); // 在调试模式下输出完整的API响应 if (this.config.devMode) { this.logger.info(`API创建订单响应 [${outTradeNo}]:`); this.logger.info(`请求URL: ${this.config.apiUrl}/mapi.php`); this.logger.info(`请求参数: ${JSON.stringify(params, null, 2)}`); this.logger.info(`响应状态: ${response.status}`); this.logger.info(`响应数据: ${JSON.stringify(response.data, null, 2)}`); } if (response.data.code == 1 || response.data.code === '1') { return response.data; } else { if (this.config.devMode) { this.logger.error(`API返回错误码: ${response.data.code}, 消息: ${response.data.msg}`); } throw new Error(response.data.msg || '创建订单失败'); } } catch (error) { if (axios_1.default.isAxiosError(error)) { if (this.config.devMode) { this.logger.error(`网络请求失败: ${error.message}, 状态码: ${error.response?.status}`); } throw new Error(`网络请求失败: ${error.message}`); } throw error; } } /** * 查询订单状态 * @param outTradeNo 商户订单号 * @returns 订单查询结果 */ async queryOrder(outTradeNo) { const url = `${this.config.apiUrl}/api.php?act=order&pid=${this.config.merchantPid}&key=${this.config.merchantKey}&out_trade_no=${outTradeNo}`; try { const response = await this.axios.get(url); // 在调试模式下输出完整的API响应 if (this.config.devMode) { this.logger.info(`API查询订单响应 [${outTradeNo}]:`); this.logger.info(`请求URL: ${url}`); this.logger.info(`响应状态: ${response.status}`); this.logger.info(`响应数据: ${JSON.stringify(response.data, null, 2)}`); } // 修复:检查code类型,可能是字符串"1"而不是数字1 if (response.data.code == 1 || response.data.code === '1') { // 验证是否真的返回了有效订单数据 if (!response.data.trade_no || !response.data.out_trade_no) { if (this.config.devMode) { this.logger.error(`订单数据不完整: trade_no=${response.data.trade_no}, out_trade_no=${response.data.out_trade_no}`); } throw new Error('订单不存在或查询失败'); } return response.data; } else { // 修复:提供更详细的错误信息 if (this.config.devMode) { this.logger.error(`API返回错误码: ${response.data.code}, 消息: ${response.data.msg}`); } throw new Error(`查询失败 [code: ${response.data.code}]: ${response.data.msg || '未知错误'}`); } } catch (error) { if (axios_1.default.isAxiosError(error)) { if (this.config.devMode) { this.logger.error(`网络请求失败: ${error.message}, 状态码: ${error.response?.status}`); } throw new Error(`网络请求失败: ${error.message}`); } throw error; } } /** * 申请退款 * @param outTradeNo 商户订单号 * @param amount 退款金额 * @returns 退款结果 */ async refundOrder(outTradeNo, amount) { const params = { pid: this.config.merchantPid, key: this.config.merchantKey, out_trade_no: outTradeNo, money: (0, utils_1.formatAmount)(amount) }; try { const response = await this.axios.post(`${this.config.apiUrl}/api.php?act=refund`, params); // 在调试模式下输出完整的API响应 if (this.config.devMode) { this.logger.info(`API退款订单响应 [${outTradeNo}]:`); this.logger.info(`请求URL: ${this.config.apiUrl}/api.php?act=refund`); this.logger.info(`请求参数: ${JSON.stringify(params, null, 2)}`); this.logger.info(`响应状态: ${response.status}`); this.logger.info(`响应数据: ${JSON.stringify(response.data, null, 2)}`); } if (response.data.code == 1 || response.data.code === '1') { return response.data; } else { if (this.config.devMode) { this.logger.error(`API返回错误码: ${response.data.code}, 消息: ${response.data.msg}`); } throw new Error(response.data.msg || '退款失败'); } } catch (error) { if (axios_1.default.isAxiosError(error)) { if (this.config.devMode) { this.logger.error(`网络请求失败: ${error.message}, 状态码: ${error.response?.status}`); } throw new Error(`网络请求失败: ${error.message}`); } throw error; } } } exports.EpayClient = EpayClient;