Commit 5199994f authored by 任国军's avatar 任国军

add wechat notify

parent ecae8929
Pipeline #24329 passed with stage
in 13 seconds
...@@ -81,6 +81,20 @@ class WechatController extends Controller { ...@@ -81,6 +81,20 @@ class WechatController extends Controller {
const ret = await service.course.v5.wechat.getUnlimitedCode(params); const ret = await service.course.v5.wechat.getUnlimitedCode(params);
ctx.success(ret); ctx.success(ret);
} }
// 支付回调
async payNotify() {
const { ctx } = this;
ctx.set('Content-Type', 'text/xml');
// 组装xml数据
let xmlData = '<xml>';
xmlData += '<return_code><![CDATA[SUCCESS]]></return_code>';
xmlData += '<return_msg><![CDATA[OK]]></return_msg>';
xmlData += '</xml>';
ctx.body = xmlData;
return ctx.body;
}
} }
module.exports = WechatController; module.exports = WechatController;
'use strict';
const moment = require('moment');
module.exports = app => {
const { STRING, INTEGER, DATE, TEXT, DECIMAL } = app.Sequelize;
const CourseUserOrder = app.classModel.define('course_user_order', {
id: {
type: INTEGER,
primaryKey: true,
autoIncrement: true,
},
order_no: STRING,
user_uuid: STRING,
class_id: INTEGER,
pay: DECIMAL,
pay_time: STRING,
pay_result: TEXT,
type: INTEGER,
redeem: STRING,
status: INTEGER,
is_deleted: INTEGER,
hash: STRING,
created_time: {
type: DATE,
allowNull: true,
get() {
const date = this.getDataValue('created_time');
return date ? moment(date).format('YYYY-MM-DD HH:mm:ss') : undefined;
},
},
updated_time: {
type: DATE,
allowNull: true,
get() {
const date = this.getDataValue('updated_time');
return date ? moment(date).format('YYYY-MM-DD HH:mm:ss') : undefined;
},
},
}, {
timestamps: false,
tableName: 'course_user_order',
});
return CourseUserOrder;
};
...@@ -25,6 +25,7 @@ module.exports = app => { ...@@ -25,6 +25,7 @@ module.exports = app => {
router.get('third', '/wechat/callbackAction', 'course.v5.wechat.check'); router.get('third', '/wechat/callbackAction', 'course.v5.wechat.check');
router.post('third', '/wechat/callbackAction', 'course.v5.wechat.callbackAction'); router.post('third', '/wechat/callbackAction', 'course.v5.wechat.callbackAction');
router.post('third', '/wechat/test', 'course.v5.wechat.test'); router.post('third', '/wechat/test', 'course.v5.wechat.test');
router.post('third', '/wechat/pay/notify', 'course.v5.wechat.payNotify');
router.post('third', '/questionnaire', auth({ is_force: 1 }), 'course.v5.option.addQuestionnaire');// 填写问卷 router.post('third', '/questionnaire', auth({ is_force: 1 }), 'course.v5.option.addQuestionnaire');// 填写问卷
router.get('third', '/questionnaire', 'course.v5.option.getQuestionnaire');// 获取问卷 router.get('third', '/questionnaire', 'course.v5.option.getQuestionnaire');// 获取问卷
router.post('third', '/channel/unlimited_code', 'course.v5.option.addUnlimitedCodeByChannel');// 保存渠道小程序码 router.post('third', '/channel/unlimited_code', 'course.v5.option.addUnlimitedCodeByChannel');// 保存渠道小程序码
......
...@@ -412,7 +412,12 @@ class InstitutionSubService extends Service { ...@@ -412,7 +412,12 @@ class InstitutionSubService extends Service {
} }
// 校验用户是否允许播放 // 校验用户是否允许播放
if (video.is_free === 0) {
const order = await ctx.classModel.V5.CourseUserOrder.findOne({ where: { class_id: video.class_id, user_uuid: userUuid, status: 1, is_deleted: 0 } });
if (ctx.isEmpty(order)) {
ctx.failed('购买后才能学习哦');
}
}
const ret = { const ret = {
id: video.id, id: video.id,
...@@ -438,8 +443,11 @@ class InstitutionSubService extends Service { ...@@ -438,8 +443,11 @@ class InstitutionSubService extends Service {
const results = []; const results = [];
let classList = []; let classList = [];
const classAll = await ctx.classMdel.V5.CourseV5ClassToCat.findAll({ where: { cat_id, status: 1, is_deleted: 0 } });
const classIds = R.pluck('class_id', classAll);
// 体验课 // 体验课
classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { price_type: 1, status: 1, is_deleted: 0 }, order: [[ 'sort', 'asc' ], [ 'id', 'desc' ]], offset: 0, limit: 3, raw: true }); classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { id: { $in: classIds }, price_type: 1, status: 1, is_deleted: 0 }, attributes, order: [[ 'sort', 'asc' ], [ 'id', 'desc' ]], offset: 0, limit: 3, raw: true });
classList = await this.formatClassList(classList); classList = await this.formatClassList(classList);
for (const i in classList) { for (const i in classList) {
classList[i].institution_icon = ''; classList[i].institution_icon = '';
...@@ -450,7 +458,7 @@ class InstitutionSubService extends Service { ...@@ -450,7 +458,7 @@ class InstitutionSubService extends Service {
}); });
// 低价课 // 低价课
classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { price_type: 2, status: 1, is_deleted: 0 }, order: [[ 'sort', 'asc' ], [ 'id', 'desc' ]], offset: 0, limit: 3, raw: true }); classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { id: { $in: classIds }, price_type: 2, status: 1, is_deleted: 0 }, attributes, order: [[ 'sort', 'asc' ], [ 'id', 'desc' ]], offset: 0, limit: 3, raw: true });
classList = await this.formatClassList(classList); classList = await this.formatClassList(classList);
for (const i in classList) { for (const i in classList) {
classList[i].institution_icon = ''; classList[i].institution_icon = '';
...@@ -461,7 +469,7 @@ class InstitutionSubService extends Service { ...@@ -461,7 +469,7 @@ class InstitutionSubService extends Service {
}); });
// 精品课 // 精品课
classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { price_type: 3, status: 1, is_deleted: 0 }, order: [[ 'sort', 'asc' ], [ 'id', 'desc' ]], offset: 0, limit: 3, raw: true }); classList = await ctx.classModel.V5.CourseV5Class.findAll({ where: { id: { $in: classIds }, price_type: 3, status: 1, is_deleted: 0 }, attributes, order: [[ 'sort', 'asc' ], [ 'id', 'desc' ]], offset: 0, limit: 3, raw: true });
classList = await this.formatClassList(classList); classList = await this.formatClassList(classList);
for (const i in classList) { for (const i in classList) {
classList[i].institution_icon = ''; classList[i].institution_icon = '';
......
...@@ -6,6 +6,7 @@ const fs = require('fs'); ...@@ -6,6 +6,7 @@ const fs = require('fs');
const request = require('request'); const request = require('request');
const crypto = require('crypto'); const crypto = require('crypto');
const xml2js = require('xml2js'); const xml2js = require('xml2js');
const moment = require('moment');
class WechatService extends Service { class WechatService extends Service {
async getAccessToken() { async getAccessToken() {
...@@ -305,6 +306,51 @@ class WechatService extends Service { ...@@ -305,6 +306,51 @@ class WechatService extends Service {
return { image }; return { image };
} }
// 统一下单
async pay(input) {
const { ctx } = this;
const appId = 'wx07a5f0ed5bdf4751';
const mchId = '1596633771';
const key = 'xuepenQuXuanKeweixinzhifu2020063';
const nonce_str = ctx.helper.md5(moment().millisecond()).splice(0, 16);
const body = input.body || '趣选课-测试';
const out_trade_no = '2020060315300001';
const total_fee = '0.01';
const spbill_create_ip = ctx.helper.getClientIP();
const notify_url = 'https://uat-nginx.jianbing.com/51business/api/course/v5/wechat/pay/notify';
const trade_type = 'JSAPI';
// 签名
const sign = ctx.helper.md5(`appid=${appId}&body=${body}&mch_id=${mchId}&nonce_str=${nonce_str}&notify_url=${notify_url}&out_trade_no=${out_trade_no}&spbill_create_ip=${spbill_create_ip}&total_fee=${total_fee}&trade_type=${trade_type}&key=${key}`);
sign.toUpperCase();
// 组装xml数据
let xmlData = '<xml>';
xmlData += '<appid>' + appId + '</appid>';
xmlData += '<body><![CDATA[' + body + ']]></body>';
xmlData += '<mch_id>' + mchId + '</mch_id>';
xmlData += '<nonce_str>' + nonce_str + '</nonce_str>';
xmlData += '<notify_url>' + notify_url + '</notify_url>';
xmlData += '<out_trade_no>' + out_trade_no + '</out_trade_no>';
xmlData += '<spbill_create_ip>' + spbill_create_ip + '</spbill_create_ip>';
xmlData += '<total_fee>' + total_fee + '</total_fee>';
xmlData += '<trade_type>' + trade_type + '</trade_type>';
xmlData += '<sign>' + sign + '</sign>';
xmlData += '</xml>';
const ret = request({ url: 'https://api.mch.weixin.qq.com/pay/unifiedorder', method: 'POST', body: xmlData }, function(err, response, body) {
if (!err && response.statusCode === 200) {
console.log(body);
return body;
}
return err;
});
return ret;
}
} }
module.exports = WechatService; module.exports = WechatService;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment