UNPKG

yungou-pay

Version:

YunGou-Pay 基于微信/支付宝授权的服务商模式, 为个人(开发者、小微商户)实现便捷的支付接入服务

607 lines (529 loc) 22.8 kB
const qs = require("querystring"); const request = require("../request.js"); const utils = require("../utils.js"); const API_URL = "https://api.pay.yungouos.com"; const sign = (params) => utils.sign(params, secret); const checkRequiredParams = (params) => utils.checkRequiredParams(params); let mid, secret; /** * 商户信息配置 * * 登录yungouos.com-》支付宝-》商户管理 支付宝商户号 获取 * * @param {*} params.mid 商户号 * @param {*} params.secret 商户密钥 */ const config = (params = {}) => { mid = params.mid; secret = params.secret; }; /** * 条码支付 * * 用户打开支付宝出示付款码,商家通过扫码枪、扫码盒子等设备主动扫描用户付款码完成扣款。 * * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/codePay * * @param {*} params.out_trade_no 商户订单号 * @param {*} params.total_fee 支付金额 单位:元 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝商户号 获取 * @param {*} params.body 商品描述 * @param {*} params.auth_code 扫码支付授权码,设备读取用户支付宝中的条码或者二维码信息 * @param {*} params.app_id 在YunGouOS平台报备的app_id,不传则按照商户号开户时的场景发起。 * @param {*} params.attach 附加数据,回调时候原路返回 * @param {*} params.notify_url 异步回调地址,用户支付成功后系统将会把支付结果发送到该地址,不填则无回调 * @param {*} params.hbfq_num 花呗分期期数。只支持3、6、12(仅限渠道商户使用) * @param {*} params.hbfq_percent 花呗分期商户承担手续费比例。只支持0、100(仅限渠道商户使用) * @param {*} params.biz_params 附加业务参数。json对象,具体参考API文档 * @return {*} 返回二维码支付链接地址或原生支付链接 */ const codePay = async (params = {}) => { const url = API_URL + "/api/pay/alipay/codePay"; // 必填参数 const payload = { out_trade_no: params.out_trade_no, total_fee: params.total_fee, mch_id: params.mch_id || mid, body: params.body, auth_code: params.auth_code, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); // 可选参数 params.app_id && (payload.app_id = params.app_id); params.attach && (payload.attach = params.attach); params.notify_url && (payload.notify_url = params.notify_url); params.biz_params && (payload.biz_params = JSON.stringify(params.biz_params)); // 花呗分期业务 const hbfqBiz = {}; params.hbfq_num && (hbfqBiz.hbfq_num = params.hbfq_num); params.hbfq_percent && (hbfqBiz.hbfq_percent = params.hbfq_percent); if (Object.keys(hbfqBiz).length) { payload.hb_fq = JSON.stringify(hbfqBiz); } return request.post(url, payload); }; /** * 扫码支付 * * 同步发起扫码支付 返回原生支付链接或二维码连接地址,根据type类型决定 * * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/nativePay * * @param {*} params.out_trade_no 商户订单号 * @param {*} params.total_fee 支付金额 单位:元 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝商户号 获取 * @param {*} params.body 商品描述 * @param {*} params.type 返回类型(1、返回支付宝原生的支付连接需要自行生成二维码;2、直接返回付款二维码地址,页面上展示即可。不填默认1) * @param {*} params.app_id 在YunGouOS平台报备的app_id,不传则按照商户号开户时的场景发起。 * @param {*} params.attach 附加数据,回调时候原路返回 * @param {*} params.notify_url 异步回调地址,用户支付成功后系统将会把支付结果发送到该地址,不填则无回调 * @param {*} params.hbfq_num 花呗分期期数。只支持3、6、12(仅限渠道商户使用) * @param {*} params.hbfq_percent 花呗分期商户承担手续费比例。只支持0、100(仅限渠道商户使用) * @param {*} params.biz_params 附加业务参数。json对象,具体参考API文档 * @return {*} 返回Promise化结果,需要自行处理返回结果 */ const nativePay = async (params = {}) => { const url = API_URL + "/api/pay/alipay/nativePay"; // 必填参数 const payload = { out_trade_no: params.out_trade_no, total_fee: params.total_fee, mch_id: params.mch_id || mid, body: params.body, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); // 可选参数 // 二维码返回类型(1、返回微信原生的支付连接需要自行生成二维码;2、直接返回付款二维码地址,页面上展示即可。不填默认1 ) payload.type = params.type || "1"; params.app_id && (payload.app_id = params.app_id); params.attach && (payload.attach = params.attach); params.notify_url && (payload.notify_url = params.notify_url); params.biz_params && (payload.biz_params = JSON.stringify(params.biz_params)); // 花呗分期业务 const hbfqBiz = {}; params.hbfq_num && (hbfqBiz.hbfq_num = params.hbfq_num); params.hbfq_percent && (hbfqBiz.hbfq_percent = params.hbfq_percent); if (Object.keys(hbfqBiz).length) { payload.hb_fq = JSON.stringify(hbfqBiz); } const rsp = await request.post(url, payload); // 二维码返回类型为文本链接时 自动生成base64二维码 if (rsp.data && payload.type === "1") { rsp.qrcode = await utils.qrbase64(rsp.data); } return rsp; }; /** * WAP支付 * * 返回支付宝WAP支付连接,重定向到该地址即可。安装了支付宝APP将自动唤起支付宝APP进行支付 * * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/wapPay * @param {*} params -请求参数 * @param {*} params.out_trade_no 商户订单号 * @param {*} params.total_fee 支付金额 单位:元 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝商户号 获取 * @param {*} params.body 商品描述 * @param {*} params.app_id 在YunGouOS平台报备的app_id,不传则按照商户号开户时的场景发起。 * @param {*} params.attach 附加数据,回调时候原路返回 * @param {*} params.notify_url 异步回调地址,用户支付成功后系统将会把支付结果发送到该地址,不填则无回调 * @param {*} params.hbfq_num 花呗分期期数。只支持3、6、12(仅限渠道商户使用) * @param {*} params.hbfq_percent 花呗分期商户承担手续费比例。只支持0、100(仅限渠道商户使用) * @param {*} params.biz_params 附加业务参数。json对象,具体参考API文档 * @return {*} 返回支付宝WAP支付连接 */ const wapPay = async (params = {}) => { const url = API_URL + "/api/pay/alipay/wapPay"; // 必填参数 const payload = { out_trade_no: params.out_trade_no, total_fee: params.total_fee, mch_id: params.mch_id || mid, body: params.body, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); // 可选参数 params.app_id && (payload.app_id = params.app_id); params.attach && (payload.attach = params.attach); params.notify_url && (payload.notify_url = params.notify_url); params.biz_params && (payload.biz_params = JSON.stringify(params.biz_params)); // 花呗分期业务 const hbfqBiz = {}; params.hbfq_num && (hbfqBiz.hbfq_num = params.hbfq_num); params.hbfq_percent && (hbfqBiz.hbfq_percent = params.hbfq_percent); if (Object.keys(hbfqBiz).length) { payload.hb_fq = JSON.stringify(hbfqBiz); } return request.post(url, payload); }; /** * JS支付 * * JS支付,适用于支付宝网页内打开的H5应用使用支付宝的JSSDK发起支付 * * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/jsPay * * @param {*} params.out_trade_no 商户订单号 * @param {*} params.total_fee 支付金额 单位:元 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝商户号 获取 * @param {*} params.buyer_id 买家的支付宝唯一用户号(2088开头的16位纯数字) * @param {*} params.body 商品描述 * @param {*} params.app_id 在YunGouOS平台报备的app_id,不传则按照商户号开户时的场景发起。 * @param {*} params.attach 附加数据,回调时候原路返回 * @param {*} params.notify_url 异步回调地址,用户支付成功后系统将会把支付结果发送到该地址,不填则无回调 * @param {*} params.hbfq_num 花呗分期期数。只支持3、6、12(仅限渠道商户使用) * @param {*} params.hbfq_percent 花呗分期商户承担手续费比例。只支持0、100(仅限渠道商户使用) * @param {*} params.biz_params 附加业务参数。json对象,具体参考API文档 * @return {*} 返回支付宝的JSSDK所需的参数 */ const jsPay = async (params = {}) => { const url = API_URL + "/api/pay/alipay/jsPay"; // 必填参数 const payload = { out_trade_no: params.out_trade_no, total_fee: params.total_fee, mch_id: params.mch_id || mid, body: params.body, buyer_id: params.buyer_id, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); // 可选参数 params.app_id && (payload.app_id = params.app_id); params.attach && (payload.attach = params.attach); params.notify_url && (payload.notify_url = params.notify_url); params.biz_params && (payload.biz_params = JSON.stringify(params.biz_params)); // 花呗分期业务 const hbfqBiz = {}; params.hbfq_num && (hbfqBiz.hbfq_num = params.hbfq_num); params.hbfq_percent && (hbfqBiz.hbfq_percent = params.hbfq_percent); if (Object.keys(hbfqBiz).length) { payload.hb_fq = JSON.stringify(hbfqBiz); } return request.post(url, payload); }; /** * H5支付 * * 支付宝H5手机网站接口,可自动打开支付宝APP支付。和WAP接口不同的是,H5可以传递return_url也就是支付后或取消支付可以自动跳回网站 * * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/mobilePay * * @param {*} params.out_trade_no 商户订单号 * @param {*} params.total_fee 支付金额 单位:元 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝商户号 获取 * @param {*} params.body 商品描述 * @param {*} params.app_id 在YunGouOS平台报备的app_id,不传则按照商户号开户时的场景发起。 * @param {*} params.attach 附加数据,回调时候原路返回 * @param {*} params.notify_url 异步回调地址,用户支付成功后系统将会把支付结果发送到该地址,不填则无回调 * @param {*} params.return_url 同步回调地址,用户支付成功后或取消支付都会跳转回到该地址 * @param {*} params.hbfq_num 花呗分期期数。只支持3、6、12(仅限渠道商户使用) * @param {*} params.hbfq_percent 花呗分期商户承担手续费比例。只支持0、100(仅限渠道商户使用) * @param {*} params.payKey 支付密钥 登录yungouos.com-》支付宝-》商户管理 支付密钥 获取 * @param {*} params.biz_params 附加业务参数。json对象,具体参考API文档 * @return {*} 返回支付宝H5支付的form表单 */ const h5Pay = async (params = {}) => { const url = API_URL + "/api/pay/alipay/mobilePay"; // 必填参数 const payload = { out_trade_no: params.out_trade_no, total_fee: params.total_fee, mch_id: params.mch_id || mid, body: params.body, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); // 可选参数 params.app_id && (payload.app_id = params.app_id); params.attach && (payload.attach = params.attach); params.notify_url && (payload.notify_url = params.notify_url); params.biz_params && (payload.biz_params = JSON.stringify(params.biz_params)); // 花呗分期业务 const hbfqBiz = {}; params.hbfq_num && (hbfqBiz.hbfq_num = params.hbfq_num); params.hbfq_percent && (hbfqBiz.hbfq_percent = params.hbfq_percent); if (Object.keys(hbfqBiz).length) { payload.hb_fq = JSON.stringify(hbfqBiz); } return request.post(url, payload); }; /** * APP支付 * * 支付宝原生APP支付,返回APP端拉起支付宝所需的参数 * * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/appPay * * @param {*} params.out_trade_no 商户订单号 * @param {*} params.total_fee 支付金额 单位:元 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝商户号 获取 * @param {*} params.body 商品描述 * @param {*} params.app_id 在YunGouOS平台报备的app_id,不传则按照商户号开户时的场景发起。 * @param {*} params.attach 附加数据,回调时候原路返回 * @param {*} params.notify_url 异步回调地址,用户支付成功后系统将会把支付结果发送到该地址,不填则无回调 * @param {*} params.hbfq_num 花呗分期期数。只支持3、6、12(仅限渠道商户使用) * @param {*} params.hbfq_percent 花呗分期商户承担手续费比例。只支持0、100(仅限渠道商户使用) * @param {*} params.payKey 支付密钥 登录yungouos.com-》支付宝-》商户管理 支付密钥 获取 * @param {*} params.biz_params 附加业务参数。json对象,具体参考API文档 * @return {*} 返回APP端拉起支付宝所需的参数 */ const appPay = async (params = {}) => { const url = API_URL + "/api/pay/alipay/appPay"; // 必填参数 const payload = { out_trade_no: params.out_trade_no, total_fee: params.total_fee, mch_id: params.mch_id || mid, body: params.body, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); // 可选参数 params.app_id && (payload.app_id = params.app_id); params.attach && (payload.attach = params.attach); params.notify_url && (payload.notify_url = params.notify_url); params.biz_params && (payload.biz_params = JSON.stringify(params.biz_params)); // 花呗分期业务 const hbfqBiz = {}; params.hbfq_num && (hbfqBiz.hbfq_num = params.hbfq_num); params.hbfq_percent && (hbfqBiz.hbfq_percent = params.hbfq_percent); if (Object.keys(hbfqBiz).length) { payload.hb_fq = JSON.stringify(hbfqBiz); } return request.post(url, payload); }; /** * 电脑网站支付 * * 支付宝电脑网站支付,适合PC端使用,返回PC端跳转表单字符串和跳转url * * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/webPay * * @param {*} params.out_trade_no 商户订单号 * @param {*} params.total_fee 支付金额 单位:元 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝商户号 获取 * @param {*} params.body 商品描述 * @param {*} params.app_id 在YunGouOS平台报备的app_id,不传则按照商户号开户时的场景发起。 * @param {*} params.attach 附加数据,回调时候原路返回 * @param {*} params.notify_url 异步回调地址,用户支付成功后系统将会把支付结果发送到该地址,不填则无回调 * @param {*} params.return_url 同步回调地址,用户支付成功后或取消支付都会跳转回到该地址 * @param {*} params.hbfq_num 花呗分期期数。只支持3、6、12(仅限渠道商户使用) * @param {*} params.hbfq_percent 花呗分期商户承担手续费比例。只支持0、100(仅限渠道商户使用) * @param {*} params.biz_params 附加业务参数。json对象,具体参考API文档 * @return {*} 返回PC端跳转表单字符串和跳转url */ const webPay = async (params = {}) => { const url = API_URL + "/api/pay/alipay/webPay"; // 必填参数 const payload = { out_trade_no: params.out_trade_no, total_fee: params.total_fee, mch_id: params.mch_id || mid, body: params.body, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); // 可选参数 params.app_id && (payload.app_id = params.app_id); params.attach && (payload.attach = params.attach); params.notify_url && (payload.notify_url = params.notify_url); params.biz_params && (payload.biz_params = JSON.stringify(params.biz_params)); // 花呗分期业务 const hbfqBiz = {}; params.hbfq_num && (hbfqBiz.hbfq_num = params.hbfq_num); params.hbfq_percent && (hbfqBiz.hbfq_percent = params.hbfq_percent); if (Object.keys(hbfqBiz).length) { payload.hb_fq = JSON.stringify(hbfqBiz); } return request.post(url, payload); }; /** * 发起退款 * * 对已支付的订单发起退款 * * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/refundOrder * * @param {*} params.out_trade_no 商户订单号 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝商户号 获取 * @param {*} params.money 退款金额 * @param {*} params.out_trade_refund_no 商户自定义退款单号 * @param {*} params.refund_desc 退款描述 * @param {*} params.notify_url 异步回调地址,退款成功后会把退款结果发送到该地址,不填则无回调 * @return {*} 参考文档:https://open.pay.yungouos.com/#/api/api/pay/alipay/refundOrder */ const refundOrder = async (params = {}) => { const url = API_URL + "/api/pay/alipay/refundOrder"; // 必填参数 const payload = { out_trade_no: params.out_trade_no, money: params.money, mch_id: params.mch_id || mid, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); // 可选参数 params.out_trade_refund_no && (payload.out_trade_refund_no = params.out_trade_refund_no); params.refund_desc && (payload.refund_desc = params.refund_desc); params.notify_url && (payload.notify_url = params.notify_url); return request.post(url, payload); }; /** * 查询退款结果 * * 对已发起退款申请的订单查询支付宝的退款结果 * * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/getRefundResult * * @param {*} params.refund_no 退款单号 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝商户号 获取 * @return {*} 参考文档:https://open.pay.yungouos.com/#/api/api/pay/alipay/getRefundResult */ const getRefundResult = async (params = {}) => { const url = API_URL + "/api/pay/alipay/getRefundResult"; // 必填参数 const payload = { refund_no: params.refund_no, mch_id: params.mch_id || mid, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); return request.post(url, payload); }; /** * 关闭订单 * * 对已经发起的订单进行关闭,订单如果已支付不能关闭。已支付订单需要关闭请使用撤销订单接口 * * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/closeOrder * * @param {*} params.out_trade_no 商户单号 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝 获取 * @return {*} 参考文档:https://open.pay.yungouos.com/#/api/api/pay/alipay/closeOrder */ const closeOrder = async (params = {}) => { const url = API_URL + "/api/pay/alipay/closeOrder"; // 必填参数 const payload = { out_trade_no: params.out_trade_no, mch_id: params.mch_id || mid, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); return request.post(url, payload); }; /** * 撤销订单 * 支付交易返回失败或支付系统超时,调用该接口撤销交易。 * @see https://open.pay.yungouos.com/#/api/api/pay/alipay/reverseOrder * * @param {*} params.out_trade_no 商户单号 * @param {*} params.mch_id 支付宝商户号 登录yungouos.com-》支付宝-》商户管理 支付宝 获取 * @return {*} 参考文档:https://open.pay.yungouos.com/#/api/api/pay/alipay/reverseOrder */ const reverseOrder = async (params = {}) => { const url = API_URL + "/api/pay/alipay/reverseOrder"; // 必填参数 const payload = { out_trade_no: params.out_trade_no, mch_id: params.mch_id || mid, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); return request.post(url, payload); }; /** * 订单查询 * * 根据订单号查询支付订单 (该接口限流,规则为1qps/10s) * * @see https://open.pay.yungouos.com/#/api/api/system/order/getPayOrderInfo * * @param {*} params.out_trade_no 商户单号 * @param {*} params.mch_id 微信支付商户号 登录yungouos.com-》微信支付-》商户管理 微信支付商户号 获取 * @return {*} 参考文档:https://open.pay.yungouos.com/#/api/api/system/order/getPayOrderInfo */ const queryOrder = async (params = {}) => { const url = API_URL + "/api/system/order/getPayOrderInfo"; // 必填参数 const payload = { mch_id: params.mch_id || mid, out_trade_no: params.out_trade_no, }; // 必填参数检查 checkRequiredParams(payload); // md5签名 (只有必传参数才参与签名) payload.sign = sign(payload); return request.get(url + "?" + qs.stringify(payload)); }; /** * 回调通知签名校验 * * 支持异步回调、同步回调签名校验 (未支持退款回调通知验签) * * @see https://open.pay.yungouos.com/#/callback/notify * * @param {*} params form表单形式数据 * @return {*} 返回验签通过后的JSON结构数据, 验签不通过则抛出错误 */ const notifyVerify = async (params = {}) => { // content-type 为 application/x-www-form-urlencoded params = qs.parse(params); // md5签名校验 const payload = { code: params.code, orderNo: params.orderNo, outTradeNo: params.outTradeNo, payNo: params.payNo, money: params.money, mchId: params.mchId, }; const checksum = sign(payload); if (checksum !== params.sign) { throw new Error("invalid notify sign"); } return params; }; module.exports = { config, codePay, nativePay, wapPay, jsPay, h5Pay, appPay, webPay, refundOrder, getRefundResult, closeOrder, reverseOrder, queryOrder, notifyVerify, };