googleplay.js 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. //GooglePlay
  2. var mysql = require('mysql');
  3. var mysqlcn = require('../../terry/mysqlcn.js');
  4. var query = mysqlcn.query;
  5. var qs = require('querystring');
  6. var encryption = require('../ordinary/encryption.js');
  7. var checkorder = require('../../terry/checkorder.js');
  8. var config = require('../config.js');
  9. var express = require('express');
  10. var router = express.Router();
  11. var https = require('https');
  12. var http = require('http');
  13. var crypto = require('crypto');
  14. // var IS_TEST = 2 //1是测试2是正式
  15. Date.prototype.Format = function (fmt) { //author: meizz
  16. var o = {
  17. "M+": this.getMonth() + 1, //月份
  18. "d+": this.getDate(), //日
  19. "h+": this.getHours(), //小时
  20. "m+": this.getMinutes(), //分
  21. "s+": this.getSeconds(), //秒
  22. "q+": Math.floor((this.getMonth() + 3) / 3), //季度
  23. "S": this.getMilliseconds() //毫秒
  24. };
  25. if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
  26. for (var k in o)
  27. if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
  28. return fmt;
  29. }
  30. var sql_insert = function(orderid, serverid,uid,rmb,moneytype,cfid,platform,channel,overtime,flag,product_id,user_id,purchase_date_ms,talkingdata,payment_type,istest){
  31. var 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=?";
  32. var values = [orderid, serverid, channel,purchase_date_ms,flag,user_id,orderid,rmb,cfid,platform,overtime,product_id,uid,moneytype,talkingdata,payment_type,istest];
  33. sql = mysql.format(sql, values);
  34. return sql;
  35. }
  36. function insert_str(str, insert_str, sn) {
  37. var newstr = "";
  38. for (var i = 0; i < str.length; i += sn) {
  39. var tmp = str.substring(i, i + sn);
  40. newstr += tmp + insert_str;
  41. }
  42. return newstr;
  43. }
  44. var RsaSha1Check = function(str,sig,publicKey){
  45. var public_key = insert_str(publicKey, '\n', 64);
  46. public_key = '-----BEGIN PUBLIC KEY-----\n' + public_key + '-----END PUBLIC KEY-----';
  47. var verifier = crypto.createVerify('RSA-SHA1');
  48. console.log('验证签名public key:\n' + public_key);
  49. console.log('验证签名src_sign:' + str);
  50. verifier.update(new Buffer(str, 'utf-8'));
  51. return verifier.verify(public_key, sig, 'base64');
  52. };
  53. var pay_success = function(args,res){
  54. if (args==null){
  55. console.log("[GooglePlay] 无效的充值请求!");
  56. try{res.send("error,1");}
  57. catch(e){}
  58. return;
  59. }
  60. var obj = null
  61. try {
  62. obj = qs.parse(args);
  63. } catch(e){
  64. console.log("[GooglePlay] 无效的充值请求!");
  65. try{res.send("error,1");}
  66. catch(e){}
  67. return
  68. }
  69. var orderid = obj.orderid; //订单号
  70. var serverid = obj.serverid;//服务器id
  71. var userid = obj.userid; //玩家的渠道帐号
  72. var uid = obj.uid; //玩家游戏uid
  73. var platformid = obj.platformid;//googleplay
  74. var gp_appid = obj.channel; //渠道
  75. var channel = config.get_channel(gp_appid)
  76. var inapp_purchase_data = obj.inapp_purchase_data;
  77. var inapp_data_signature = obj.inapp_data_signature;
  78. var ti = new Date().Format("yyyy-MM-dd hh:mm:ss");
  79. var payment_type = "GooglePlay" + gp_appid
  80. var is_test = obj.is_test
  81. var IS_TEST = config.get_istest(gp_appid)
  82. console.log("[GooglePlay] 订单 %s 请求 (%s):\n\tserverid=%s,uid=%s,userid=%s,platform=%s,channel=%s,inapp_purchase_data=%s,inapp_data_signature=%s,gp_appid=%s",
  83. orderid, ti, serverid,uid,userid,platformid,channel,inapp_purchase_data,inapp_data_signature,gp_appid);
  84. if (is_test != IS_TEST){
  85. console.log("订单状态不正常is_test:%s,IS_TEST:%s",is_test,IS_TEST)
  86. try{res.send("error,2");}
  87. catch(e){}
  88. return
  89. }
  90. if (config.allowed_googleplay_channel(channel) == false) {
  91. try{res.send("error,2");}
  92. catch(e){}
  93. console.log("[GooglePlay] 订单 %s: 不支持的渠道!,channel:%s", orderid,channel);
  94. return
  95. }
  96. if (platformid != "googleplay"){
  97. try{res.send("error,7");}
  98. catch(e){}
  99. console.log("[GooglePlay] 订单 %s: 不支持的平台!,platformid:%s", orderid,platformid);
  100. return
  101. }
  102. var token = config.get_googleplay_sig(gp_appid);
  103. //签名验证
  104. var istrue = false
  105. // if(config.get_googleplay_sig(gp_appid)){
  106. // console.log("[GooglePlay] 不验证md5 渠道:appid %s:%s", channel,gp_appid);
  107. // istrue = true
  108. // }else{
  109. console.log("[GooglePlay] 验证md5 渠道:appid %s:%s", channel,gp_appid);
  110. console.log("inapp_purchase_data:%s",inapp_purchase_data)
  111. console.log("inapp_data_signature:%s",inapp_data_signature)
  112. console.log("token:%s",token)
  113. istrue=RsaSha1Check(inapp_purchase_data,inapp_data_signature,token);
  114. // }
  115. console.log(istrue);
  116. if(istrue){
  117. var result = JSON.parse(inapp_purchase_data);
  118. //var consumptionState = result.consumptionState;//inapp产品的消费状态。0:还有待消耗,1:消费
  119. //var developerPayload = result.developerPayload;//包含有关订单的补充信息的开发人员指定的字符串。
  120. //var kind = result.kind; //这种类型表示androidpublisher服务中的一个inappPurchase对象。
  121. var channelorderID = result.orderId // GooglePlay订单
  122. var purchaseState = result.purchaseState; //订单的购买状态。0:购买,1:取消
  123. var purchaseTime = result.purchaseTime; //购买产品的时间,以毫秒为单位
  124. //var purchaseType = result.purchaseType; //购买inapp产品的类型。如果此购买不是使用标准应用内结算流程进行的,则仅设置此字段。0:测试
  125. var productId = result.productId; //玩家购买的产品包
  126. console.log("[GooglePlay] cp订单 %s, GooglePlay订单 %s, 购买参数(0:购买,1:取消) %s, 时间 %s, 购买的产品包 %s", orderid, channelorderID,purchaseState,purchaseTime,productId)
  127. if (purchaseState != 0){
  128. try {res.send('erron,3');}
  129. catch(e){}
  130. console.log("[GooglePlay] 未购买!")
  131. return
  132. }
  133. // //检查订单
  134. purchaseTime = purchaseTime / 1000;
  135. var conf = config.parse(platformid, channel, productId);
  136. var appId = config.getAppID(channel);
  137. var chargeTime = Date.parse(new Date()) / 1000;
  138. var rmb = conf.price;
  139. var cfid = conf.cfid;
  140. var moneytype = conf.typename;
  141. if (cfid == 0){
  142. console.log("[GooglePlay] channel:%s获取cfid失败为platformid:%s,productId:%s",channel,platformid,productId);
  143. try{res.send("fail");}
  144. catch(e){}
  145. return
  146. }
  147. console.log("[GooglePlay] 订单 %s 处理:\n\t商品配置:%s, 金额:%s, 类型:%s, 用户:%s, 服务器:%s",
  148. channelorderID,cfid,rmb,moneytype,uid,serverid);
  149. var callback = function(code) {
  150. var errnoa = "error," + code
  151. try{res.send(errnoa);}
  152. catch(e){}
  153. }
  154. var sql = sql_insert(channelorderID, serverid,uid,rmb,moneytype,cfid,"android",channel,chargeTime,1,productId,userid,purchaseTime,1,payment_type,is_test);
  155. var execute = function(channelo_rderID,_cfid,_rmb,_conf) {
  156. query(sql,function(qerr,vals,fields){
  157. try {
  158. if (qerr) {
  159. if (qerr.errno == 1062) {
  160. // 视为成功,但不再发货。
  161. try{res.send('erron,0#' + channelo_rderID);}
  162. catch(e){}
  163. console.log("[GooglePlay] 订单 %s: 已存在!", channelo_rderID);
  164. } else {
  165. callback(7);
  166. console.log("[GooglePlay] 订单 %s: 存储失败!\n\t%s",channelo_rderID, JSON.stringify(qerr));
  167. }
  168. } else {
  169. //通知游戏服务器发货
  170. serverid = parseInt(serverid);
  171. checkorder.pushproduct(query,channelo_rderID,uid,serverid,_cfid, function(ok){
  172. if (ok) {
  173. try{res.send("ok#" + channelo_rderID);}
  174. catch(e){}
  175. console.log("[GooglePlay] 订单 %s: 成功发货!",channelo_rderID);
  176. } else{
  177. callback(8)
  178. console.log("[GooglePlay] 订单 %s: 发货地址无效!", channelo_rderID);
  179. }
  180. })
  181. // 向 TalkingData 报告充值数据
  182. checkorder.pushtalkingdata(query,appId,"android",uid,channelo_rderID,_conf.price,_conf.typename,_conf.diamond,chargeTime,"GooglePlay",serverid);
  183. }
  184. } catch(err) {
  185. console.log(err);
  186. }
  187. })
  188. }
  189. // 存盘并发货
  190. execute(channelorderID, cfid, rmb, conf)
  191. // try{res.send("ok");}
  192. // catch(e){}
  193. console.log("[GooglePlay] 订单 %s 交易成功!", orderid);
  194. }else{
  195. try {res.send('erron,4');}
  196. catch(e){}
  197. console.log("[GooglePlay] 非法的订单数据!")
  198. return
  199. }
  200. }
  201. let googleplay = function(args, res){
  202. if (args==null){
  203. console.log("[GooglePlay] 无效的充值请求!");
  204. try{res.send("error,1");}
  205. catch(e){}
  206. return;
  207. }
  208. let obj = null
  209. try {
  210. obj = qs.parse(args);
  211. } catch(e){
  212. console.log("[GooglePlay] 无效的充值请求!");
  213. try{res.send("error,1");}
  214. catch(e){}
  215. return
  216. }
  217. const data = JSON.stringify({
  218. grant_type : "refresh_token",
  219. refresh_token : "1//0e3sYXF6c7hfMCgYIARAAGA4SNwF-L9IrVKAk6l2BMnTqOTqTxZ6_6Sy7y5LHfKUYqXQFvHuOu8WUuTq31l1kGTeLvylvo-hg8pc",
  220. client_id : "1053688457546-djajb15ii7v0q6pjsh7361fpsh97353g.apps.googleusercontent.com",
  221. client_secret : "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"
  222. })
  223. console.log(data)
  224. let options = {
  225. hostname: 'accounts.google.com',
  226. port: 443,
  227. path: '/o/oauth2/token',
  228. method: 'POST',
  229. rejectUnauthorized: false,
  230. headers: {
  231. 'Content-Type': 'Application/json',
  232. 'Content-Length':data.length
  233. },
  234. };
  235. let req = https.request(options, function (res){
  236. let responseData = '';
  237. res.on('data', (chunk) => {
  238. responseData += chunk;
  239. });
  240. res.on('end', () => {
  241. console.log('Response:', responseData);
  242. // 在这里可以处理响应数据
  243. });
  244. }).on('error', (err) => {
  245. if (err.code === 'ECONNRESET') {
  246. console.error('连接被重置:', err.message);
  247. } else {
  248. console.error('网络请求时发生错误:', err.message);
  249. }
  250. });
  251. req.write(data);
  252. req.end();
  253. let orderid = obj.orderid; //订单号
  254. let serverid = obj.serverid;//服务器id
  255. let userid = obj.userid; //玩家的渠道帐号
  256. let uid = obj.uid; //玩家游戏uid
  257. let platformid = obj.platformid;//googleplay
  258. let gp_appid = obj.channel; //渠道
  259. let ti = new Date().Format("yyyy-MM-dd hh:mm:ss");
  260. let payment_type = "GooglePlay" + gp_appid;
  261. }
  262. router.post('/googleplay', function(req, res) {
  263. console.log("谷歌,post ,host:%s, ip:%s,date:%s",req.hostname,req.ip,new Date());
  264. var data = "";
  265. req.on("data",function(chunk){
  266. data += chunk;
  267. })
  268. req.on("end",function(){
  269. googleplay(data,res);
  270. })
  271. req.on("error",function(err){
  272. res.send('erron,1');
  273. })
  274. });
  275. module.exports = router;