shengtian.js 9.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. //ShengtianPlay
  2. let mysql = require('mysql');
  3. let mysqlcn = require('../../terry/mysqlcn.js');
  4. let query = mysqlcn.query;
  5. let qs = require('querystring');
  6. let checkorder = require('../../terry/checkorder.js');
  7. let config = require('../config.js');
  8. let express = require('express');
  9. let router = express.Router();
  10. let crypto = require('crypto');
  11. const IS_TEST = 1 //1是测试2是正式
  12. // Date.prototype.Format = function (fmt) { //author: meizz
  13. // let o = {
  14. // "M+": this.getMonth() + 1, //月份
  15. // "d+": this.getDate(), //日
  16. // "h+": this.getHours(), //小时
  17. // "m+": this.getMinutes(), //分
  18. // "s+": this.getSeconds(), //秒
  19. // "q+": Math.floor((this.getMonth() + 3) / 3), //季度
  20. // "S": this.getMilliseconds() //毫秒
  21. // };
  22. // if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
  23. // for (let k in o)
  24. // if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  25. // return fmt;
  26. // }
  27. // let sql_insert = function(orderid, serverid,uid,rmb,moneytype,cfid,platform,channel,overtime,flag,product_id,user_id,purchase_date_ms,talkingdata,payment_type,istest){
  28. // let sql = "INSERT INTO payinfo SET orderid=?, serverid=?, channel=?, submittime=?, flag=?, user_id=?, channel_order_id=?, money=?, cfid=?, platform=?,overtime=?,product_id=?,uid=?,moneytype=?,talkingdata=?,payment_type=?,istest=?";
  29. // let values = [orderid, serverid, channel,purchase_date_ms,flag,user_id,orderid,rmb,cfid,platform,overtime,product_id,uid,moneytype,talkingdata,payment_type,istest];
  30. // sql = mysql.format(sql, values);
  31. // return sql;
  32. // }
  33. // function insert_str(str, insert_str, sn) {
  34. // let newstr = "";
  35. // for (let i = 0; i < str.length; i += sn) {
  36. // let tmp = str.substring(i, i + sn);
  37. // newstr += tmp + insert_str;
  38. // }
  39. // return newstr;
  40. // }
  41. // let RsaSha1Check = function(str,sig,publicKey){
  42. // let public_key = insert_str(publicKey, '\n', 64);
  43. // public_key = '-----BEGIN PUBLIC KEY-----\n' + public_key + '-----END PUBLIC KEY-----';
  44. // let verifier = crypto.createVerify('RSA-SHA1');
  45. // console.log('验证签名public key:\n' + public_key);
  46. // console.log('验证签名src_sign:' + str);
  47. // verifier.update(new Buffer(str, 'utf-8'));
  48. // return verifier.verify(public_key, sig, 'base64');
  49. // };
  50. let sdk_conf = {
  51. 'key':"fkybt_519d7c1a09",
  52. 'secret':"226f965616a3daac306f9cfb2aa72f58"
  53. }
  54. //md5加密
  55. let md5 = function (str){
  56. var md5sum = crypto.createHash('md5');
  57. md5sum.update(str);
  58. str = md5sum.digest('hex');
  59. return str;
  60. };
  61. let queryString = function(str){
  62. const pairs = str.split("&");
  63. let ret = {}
  64. pairs.forEach(pair => {
  65. const [key, value] = pair.split("=");
  66. ret[key]=value
  67. });
  68. return ret
  69. }
  70. let ret_str = function(code, msg){
  71. let status = "success"
  72. if(code != 200){
  73. status = "failure"
  74. }
  75. let ret ={
  76. 'code': code,
  77. 'status':status,
  78. 'msg':"",
  79. }
  80. if (msg != null) {
  81. ret.msg = msg
  82. }
  83. let returndata = JSON.stringify(ret);
  84. return returndata
  85. }
  86. let pay_success = function(args, res){
  87. let istest = IS_TEST
  88. if (args==null){
  89. console.log("[ShengtianPlay] 无效的充值请求!");
  90. try{res.send(ret_str(1, "无效的充值请求"));}
  91. catch(e){}
  92. return;
  93. }
  94. let obj = null
  95. try {
  96. obj = queryString(args);
  97. } catch(e){
  98. console.log("[ShengtianPlay] 解析失败!");
  99. try{res.send(ret_str(1, "无效的充值请求"));}
  100. catch(e){}
  101. return
  102. }
  103. console.log(obj)
  104. let content = {
  105. app_key:obj.app_key,
  106. game_order_id:obj.game_order_id,
  107. money:obj.money,
  108. timestamp:obj.timestamp,
  109. }
  110. let mysign = md5(config.url_sort2(content)+sdk_conf.secret).toLowerCase()
  111. if(mysign!=obj.sign){
  112. console.log("[ShengtianPlay] 验证失败! mysign=%s, obj.sign=%s", mysign, obj.sign);
  113. try{res.send(ret_str(2, "验证失败"));}
  114. catch(e){}
  115. return;
  116. }
  117. let money = obj.money; // 支付金额
  118. let orderid = obj.game_order_id; // 订单id
  119. let channel_order_id = obj.order_id // 渠道订单id
  120. let platform = "Android";
  121. let payment_type = "ShengtianPlay"
  122. let ti = new Date().Format("yyyy-MM-dd hh:mm:ss");
  123. console.log("[ShengtianPlay] 订单 %s:\n\t, ti=%s, 请求[%s], channel_order_id=%s, platform=%s",
  124. orderid, ti, args, channel_order_id, platform);
  125. let sql = mysql.format("SELECT * FROM payinfo where orderid=?", [orderid]);//在mysql库中检查订单号
  126. query(sql,function(qerr,vals,fields){
  127. if (qerr==null){
  128. if (vals[0]==null){
  129. console.log("[ShengtianPlay] 没有找到该订单: %s", orderid);
  130. try{res.send(ret_str(4, "未知订单"));}
  131. catch(e){}
  132. return;
  133. }
  134. if (vals[0].overtime>0){
  135. console.log("[ShengtianPlay] 已经处理的订单: %s", orderid);
  136. try{res.send(ret_str(200, "已经处理"));}
  137. catch(e){}
  138. return;
  139. }
  140. //检查订单
  141. let channel = vals[0].channel
  142. let cfid = vals[0].cfid
  143. let extension
  144. try {
  145. extension = JSON.parse(decodeURIComponent(obj.extension))
  146. } catch(e) {
  147. console.log("[ShengtianPlay] 额外参数解析失败!");
  148. res.send(ret_str(1, "无效的充值请求"));
  149. return
  150. }
  151. let conf = config.parse(platform, channel+extension.currency, cfid);
  152. let amountnum = conf.price
  153. let moneytype = conf.typename;
  154. let uid = vals[0].uid
  155. let serverid = vals[0].serverid
  156. if (conf.cfid == 0){
  157. console.log("[ShengtianPlay] channel:%s获取cfid失败为platform:%s,cfid:%s",channel, platform, cfid);
  158. try{res.send(ret_str(3, "异常的计费点"));}
  159. catch(e){}
  160. return
  161. }
  162. if (amountnum != money) {
  163. console.log("[ShengtianPlay] 充值金额不匹配:amountnum = %s, money = %s!!", amountnum, money);
  164. try{res.send(ret_str(2, "验证失败"));}
  165. catch(e){}
  166. return
  167. }
  168. console.log("[ShengtianPlay] 订单 %s 处理:\n\t, 商品配置:%s, 金额:%s, 类型:%s, 用户:%s, 服务器:%s",
  169. orderid, cfid, amountnum, moneytype, uid, serverid);
  170. let timestamp = Date.parse(new Date()) / 1000;
  171. //填充充值信息
  172. let sql_1 = "UPDATE payinfo SET \
  173. channel_order_id=?,\
  174. overtime=?,\
  175. flag=?,\
  176. money=?,\
  177. platform=?,\
  178. moneytype=?,\
  179. payment_type=?, \
  180. istest=?\
  181. WHERE orderid=? \
  182. AND flag=2";//增加flag判断防止重复写入
  183. let values_2 = [channel_order_id,timestamp,1,amountnum,platform,moneytype,payment_type,istest,orderid];
  184. let sql_2 = mysql.format(sql_1, values_2);
  185. query(sql_2,function(qerr,rows,fields_)
  186. {
  187. if (qerr){
  188. console.log("[ShengtianPlay]逻辑错误,请检查数据表结构和sql语句:\n\t%s", qerr);
  189. try{res.send(ret_str(4));}
  190. catch(e){}
  191. return;
  192. }
  193. if (rows.affectedRows > 0){//判断修改了多少个记录
  194. console.log("[ShengtianPlay]支付成功了,现在通知游戏服务器, orderId:%s, uid:%s, serverid:%s ,cfid:%s",orderid,vals[0].uid,vals[0].serverid,cfid);
  195. checkorder.pushproduct(query,vals[0].serverid, orderid, function(ok){
  196. if (ok) {
  197. console.log("[ShengtianPlay] 订单 %s: 成功发货!", orderid);
  198. } else{
  199. console.log("[ShengtianPlay] 订单 %s: 发货地址无效!", orderid);//在无效时返回成功,我们自己补单中会派发flag为1支付成功但是没成功发货的单
  200. }
  201. try{res.send(ret_str(200));}
  202. catch(e){}
  203. });
  204. res.send(ret_str(200));
  205. return;
  206. }else{
  207. console.log("SQL重复写入[ShengtianPlay]已经处理的订单");
  208. try{res.send(ret_str(200));}
  209. catch(e){}
  210. return;
  211. }
  212. })
  213. }else{
  214. console.log("[ShengtianPlay] 查询订单列表错误,请检查数据表结构和sql语句:\n\t%s", qerr);
  215. try{res.send(ret_str(4));}
  216. catch(e){}
  217. return;
  218. }
  219. })
  220. }
  221. router.post('/shengtianplay', function(req, res) {
  222. console.log("圣天,post ,host:%s, ip:%s,date:%s",req.hostname,req.ip,new Date());
  223. let data = "";
  224. req.on("data",function(chunk){
  225. data += chunk;
  226. })
  227. req.on("end",function(){
  228. pay_success(data,res);
  229. })
  230. req.on("error",function(err){
  231. res.send(ret_str(7));
  232. })
  233. });
  234. module.exports = router;