NotifyService.php 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. <?php
  2. namespace app\api\service;
  3. use app\common\model\ComplexChannelModel;
  4. use think\Db;
  5. use think\Env;
  6. use think\Exception;
  7. use app\common\model\ComplexPay;
  8. use app\common\model\PayCpinfo;
  9. use app\common\model\ComplexMembers;
  10. use app\common\model\PolychannelGame;
  11. use app\common\logic\PayCallback;
  12. class NotifyService
  13. {
  14. protected $payInfo; //订单支付信息,子类里面有调用
  15. // ## TODO:每次新渠道,当前两个必须要添加
  16. // H5渠道游戏使用渠道逻辑处理
  17. protected $h5_handle_channel = ['zhaosy'];
  18. public function notify($channel, $input)
  19. {
  20. $channelModel = new ComplexChannelModel();
  21. try {
  22. if (!is_numeric($input['gameidqf'])) {
  23. echo 'no game';
  24. exit();
  25. }
  26. if (!($channel_id = $channelModel->where(['status' => 1, 'mark' => $channel])->value('id'))) {
  27. echo 'no channel';
  28. exit();
  29. }
  30. $polyChannelGame = [];
  31. if(isset($input['gameidqf']) && $input['gameidqf']>0){
  32. if (!$polyChannelGame = (new PolychannelGame())->alias('cpg')->join('cy_game cg', 'cpg.game_id=cg.id')->field('cpg.*, cg.type as game_type')->where(['cpg.channel_id' => $channel_id, 'cpg.game_id' => $input['gameidqf']])->find()) {
  33. echo 'no game';
  34. exit();
  35. }
  36. }
  37. $sentence = ucfirst($channel);
  38. $className = 'app\api\complex\\' . $sentence;
  39. $model = new $className;
  40. // H5 渠道游戏,单独处理
  41. if(in_array($channel, $this->h5_handle_channel) && $polyChannelGame['game_type'] == 3){
  42. $payResult = $model->paySignH5($input, $polyChannelGame);
  43. }else{
  44. $payResult = $model->paySign($input, $polyChannelGame);
  45. }
  46. if($payResult !== true){
  47. // 优化提示判断
  48. if(!empty($payResult['code']) && $payResult['code'] < 0){
  49. $msg = "回调处理失败, (c_err:{$payResult['code']})";
  50. $model->getFail($msg);
  51. }
  52. $model->getFail('回调处理失败!');
  53. }
  54. // 获取后续系统所需参数
  55. $dataResult = $model->getData($input);
  56. if ($dataResult === false) {
  57. log_message('非法操作!渠道回调参数有误!', 'error', LOG_PATH . 'complexPaylog/' . $channel . '/');
  58. $model->getFail("回调处理异常!(参数有误)");
  59. }
  60. // 优化提示判断
  61. if(!empty($dataResult['code'])){
  62. if($dataResult['code'] < 0){
  63. $dataMsg = "回调处理失败, (c_err:{$dataResult['code']})";
  64. $model->getFail($dataMsg);
  65. }
  66. }
  67. if (!$dataResult) {
  68. log_message('签名不一致,orderid=' . $dataResult['orderid'], 'error', LOG_PATH . 'complexPaylog/' . $channel . '/');
  69. $model->getFail('签名不一致');
  70. }
  71. //金额验证
  72. if (!$this->checkOrder($dataResult['orderid'], $dataResult['amount'])) {
  73. log_message('订单不存在或订单金额不一致,orderid=' . $dataResult['orderid'], 'error', LOG_PATH . 'complexPaylog/' . $channel . '/');
  74. $model->getFail('订单不存在或订单金额不一致');
  75. }
  76. if ($this->payInfo['status'] == 0) {
  77. // 启动事务
  78. Db::startTrans();
  79. try {
  80. $this->updateOrder($dataResult['orderid'], $dataResult['sub_orderid']);
  81. // 提交事务
  82. Db::commit();
  83. } catch (\Exception $e) {
  84. // curlDD('渠道支付回调:' . $e->getMessage(), Env::get('warning_url'));
  85. // 回滚事务
  86. Db::rollback();
  87. $model->getFail('渠道支付回调:' . $e->getMessage());
  88. }
  89. } else {
  90. $model->getSuccess('支付成功');
  91. }
  92. // 【产品确认:测试阶段暂时不用通知CP】通知CP,支付成功
  93. if ((new PayCallback())->callBackToCp($dataResult['orderid'])) {
  94. $model->getSuccess('支付成功');
  95. } else {
  96. $model->getFail('厂商支付回调失败');
  97. }
  98. } catch (Exception $e) {
  99. // dump($e->getMessage().' - '.$e->getFile().':'.$e->getLine());
  100. log_message("渠道支付回调-{$channel}:" . $e->getMessage(), 'error', LOG_PATH . 'complexPaylog/' . $channel . '/');
  101. curlDD("渠道支付回调-{$sentence}:" . $e->getMessage().' - '.$e->getFile().':'.$e->getLine() . ' \n input:'.json_encode($input), Env::get('dingtalk.notic_url'));
  102. echo 'FAIL:ERROR='.$e->getMessage();
  103. exit();
  104. }
  105. }
  106. /**
  107. * 检验订单
  108. *
  109. * @param $orderid string 订单ID
  110. * @param $amount string 订单金额
  111. *
  112. * @return boolean 验签结果
  113. */
  114. protected function checkOrder($orderid, $amount)
  115. {
  116. $payModel = new ComplexPay();
  117. $payInfo = $payModel->field('userid,amount,gameid,channel_id,status')->where(['orderid' => $orderid])->find();
  118. if (empty($payInfo)) {
  119. return false;
  120. // } elseif (floatval($payInfo['amount']) != floatval($amount)) {
  121. } elseif (bccomp(floatval($payInfo['amount']), floatval($amount), 2) !== 0) {
  122. return false;
  123. }
  124. $this->payInfo = $payInfo;
  125. return true;
  126. }
  127. /**
  128. * 更新订单信息
  129. *
  130. * @param $orderId string 订单号
  131. * @param $sub_orderid string 下级渠道订单号
  132. * @param $pay_time int 支付时间
  133. *
  134. * @return bool
  135. */
  136. protected function updateOrder($orderid, $sub_orderid, $pay_time = NOW_TIMESTAMP)
  137. {
  138. $payModel = new ComplexPay();
  139. $payCpinfoModel = new PayCpinfo;
  140. $memberModel = new ComplexMembers;
  141. //消费订单信息
  142. $payInfo = $payModel->field('id,pay_amount,userid,gameid,channel_id')->where(['orderid' => $orderid])->find();
  143. if ($payInfo) {
  144. // 订单表 = 已完成
  145. $payModel->save(['status' => 1, 'sub_orderid' => $sub_orderid, 'pay_time' => $pay_time], ['orderid' => $orderid]);
  146. // cp信息 = 支付成功
  147. $payCpinfoModel->save(['payflag' => 1], ['orderid' => $orderid]);
  148. //更新nw_complex_members表的total_pay_amount
  149. $memberModel->where(['id' => $payInfo['userid']])->update(['total_pay_amount' => Db::raw('total_pay_amount+' . $payInfo['pay_amount'])]);
  150. }
  151. }
  152. }