diff --git a/qq/Account.php b/qq/Account.php new file mode 100644 index 0000000..9d0601f --- /dev/null +++ b/qq/Account.php @@ -0,0 +1,211 @@ +savePath = $path; + } + + /** + * @param $code + * @return Result + */ + public function login($code) + { + $param['appid'] = $this->config->getAppid(); + $param['secret'] = $this->config->getAppsecret(); + $param['js_code'] = $code; + $param['grant_type'] = 'authorization_code'; + + $this->request->setHost('api.q.qq.com'); + $this->request->setMethod(WxClient::GET); + $this->request->addHeader('Content-Type', 'text/xml'); + + return $this->request->get('sns/jscode2session', $param); + } + + /** + * @param $openid + * @return array|mixed|Result + * @throws \Exception + */ + public function getPublicUserInfo($openid) + { + $query = [ + 'access_token' => $this->getAccessToken(), + 'openid' => $openid, + 'lang' => 'zh_CN' + ]; + + $this->request->setMethod(WxClient::GET); + $this->request->setIsSSL(true); + return $this->request->get($this->publicInfo, $query); + } + + + /** + * @param $encryptedData + * @param $iv + * @param $sessionKey + * @param $asArray + * @return object|array + * @throws + * + * *
  • -41001: encodingAesKey 非法
  • + *
  • -41003: aes 解密失败
  • + *
  • -41004: 解密后得到的buffer非法
  • + *
  • -41005: base64加密失败
  • + *
  • -41016: base64解密失败
  • + */ + public function decode($encryptedData, $iv, $sessionKey, $asArray = false) + { + $config = Wx::getMiniProGaRamPage()->getConfig(); + if (strlen($sessionKey) != 24) { + throw new \Exception('encodingAesKey 非法', $this->IllegalAesKey); + } + + $aesKey = base64_decode($sessionKey); + if (strlen($iv) != 24) { + throw new \Exception('base64解密失败', $this->IllegalIv); + } + + $aesIV = base64_decode($iv); + $aesCipher = base64_decode($encryptedData); + $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, OPENSSL_RAW_DATA, $aesIV); + if ($result === false) { + throw new \Exception('aes 解密失败', $this->IllegalBuffer); + } + + $dataObj = json_decode($result); + if ($dataObj->watermark->appid != $config->getAppid()) { + throw new \Exception('aes 解密失败', $this->IllegalBuffer); + } + + if ($asArray) { + return get_object_vars($dataObj); + } + + return $dataObj; + } + + + /** + * @param $path + * @param $width + * @return array|mixed|Result + * @throws \Exception + */ + public function createwxaqrcode($path, $width) + { + $url = $this->wxaqr . $this->getAccessToken(); + + $sendBody['path'] = $path; + $sendBody['width'] = $width; + + $this->request->setMethod(WxClient::POST); + $this->request->setCallback([$this, 'saveByPath']); + + return $this->request->post($url, $sendBody); + } + + + /** + * @param $path + * @param $width + * @param bool $is_hyaline + * @param bool $auto_color + * @param string $line_color + * @return array|mixed|Result + * @throws \Exception + */ + public function getwxacode($path, $width, $is_hyaline = false, $auto_color = false, $line_color = '') + { + $sendBody['path'] = $path; + $sendBody['width'] = $width; + $sendBody['auto_color'] = $auto_color; + $sendBody['is_hyaline'] = $is_hyaline; + if ($auto_color) { + $sendBody['line_color'] = $line_color; + } + + $url = $this->getwxacode . $this->getAccessToken(); + + $this->request->setMethod(WxClient::POST); + $this->request->setCallback([$this, 'saveByPath']); + return $this->request->post($url, $sendBody); + } + + + /** + * @param $path + * @param $width + * @param bool $is_hyaline + * @param bool $auto_color + * @param string $line_color + * @return array|mixed|Result + * @throws \Exception + */ + public function getwxacodeunlimit($path, $width, $is_hyaline = false, $auto_color = false, $line_color = '') + { + $sendBody['path'] = $path; + $sendBody['width'] = $width; + $sendBody['auto_color'] = $auto_color; + $sendBody['is_hyaline'] = $is_hyaline; + if ($auto_color) { + $sendBody['line_color'] = $line_color; + } + + $url = $this->getwxacodeunlimit . $this->getAccessToken(); + + $this->request->setMethod(WxClient::POST); + $this->request->setCallback([$this, 'saveByPath']); + return $this->request->post($url, $sendBody); + } + + /** + * @param mixed $body + * @return string + * @throws \Exception + */ + public function saveByPath($body) + { + if (!is_null($json = json_decode($body))) { + throw new \Exception($json['errmsg'], $json['errcode']); + } + + $push = md5_file($body) . '.png'; + file_put_contents($this->savePath . $push, $this->savePath); + return $this->savePath . $push; + } +} diff --git a/qq/Message.php b/qq/Message.php new file mode 100644 index 0000000..a6adfe5 --- /dev/null +++ b/qq/Message.php @@ -0,0 +1,314 @@ +openid = $openid; + $this->msgData['touser'] = $openid; + } + + /** + * @param string $content + * @return Result + * @throws \Exception + */ + public function sendTextNews(string $content) + { + $this->msgData['msgtype'] = 'text'; + $this->msgData['text[content]'] = $content; + + return $this->sendKefuMsg(); + } + + /** + * @param $media_id + * @return Result + * @throws \Exception + */ + public function sendImageNews(string $media_id) + { + $this->msgData['msgtype'] = 'image'; + $this->msgData['image[media_id]'] = $media_id; + + return $this->sendKefuMsg(); + } + + + /** + * @param $media_id + * @return Result + * @throws \Exception + */ + public function sendVoiceNews(string $media_id) + { + $this->msgData['msgtype'] = 'voice'; + $this->msgData['voice[media_id]'] = $media_id; + + return $this->sendKefuMsg(); + } + + /** + * @param $media_id + * @return Result + * @throws \Exception + */ + public function sendMpNewsNews(string $media_id) + { + $this->msgData['msgtype'] = 'mpnews'; + $this->msgData['mpnews[media_id]'] = $media_id; + + return $this->sendKefuMsg(); + } + + + /** + * @param string $title + * @param string $description + * @param string $url + * @param string $picurl + * @return Result + * @throws \Exception + */ + public function sendNewsNews(string $title, string $description, string $url, string $picurl) + { + $this->msgData['msgtype'] = 'news'; + $this->msgData['news[articles][0][title]'] = $title; + $this->msgData['news[articles][0][description]'] = $description; + $this->msgData['news[articles][0][url]'] = $url; + $this->msgData['news[articles][0][picurl]'] = $picurl; + + return $this->sendKefuMsg(); + } + + + /** + * @param string $title + * @return Result + * @throws \Exception + */ + public function sendCardNews(string $title) + { + $this->msgData['msgtype'] = 'wxcard'; + $this->msgData['wxcard[card_id]'] = $title; + + return $this->sendKefuMsg(); + } + + + /** + * @param string $media_id + * @param string $thumb_media_id + * @param string $title + * @param string $description + * @return Result + * @throws \Exception + */ + public function sendVideoNews(string $media_id, string $thumb_media_id, string $title, string $description) + { + $this->msgData['msgtype'] = 'video'; + $this->msgData['video[media_id]'] = $media_id; + $this->msgData['video[thumb_media_id]'] = $thumb_media_id; + $this->msgData['video[title]'] = $title; + $this->msgData['video[description]'] = $description; + + return $this->sendKefuMsg(); + } + + + /** + * @param string $musicurl + * @param string $hqmusicurl + * @param string $thumb_media_id + * @param string $title + * @param string $description + * @return Result + * @throws \Exception + */ + public function sendMusicNews(string $musicurl, string $hqmusicurl, string $thumb_media_id, string $title, string $description) + { + $this->msgData['msgtype'] = 'music'; + $this->msgData['music[title]'] = $title; + $this->msgData['music[description]'] = $description; + $this->msgData['music[musicurl]'] = $musicurl; + $this->msgData['music[hqmusicurl]'] = $hqmusicurl; + $this->msgData['music[thumb_media_id]'] = $thumb_media_id; + + return $this->sendKefuMsg(); + } + + + /** + * @param string $head_content + * @param string $tail_content + * @param array $menus + * @return Result + * @throws \Exception + */ + public function sendMenuNews(string $head_content, string $tail_content, array $menus = []) + { + $this->msgData['msgtype'] = 'msgmenu'; + $this->msgData['msgmenu[head_content]'] = $head_content; + $this->msgData['msgmenu[tail_content]'] = $tail_content; + + if (empty($menus) || !is_array($menus) || count($menus) < 2) { + throw new \Exception('菜单选项必须有2个'); + } + + foreach ($menus as $key => $val) { + $this->addNewsMenu($val['id'], $val['name']); + } + + return $this->sendKefuMsg(); + } + + private $index = 0; + + /** + * @param $id + * @param $menuName + * @return $this + */ + public function addNewsMenu($id, $menuName) + { + $this->msgData['msgmenu[list][' . $this->index . '][id]'] = $id; + $this->msgData['msgmenu[list][' . $this->index . '][content]'] = $menuName; + + ++$this->index; + + return $this; + } + + /** + * @param $title + * @param $appid + * @param $pagepath + * @param $thumb_media_id + * @return Result + * @throws \Exception + */ + public function sendMiniprogrampageNews(string $title, string $appid, string $pagepath, string $thumb_media_id) + { + $this->msgData['msgtype'] = 'msgmenu'; + $this->msgData['miniprogrampage[title]'] = $title; + $this->msgData['miniprogrampage[appid]'] = $appid; + $this->msgData['miniprogrampage[pagepath]'] = $pagepath; + $this->msgData['miniprogrampage[thumb_media_id]'] = $thumb_media_id; + + return $this->sendKefuMsg(); + } + + /** + * @param string $filePath + * @param string $type + * @param bool $isPermanent + * @param string $title + * @param string $introduction + * @return mixed + * @throws \Exception + */ + public function upload(string $filePath, string $type, $isPermanent = false, string $title = '', string $introduction = '') + { + if (!file_exists($filePath)) { + throw new \Exception('文件不存在'); + } + + if (!in_array($type, ['image', 'voice', 'video', 'thumb'])) { + throw new \Exception('暂不支持的文件类型'); + } + + $token = $this->getAccessToken(); + if ($isPermanent) { + $url = "https://api.weixin.qq.com/cgi-bin/material/add_material?access_token={$token}&type={$type}"; + } else { + $url = "https://api.weixin.qq.com/cgi-bin/media/upload?access_token={$token}&type={$type}"; + } + + $mime = mime_content_type($filePath); + + $real_path = new \CURLFile(realpath($filePath)); + + $data = array("media" => $real_path, 'form-data[filename]' => $filePath, 'form-data[content-type]' => $mime); + if ($isPermanent && $mime == 'video/mp3') { + $data = ['media' => $real_path, 'description[title]' => $title, 'description[introduction]' => $introduction]; + } + + $this->request->setMethod(WxClient::POST); + + /** @var Result $body */ + $data = $this->request->post($url, $data); + if (!$data->isResultsOK()) { + throw new \Exception($data->getMessage()); + } + + return $data->getData(); + } + + /** + * @param $mime + * @throws \Exception + */ + private function checkExtinfo($mime) + { + switch (strtolower($mime)) { + case 'image/bmp': + case 'image/png': + case 'image/jpeg': + case 'image/jpg': + case 'image/gif': + break; + case 'mp3/wma/wav/amr': + break; + case 'mp4'; + break; + case 'jpg'; + break; + default: + throw new \Exception('不支持的文件格式'); + } + } + + /** + * @param $data + * @return Result + * @throws \Exception + */ + private function sendKefuMsg() + { + $data = json_encode($this->msgData, JSON_UNESCAPED_UNICODE); + + $url = '/cgi-bin/message/custom/send?access_token=' . $this->getAccessToken(); + $this->request->setMethod(WxClient::POST); + + /** @var Result $body */ + $body = $this->request->post($url, $data); + + if (!$body->isResultsOK()) { + throw new \Exception($body->getMessage()); + } + return $body; + } +} diff --git a/qq/Notify.php b/qq/Notify.php new file mode 100644 index 0000000..1e624e4 --- /dev/null +++ b/qq/Notify.php @@ -0,0 +1,600 @@ +getReturnCode() != "SUCCESS") { + return false; + } + + if ($this->getResultCode() != 'SUCCESS') { + return false; + } + + return true; + } + + /** + * @param array $params + * @return $this + */ + public function setPayNotifyData(array $params) + { + if (!$this->validation($params)) { + $this->setResultCode('FAIL'); + $this->setErrCodeDes('签名错误'); + unset($params['result_code'], $params['err_code_des']); + } + foreach ($params as $key => $val) { + if (!property_exists($this, $key)) { + continue; + } + $this->$key = $val; + } + return $this; + } + + + /** + * @param array $params + * @return bool + */ + public function validation(array $params) + { + $sign = $params['sign']; + unset($params['sign']); + + $signType = $this->config->getSignType(); + $privateKey = $this->config->getKey(); + $nowSign = Help::sign($params, $privateKey, $signType); + if ($sign === $nowSign) { + return true; + } + return false; + } + + /** + * @return mixed + */ + public function getAppid() + { + return $this->appid; + } + + /** + * @param mixed $appid + * @return Notify + */ + public function setAppid($appid) + { + $this->appid = $appid; + return $this; + } + + /** + * @return mixed + */ + public function getMchId() + { + return $this->mch_id; + } + + /** + * @param mixed $mch_id + * @return Notify + */ + public function setMchId($mch_id) + { + $this->mch_id = $mch_id; + return $this; + } + + /** + * @return mixed + */ + public function getDeviceInfo() + { + return $this->device_info; + } + + /** + * @param mixed $device_info + * @return Notify + */ + public function setDeviceInfo($device_info) + { + $this->device_info = $device_info; + return $this; + } + + /** + * @return mixed + */ + public function getNonceStr() + { + return $this->nonce_str; + } + + /** + * @param mixed $nonce_str + * @return Notify + */ + public function setNonceStr($nonce_str) + { + $this->nonce_str = $nonce_str; + return $this; + } + + /** + * @return mixed + */ + public function getSign() + { + return $this->sign; + } + + /** + * @param mixed $sign + * @return Notify + */ + public function setSign($sign) + { + $this->sign = $sign; + return $this; + } + + /** + * @return mixed + */ + public function getSignType() + { + return $this->sign_type; + } + + /** + * @param mixed $sign_type + * @return Notify + */ + public function setSignType($sign_type) + { + $this->sign_type = $sign_type; + return $this; + } + + /** + * @return mixed + */ + public function getResultCode() + { + return $this->result_code; + } + + /** + * @param mixed $result_code + * @return Notify + */ + public function setResultCode($result_code) + { + $this->result_code = $result_code; + return $this; + } + + /** + * @return mixed + */ + public function getErrCode() + { + return $this->err_code; + } + + /** + * @param mixed $err_code + * @return Notify + */ + public function setErrCode($err_code) + { + $this->err_code = $err_code; + return $this; + } + + /** + * @return mixed + */ + public function getErrCodeDes() + { + return $this->err_code_des; + } + + /** + * @param mixed $err_code_des + * @return Notify + */ + public function setErrCodeDes($err_code_des) + { + $this->err_code_des = $err_code_des; + return $this; + } + + /** + * @return mixed + */ + public function getOpenid() + { + return $this->openid; + } + + /** + * @param mixed $openid + * @return Notify + */ + public function setOpenid($openid) + { + $this->openid = $openid; + return $this; + } + + /** + * @return mixed + */ + public function getIsSubscribe() + { + return $this->is_subscribe; + } + + /** + * @param mixed $is_subscribe + * @return Notify + */ + public function setIsSubscribe($is_subscribe) + { + $this->is_subscribe = $is_subscribe; + return $this; + } + + /** + * @return mixed + */ + public function getTradeType() + { + return $this->trade_type; + } + + /** + * @param mixed $trade_type + * @return Notify + */ + public function setTradeType($trade_type) + { + $this->trade_type = $trade_type; + return $this; + } + + /** + * @return mixed + */ + public function getBankType() + { + return $this->bank_type; + } + + /** + * @param mixed $bank_type + * @return Notify + */ + public function setBankType($bank_type) + { + $this->bank_type = $bank_type; + return $this; + } + + /** + * @return mixed + */ + public function getTotalFee() + { + return $this->total_fee; + } + + /** + * @param mixed $total_fee + * @return Notify + */ + public function setTotalFee($total_fee) + { + $this->total_fee = $total_fee; + return $this; + } + + /** + * @return mixed + */ + public function getSettlementTotalFee() + { + return $this->settlement_total_fee; + } + + /** + * @param mixed $settlement_total_fee + * @return Notify + */ + public function setSettlementTotalFee($settlement_total_fee) + { + $this->settlement_total_fee = $settlement_total_fee; + return $this; + } + + /** + * @return mixed + */ + public function getFeeType() + { + return $this->fee_type; + } + + /** + * @param mixed $fee_type + * @return Notify + */ + public function setFeeType($fee_type) + { + $this->fee_type = $fee_type; + return $this; + } + + /** + * @return mixed + */ + public function getCashFee() + { + return $this->cash_fee; + } + + /** + * @param mixed $cash_fee + * @return Notify + */ + public function setCashFee($cash_fee) + { + $this->cash_fee = $cash_fee; + return $this; + } + + /** + * @return mixed + */ + public function getCashFeeType() + { + return $this->cash_fee_type; + } + + /** + * @param mixed $cash_fee_type + * @return Notify + */ + public function setCashFeeType($cash_fee_type) + { + $this->cash_fee_type = $cash_fee_type; + return $this; + } + + /** + * @return mixed + */ + public function getCouponFee() + { + return $this->coupon_fee; + } + + /** + * @param mixed $coupon_fee + * @return Notify + */ + public function setCouponFee($coupon_fee) + { + $this->coupon_fee = $coupon_fee; + return $this; + } + + /** + * @return mixed + */ + public function getCouponCount() + { + return $this->coupon_count; + } + + /** + * @param mixed $coupon_count + * @return Notify + */ + public function setCouponCount($coupon_count) + { + $this->coupon_count = $coupon_count; + return $this; + } + + /** + * @return mixed + */ + public function getCouponTypeN() + { + return $this->coupon_type_n; + } + + /** + * @param mixed $coupon_type_n + * @return Notify + */ + public function setCouponTypeN($coupon_type_n) + { + $this->coupon_type_n = $coupon_type_n; + return $this; + } + + /** + * @return mixed + */ + public function getCouponIdN() + { + return $this->coupon_id_n; + } + + /** + * @param mixed $coupon_id_n + * @return Notify + */ + public function setCouponIdN($coupon_id_n) + { + $this->coupon_id_n = $coupon_id_n; + return $this; + } + + /** + * @return mixed + */ + public function getCouponFeeN() + { + return $this->coupon_fee_n; + } + + /** + * @param mixed $coupon_fee_n + * @return Notify + */ + public function setCouponFeeN($coupon_fee_n) + { + $this->coupon_fee_n = $coupon_fee_n; + return $this; + } + + /** + * @return mixed + */ + public function getTransactionId() + { + return $this->transaction_id; + } + + /** + * @param mixed $transaction_id + * @return Notify + */ + public function setTransactionId($transaction_id) + { + $this->transaction_id = $transaction_id; + return $this; + } + + /** + * @return mixed + */ + public function getOutTradeNo() + { + return $this->out_trade_no; + } + + /** + * @param mixed $out_trade_no + * @return Notify + */ + public function setOutTradeNo($out_trade_no) + { + $this->out_trade_no = $out_trade_no; + return $this; + } + + /** + * @return mixed + */ + public function getAttach() + { + return $this->attach; + } + + /** + * @param mixed $attach + * @return Notify + */ + public function setAttach($attach) + { + $this->attach = $attach; + return $this; + } + + /** + * @return mixed + */ + public function getTimeEnd() + { + return $this->time_end; + } + + /** + * @param mixed $time_end + * @return Notify + */ + public function setTimeEnd($time_end) + { + $this->time_end = $time_end; + return $this; + } + + /** + * @return mixed + */ + public function getReturnCode() + { + return $this->return_code; + } + + /** + * @param mixed $return_code + * @return Notify + */ + public function setReturnCode($return_code) + { + $this->return_code = $return_code; + return $this; + } + +} diff --git a/qq/PublicTemplate.php b/qq/PublicTemplate.php new file mode 100644 index 0000000..7044d30 --- /dev/null +++ b/qq/PublicTemplate.php @@ -0,0 +1,157 @@ +keywords = $keywords; + } + + /** + * @param string $templateId + */ + public function setTemplateId(string $templateId) + { + $this->templateId = $templateId; + } + + /** + * @param string $openId + */ + public function setOpenId(string $openId) + { + $this->openId = $openId; + } + + /** + * @param string $defaultUrl + */ + public function setDefaultUrl(string $defaultUrl) + { + $this->defaultUrl = $defaultUrl; + } + + /** + * @param $name + * @param $context + * @param string $color + */ + public function replaceKeyword($name, $context, $color = '') + { + $this->keywords[$name] = ['value' => $context, 'color' => $color]; + } + + + /** + * @param $name + * @param $context + * @param null $color + */ + public function addKeyword($name, $context, $color = null) + { + if (empty($color)) { + $color = '#000'; + } + $this->keywords[$name] = [ + 'value' => $context, + 'color' => $color + ]; + } + + /** + * @param $context + * @param string $color + */ + public function setFirst($context, $color = '#f00') + { + $this->first = [ + 'value' => $context, + 'color' => $color + ]; + } + + /** + * @param $context + * @param string $color + */ + public function setRemark($context, $color = '#000') + { + $this->remark = [ + 'value' => $context, + 'color' => $color + ]; + } + + /** + * @param $appid + * @param $pagepath + */ + public function setMiniprogram($appid, $pagepath) + { + $this->miniprogram = [ + 'appid' => $appid, + 'pagepath' => $pagepath + ]; + } + + /** + * @return Result + * @throws \Exception + * + * 奴隶交易通知 + */ + public function sendTemplate() + { + $url = $this->sendUrl . '?access_token=' . $this->getAccessToken(); + + $keywords = $this->keywords; + $keywords['first'] = $this->first; + $keywords['remark'] = $this->remark; + + $default = [ + "touser" => $this->openId, + "template_id" => $this->templateId, + "url" => $this->defaultUrl, + "data" => $keywords, + ]; + + if (!empty($this->miniprogram)) { + $default['miniprogram'] = $this->miniprogram; + } + + $params = json_encode($default, JSON_UNESCAPED_UNICODE); + + $this->request->setIsSSL(true); + $this->request->addHeader('content-type', 'application/json'); + + $result = $this->request->post($url, $params); + $result->append('postBody', $params); + + return $result; + } +} diff --git a/qq/Recharge.php b/qq/Recharge.php new file mode 100644 index 0000000..e83e723 --- /dev/null +++ b/qq/Recharge.php @@ -0,0 +1,182 @@ + 500, 'message' => '充值金额不能小于0.']); + } + $this->money = $money; + $this->orderNo = $orderNo; + $this->data['openid'] = $openId; + + $config = $this->config; + $this->request->setCallback(function ($result, $body) use ($config) { + $data = Help::toArray($result); + if (isset($data['sign'])) { + $sign = $data['sign']; + unset($data['sign']); + } + $return = []; + $_sign = Help::sign($data, $config->getKey(), $config->getSignType()); + if (!isset($sign) || $sign != $_sign) { + $return['code'] = -1; + $return['message'] = $data['return_msg'] ?? '返回数据签名验证失败'; + } else { + $return['code'] = 0; + $return['data'] = $data; + $return['data']['postBody'] = $body; + if ($data['return_code'] == 'FAIL') { + $return['code'] = -1; + $return['message'] = $data['return_msg']; + } + } + return $return; + }); + return $this->send($this->unifiedorder, $this->builder()); + } + + /** + * 'appId' => $result['appid'], + * 'nonceStr' => $result['nonce_str'], + * 'package' => 'prepay_id=' . $result['prepay_id'], + * 'signType' => 'MD5', + * 'timeStamp' => (string)time(), + * @param $prepay_id + * @return array + */ + public function reception($prepay_id) + { + $array = [ + 'appId' => $this->config->getAppid(), + 'nonceStr' => Help::random(32), + 'package' => 'prepay_id=' . $prepay_id, + 'signType' => 'MD5', + 'timeStamp' => (string)time(), + ]; + $key = $this->config->getKey(); + $sign_type = $this->config->getSignType(); + $array['paySign'] = Help::sign($array, $key, $sign_type); + $array['appId'] = $this->config->getAppid(); + return $array; + } + + /** + * @return string + */ + protected function builder() + { + $data = [ + 'appid' => $this->config->getAppid(), + 'mch_id' => $this->config->getMchId(), + 'nonce_str' => Help::random(32), + 'body' => $this->config->getBody(), + 'out_trade_no' => $this->orderNo, + 'total_fee' => $this->money, + 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], + 'notify_url' => $this->config->getNotifyUrl(), + 'trade_type' => $this->config->getTradeType(), + ]; + + $this->data = array_merge($data, $this->data); + + $key = $this->config->getKey(); + $sign_type = $this->config->getSignType(); + + $this->data['sign_type'] = $this->config->getSignType(); + $this->data['sign'] = Help::sign($this->data, $key, $sign_type); + + return Help::toXml($this->data); + } + + public function getSignData() + { + $data = $this->data; + $data['key'] = $this->config->getKey(); + return $data; + } + + /** + * @param $money + * @param $openid + * @param $order + * @param $desc + * @return Result + * @throws + * + * 提现 + */ + public function cashWithdrawal($money, $openid, $order, $desc = '零钱提现') + { + $array = [ + 'nonce_str' => Help::random(32), + 'partner_trade_no' => $order, + 'mchid' => $this->config->getMchId(), + 'mch_appid' => $this->config->getAppid(), + 'openid' => $openid, + 'check_name' => 'NO_CHECK', + 'amount' => $money * 100, + 'spbill_create_ip' => $this->config->getRemoteAddr(), + 'desc' => $desc, + ]; + + $key = $this->config->getKey(); + $sign_type = $this->config->getSignType(); + $array['sign'] = Help::sign($array, $key, $sign_type); + + $this->request->setCallback(function ($data) { + $array = Help::toArray($data); + if ($array['result_code'] != 'SUCCESS') { + $data = ['code' => $array['err_code'], 'message' => $array['err_code_des']]; + } else { + $data = ['code' => 0, 'message' => '支付成功']; + } + return new Result($data); + }); + return $this->send($this->transfers, Help::toXml($array)); + } + + /** + * @param $url + * @param $data + * @return array|mixed|Result + * @throws \Exception + */ + private function send($url, $data) + { + $this->request->setIsSSL(true); + $this->request->setMethod(WxClient::POST); + $this->request->addHeader('Content-Type', 'text/xml'); + return $this->request->send($url, $data); + } +} diff --git a/qq/Template.php b/qq/Template.php new file mode 100644 index 0000000..ef58ece --- /dev/null +++ b/qq/Template.php @@ -0,0 +1,155 @@ +keywords = $keywords; + } + + /** + * @param string $templateId + */ + public function setTemplateId(string $templateId) + { + $this->templateId = $templateId; + } + + /** + * @param string $formId + */ + public function setFormId(string $formId) + { + $this->formId = $formId; + } + + /** + * @param string $openId + */ + public function setOpenId(string $openId) + { + $this->openId = $openId; + } + + /** + * @param string $defaultUrl + */ + public function setDefaultUrl(string $defaultUrl) + { + $this->defaultUrl = $defaultUrl; + } + + /** + * @param string $page + */ + public function setPage(string $page) + { + $this->page = $page; + } + + /** + * @param string $emphasis_keyword + */ + public function setEmphasisKeyword(string $emphasis_keyword) + { + $this->emphasis_keyword = $emphasis_keyword; + } + + /** + * @param $index + * @param $context + * @param $color + */ + public function replaceKeyword($index, $context, $color = '') + { + if (empty($color)) { + $color = '#000'; + } + $this->keywords['keyword' . $index] = [ + 'value' => $context, + 'color' => $color + ]; + } + + + /** + * @param $color + * @param $context + */ + public function addKeyword($context, $color = null) + { + if (empty($color)) { + $color = '#000'; + } + $this->keywords['keyword' . (count($this->keywords) + 1)] = [ + 'value' => $context, + 'color' => $color + ]; + } + + /** + * @return Result + * @throws \Exception + * + * 奴隶交易通知 + */ + public function sendTemplate() + { + $url = $this->sendUrl . '?access_token=' . $this->config->getAccessToken(); + + $params = json_encode([ + "touser" => $this->openId, + "template_id" => $this->templateId, + "page" => $this->page, + "form_id" => $this->formId, + "data" => $this->keywords, + ], JSON_UNESCAPED_UNICODE); + + if (!empty($this->emphasis_keyword)) { + $params['emphasis_keyword'] = $this->emphasis_keyword; + } + + $this->request->setIsSSL(true); + $this->request->addHeader('content-type', 'application/json'); + + $result = $this->request->post($url, $params); + $result->append('postBody', $params); + + $this->openId = ''; + $this->keywords = []; + $this->formId = ''; + $this->templateId = ''; + $this->page = ''; + + return $result; + } +} diff --git a/qq/Token.php b/qq/Token.php new file mode 100644 index 0000000..b7c3070 --- /dev/null +++ b/qq/Token.php @@ -0,0 +1,32 @@ + 'client_credential', + 'appid' => $this->config->getAppid(), + 'secret' => $this->config->getAppsecret() + ]; + $param = $this->request->get($this->url, $query); + if (!$param->isResultsOK()) { + return null; + } + return $param->getData('access_token'); + } + +} diff --git a/qq/Wx.php b/qq/Wx.php new file mode 100644 index 0000000..202f969 --- /dev/null +++ b/qq/Wx.php @@ -0,0 +1,116 @@ +config; + } + + + /** + * @param Config $config + * @return $this + */ + public function setConfig(Config $config) + { + $this->config = $config; + return $this; + } + + /** + * @return Template + */ + public function getTemplate() + { + return Template::getInstance($this->config); + } + + + /** + * @return PublicTemplate + */ + public function getPublicTemplate() + { + return PublicTemplate::getInstance($this->config); + } + + /** + * @return Account + */ + public function getAccount() + { + return Account::getInstance($this->config); + } + + /** + * @return Message + */ + public function getMessage() + { + return Message::getInstance($this->config); + } + + /** + * @return Recharge + */ + public function getRecharge() + { + return Recharge::getInstance($this->config); + } + + /** + * @return Notify + */ + public function getNotify() + { + return Notify::getInstance($this->config); + } + + /** + * @return WxClient + */ + public function getClient() + { + $client = WxClient::getInstance(); + $client->setAgent($this->config->getAgent()); + return $client; + } + + + /** + * @return WxClient + */ + public function getAccessToken() + { + return Token::getInstance($this->config); + } + +} diff --git a/wx/Template.php b/wx/Template.php index 4eeff22..2f13aff 100644 --- a/wx/Template.php +++ b/wx/Template.php @@ -118,14 +118,13 @@ class Template extends Miniprogarampage */ public function sendTemplate() { - $url = $this->sendUrl . '?access_token=' . $this->getAccessToken(); - + $url = $this->sendUrl . '?access_token=' . $this->config->getAccessToken(); $params = json_encode([ - "touser" => $this->openId, + "touser" => $this->openId, "template_id" => $this->templateId, - "page" => $this->page, - "form_id" => $this->formId, - "data" => $this->keywords, + "page" => $this->page, + "form_id" => $this->formId, + "data" => $this->keywords, ], JSON_UNESCAPED_UNICODE); if (!empty($this->emphasis_keyword)) { diff --git a/wx/Token.php b/wx/Token.php new file mode 100644 index 0000000..ade606d --- /dev/null +++ b/wx/Token.php @@ -0,0 +1,31 @@ + 'client_credential', + 'appid' => $this->config->getAppid(), + 'secret' => $this->config->getAppsecret() + ]; + $param = $this->request->get($this->url, $query); + if (!$param->isResultsOK()) { + return null; + } + return $param->getData('access_token'); + } + + +} diff --git a/wx/Wx.php b/wx/Wx.php index 02d3dfd..f6b73d8 100644 --- a/wx/Wx.php +++ b/wx/Wx.php @@ -92,6 +92,15 @@ class Wx return Notify::getInstance($this->config); } + + /** + * @return Token + */ + public function getToken() + { + return Token::getInstance($this->config); + } + /** * @return WxClient */