mid = $config['mid']; $this->tid = $config['tid']; $this->instMid = $config['instMid']; $this->msgSrc = $config['msgSrc']; $this->msgSrcId = $config['msgSrcId']; $this->key = $config['key']; } private function setConfig(array $config) { $this->mid = $config['mid']; $this->tid = $config['tid']; $this->instMid = $config['instMid']; $this->msgSrc = $config['msgSrc']; $this->msgSrcId = $config['msgSrcId']; $this->key = $config['key']; } public function send(array $data) { $result = [ 'mid' => $this->mid, 'tid' => $this->tid, 'instMid' => $this->instMid, 'msgSrc' => $this->msgSrc, 'msgSrcId' => $this->msgSrcId, 'msgType' => $this->msgType, 'signType' => $this->signType, 'requestTimestamp' => date('Y-m-d H:i:s'), 'notifyUrl' => env('UNIONPAY_NOFITY_URL'), 'returnUrl' => urlencode($data['pay_wait_url']), 'totalAmount' => $data['price'], 'merOrderId' => $this->msgSrcId . $data['trade_no'], ]; $result['sign'] = $this->makeSign($result); $query_params = http_build_query($result); return $this->make_order_url . '?' . $query_params; } public function query(string $trade_no) { $query_params = [ 'msgType' => 'query', 'requestTimestamp' => date('Y-m-d H:i:s'), 'mid' => $this->mid, 'tid' => $this->tid, 'instMid' => $this->instMid, 'msgSrc' => $this->msgSrc, 'msgSrcId' => $this->msgSrcId, 'signType' => $this->signType, 'merOrderId' => $trade_no, ]; $query_params['sign'] = $this->makeSign($query_params); try { $client = new Client(['base_uri' => $this->query_order_url, 'timeout' => 3]); $result = $client->request('POST', '/mct1/payorder', ['form_params' => $query_params])->getBody()->getContents(); if ($result) { $result = json_decode($result); if ($result->errCode === 'SUCCESS' && $result->status === 'TRADE_SUCCESS') { return true; } } } catch (Exception $e) { } return false; } public static function notify(Request $request, callable $callback) { $data = $request->all(); if ($data['status'] === 'TRADE_SUCCESS') { $trade_no = $data['merOrderId']; if ($trade_no) { $order = OrderService::getByTradeNo($trade_no); $order->transaction_id = $data['targetOrderId']; if ($order) { $pay_merchant = DB::table('pay_merchants')->select('appid', 'source', 'config_info') ->where('id', $order->pay_merchant_id)->where('is_enabled', 1)->first(); $instance = new UnionPay(json_decode($pay_merchant->config_info, true)); $sign = $instance->makeSign($data); if ($sign === $data['sign']) { if (call_user_func_array($callback, [$order])) { return 'SUCCESS'; } } } } } return 'FAILED'; } /** * 生成订单号 */ public function generateTradeNo() { return $this->msgSrcId . date("YmdHis") . substr(uniqid(), 0, 12); } private function makeSign(array $data) { //签名步骤一:按字典序排序参数 ksort($data); $buff = ""; foreach ($data as $k => $v) { if ($k != "sign" && $v != "" && !is_array($v)) { $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); //签名步骤二:在string后加入KEY $string = $buff . $this->key; //签名步骤三:MD5加密 $string = md5($string); //签名步骤四:所有字符转为大写 $result = strtoupper($string); return $result; } }