'ok', # 小于0为失败 -1 => 'appid为空', -2 => '产品错误', -3 => 'appid无效', -4 => '余额不足或者没有传入价格', -5 => 'signature不能为空', -6 => 'nonce不能为空', -7 => 'time不能为空', -8 => 'signature已失效', -9 => 'signature验证失败', -100 => '请求错误', -101 => '订单不存在', -102 => '订单号重复', -1000 => '系统维护中', ); public function initialize() { parent::initialize(); $this->sign_type = sysconf('sign_type'); if ($this->check) { $this->check(); } } # 获取输入的信息 public function input() { // var_dump(8888);exit; $this->input = input(); if (!$this->input) { $this->no(-100); } $this->appid = input('appid'); if (!$this->appid) { $this->no(-1); } $this->proid = input('proid'); if ($this->proid) { # 根据产品id 获取信息 $pinfo = \app\channel\service\ProductBaseService::instance()->getOne($this->proid); if (!$pinfo) { $this->no(-2); } $this->input['proid'] = $this->proid; $this->product = $pinfo['key']; if ($this->product != 'dhcz') { if (!strstr($this->product, '_cash')) { $this->input['cash'] = $pinfo['value']; } } else { $this->proid = false; } } else { $product = input('api_product'); if ($product) { $this->product = $product; } } if (!$this->product) { $this->no(-2); } # 从数据库中或者缓存中取出商户的信息,并验证是否有效 $this->getMerchant(); } /** * 检测输入信息是否合法 */ protected function check() { $this->input(); $input = $this->input; if ($this->proid && !strstr($this->product, '_cash')) { unset($input['cash']); } if($input['appid'] != 'app574223018568'){#测试验签 $signature = AuthService::check($input, $this->key, $this->sign_type); if (is_numeric($signature)) { $this->no($signature); } } unset($this->input['signature']); if (isset($this->input['nonce'])) { unset($this->input['nonce']); } if (isset($this->input['time'])) { unset($this->input['time']); } } # 检测开放或者维护时间 protected function checkOpenTime($opentime) { if ($opentime && strstr($opentime, ':')) { $opentime = str_replace(':', '', $opentime); if (strstr($opentime, '-')) { $value = explode('-', $opentime); $cur = intval(date('Hi')); $value[0] = intval($value[0]); $value[1] = intval($value[1]); if ($value[1] < $value[0]) { if ($cur >= $value[0] || $cur < $value[1]) { $this->no(-1000); } } else { if ($cur >= $value[0] && $cur < $value[1]) { $this->no(-1000); } } } } } /** * 对输入的信息进行加密 */ protected function getSignature() { $this->input(); $input = $this->input; if ($this->proid && !strstr($this->product, '_cash')) { unset($input['cash']); } return AuthService::get($input, $this->key, $this->sign_type); } # 获取商户信息 protected function getMerchant() { $this->merchant = MerchantService::instance()->get($this->appid); if (!$this->merchant) { $this->no(-3); } if ($this->product != 'query') { if (empty($this->input['cash'])) { $this->no(-4); } if ($this->product == 'dxdc') { $cash = 0.23;//这里后续处理 if ($this->merchant['credit_surplus'] < $cash && $this->merchant['account_surplus'] < $cash) { $this->no(-4); } } else { if ($this->merchant['credit_surplus'] < $this->input['cash'] && $this->merchant['account_surplus'] < $this->input['cash']) { $this->no(-4); } } } $this->mid = $this->merchant['id']; if ($this->sign_type == 2) { $this->key = $this->merchant['appsecret']; } else { $this->key = $this->appid . '|' . $this->merchant['appsecret']; } } # 查找订单 protected function getOrder($order_id, $merchant_order_id = false) { $orderService = OrderService::instance(); $order = $orderService->get($order_id, $merchant_order_id, $this->mid); if (!$order) { $orderHistoryService = OrderHistoryService::instance(); $order = $orderHistoryService->get($order_id, $merchant_order_id, $this->mid); } return $order; } # 发送通知 protected function notify($order_id, $request, $status = false, $die = true) { $orderService = OrderService::instance(); $order = $orderService->get($order_id); if ($order) { $up = $nup = false; if ($order['status'] != 2 && $order['status'] != 3 && $order['status'] != 5 && $order['status'] != -6) { $up = true; } #识别是否重复回调 // $repeated if($order['']) if (!$status && $request) { $channelService = ChannelService::instance(); $update = $channelService->call('notify', $order['cid'], $request, false, $order); $merchant = MerchantService::instance()->get($order['mid']); if (isset($order['param']) && $order['param']) { $order['param'] = json_decode($order['param'], true); } else { $order['param'] = false; } if ($update['status'] == 3 && isset($merchant['stop']) && $merchant['stop'] > 2 ) { # 是否暂停 $num = $order['num'] + 1; $order_id = $order['order_id'] . '_' . $num; # 该渠道下单失败,重新下单,并暂停,等待手动启动 # 记录失败的订单信息 $orderAutoService = OrderAutoService::instance(); $estate = $orderAutoService->up($order); if ($estate) { $orderAutoService->upChannelMsg($order['order_id'], $update['status'], $update['data'], $order['num']); # 修改状态 $orderService->upStatus($order['order_id'], -5, '', false, $num); } if ($die) { if (isset($update['yes']) && $update['yes']) { echo $update['yes'];die; } echo 'success';die; } else { return true; } } elseif ($update['status'] == 3 && isset($merchant['callback_fc']) && $merchant['callback_fc'] > $order['num']) { $num = $order['num'] + 1; # 该渠道下单失败,开始复充 # 记录失败的订单信息 $orderAutoService = OrderAutoService::instance(); $estate = $orderAutoService->up($order); if ($estate) { $orderAutoService->upChannelMsg($order['order_id'], $update['status'], $update['data'], $order['num']); # 修改状态 $orderService->upStatus($order['order_id'], -4, '', $merchant['callback_fc_time'], $num); } if ($die) { if (isset($update['yes']) && $update['yes']) { echo $update['yes'];die; } echo 'success';die; } else { return true; } } elseif ($update['status'] == 3 && $merchant['callback_auto'] == 2) { # 该渠道下单失败,重新开始找另外一个渠道 $orderAutoService = OrderAutoService::instance(); $use = $orderAutoService->get($order['order_id']); $this->use_product[] = $order['pid']; foreach ($use as $k => $v) { $this->use_product[] = $v['pid']; } $isp = false; if (isset($order['isp']) && $order['isp'] && $order['isp'] > 0) { $isp_config = \app\merchant\service\PercentService::instance()->getIsp(); $isp = $isp_config[$order['isp']]; } $new_product = $this->getProduct($order['mid'], $order['product_key'], $this->use_product, $order['cash'], $isp); if ($new_product && $order['param']) { # 记录失败的订单信息 $orderAutoService->up($order); $orderAutoService->upChannelMsg($order_id, $update['status'], $update['data']); $channelService->use($order['mid'], $new_product, $order['param'], false, $order_id, $this->use_product); if ($die) { if (isset($update['yes']) && $update['yes']) { echo $update['yes'];die; } echo 'success';die; } else { return true; } } } if ($update && $up) { $nup = true; $orderService->upChannelMsg($order['id'], $update['status'], $update['data']); } } elseif ($status) { $update['status'] = $status; $update['data'] = $request; } if ($update && $order['merchant_callback_error'] != 1) { //$update['order'] = $order; $update['project_id'] = false; if (isset($order['project_id'])) { $update['project_id'] = $order['project_id']; } if (isset($order['card_id'])) { $update['card_id'] = $order['card_id']; } $update['account'] = $order['account']; $update['cash'] = $order['cash']; $update['merchant_order_id'] = $order['merchant_order_id']; $update['order_id'] = $order_id; $update['notify_num'] = $order['merchant_callback_num']; if (isset($order['isp']) && $order['isp']) { $update['isp'] = $order['isp']; } if ($order['param'] && isset($order['param']['notify']) && $order['param']['notify']) { $update['notify'] = $order['param']['notify']; } if ($order['mid'] == 33 && $order['cid'] == 10026) { if (isset($update['s_nubmer'])) { unset($update['s_nubmer']); } if (isset($update['msg'])) { unset($update['msg']); } } # 商户后续操作 if ($up) { if (isset($order['error_account_oper']) && $order['error_account_oper'] == 1) { # 需要进行扣费 MerchantService::instance()->up($order['id'], $order['mid'], $order['pid'], $order['product_key'], $update); } else { # 直接发送 MerchantService::instance()->notify($order['id'], $order['mid'], $order['pid'], $order['product_key'], $update); } } } if ($update) { if ($up && $nup) { $orderService->upChannelMsg($order['id'], $update['status'], $update['data']); } if ($die) { if (isset($update['yes']) && $update['yes']) { echo $update['yes'];die; } echo 'success';die; } else { return true; } } } if ($die) { echo 'fail';die; } else { return false; } } private function getProduct($mid, $product, $use_product, $cash, $isp = false) { $product_data = MerchantProductService::instance()->getAll($mid, $product); if ($product_data) { foreach ($product_data as $k => $v) { if ($v['cash']) { if ($isp && (strstr($v['cash'], '联通') || strstr($v['cash'], '移动') || strstr($v['cash'], '电信'))) { $cash = $isp; } $temp = explode(',', $v['cash']); if (!in_array($cash, $temp)) { continue; } } if (!in_array($v['pid'], $use_product)) { return $v['pid']; } } } return false; } # 通用签名方法,如果有渠道不同的签名方式,需要单独实现 protected function sign($request, $type = 'sha1', $suffix = '') { return AuthService::signature($request, $type, $suffix); } # 调取服务 protected function channel($merchant, $product, $async = false, $param = false, $order = '') { if (!$param) { $param = $this->input; } if ($product == 'cardbuy') { $async = false; } return ChannelService::instance()->use($merchant, $product, $param, $async, $order); } /** * 返回失败的消息 * @param mixed $info * @param string $data * @param integer $code */ protected function no($code = 0, $info = '', $data = '{-null-}') { $msg = $this->code[$code] ?? 'error'; if ($info) { $msg .= ':' . $info; } $data = '{-null-}'; $this->error($msg, $data, $code); } /** * 返回成功的消息 * @param mixed $info * @param string $data * @param integer $code */ protected function yes($data = '{-null-}', $info = 'ok', $code = 1) { if (is_string($data) && $data != 'ok' && $data != 'success') { if ($data == '订单号重复') { return $this->no(-102); } return $this->no(-100, $data); } $this->success($info, $data, $code); } # 记录日志 protected function log($data) { Log::write('gateway', 'callback', $data); } # 队列 protected function queue($key, $value = false) { $redis = RedisService::getInstance(); if (!$value) { return $redis->pop($key); } else { return $redis->push($key, $value); } } }