page.js 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. const wxpay = require('../pay/wechat_pay');
  2. const sysUser = require('../db/fuxi/sys_user');
  3. const course = require('../db/models/course');
  4. const order = require('../db/models/order');
  5. const inviter = require('../db/models/inviter');
  6. const sseClient = require('./sse_client');
  7. const { onError, createTradeNo, onSuccess, fixPrice } = require('../utils');
  8. const { isProd, host, ORDER_STATUS } = require('../server/config');
  9. const { Op } = require('sequelize');
  10. const _ = require('lodash');
  11. const API = {
  12. async buyCourse(obj) {
  13. const { uid, cid, code = '' } = obj;
  14. const cdata = await course.findOne({ where: { id: cid } });
  15. if (!cdata) {
  16. return onError('课程不存在');
  17. }
  18. const edata = await order.findOne({
  19. where: { cid, uid, status: { [Op.in]: [ORDER_STATUS.已支付, ORDER_STATUS.渠道] } },
  20. });
  21. if (edata) {
  22. return onError('课程已购买');
  23. }
  24. const { title, oprice, detailimg, recordId } = cdata;
  25. let { price } = cdata;
  26. let discount = '';
  27. if (code) {
  28. const idata = await inviter.findOne({ where: { code } });
  29. if (idata) {
  30. price = fixPrice(price * idata.discount);
  31. discount = idata.discount;
  32. }
  33. }
  34. const id = createTradeNo();
  35. const odata = await order.create({
  36. id,
  37. cid,
  38. uid,
  39. title,
  40. detailimg,
  41. price,
  42. recordId,
  43. discount,
  44. code,
  45. });
  46. if (!parseFloat(price)) {
  47. await API.buySuccess(
  48. {
  49. trade_state: 'SUCCESS',
  50. out_trade_no: id,
  51. },
  52. false
  53. );
  54. return onSuccess({ id });
  55. }
  56. const wdata = await wxpay.transactions_native({
  57. description: title,
  58. out_trade_no: id,
  59. amount: {
  60. total: isProd() ? Math.ceil(price * 100) : 1,
  61. },
  62. notify_url: `${host}/external/pay/notice`,
  63. // total: 1,
  64. });
  65. if (!wdata.code_url) {
  66. return onError(wdata);
  67. }
  68. return onSuccess({
  69. id,
  70. url: wdata.code_url,
  71. });
  72. },
  73. // 购买结果轮训
  74. async buyCheck(oid) {
  75. const { data: odata } = await order.findOne({ id: oid });
  76. if (!odata) {
  77. return onError('订单不存在');
  78. }
  79. return onSuccess(odata.status === ORDER_STATUS.已支付);
  80. },
  81. async buySuccess(obj, decode = true) {
  82. let data = obj;
  83. if (decode) {
  84. // eslint-disable-next-line camelcase
  85. const { original_type, algorithm, ciphertext, associated_data, nonce } = obj;
  86. data = wxpay.decipher_gcm(ciphertext, associated_data, nonce);
  87. }
  88. if (data.trade_state !== 'SUCCESS') {
  89. return;
  90. }
  91. const { out_trade_no: id } = data;
  92. const odata = await order.findOne({ where: { id } });
  93. if (!odata || odata.payAt) {
  94. return;
  95. }
  96. await order.update(
  97. {
  98. payAt: new Date(),
  99. status: ORDER_STATUS.已支付,
  100. },
  101. { where: { id } }
  102. );
  103. if (sseClient[id]) {
  104. sseClient[id].send('done');
  105. sseClient[id].close();
  106. }
  107. },
  108. async inviteCheck(obj) {
  109. const { code, cid } = obj;
  110. const idata = await inviter.findOne({ where: { code } });
  111. if (!idata) {
  112. return onError('邀请码不存在');
  113. }
  114. const cdata = await course.findOne({ where: { id: cid } });
  115. const { price: oprice } = cdata;
  116. const price = fixPrice(oprice * idata.discount);
  117. const discountPrice = fixPrice(oprice - price);
  118. return onSuccess({
  119. price,
  120. discountPrice,
  121. ..._.pick(idata, ['name', 'discount']),
  122. });
  123. },
  124. };
  125. module.exports = API;