|
@@ -1,20 +1,17 @@
|
|
|
//GooglePlay
|
|
|
-var mysql = require('mysql');
|
|
|
-var mysqlcn = require('../../terry/mysqlcn.js');
|
|
|
-var query = mysqlcn.query;
|
|
|
-var qs = require('querystring');
|
|
|
-var encryption = require('../ordinary/encryption.js');
|
|
|
-var checkorder = require('../../terry/checkorder.js');
|
|
|
-var config = require('../config.js');
|
|
|
-var express = require('express');
|
|
|
-var router = express.Router();
|
|
|
-var https = require('https');
|
|
|
-var http = require('http');
|
|
|
-var crypto = require('crypto');
|
|
|
-
|
|
|
-// var IS_TEST = 2 //1是测试2是正式
|
|
|
+let mysql = require('mysql');
|
|
|
+let mysqlcn = require('../../terry/mysqlcn.js');
|
|
|
+let query = mysqlcn.query;
|
|
|
+let qs = require('querystring');
|
|
|
+let checkorder = require('../../terry/checkorder.js');
|
|
|
+let config = require('../config.js');
|
|
|
+let express = require('express');
|
|
|
+let router = express.Router();
|
|
|
+let crypto = require('crypto');
|
|
|
+
|
|
|
+// let IS_TEST = 2 //1是测试2是正式
|
|
|
Date.prototype.Format = function (fmt) { //author: meizz
|
|
|
- var o = {
|
|
|
+ let o = {
|
|
|
"M+": this.getMonth() + 1, //月份
|
|
|
"d+": this.getDate(), //日
|
|
|
"h+": this.getHours(), //小时
|
|
@@ -24,199 +21,39 @@ Date.prototype.Format = function (fmt) { //author: meizz
|
|
|
"S": this.getMilliseconds() //毫秒
|
|
|
};
|
|
|
if (/(y+)/.test(fmt)) fmt = fmt.replace(RegExp.$1, (this.getFullYear() + "").substr(4 - RegExp.$1.length));
|
|
|
- for (var k in o)
|
|
|
+ for (let k in o)
|
|
|
if (new RegExp("(" + k + ")").test(fmt)) fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
|
|
|
return fmt;
|
|
|
}
|
|
|
|
|
|
-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){
|
|
|
- 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=?";
|
|
|
- var values = [orderid, serverid, channel,purchase_date_ms,flag,user_id,orderid,rmb,cfid,platform,overtime,product_id,uid,moneytype,talkingdata,payment_type,istest];
|
|
|
+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){
|
|
|
+ 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=?";
|
|
|
+ let values = [orderid, serverid, channel,purchase_date_ms,flag,user_id,orderid,rmb,cfid,platform,overtime,product_id,uid,moneytype,talkingdata,payment_type,istest];
|
|
|
sql = mysql.format(sql, values);
|
|
|
return sql;
|
|
|
}
|
|
|
|
|
|
function insert_str(str, insert_str, sn) {
|
|
|
- var newstr = "";
|
|
|
- for (var i = 0; i < str.length; i += sn) {
|
|
|
- var tmp = str.substring(i, i + sn);
|
|
|
+ let newstr = "";
|
|
|
+ for (let i = 0; i < str.length; i += sn) {
|
|
|
+ let tmp = str.substring(i, i + sn);
|
|
|
newstr += tmp + insert_str;
|
|
|
}
|
|
|
return newstr;
|
|
|
}
|
|
|
|
|
|
-var RsaSha1Check = function(str,sig,publicKey){
|
|
|
- var public_key = insert_str(publicKey, '\n', 64);
|
|
|
+let RsaSha1Check = function(str,sig,publicKey){
|
|
|
+ let public_key = insert_str(publicKey, '\n', 64);
|
|
|
public_key = '-----BEGIN PUBLIC KEY-----\n' + public_key + '-----END PUBLIC KEY-----';
|
|
|
|
|
|
- var verifier = crypto.createVerify('RSA-SHA1');
|
|
|
+ let verifier = crypto.createVerify('RSA-SHA1');
|
|
|
console.log('验证签名public key:\n' + public_key);
|
|
|
console.log('验证签名src_sign:' + str);
|
|
|
verifier.update(new Buffer(str, 'utf-8'));
|
|
|
return verifier.verify(public_key, sig, 'base64');
|
|
|
};
|
|
|
|
|
|
-var pay_success = function(args,res){
|
|
|
- if (args==null){
|
|
|
- console.log("[GooglePlay] 无效的充值请求!");
|
|
|
- try{res.send("error,1");}
|
|
|
- catch(e){}
|
|
|
- return;
|
|
|
- }
|
|
|
-
|
|
|
- var obj = null
|
|
|
- try {
|
|
|
- obj = qs.parse(args);
|
|
|
- } catch(e){
|
|
|
- console.log("[GooglePlay] 无效的充值请求!");
|
|
|
- try{res.send("error,1");}
|
|
|
- catch(e){}
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- var orderid = obj.orderid; //订单号
|
|
|
- var serverid = obj.serverid;//服务器id
|
|
|
- var userid = obj.userid; //玩家的渠道帐号
|
|
|
- var uid = obj.uid; //玩家游戏uid
|
|
|
- var platformid = obj.platformid;//googleplay
|
|
|
- var gp_appid = obj.channel; //渠道
|
|
|
- var channel = config.get_channel(gp_appid)
|
|
|
- var inapp_purchase_data = obj.inapp_purchase_data;
|
|
|
- var inapp_data_signature = obj.inapp_data_signature;
|
|
|
- var ti = new Date().Format("yyyy-MM-dd hh:mm:ss");
|
|
|
- var payment_type = "GooglePlay" + gp_appid
|
|
|
- var is_test = obj.is_test
|
|
|
-
|
|
|
- var IS_TEST = config.get_istest(gp_appid)
|
|
|
- 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",
|
|
|
- orderid, ti, serverid,uid,userid,platformid,channel,inapp_purchase_data,inapp_data_signature,gp_appid);
|
|
|
-
|
|
|
- if (is_test != IS_TEST){
|
|
|
- console.log("订单状态不正常is_test:%s,IS_TEST:%s",is_test,IS_TEST)
|
|
|
- try{res.send("error,2");}
|
|
|
- catch(e){}
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- if (config.allowed_googleplay_channel(channel) == false) {
|
|
|
- try{res.send("error,2");}
|
|
|
- catch(e){}
|
|
|
- console.log("[GooglePlay] 订单 %s: 不支持的渠道!,channel:%s", orderid,channel);
|
|
|
- return
|
|
|
- }
|
|
|
- if (platformid != "googleplay"){
|
|
|
- try{res.send("error,7");}
|
|
|
- catch(e){}
|
|
|
- console.log("[GooglePlay] 订单 %s: 不支持的平台!,platformid:%s", orderid,platformid);
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- var token = config.get_googleplay_sig(gp_appid);
|
|
|
- //签名验证
|
|
|
- var istrue = false
|
|
|
- // if(config.get_googleplay_sig(gp_appid)){
|
|
|
- // console.log("[GooglePlay] 不验证md5 渠道:appid %s:%s", channel,gp_appid);
|
|
|
- // istrue = true
|
|
|
- // }else{
|
|
|
- console.log("[GooglePlay] 验证md5 渠道:appid %s:%s", channel,gp_appid);
|
|
|
- console.log("inapp_purchase_data:%s",inapp_purchase_data)
|
|
|
- console.log("inapp_data_signature:%s",inapp_data_signature)
|
|
|
- console.log("token:%s",token)
|
|
|
- istrue=RsaSha1Check(inapp_purchase_data,inapp_data_signature,token);
|
|
|
- // }
|
|
|
- console.log(istrue);
|
|
|
- if(istrue){
|
|
|
- var result = JSON.parse(inapp_purchase_data);
|
|
|
- //var consumptionState = result.consumptionState;//inapp产品的消费状态。0:还有待消耗,1:消费
|
|
|
- //var developerPayload = result.developerPayload;//包含有关订单的补充信息的开发人员指定的字符串。
|
|
|
- //var kind = result.kind; //这种类型表示androidpublisher服务中的一个inappPurchase对象。
|
|
|
- var channelorderID = result.orderId // GooglePlay订单
|
|
|
- var purchaseState = result.purchaseState; //订单的购买状态。0:购买,1:取消
|
|
|
- var purchaseTime = result.purchaseTime; //购买产品的时间,以毫秒为单位
|
|
|
- //var purchaseType = result.purchaseType; //购买inapp产品的类型。如果此购买不是使用标准应用内结算流程进行的,则仅设置此字段。0:测试
|
|
|
- var productId = result.productId; //玩家购买的产品包
|
|
|
- console.log("[GooglePlay] cp订单 %s, GooglePlay订单 %s, 购买参数(0:购买,1:取消) %s, 时间 %s, 购买的产品包 %s", orderid, channelorderID,purchaseState,purchaseTime,productId)
|
|
|
- if (purchaseState != 0){
|
|
|
- try {res.send('erron,3');}
|
|
|
- catch(e){}
|
|
|
- console.log("[GooglePlay] 未购买!")
|
|
|
- return
|
|
|
- }
|
|
|
- // //检查订单
|
|
|
- purchaseTime = purchaseTime / 1000;
|
|
|
- var conf = config.parse(platformid, channel, productId);
|
|
|
- var appId = config.getAppID(channel);
|
|
|
-
|
|
|
- var chargeTime = Date.parse(new Date()) / 1000;
|
|
|
- var rmb = conf.price;
|
|
|
- var cfid = conf.cfid;
|
|
|
- var moneytype = conf.typename;
|
|
|
- if (cfid == 0){
|
|
|
- console.log("[GooglePlay] channel:%s获取cfid失败为platformid:%s,productId:%s",channel,platformid,productId);
|
|
|
- try{res.send("fail");}
|
|
|
- catch(e){}
|
|
|
- return
|
|
|
- }
|
|
|
- console.log("[GooglePlay] 订单 %s 处理:\n\t商品配置:%s, 金额:%s, 类型:%s, 用户:%s, 服务器:%s",
|
|
|
- channelorderID,cfid,rmb,moneytype,uid,serverid);
|
|
|
-
|
|
|
- var callback = function(code) {
|
|
|
- var errnoa = "error," + code
|
|
|
- try{res.send(errnoa);}
|
|
|
- catch(e){}
|
|
|
- }
|
|
|
-
|
|
|
- var sql = sql_insert(channelorderID, serverid,uid,rmb,moneytype,cfid,"android",channel,chargeTime,1,productId,userid,purchaseTime,1,payment_type,is_test);
|
|
|
- var execute = function(channelo_rderID,_cfid,_rmb,_conf) {
|
|
|
- query(sql,function(qerr,vals,fields){
|
|
|
- try {
|
|
|
- if (qerr) {
|
|
|
- if (qerr.errno == 1062) {
|
|
|
- // 视为成功,但不再发货。
|
|
|
- try{res.send('erron,0#' + channelo_rderID);}
|
|
|
- catch(e){}
|
|
|
- console.log("[GooglePlay] 订单 %s: 已存在!", channelo_rderID);
|
|
|
- } else {
|
|
|
- callback(7);
|
|
|
- console.log("[GooglePlay] 订单 %s: 存储失败!\n\t%s",channelo_rderID, JSON.stringify(qerr));
|
|
|
- }
|
|
|
- } else {
|
|
|
- //通知游戏服务器发货
|
|
|
- serverid = parseInt(serverid);
|
|
|
- checkorder.pushproduct(query,channelo_rderID,uid,serverid,_cfid, function(ok){
|
|
|
- if (ok) {
|
|
|
- try{res.send("ok#" + channelo_rderID);}
|
|
|
- catch(e){}
|
|
|
- console.log("[GooglePlay] 订单 %s: 成功发货!",channelo_rderID);
|
|
|
-
|
|
|
- } else{
|
|
|
- callback(8)
|
|
|
- console.log("[GooglePlay] 订单 %s: 发货地址无效!", channelo_rderID);
|
|
|
- }
|
|
|
- })
|
|
|
-
|
|
|
- // 向 TalkingData 报告充值数据
|
|
|
- checkorder.pushtalkingdata(query,appId,"android",uid,channelo_rderID,_conf.price,_conf.typename,_conf.diamond,chargeTime,"GooglePlay",serverid);
|
|
|
- }
|
|
|
- } catch(err) {
|
|
|
- console.log(err);
|
|
|
- }
|
|
|
- })
|
|
|
- }
|
|
|
- // 存盘并发货
|
|
|
- execute(channelorderID, cfid, rmb, conf)
|
|
|
- // try{res.send("ok");}
|
|
|
- // catch(e){}
|
|
|
- console.log("[GooglePlay] 订单 %s 交易成功!", orderid);
|
|
|
- }else{
|
|
|
- try {res.send('erron,4');}
|
|
|
- catch(e){}
|
|
|
- console.log("[GooglePlay] 非法的订单数据!")
|
|
|
- return
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-let googleplay = function(args, res){
|
|
|
+let pay_success = function(args, res){
|
|
|
if (args==null){
|
|
|
console.log("[GooglePlay] 无效的充值请求!");
|
|
|
try{res.send("error,1");}
|
|
@@ -234,67 +71,120 @@ let googleplay = function(args, res){
|
|
|
return
|
|
|
}
|
|
|
|
|
|
- const data = JSON.stringify({
|
|
|
- grant_type : "refresh_token",
|
|
|
- refresh_token : "1//0e3sYXF6c7hfMCgYIARAAGA4SNwF-L9IrVKAk6l2BMnTqOTqTxZ6_6Sy7y5LHfKUYqXQFvHuOu8WUuTq31l1kGTeLvylvo-hg8pc",
|
|
|
- client_id : "1053688457546-djajb15ii7v0q6pjsh7361fpsh97353g.apps.googleusercontent.com",
|
|
|
- client_secret : "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"
|
|
|
- })
|
|
|
-
|
|
|
- console.log(data)
|
|
|
-
|
|
|
- let options = {
|
|
|
- hostname: 'accounts.google.com',
|
|
|
- port: 443,
|
|
|
- path: '/o/oauth2/token',
|
|
|
- method: 'POST',
|
|
|
- rejectUnauthorized: false,
|
|
|
- headers: {
|
|
|
- 'Content-Type': 'Application/json',
|
|
|
- 'Content-Length':data.length
|
|
|
- },
|
|
|
- };
|
|
|
-
|
|
|
- let req = https.request(options, function (res){
|
|
|
- let responseData = '';
|
|
|
- res.on('data', (chunk) => {
|
|
|
- responseData += chunk;
|
|
|
- });
|
|
|
-
|
|
|
- res.on('end', () => {
|
|
|
- console.log('Response:', responseData);
|
|
|
- // 在这里可以处理响应数据
|
|
|
- });
|
|
|
- }).on('error', (err) => {
|
|
|
- if (err.code === 'ECONNRESET') {
|
|
|
- console.error('连接被重置:', err.message);
|
|
|
- } else {
|
|
|
- console.error('网络请求时发生错误:', err.message);
|
|
|
- }
|
|
|
- });
|
|
|
-
|
|
|
- req.write(data);
|
|
|
- req.end();
|
|
|
-
|
|
|
let orderid = obj.orderid; //订单号
|
|
|
+ let channel_order_id = obj.channel_order_id //渠道订单id
|
|
|
let serverid = obj.serverid;//服务器id
|
|
|
let userid = obj.userid; //玩家的渠道帐号
|
|
|
let uid = obj.uid; //玩家游戏uid
|
|
|
- let platformid = obj.platformid;//googleplay
|
|
|
- let gp_appid = obj.channel; //渠道
|
|
|
+ let product_id = obj.product_id // 计费点
|
|
|
+ let platformid = "googleplay";
|
|
|
let ti = new Date().Format("yyyy-MM-dd hh:mm:ss");
|
|
|
- let payment_type = "GooglePlay" + gp_appid;
|
|
|
|
|
|
+ console.log("[GooglePlay] 订单 %s 请求 (%s):\n\tchannel_order_id=%s, serverid=%s,uid=%s,userid=%s,platform=%s,gp_appid=%s",
|
|
|
+ orderid, ti, channel_order_id, serverid, uid, userid, platformid, gp_appid);
|
|
|
+
|
|
|
+
|
|
|
+ console.log("[GooglePlay] 订单 %s 处理:\n\t商品配置:%s, 金额:%s, 类型:%s, 用户:%s, 服务器:%s",
|
|
|
+ channel_order_id,cfid,money,moneytype,uid,serverid);
|
|
|
+
|
|
|
+ let sql = mysql.format("SELECT * FROM payinfo where orderid=?", [orderid]);//在mysql库中检查订单号
|
|
|
+ query(sql,function(qerr,vals,fields){
|
|
|
+ if (qerr==null){
|
|
|
+ if (vals[0]==null){
|
|
|
+ console.log("[GooglePlay] 没有找到该订单");
|
|
|
+ try{res.send("FAILURE");}
|
|
|
+ catch(e){}
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (vals[0].overtime>0){
|
|
|
+ console.log("[GooglePlay] 已经处理的订单");
|
|
|
+ try{res.send("SUCCESS");}
|
|
|
+ catch(e){}
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ //检查订单
|
|
|
+ let channel = vals[0].channel
|
|
|
+ let conf = config.parse(platformid, channel, product_id);
|
|
|
+ let cfid = conf.cfid;
|
|
|
+ let amountnum = conf.price
|
|
|
+ let moneytype = conf.typename;
|
|
|
+ if (cfid == 0){
|
|
|
+ console.log("[GooglePlay] channel:%s获取cfid失败为platformid:%s,product_id:%s",channel, platformid, product_id);
|
|
|
+ try{res.send("fail");}
|
|
|
+ catch(e){}
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ if (product_id != vals[0].product_id) {
|
|
|
+ console.log("[GooglePlay] 充值订单不匹配:product_id = %s, vals[0].product_id = %s!!", product_id, vals[0].product_id);
|
|
|
+ }
|
|
|
+
|
|
|
+ let timestamp = Date.parse(new Date()) / 1000;
|
|
|
+ //填充充值信息
|
|
|
+ let sql_1 = "UPDATE payinfo SET \
|
|
|
+ channel_order_id=?,\
|
|
|
+ overtime=?,\
|
|
|
+ flag=?,\
|
|
|
+ money=?,\
|
|
|
+ cfid=?,\
|
|
|
+ platform=?,\
|
|
|
+ channel=?,\
|
|
|
+ moneytype=?,\
|
|
|
+ product_id=?,\
|
|
|
+ talkingdata=?,\
|
|
|
+ payment_type=?, \
|
|
|
+ istest=?\
|
|
|
+ WHERE orderid=? \
|
|
|
+ AND flag=2";//增加flag判断防止重复写入
|
|
|
+ let values_2 = [channel_order_id,timestamp,1,amountnum,cfid,platform,channel,moneytype,product_id,1,payment_type,istest,cp_order_id];
|
|
|
+ let sql_2 = mysql.format(sql_1, values_2);
|
|
|
+ query(sql_2,function(qerr,rows,fields_)
|
|
|
+ {
|
|
|
+ if (qerr){
|
|
|
+ console.log("[GooglePlay]逻辑错误,请检查数据表结构和sql语句:\n\t%s", qerr);
|
|
|
+ try{res.send("FAILURE");}
|
|
|
+ catch(e){}
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ if (rows.affectedRows > 0){//判断修改了多少个记录
|
|
|
+ console.log("[GooglePlay]支付成功了,现在通知游戏服务器, orderId:%s, uid:%s, serverid:%s ,cfid:%s",
|
|
|
+ cp_order_id,vals[0].uid,vals[0].serverid,cfid);
|
|
|
+ checkorder.pushproduct(query,vals[0].serverid, cp_order_id, function(ok){
|
|
|
+ if (ok) {
|
|
|
+ console.log("[GooglePlay] 订单 %s: 成功发货!", cp_order_id);
|
|
|
+ } else{
|
|
|
+ console.log("[GooglePlay] 订单 %s: 发货地址无效!", cp_order_id);//在无效时返回成功,我们自己补单中会派发flag为1支付成功但是没成功发货的单
|
|
|
+ }
|
|
|
+ try{res.send("SUCCESS");}
|
|
|
+ catch(e){}
|
|
|
+ });
|
|
|
+ res.send("SUCCESS");
|
|
|
+ return;
|
|
|
+ }else{
|
|
|
+ console.log("SQL重复写入[GooglePlay]已经处理的订单");
|
|
|
+ try{res.send("SUCCESS");}
|
|
|
+ catch(e){}
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ })
|
|
|
+ }else{
|
|
|
+ console.log("[GooglePlay] 查询订单列表错误,请检查数据表结构和sql语句:\n\t%s", qerr);
|
|
|
+ try{res.send("FAILURE");}
|
|
|
+ catch(e){}
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ })
|
|
|
}
|
|
|
|
|
|
router.post('/googleplay', function(req, res) {
|
|
|
console.log("谷歌,post ,host:%s, ip:%s,date:%s",req.hostname,req.ip,new Date());
|
|
|
- var data = "";
|
|
|
+ let data = "";
|
|
|
req.on("data",function(chunk){
|
|
|
data += chunk;
|
|
|
})
|
|
|
req.on("end",function(){
|
|
|
- googleplay(data,res);
|
|
|
+ pay_success(data,res);
|
|
|
})
|
|
|
req.on("error",function(err){
|
|
|
res.send('erron,1');
|