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' => $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 = [ 'mid' => $this->mid, 'tid' => $this->tid, 'instMid' => $this->instMid, 'msgSrc' => $this->msgSrc, 'msgSrcId' => $this->msgSrcId, 'signType' => $this->signType, 'msgType' => 'query', 'requestTimestamp' => date('Y-m-d H:i:s'), 'merOrderId' => $trade_no, ]; $result = $this->request($query_params); if ($result->errCode === 'SUCCESS' && $result->status === 'TRADE_SUCCESS') { return true; } else { \Log::info('union_pay.query: '); \Log::info(object_to_array($result)); } return false; } public function notify(array $data) { if ($data['status'] === 'TRADE_SUCCESS') { $sign = $this->makeSign($data); if ($sign === $data['sign']) { return true; } } return false; } public function refund(array $data) { $refund_params = [ 'mid' => $this->mid, 'tid' => $this->tid, 'instMid' => $this->instMid, 'msgSrc' => $this->msgSrc, 'msgSrcId' => $this->msgSrcId, 'signType' => $this->signType, 'msgType' => 'refund', 'requestTimestamp' => date('Y-m-d H:i:s'), 'merOrderId' => $data['trade_no'], 'refundAmount' => $data['price'], ]; $result = $this->request($refund_params); if ($result->errCode === 'SUCCESS' && $result->refundStatus === 'SUCCESS' && $result->status === 'TRADE_SUCCESS') { return true; } else { \Log::info('union_pay.refund: '); \Log::info(object_to_array($result)); } return false; } /** * 生成订单号 */ public function generateTradeNo() { return substr($this->msgSrcId . date("YmdHis") . hexdec(uniqid()), 0, 30); } public 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; } private function request(array $data) { try { $data['sign'] = $this->makeSign($data); $client = new Client(['timeout' => 3]); $result = $client->request('post', $this->query_order_url, ['json' => $data])->getBody()->getContents(); if ($result) { $result = json_decode($result); } return $result; } catch (Exception $e) { \Log::error('union_pay.request: ' . $e->getMessage()); } } }