ComplexPay.php 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208
  1. <?php
  2. /**
  3. * 聚合渠道统一下单接口
  4. *
  5. */
  6. namespace app\api\controller\v1;
  7. use app\api\controller\Api;
  8. use app\common\library\RsaSign;
  9. use app\common\model\ComplexMembers;
  10. use app\common\model\Game;
  11. use app\common\model\ComplexChannel;
  12. use app\common\model\Cpurl;
  13. use app\common\model\ComplexPay as PayModel;
  14. use app\common\model\PayCpinfo;
  15. use app\common\logic\Complex;
  16. use app\common\model\PolychannelGame;
  17. use think\Db;
  18. use think\Config;
  19. use think\Env;
  20. use think\Exception;
  21. use think\Model;
  22. class ComplexPay extends Api
  23. {
  24. protected $nowTime;
  25. // 需要进行单独处理的渠道标识
  26. protected $_neekCheckChannel = ['sanjiu', 'ledaoios', 'dangle', 'kuaishou', 'quchen', 'simo', 'gyln', 'kshy', 'weilian'];
  27. public function _initialize()
  28. {
  29. parent::_initialize();
  30. $this->nowTime = NOW_TIMESTAMP;
  31. }
  32. /**
  33. * 支付处理
  34. */
  35. public function index()
  36. {
  37. $gameid = $this->input('gameid'); //游戏ID
  38. $member_id = $this->input('userid'); //用户ID
  39. $serverid = $this->input('serverid'); //服务器ID
  40. $amount = $this->input('amount'); //充值金额(单位为分)
  41. $roleid = $this->input('roleid'); //角色ID
  42. $attach = $this->input('attach'); // CP方的扩展参数
  43. $imeil = $this->input('imeil'); //手机imeil码
  44. $rolename = $this->input('rolename', ''); //角色名
  45. $rolelevel = $this->input('rolelevel', ''); //角色角色等级
  46. $channel_mark = $this->input('channel_mark'); //渠道标识
  47. $orderid = 'CM' . makeOrderid();
  48. $memberModel = new ComplexMembers;
  49. $cpurlModel = new Cpurl;
  50. $gameModel = new Game;
  51. $payModel = new PayModel;
  52. $payCpinfoModel = new PayCpinfo;
  53. $channelModel = new ComplexChannel;
  54. $complexLogic = new Complex;
  55. $checkResult = $this->validate($this->input, [
  56. ['gameid', 'require|integer', '游戏id不能为空|游戏ID必须为整型'],
  57. ['userid', 'require|integer', '用户ID不能为空|用户ID必须为整型'],
  58. ['serverid', 'require', '游戏服务器id不能为空'],
  59. ['amount', 'require|gt:0', '充值金额不能为空|充值金额必须大于0'],
  60. ['roleid', 'require', '角色id不能为空'],
  61. ['attach', 'require', '游戏合作方订单参数不能为空'],
  62. ['channel_mark', 'require', '渠道标识不能为空']
  63. ]);
  64. if (true !== $checkResult) {
  65. $this->jsonResult('', 0, $checkResult);
  66. }
  67. if (!($channel_id = $channelModel->where(['status' => 1, 'mark' => $channel_mark])->value('id'))) {
  68. $this->jsonResult('', 0, '渠道信息不存在');
  69. } elseif ($payModel->where(['attach' => $attach, 'gameid' => $gameid])->find()) {
  70. $this->jsonResult('', 0, '游戏合作方订单参数不能重复');
  71. }
  72. if (!$polyChannelGame = (new PolychannelGame())->where(['channel_id' => $channel_id, 'game_id' => $gameid])->find()) {
  73. $this->jsonResult('', 0, '渠道游戏不存在');
  74. }
  75. $memberInfo = $memberModel->field('mg_username,complex_id,complex_username,extparam')->where(['id' => $member_id])->find();
  76. if (empty($memberInfo)) {
  77. $this->jsonResult('', 0, '用户不存在');
  78. }
  79. //当前游戏的渠道是否禁止消费(非归属渠道)
  80. if ($complexLogic->isFrozen($channel_id, $gameid, 'consume')) {
  81. $this->jsonResult('', 0, '您所在渠道已经被禁止在此游戏消费');
  82. }
  83. //充值回调地址
  84. $cpurl = $cpurlModel->where(['appid' => $this->appInfo['id']])->value('url');
  85. if (empty($cpurl)) {
  86. $this->jsonResult('', 0, '没有回调地址,请通知我方配置');
  87. }
  88. //游戏信息
  89. $gameInfo = $gameModel->field('order_recheck,nickname')->where(['id' => $gameid])->find();
  90. if(empty($gameInfo)){
  91. $this->jsonResult('', 0, '游戏id参数错误');
  92. }
  93. $payData['orderid'] = $orderid;
  94. $payData['amount'] = $amount;
  95. $payData['userid'] = $member_id;
  96. $payData['username'] = $memberInfo['mg_username'];
  97. $payData['roleid'] = $roleid;
  98. $payData['rolename'] = $rolename;
  99. $payData['rolelevel'] = $rolelevel;
  100. $payData['serverid'] = $serverid;
  101. $payData['gameid'] = $gameid;
  102. $payData['status'] = 0;
  103. $payData['ip'] = request()->ip();
  104. $payData['imei'] = $imeil;
  105. $payData['create_time'] = $this->nowTime;
  106. $payData['channel_id'] = $channel_id;
  107. $payData['attach'] = $attach;
  108. $payData['pay_amount'] = $amount;
  109. $payData['discount'] = 1.00;
  110. // ## 折扣 - 实付金额 ##
  111. $proportion = Db::table('cy_game_pay_discount')->where(['game_id' => $gameid])->value('proportion');
  112. if($proportion > 0 && $proportion < 1){
  113. // 先计算折扣后的应付总额
  114. $payData['pay_amount'] = round(bcmul((string)$amount, (string)$proportion, 3), 2);
  115. $payData['discount'] = $proportion;
  116. }
  117. // 启动事务
  118. Db::startTrans();
  119. try{
  120. $result = []; //返回值
  121. $payModel->insert($payData);
  122. $str = "orderid=".urlencode($orderid)."&username=".urlencode($memberInfo['mg_username'])."&gameid=".$gameid."&roleid=".urlencode($roleid)."&serverid=".urlencode($serverid)."&paytype=".urlencode('jhzf')."&amount=".$amount."&paytime=".$this->nowTime."&attach=".urlencode($attach);
  123. $param = $str."&appkey=".urlencode($this->appInfo['appkey']);
  124. $md5params = md5($param);
  125. $params = $str . "&sign=".urlencode($md5params);
  126. $paycpData['orderid'] = $orderid;
  127. $paycpData['fcallbackurl'] = $cpurl;
  128. $paycpData['params'] = $params;
  129. $paycpData['create_time'] = $this->nowTime;
  130. $paycpData['payflag'] = 0;
  131. //写入cy_paycpinfo表数据
  132. $payCpinfoModel->insert($paycpData);
  133. // 提交事务
  134. Db::commit();
  135. } catch (\Exception $e) {
  136. // 回滚事务
  137. Db::rollback();
  138. $this->jsonResult('', 0, '订单生成失败' . $e->getMessage());
  139. }
  140. $result['username'] = $memberInfo['complex_username']; //聚合子渠道的玩家用户名
  141. $result['orderid'] = (Config::get('self_complex_channel_mark') == $channel_mark) ? 'xkhyn###' . $orderid : $orderid;
  142. $result['extend'] = ['notify_url' => ''];
  143. // 判断是否有做登录验证的渠道
  144. if (in_array($channel_mark, $this->_neekCheckChannel)) {
  145. try {
  146. $sentence = ucfirst($channel_mark);
  147. $className = 'app\api\complex\\' . $sentence;
  148. $model = new $className;
  149. $channelData = $this->input;
  150. $channelData['pay_info'] = $payData;
  151. $channelData['member_info'] = $memberInfo->toArray();
  152. $channelData['game_info'] = $gameInfo->toArray();
  153. $channelData['channel_info'] = $polyChannelGame->toArray();
  154. $channelData['notify_url'] = API_DOMAINS."/v1.complex_pay_notify/notify/channelqf/{$channel_mark}/gameidqf/{$channelData['gameid']}";
  155. $channelData['extparam'] = [];
  156. if(!empty($memberInfo['extparam'])){
  157. $channelData['extparam'] = json_decode($memberInfo['extparam'],true);
  158. }
  159. $resultData = $model->getOrder($channelData);
  160. if ($resultData['code'] != 200) {
  161. curlDD("渠道-" . $sentence . '-下单异常_创建订单失败:' . $resultData['msg'], Env::get('dingtalk.notic_url'));
  162. if($resultData['code'] == -200){
  163. $this->jsonResult('', 0, '订单创建失败:'.$resultData['msg']);
  164. }
  165. $this->jsonResult('', 0, "订单创建失败({$resultData['code']}={$resultData['msg']})");
  166. }
  167. $result['extend'] = $resultData['param']??"{}";
  168. } catch (Exception $e) {
  169. // dump($e->getMessage(), $e->getFile(), $e->getLine());
  170. curlDD("渠道-" . $sentence . '-下单异常:' . $e->getMessage().' - '.$e->getFile().":".$e->getLine(), Env::get('dingtalk.notic_url'));
  171. $this->jsonResult('', 0, '订单创建异常:' . $e->getMessage());
  172. }
  173. }
  174. $this->jsonResult($result, 1, '订单生成成功');
  175. }
  176. }