123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115 |
- 'use strict';
- const Controller = require('egg').Controller;
- const Payment = require('../../lib/wxpay');
- const { readFileSync } = require('fs');
- const uuid = require('uuid');
- class WxpayController extends Controller {
- // 预支付交易单 # description = 商品描述, out_trade_no = 自定义订单号
- async book_order() {
- const { openid, description, out_trade_no, money } = this.ctx.request.body;
- const { wxconfig } = this.app.config;
- const paymnet = new Payment({
- appid: wxconfig.appid,
- mchid: wxconfig.mchid,
- private_key: readFileSync(wxconfig.wxKey).toString(), // 或者直接复制证书文件内容
- serial_no: wxconfig.certid,
- apiv3_private_key: wxconfig.v3key,
- });
- const host = this.ctx.header.referer.split('/')[2];
- const backUrl = encodeURI(`${this.ctx.protocol}://${host}${this.ctx.path}`);
- // jsapi 支付下单
- const result = await paymnet.jsapi({
- description,
- out_trade_no,
- notify_url: backUrl,
- amount: {
- total: money * 100,
- currency: 'CNY',
- },
- payer: {
- openid,
- },
- });
- // 如果请求成功 redis存数据
- if (result.status === 200) {
- const { prepay_id } = JSON.parse(result.data);
- const order = JSON.stringify({ openid, prepay_id, out_trade_no });
- await this.app.redis.set(out_trade_no, order, 'EX', 6000 * 5);
- return { errcode: 0, errmsg: '', data: 'book_order' };
- }
- }
- // 跳转发起支付页面
- async pay() {
- const { out_trade_no, redirect_uri } = this.ctx.request.body;
- const { wxconfig } = this.app.config;
- const orderPay = await this.app.redis.get(out_trade_no);
- const orderinfo = JSON.parse(orderPay);
- const appid = wxconfig.appid;
- // 商户密钥证书
- const privateKey = readFileSync(wxconfig.wxKey).toString();
- // 32位随机字符串
- const payment = new Payment({
- appid: wxconfig.appid,
- mchid: wxconfig.mchid,
- private_key: readFileSync(wxconfig.wxKey).toString(), // 或者直接复制证书文件内容
- serial_no: wxconfig.certid,
- apiv3_private_key: wxconfig.v3key,
- });
- const payNonceStr = payment.generate();
- // 时间戳
- const payTimestamp = new Date().getTime();
- // 签名
- const data = `${appid}\n${payTimestamp}\n${payNonceStr}\nprepay_id=${orderinfo.prepay_id}\n`;
- const createSign = payment.rsaSign(data, privateKey);
- // TODO: 重定向到支付页面
- await this.ctx.render('pay.njk', { appid, payNonceStr, payTimestamp, createSign, redirect_uri, ...orderinfo });
- }
- // 关闭订单
- async orderClose() {
- const { out_trade_no } = this.ctx.request.body;
- const { wxconfig } = this.app.config;
- const payment = new Payment({
- appid: wxconfig.appid,
- mchid: wxconfig.mchid,
- private_key: readFileSync(wxconfig.wxKey).toString(),
- serial_no: wxconfig.certid,
- apiv3_private_key: wxconfig.v3key,
- });
- const res = await payment.close({ out_trade_no });
- if (res.status === 204) {
- // 订单关闭成功
- return { errcode: 0, errmsg: '', data: '' };
- }
- return { errcode: -2001, errmsg: '订单关闭失败', data: '' };
- }
- /* 取消订单
- * out_trade_no = 原订单号, refundMoney = 退款单号, reason = 退款原因, money = 原商品总金额, refundMoney = 退款金额
- */
- async refund() {
- const { out_trade_no, reason, refundMoney, money } = this.ctx.request.body;
- const { wxconfig } = this.app.config;
- const payment = new Payment({
- appid: wxconfig.appid,
- mchid: wxconfig.mchid,
- private_key: readFileSync(wxconfig.wxKey).toString(),
- serial_no: wxconfig.certid,
- apiv3_private_key: wxconfig.v3key,
- });
- let out_refund_no = uuid.v1();
- out_refund_no = out_refund_no.replace(/-/g, '');
- const res = await payment.refund({
- out_trade_no,
- reason,
- out_refund_no,
- amount: {
- refund: refundMoney * 100,
- total: money * 100,
- currency: 'CNY',
- },
- });
- return { errcode: 0, errmsg: '', data: res };
- }
- }
- module.exports = WxpayController;
|