local skynet = require "skynet" local oo = require "Class" local gameCmd = require "GameCmd" local json =require "json" local log = require "Log" local sqlUrl = require "SqlUrl" local errorInfo = require "ErrorInfo" local serverId = tonumber(skynet.getenv "serverId") local redisKeyUrl = require "RedisKeyUrl" local clusterServer = require "ClusterServer" local crypt = require "skynet.crypt" local sha1 = crypt.sha1 local PayServer = oo.class(clusterServer) PayServer.apiKey = "407dcc74075cee33f40e76f0ec2f5817" --初始化 function PayServer:Init() end --跨天 function PayServer:OnNewDay() end --1秒Timer function PayServer:On1SecTimer() end --5秒Timer function PayServer:On5SecTimer() end --接收集群数据 function PayServer:ClusterRecv(...) local cmd , c2sData = ... local s2cData = {} s2cData.code = errorInfo.Suc if self.Center2All_ServerManageCmd == cmd then --中心服集群消息 elseif self.Center2All_SyncClusterInfo == cmd then self:RecvSyncClusterInfo( c2sData ) elseif self.Center2All_SyncServerConfig == cmd then --同步服务器配置 self:RecvSyncServerConfig( c2sData ) else log.info(string.format("集群服务器 消息接口 %d 不存在", cmd)) s2cData.code = errorInfo.ErrorCode.NoExistInterface end log.info("集群服务器 消息接口", cmd , "返回信息",s2cData.code) return s2cData end --[[ [addr]=192.168.50.188, [sign]=8513b67c21afc1238adb734771cebdfc43b9c917, [paymentMethod]=$%7BpaymentMethod%7D, [timestamp]=1566793027, [rebate]=$%7BurlEncode%28rebateInfo%29%7D, [provider]=$%7Bprovider%7D, [currency]=CNY, [gameId]=h5_test, [price]=60.0, [extra]=$%7BurlEncode%28userdata%29%7D, [gameAccountId]=12345, [gameOrderId]=15667930060415003, [cpOrderId]=960198, [itemId]=com_1, [minPrice]=6000, } ]] --接收HTTP数据 function PayServer:HttpRecv( c2sData , url , addr ) local s2cData = {} s2cData.state = {} c2sData = skynet.server.httpServer:Translate(c2sData) s2cData.state.code = errorInfo.Suc c2sData.addr = addr if "AddPayInfo" == url then self:AddPayInfo( c2sData , s2cData ) else log.info(string.format("Http服务器 消息接口 %s 不存在", url)) s2cData.code = errorInfo.ErrorCode.NoExistInterface end log.info("Http服务器 消息接口 ",url ,"返回信息",s2cData.code) return s2cData end --新增充值信息 function PayServer:AddPayInfo( c2sData , s2cData ) local clusterReturn = {} --c2sData.extra = skynet.server.common:UrlDecode( c2sData.extra or "" ) --先进行URL解码 --c2sData.extra = json:decode(c2sData.extra) --把JSON再转成表 --根据发的数据查找对应的配置 local itemId = c2sData.itemId local cfgStorePrice = skynet.server.gameConfig.StorePrice local cfgCur = nil for k, v in pairs(cfgStorePrice) do if itemId == v.productId then cfgCur = v break end end if not self:CheckPayInfo( c2sData , cfgCur , itemId ) then s2cData.state.code = 2 --失败 else local sign = self:GenerateSign( c2sData ) log.info(string.format("生成的Sign %s 收到的Sign %s", sign , c2sData.sign)) if sign ~= c2sData.sign then s2cData.state.code = 2 --发货失败 log.info("Sign不一致") else local sendData = {} sendData.account = tostring(c2sData.gameAccountId) sendData.storeId = cfgCur.storePackId sendData.count = 1 log.info(string.format("开始发放充值 帐号 %s 充值平台id %s", sendData.account , sendData.storeId)) local isSucSend = false for k, v in pairs(self.clusterInfo) do if self:IsGameServer( v.serverId ) and v.status == self.Status_Running or v.status == self.Status_Stop then clusterReturn = self:CallMsgToServer(v.serverId , self.Pay2Game_AddPayInfo , sendData ) if errorInfo.Suc == clusterReturn.code then log.info(string.format("充值服向游戏服 %d 发送充值信息成功", v.serverId )) isSucSend = true break elseif errorInfo.ErrorCode.NoExistUser == clusterReturn.code then log.info(string.format("游戏服 %d 不存在玩家", v.serverId )) else s2cData.state.code = 2 --失败 log.info(string.format("充值服向游戏服 %d 发送充值信息失败", v.serverId )) end end end if not isSucSend then s2cData.state.code = 2 --发货失败 else s2cData.state.code = 1 --发货成功 end end end end --对充值信息的合法性检测 function PayServer:CheckPayInfo( c2sData , cfgCur , itemId) local sign = self:GenerateSign( c2sData ) log.info(string.format("生成的Sign %s 收到的Sign %s", sign , c2sData.sign)) local minPrice = c2sData.minPrice local buyPrice = cfgCur.price if not cfgCur then log.info(string.format("不存在充值礼包 %s 配置", itemId )) return false elseif minPrice ~= buyPrice then log.info(string.format("充值礼包 %d 价格不一致配置 %d %d", cfgCur.storePackId , buyPrice , minPrice)) return false else return true end end --生成签名 function PayServer:GenerateSign( c2sData ) local param = "" local allData = {} for k, v in pairs( c2sData ) do table.insert( allData , { key = k , value = v }) end --对参数进行一个升序 table.sort( allData , function(a,b) return a.key < b.key end) for k, v in pairs( allData ) do if "sign" ~= v.key and "addr" ~= v.key then log.info("签名参数:",v.key,"值:",v.value) local tmpText = "" if "table" == type(v.value) then --如果是表需要进行转JSON,URL编码 tmpText = json:encode(v.value) tmpText = skynet.server.common:UrlEncode(tmpText) else tmpText = v.value end local tmp = v.key.."="..tmpText if "" == param then param = param .. tmp else param = param .. "&" param = param .. tmp end end end param = param..self.apiKey --param = "cpOrderId=960198¤cy=CNY&gameAccountId=12345&gameId=h5_test&gameOrderId=15667930060415003&itemId=com_1&minPrice=6000&paymentMethod=${paymentMethod}&price=60.0&provider=${provider}&rebate=${urlEncode(rebateInfo)}×tamp=1566793027407dcc74075cee33f40e76f0ec2f5817" local sign = string.lower(skynet.server.common:HexToStr(sha1(param))) log.info("加密前生成的参数组合:",param) log.info("加密后的数据:",sign) return sign end skynet.server.payServer = PayServer return PayServer