├── .github └── workflows │ └── release.yml ├── .gitignore ├── AliPay ├── App.php ├── Bill.php ├── Pos.php ├── Scan.php ├── Trade.php ├── Transfer.php ├── Wap.php └── Web.php ├── We.php ├── WeChat ├── Card.php ├── Contracts │ ├── BasicAliPay.php │ ├── BasicPushEvent.php │ ├── BasicWeChat.php │ ├── BasicWePay.php │ ├── BasicWeWork.php │ ├── DataArray.php │ ├── DataError.php │ ├── MyCurlFile.php │ └── Tools.php ├── Custom.php ├── Draft.php ├── Exceptions │ ├── InvalidArgumentException.php │ ├── InvalidDecryptException.php │ ├── InvalidInstanceException.php │ ├── InvalidResponseException.php │ └── LocalCacheException.php ├── Freepublish.php ├── Limit.php ├── Media.php ├── Menu.php ├── Oauth.php ├── Pay.php ├── Product.php ├── Prpcrypt │ ├── ErrorCode.php │ ├── PKCS7Encoder.php │ └── Prpcrypt.php ├── Qrcode.php ├── Receive.php ├── Scan.php ├── Script.php ├── Shake.php ├── Tags.php ├── Template.php ├── User.php └── Wifi.php ├── WeMini ├── Crypt.php ├── Custom.php ├── Delivery.php ├── Guide.php ├── Image.php ├── Insurance.php ├── Live.php ├── Logistics.php ├── Market.php ├── Media.php ├── Message.php ├── Newtmpl.php ├── Ocr.php ├── Operation.php ├── Plugs.php ├── Poi.php ├── Qrcode.php ├── Scheme.php ├── Search.php ├── Security.php ├── Shipping.php ├── Shopping.php ├── Soter.php ├── Template.php ├── Total.php └── crypt │ ├── errorCode.php │ └── wxBizDataCrypt.php ├── WePay ├── Bill.php ├── Coupon.php ├── Custom.php ├── Order.php ├── ProfitSharing.php ├── Redpack.php ├── Refund.php ├── Transfers.php └── TransfersBank.php ├── WePayV3 ├── Cert.php ├── Complaints.php ├── Contracts │ ├── BasicWePay.php │ └── DecryptAes.php ├── Coupon.php ├── Ecommerce.php ├── Order.php ├── ProfitSharing.php ├── Refund.php └── Transfers.php ├── _test ├── alipay-app.php ├── alipay-bill.php ├── alipay-notify.php ├── alipay-pos.php ├── alipay-refund.php ├── alipay-scan.php ├── alipay-transfer-account.php ├── alipay-transfer-create.php ├── alipay-transfer-query.php ├── alipay-transfer.php ├── alipay-wap.php ├── alipay-web.php ├── alipay.php ├── alipay │ ├── alipayPublicCert.crt │ ├── alipayRootCert.crt │ └── appPublicCert.crt ├── alipay2.php ├── config.php ├── mini-login.php ├── mini-qrc.php ├── pay-config.php ├── pay-download-bill.php ├── pay-order-close.php ├── pay-order-create.php ├── pay-order-notify.php ├── pay-order-query.php ├── pay-redpack-create.php ├── pay-refund-create.php ├── pay-refund-query.php ├── pay-transfers-create.php ├── pay-transfersbank-create.php ├── pay-v3-config-cert.php ├── pay-v3-config.php ├── pay-v3-order-app.php ├── pay-v3-order-h5.php ├── pay-v3-order-jsapi.php ├── pay-v3-order-native.php ├── pay-v3-transfer.php ├── wechat-jssdk-sign.php ├── wechat-menu-get.php ├── wechat-qrcode-create.php ├── wechat-user-get.php ├── work-config.php └── work-department.php ├── composer.json ├── helper.php ├── include.php ├── license └── readme.md /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | on: 2 | push: 3 | # Sequence of patterns matched against refs/tags 4 | tags: 5 | - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 6 | 7 | name: Create Release 8 | permissions: write-all 9 | 10 | jobs: 11 | release: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout code 15 | uses: actions/checkout@v4 16 | with: 17 | fetch-depth: 0 18 | 19 | - name: Setup Node.js 20 | uses: actions/setup-node@v4 21 | with: 22 | node-version: 18 23 | 24 | - name: Install dependencies 25 | run: npm install -g gen-git-log 26 | 27 | - name: Find Last Tag 28 | id: last_tag 29 | run: | 30 | 31 | # 获取所有标签,按版本排序(降序) 32 | Tags=$(git tag --list --sort=-version:refname) 33 | 34 | # 获取最新的标签(即列表中的第一个) 35 | LATEST_TAG=$(echo "$Tags" | awk 'NR==1 {print $1; exit}') 36 | 37 | # 获取倒数第二个标签(如果存在) 38 | if [[ -n "$Tags" ]]; then 39 | # 使用 tail 获取除了最后一个标签之外的所有标签,然后用 head 获取第一个 40 | SECOND_LATEST_TAG=$(echo "$Tags" | tail -n +2 | head -n 1) 41 | else 42 | SECOND_LATEST_TAG="" 43 | fi 44 | 45 | # 设置输出变量 46 | echo "::set-output name=tag_last::${LATEST_TAG:-v1.0.0}" 47 | echo "::set-output name=tag_second::${SECOND_LATEST_TAG:-v1.0.0}" 48 | 49 | - name: Generate Release Notes 50 | run: | 51 | rm -rf log 52 | newTag=${{ steps.last_tag.outputs.tag_last }} 53 | git-log -m tag -f -S ${{ steps.last_tag.outputs.tag_second }} -v ${newTag#v} 54 | 55 | - name: Create Release 56 | id: create_release 57 | uses: actions/create-release@v1 58 | env: 59 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 60 | with: 61 | tag_name: ${{ steps.last_tag.outputs.tag_last }} 62 | release_name: Release ${{ steps.last_tag.outputs.tag_last }} 63 | body_path: log/${{steps.last_tag.outputs.tag_last}}.md 64 | draft: false 65 | prerelease: false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /.git 2 | /.idea 3 | /.DS_Store 4 | /vendor 5 | /Cache 6 | /Test/cert 7 | /nbproject 8 | /composer.lock 9 | /_test/cert -------------------------------------------------------------------------------- /AliPay/App.php: -------------------------------------------------------------------------------- 1 | options->set('method', 'alipay.trade.app.pay'); 37 | $this->params->set('product_code', 'QUICK_MSECURITY_PAY'); 38 | } 39 | 40 | /** 41 | * 创建数据操作 42 | * @param array $options 43 | * @return string 44 | */ 45 | public function apply($options) 46 | { 47 | $this->applyData($options); 48 | return http_build_query($this->options->get()); 49 | } 50 | } -------------------------------------------------------------------------------- /AliPay/Bill.php: -------------------------------------------------------------------------------- 1 | options->set('method', 'alipay.data.dataservice.bill.downloadurl.query'); 36 | } 37 | 38 | /** 39 | * 创建数据操作 40 | * @param array $options 41 | * @return array|bool 42 | * @throws \WeChat\Exceptions\InvalidResponseException 43 | * @throws \WeChat\Exceptions\LocalCacheException 44 | */ 45 | public function apply($options) 46 | { 47 | return $this->getResult($options); 48 | } 49 | } -------------------------------------------------------------------------------- /AliPay/Pos.php: -------------------------------------------------------------------------------- 1 | options->set('method', 'alipay.trade.pay'); 36 | $this->params->set('product_code', 'FACE_TO_FACE_PAYMENT'); 37 | } 38 | 39 | /** 40 | * 创建数据操作 41 | * @param array $options 42 | * @return array|bool 43 | * @throws \WeChat\Exceptions\InvalidResponseException 44 | * @throws \WeChat\Exceptions\LocalCacheException 45 | */ 46 | public function apply($options) 47 | { 48 | return $this->getResult($options); 49 | } 50 | } -------------------------------------------------------------------------------- /AliPay/Scan.php: -------------------------------------------------------------------------------- 1 | options->set('method', 'alipay.trade.precreate'); 36 | } 37 | 38 | /** 39 | * 创建数据操作 40 | * @param array $options 41 | * @return array|bool 42 | * @throws \WeChat\Exceptions\InvalidResponseException 43 | * @throws \WeChat\Exceptions\LocalCacheException 44 | */ 45 | public function apply($options) 46 | { 47 | return $this->getResult($options); 48 | } 49 | } -------------------------------------------------------------------------------- /AliPay/Trade.php: -------------------------------------------------------------------------------- 1 | options->set('method', $method); 37 | return $this; 38 | } 39 | 40 | /** 41 | * 获取交易接口地址 42 | * @return string 43 | */ 44 | public function getMethod() 45 | { 46 | return $this->options->get('method'); 47 | } 48 | 49 | /** 50 | * 设置接口公共参数 51 | * @param array $option 52 | * @return Trade 53 | */ 54 | public function setOption($option = []) 55 | { 56 | foreach ($option as $key => $vo) { 57 | $this->options->set($key, $vo); 58 | } 59 | return $this; 60 | } 61 | 62 | /** 63 | * 获取接口公共参数 64 | * @return array|string|null 65 | */ 66 | public function getOption() 67 | { 68 | return $this->options->get(); 69 | } 70 | 71 | /** 72 | * 执行通过接口 73 | * @param array $options 74 | * @return array|boolean 75 | * @throws \WeChat\Exceptions\InvalidResponseException 76 | * @throws \WeChat\Exceptions\LocalCacheException 77 | */ 78 | public function apply($options) 79 | { 80 | return $this->getResult($options); 81 | } 82 | } -------------------------------------------------------------------------------- /AliPay/Transfer.php: -------------------------------------------------------------------------------- 1 | options->set('method', 'alipay.fund.trans.toaccount.transfer'); 39 | return $this->getResult($options); 40 | } 41 | 42 | /** 43 | * 新版 向指定支付宝账户转账 44 | * @param array $options 45 | * @return array|bool 46 | * @throws \WeChat\Exceptions\InvalidResponseException 47 | * @throws \WeChat\Exceptions\LocalCacheException 48 | */ 49 | public function create($options = []) 50 | { 51 | $this->options->set('method', 'alipay.fund.trans.uni.transfer'); 52 | return $this->getResult($options); 53 | } 54 | 55 | /** 56 | * 新版 转账业务单据查询接口 57 | * @param array $options 58 | * @return array|bool 59 | * @throws \WeChat\Exceptions\InvalidResponseException 60 | * @throws \WeChat\Exceptions\LocalCacheException 61 | */ 62 | public function queryResult($options = []) 63 | { 64 | $this->options->set('method', 'alipay.fund.trans.common.query'); 65 | return $this->getResult($options); 66 | } 67 | 68 | /** 69 | * 新版 支付宝资金账户资产查询接口 70 | * @param array $options 71 | * @return array|bool 72 | * @throws \WeChat\Exceptions\InvalidResponseException 73 | * @throws \WeChat\Exceptions\LocalCacheException 74 | */ 75 | public function queryAccount($options = []) 76 | { 77 | $this->options->set('method', 'alipay.fund.account.query'); 78 | return $this->getResult($options); 79 | } 80 | } -------------------------------------------------------------------------------- /AliPay/Wap.php: -------------------------------------------------------------------------------- 1 | options->set('method', 'alipay.trade.wap.pay'); 36 | $this->params->set('product_code', 'QUICK_WAP_WAY'); 37 | } 38 | 39 | /** 40 | * 创建数据操作 41 | * @param array $options 42 | * @return string 43 | */ 44 | public function apply($options) 45 | { 46 | parent::applyData($options); 47 | return $this->buildPayHtml(); 48 | } 49 | } -------------------------------------------------------------------------------- /AliPay/Web.php: -------------------------------------------------------------------------------- 1 | options->set('method', 'alipay.trade.page.pay'); 36 | $this->params->set('product_code', 'FAST_INSTANT_TRADE_PAY'); 37 | } 38 | 39 | /** 40 | * 创建数据操作 41 | * @param array $options 42 | * @return string 43 | */ 44 | public function apply($options) 45 | { 46 | parent::applyData($options); 47 | return $this->buildPayHtml(); 48 | } 49 | } -------------------------------------------------------------------------------- /WeChat/Contracts/BasicWeWork.php: -------------------------------------------------------------------------------- 1 | access_token) return $this->access_token; 35 | $ckey = $this->config->get('appid') . '_access_token'; 36 | if ($this->access_token = Tools::getCache($ckey)) return $this->access_token; 37 | list($appid, $secret) = [$this->config->get('appid'), $this->config->get('appsecret')]; 38 | $result = Tools::json2arr(Tools::get("https://qyapi.weixin.qq.com/cgi-bin/gettoken?corpid={$appid}&corpsecret={$secret}")); 39 | if (isset($result['access_token']) && $result['access_token']) Tools::setCache($ckey, $result['access_token'], 7000); 40 | return $this->access_token = $result['access_token']; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /WeChat/Contracts/DataArray.php: -------------------------------------------------------------------------------- 1 | config = $options; 41 | } 42 | 43 | /** 44 | * 设置配置项值 45 | * @param string $offset 46 | * @param string|array|null|integer $value 47 | */ 48 | public function set($offset, $value) 49 | { 50 | $this->offsetSet($offset, $value); 51 | } 52 | 53 | /** 54 | * 获取配置项参数 55 | * @param string|null $offset 56 | * @return array|string|null|mixed 57 | */ 58 | public function get($offset = null) 59 | { 60 | return $this->offsetGet($offset); 61 | } 62 | 63 | /** 64 | * 合并数据到对象 65 | * @param array $data 需要合并的数据 66 | * @param bool $append 是否追加数据 67 | * @return array 68 | */ 69 | public function merge(array $data, $append = false) 70 | { 71 | if ($append) { 72 | return $this->config = array_merge($this->config, $data); 73 | } 74 | return array_merge($this->config, $data); 75 | } 76 | 77 | /** 78 | * 设置配置项值 79 | * @param string $offset 80 | * @param string|array|null|integer $value 81 | * @return void 82 | */ 83 | #[\ReturnTypeWillChange] 84 | public function offsetSet($offset, $value) 85 | { 86 | if (is_null($offset)) { 87 | $this->config[] = $value; 88 | } else { 89 | $this->config[$offset] = $value; 90 | } 91 | } 92 | 93 | /** 94 | * 判断配置Key是否存在 95 | * @param string $offset 96 | * @return bool 97 | */ 98 | #[\ReturnTypeWillChange] 99 | public function offsetExists($offset) 100 | { 101 | return isset($this->config[$offset]); 102 | } 103 | 104 | /** 105 | * 清理配置项 106 | * @param string|null $offset 107 | * @return void 108 | */ 109 | #[\ReturnTypeWillChange] 110 | public function offsetUnset($offset = null) 111 | { 112 | if (is_null($offset)) { 113 | $this->config = []; 114 | } else { 115 | unset($this->config[$offset]); 116 | } 117 | } 118 | 119 | /** 120 | * 获取配置项参数 121 | * @param string|null $offset 122 | * @return mixed 123 | */ 124 | #[\ReturnTypeWillChange] 125 | public function offsetGet($offset = null) 126 | { 127 | if (is_null($offset)) return $this->config; 128 | return isset($this->config[$offset]) ? $this->config[$offset] : null; 129 | } 130 | } -------------------------------------------------------------------------------- /WeChat/Contracts/MyCurlFile.php: -------------------------------------------------------------------------------- 1 | $v) $this->{$k} = $v; 43 | } else { 44 | $this->mimetype = $mimetype; 45 | $this->postname = $postname; 46 | $this->extension = pathinfo($filename, PATHINFO_EXTENSION); 47 | if (empty($this->extension)) $this->extension = 'tmp'; 48 | if (empty($this->mimetype)) $this->mimetype = Tools::getExtMine($this->extension); 49 | if (empty($this->postname)) $this->postname = pathinfo($filename, PATHINFO_BASENAME); 50 | $this->content = base64_encode(file_get_contents($filename)); 51 | $this->tempname = md5($this->content) . ".{$this->extension}"; 52 | } 53 | } 54 | 55 | /** 56 | * 获取文件上传信息 57 | * @return \CURLFile|string 58 | * @throws \WeChat\Exceptions\LocalCacheException 59 | */ 60 | public function get() 61 | { 62 | $this->filename = Tools::pushFile($this->tempname, base64_decode($this->content)); 63 | if (class_exists('CURLFile')) { 64 | return new \CURLFile($this->filename, $this->mimetype, $this->postname); 65 | } else { 66 | return "@{$this->tempname};filename={$this->postname};type={$this->mimetype}"; 67 | } 68 | } 69 | 70 | /** 71 | * 通用销毁函数清理缓存文件 72 | * 提前删除过期因此放到了网络请求之后 73 | */ 74 | public function __destruct() 75 | { 76 | // Tools::delCache($this->tempname); 77 | } 78 | 79 | } -------------------------------------------------------------------------------- /WeChat/Exceptions/InvalidArgumentException.php: -------------------------------------------------------------------------------- 1 | raw = $raw; 41 | } 42 | } -------------------------------------------------------------------------------- /WeChat/Exceptions/InvalidDecryptException.php: -------------------------------------------------------------------------------- 1 | raw = $raw; 41 | } 42 | } -------------------------------------------------------------------------------- /WeChat/Exceptions/InvalidInstanceException.php: -------------------------------------------------------------------------------- 1 | raw = $raw; 41 | } 42 | } -------------------------------------------------------------------------------- /WeChat/Exceptions/InvalidResponseException.php: -------------------------------------------------------------------------------- 1 | raw = $raw; 41 | } 42 | 43 | } -------------------------------------------------------------------------------- /WeChat/Exceptions/LocalCacheException.php: -------------------------------------------------------------------------------- 1 | raw = $raw; 42 | } 43 | 44 | } -------------------------------------------------------------------------------- /WeChat/Freepublish.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, ['media_id' => $mediaId]); 41 | } 42 | 43 | /** 44 | * 发布状态轮询接口 45 | * @param mixed $publishId 46 | * @return array 47 | * @throws \WeChat\Exceptions\InvalidResponseException 48 | * @throws \WeChat\Exceptions\LocalCacheException 49 | */ 50 | public function get($publishId) 51 | { 52 | $url = "https://api.weixin.qq.com/cgi-bin/freepublish/get?access_token=ACCESS_TOKEN"; 53 | return $this->callPostApi($url, ['publish_id' => $publishId]); 54 | } 55 | 56 | /** 57 | * 删除发布 58 | * 发布成功之后,随时可以通过该接口删除。此操作不可逆,请谨慎操作。 59 | * @param mixed $articleId 成功发布时返回的 article_id 60 | * @param int $index 要删除的文章在图文消息中的位置,第一篇编号为1,该字段不填或填0会删除全部文章 61 | * @return array 62 | * @throws \WeChat\Exceptions\InvalidResponseException 63 | * @throws \WeChat\Exceptions\LocalCacheException 64 | */ 65 | public function delete($articleId, $index = 0) 66 | { 67 | $url = "https://api.weixin.qq.com/cgi-bin/freepublish/delete?access_token=ACCESS_TOKEN"; 68 | return $this->callPostApi($url, ['article_id' => $articleId, 'index' => $index]); 69 | } 70 | 71 | /** 72 | * 通过 article_id 获取已发布文章 73 | * @param mixed $articleId 要获取的草稿的article_id 74 | * @return array 75 | * @throws \WeChat\Exceptions\InvalidResponseException 76 | * @throws \WeChat\Exceptions\LocalCacheException 77 | */ 78 | public function getArticle($articleId) 79 | { 80 | $url = "https://api.weixin.qq.com/cgi-bin/freepublish/getarticle?access_token=ACCESS_TOKEN"; 81 | return $this->callPostApi($url, ['article_id' => $articleId]); 82 | } 83 | 84 | /** 85 | * 获取成功发布列表 86 | * @param int $offset 从全部素材的该偏移位置开始返回,0表示从第一个素材返回 87 | * @param int $count 返回素材的数量,取值在1到20之间 88 | * @param int $noContent 1 表示不返回 content 字段,0 表示正常返回,默认为 0 89 | * @return array 90 | * @throws \WeChat\Exceptions\InvalidResponseException 91 | * @throws \WeChat\Exceptions\LocalCacheException 92 | */ 93 | public function batchGet($offset = 0, $count = 20, $noContent = 0) 94 | { 95 | $url = "https://api.weixin.qq.com/cgi-bin/freepublish/batchget?access_token=ACCESS_TOKEN"; 96 | return $this->callPostApi($url, ['no_content' => $noContent, 'offset' => $offset, 'count' => $count]); 97 | } 98 | } -------------------------------------------------------------------------------- /WeChat/Limit.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, ['appid' => $this->config->get('appid')]); 39 | } 40 | 41 | /** 42 | * 网络检测 43 | * @param string $action 执行的检测动作 44 | * @param string $operator 指定平台从某个运营商进行检测 45 | * @return array 46 | * @throws \WeChat\Exceptions\InvalidResponseException 47 | * @throws \WeChat\Exceptions\LocalCacheException 48 | */ 49 | public function ping($action = 'all', $operator = 'DEFAULT') 50 | { 51 | $url = 'https://api.weixin.qq.com/cgi-bin/callback/check?access_token=ACCESS_TOKEN'; 52 | return $this->callPostApi($url, ['action' => $action, 'check_operator' => $operator]); 53 | } 54 | 55 | /** 56 | * 获取微信服务器IP地址 57 | * @return array 58 | * @throws \WeChat\Exceptions\InvalidResponseException 59 | * @throws \WeChat\Exceptions\LocalCacheException 60 | */ 61 | public function getCallbackIp() 62 | { 63 | $url = 'https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=ACCESS_TOKEN'; 64 | return $this->callGetApi($url); 65 | } 66 | } -------------------------------------------------------------------------------- /WeChat/Menu.php: -------------------------------------------------------------------------------- 1 | callGetApi($url); 39 | } 40 | 41 | /** 42 | * 自定义菜单删除接口 43 | * @return array 44 | * @throws \WeChat\Exceptions\InvalidResponseException 45 | * @throws \WeChat\Exceptions\LocalCacheException 46 | */ 47 | public function delete() 48 | { 49 | $url = "https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=ACCESS_TOKEN"; 50 | return $this->callGetApi($url); 51 | } 52 | 53 | /** 54 | * 自定义菜单创建 55 | * @param array $data 56 | * @return array 57 | * @throws \WeChat\Exceptions\InvalidResponseException 58 | * @throws \WeChat\Exceptions\LocalCacheException 59 | */ 60 | public function create(array $data) 61 | { 62 | $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=ACCESS_TOKEN"; 63 | return $this->callPostApi($url, $data); 64 | } 65 | 66 | /** 67 | * 创建个性化菜单 68 | * @param array $data 69 | * @return array 70 | * @throws \WeChat\Exceptions\InvalidResponseException 71 | * @throws \WeChat\Exceptions\LocalCacheException 72 | */ 73 | public function addConditional(array $data) 74 | { 75 | $url = "https://api.weixin.qq.com/cgi-bin/menu/addconditional?access_token=ACCESS_TOKEN"; 76 | return $this->callPostApi($url, $data); 77 | } 78 | 79 | /** 80 | * 删除个性化菜单 81 | * @param string $menuid 82 | * @return array 83 | * @throws \WeChat\Exceptions\InvalidResponseException 84 | * @throws \WeChat\Exceptions\LocalCacheException 85 | */ 86 | public function delConditional($menuid) 87 | { 88 | $url = "https://api.weixin.qq.com/cgi-bin/menu/delconditional?access_token=ACCESS_TOKEN"; 89 | return $this->callPostApi($url, ['menuid' => $menuid]); 90 | } 91 | 92 | /** 93 | * 测试个性化菜单匹配结果 94 | * @param string $openid 95 | * @return array 96 | * @throws \WeChat\Exceptions\InvalidResponseException 97 | * @throws \WeChat\Exceptions\LocalCacheException 98 | */ 99 | public function tryConditional($openid) 100 | { 101 | $url = "https://api.weixin.qq.com/cgi-bin/menu/trymatch?access_token=ACCESS_TOKEN"; 102 | return $this->callPostApi($url, ['user_id' => $openid]); 103 | } 104 | } -------------------------------------------------------------------------------- /WeChat/Oauth.php: -------------------------------------------------------------------------------- 1 | config->get('appid'); 39 | $redirect_uri = urlencode($redirect_url); 40 | return "https://open.weixin.qq.com/connect/oauth2/authorize?appid={$appid}&redirect_uri={$redirect_uri}&response_type=code&scope={$scope}&state={$state}#wechat_redirect"; 41 | } 42 | 43 | /** 44 | * 通过 code 获取 AccessToken 和 openid 45 | * @param string $code 授权Code值,不传则取GET参数 46 | * @return array 47 | * @throws \WeChat\Exceptions\InvalidResponseException 48 | * @throws \WeChat\Exceptions\LocalCacheException 49 | */ 50 | public function getOauthAccessToken($code = '') 51 | { 52 | $appid = $this->config->get('appid'); 53 | $appsecret = $this->config->get('appsecret'); 54 | $code = $code ? $code : (isset($_GET['code']) ? $_GET['code'] : ''); 55 | $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$appsecret}&code={$code}&grant_type=authorization_code"; 56 | return $this->httpGetForJson($url); 57 | } 58 | 59 | /** 60 | * 刷新AccessToken并续期 61 | * @param string $refresh_token 62 | * @return array 63 | * @throws \WeChat\Exceptions\InvalidResponseException 64 | * @throws \WeChat\Exceptions\LocalCacheException 65 | */ 66 | public function getOauthRefreshToken($refresh_token) 67 | { 68 | $appid = $this->config->get('appid'); 69 | $url = "https://api.weixin.qq.com/sns/oauth2/refresh_token?appid={$appid}&grant_type=refresh_token&refresh_token={$refresh_token}"; 70 | return $this->httpGetForJson($url); 71 | } 72 | 73 | /** 74 | * 检验授权凭证(access_token)是否有效 75 | * @param string $accessToken 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 76 | * @param string $openid 用户的唯一标识 77 | * @return array 78 | * @throws \WeChat\Exceptions\InvalidResponseException 79 | * @throws \WeChat\Exceptions\LocalCacheException 80 | */ 81 | public function checkOauthAccessToken($accessToken, $openid) 82 | { 83 | $url = "https://api.weixin.qq.com/sns/auth?access_token={$accessToken}&openid={$openid}"; 84 | return $this->httpGetForJson($url); 85 | } 86 | 87 | /** 88 | * 拉取用户信息(需scope为 snsapi_userinfo) 89 | * @param string $accessToken 网页授权接口调用凭证,注意:此access_token与基础支持的access_token不同 90 | * @param string $openid 用户的唯一标识 91 | * @param string $lang 返回国家地区语言版本,zh_CN 简体,zh_TW 繁体,en 英语 92 | * @return array 93 | * @throws \WeChat\Exceptions\InvalidResponseException 94 | * @throws \WeChat\Exceptions\LocalCacheException 95 | */ 96 | public function getUserInfo($accessToken, $openid, $lang = 'zh_CN') 97 | { 98 | $url = "https://api.weixin.qq.com/sns/userinfo?access_token={$accessToken}&openid={$openid}&lang={$lang}"; 99 | return $this->httpGetForJson($url); 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /WeChat/Prpcrypt/ErrorCode.php: -------------------------------------------------------------------------------- 1 | '处理成功', 27 | '40001' => '校验签名失败', 28 | '40002' => '解析xml失败', 29 | '40003' => '计算签名失败', 30 | '40004' => '不合法的AESKey', 31 | '40005' => '校验AppID失败', 32 | '40006' => 'AES加密失败', 33 | '40007' => 'AES解密失败', 34 | '40008' => '公众平台发送的xml不合法', 35 | '40009' => 'Base64编码失败', 36 | '40010' => 'Base64解码失败', 37 | '40011' => '公众帐号生成回包xml失败', 38 | ]; 39 | 40 | /** 41 | * 获取错误消息内容 42 | * @param string $code 错误代码 43 | * @return bool 44 | */ 45 | public static function getErrText($code) 46 | { 47 | if (isset(self::$errCode[$code])) { 48 | return self::$errCode[$code]; 49 | } 50 | return false; 51 | } 52 | 53 | } -------------------------------------------------------------------------------- /WeChat/Prpcrypt/PKCS7Encoder.php: -------------------------------------------------------------------------------- 1 | PKCS7Encoder::$blockSize) { 41 | $pad = 0; 42 | } 43 | return substr($text, 0, strlen($text) - $pad); 44 | } 45 | 46 | } -------------------------------------------------------------------------------- /WeChat/Prpcrypt/Prpcrypt.php: -------------------------------------------------------------------------------- 1 | key = base64_decode("{$key}="); 33 | } 34 | 35 | /** 36 | * 对明文进行加密 37 | * @param string $text 需要加密的明文 38 | * @param string $appid 公众号APPID 39 | * @return array 40 | */ 41 | public function encrypt($text, $appid) 42 | { 43 | try { 44 | $random = $this->getRandomStr(); 45 | $iv = substr($this->key, 0, 16); 46 | $pkcEncoder = new PKCS7Encoder(); 47 | $text = $pkcEncoder->encode($random . pack("N", strlen($text)) . $text . $appid); 48 | $encrypted = openssl_encrypt($text, 'AES-256-CBC', substr($this->key, 0, 32), OPENSSL_ZERO_PADDING, $iv); 49 | return [ErrorCode::$OK, $encrypted]; 50 | } catch (\Exception $e) { 51 | return [ErrorCode::$EncryptAESError, null]; 52 | } 53 | } 54 | 55 | /** 56 | * 对密文进行解密 57 | * @param string $encrypted 需要解密的密文 58 | * @return array 59 | */ 60 | public function decrypt($encrypted) 61 | { 62 | try { 63 | $iv = substr($this->key, 0, 16); 64 | $decrypted = openssl_decrypt($encrypted, 'AES-256-CBC', substr($this->key, 0, 32), OPENSSL_ZERO_PADDING, $iv); 65 | } catch (\Exception $e) { 66 | return [ErrorCode::$DecryptAESError, null]; 67 | } 68 | try { 69 | $pkcEncoder = new PKCS7Encoder(); 70 | $result = $pkcEncoder->decode($decrypted); 71 | if (strlen($result) < 16) { 72 | return [ErrorCode::$DecryptAESError, null]; 73 | } 74 | $content = substr($result, 16, strlen($result)); 75 | $len_list = unpack("N", substr($content, 0, 4)); 76 | $xml_len = $len_list[1]; 77 | return [0, substr($content, 4, $xml_len), substr($content, $xml_len + 4)]; 78 | } catch (\Exception $e) { 79 | return [ErrorCode::$IllegalBuffer, null]; 80 | } 81 | } 82 | 83 | /** 84 | * 随机生成16位字符串 85 | * @param string $str 86 | * @return string 生成的字符串 87 | */ 88 | function getRandomStr($str = "") 89 | { 90 | $str_pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz"; 91 | $max = strlen($str_pol) - 1; 92 | for ($i = 0; $i < 16; $i++) { 93 | $str .= $str_pol[mt_rand(0, $max)]; 94 | } 95 | return $str; 96 | } 97 | 98 | } 99 | -------------------------------------------------------------------------------- /WeChat/Qrcode.php: -------------------------------------------------------------------------------- 1 | ['scene' => ['scene_id' => $scene]]]; 41 | } else { 42 | $data = ['action_info' => ['scene' => ['scene_str' => $scene]]]; 43 | } 44 | if ($expire_seconds > 0) { // 临时二维码 45 | $data['expire_seconds'] = $expire_seconds; 46 | $data['action_name'] = is_integer($scene) ? 'QR_SCENE' : 'QR_STR_SCENE'; 47 | } else { // 永久二维码 48 | $data['action_name'] = is_integer($scene) ? 'QR_LIMIT_SCENE' : 'QR_LIMIT_STR_SCENE'; 49 | } 50 | $url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=ACCESS_TOKEN"; 51 | return $this->callPostApi($url, $data); 52 | } 53 | 54 | /** 55 | * 通过ticket换取二维码 56 | * @param string $ticket 获取的二维码ticket,凭借此ticket可以在有效时间内换取二维码。 57 | * @return string 58 | */ 59 | public function url($ticket) 60 | { 61 | return "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=" . urlencode($ticket); 62 | } 63 | 64 | /** 65 | * 长链接转短链接接口 66 | * @param string $longUrl 需要转换的长链接 67 | * @return array 68 | * @throws \WeChat\Exceptions\InvalidResponseException 69 | * @throws \WeChat\Exceptions\LocalCacheException 70 | */ 71 | public function shortUrl($longUrl) 72 | { 73 | $url = "https://api.weixin.qq.com/cgi-bin/shorturl?access_token=ACCESS_TOKEN"; 74 | return $this->callPostApi($url, ['action' => 'long2short', 'long_url' => $longUrl]); 75 | } 76 | } -------------------------------------------------------------------------------- /WeChat/Tags.php: -------------------------------------------------------------------------------- 1 | callGetApi($url); 37 | } 38 | 39 | /** 40 | * 创建粉丝标签 41 | * @param string $name 42 | * @return array 43 | * @throws Exceptions\InvalidResponseException 44 | * @throws Exceptions\LocalCacheException 45 | */ 46 | public function createTags($name) 47 | { 48 | $url = "https://api.weixin.qq.com/cgi-bin/tags/create?access_token=ACCESS_TOKEN"; 49 | return $this->callPostApi($url, ['tag' => ['name' => $name]]); 50 | } 51 | 52 | /** 53 | * 更新粉丝标签 54 | * @param integer $id 标签ID 55 | * @param string $name 标签名称 56 | * @return array 57 | * @throws Exceptions\InvalidResponseException 58 | * @throws Exceptions\LocalCacheException 59 | */ 60 | public function updateTags($id, $name) 61 | { 62 | $url = "https://api.weixin.qq.com/cgi-bin/tags/update?access_token=ACCESS_TOKEN"; 63 | return $this->callPostApi($url, ['tag' => ['name' => $name, 'id' => $id]]); 64 | } 65 | 66 | /** 67 | * 删除粉丝标签 68 | * @param int $tagId 69 | * @return array 70 | * @throws Exceptions\InvalidResponseException 71 | * @throws Exceptions\LocalCacheException 72 | */ 73 | public function deleteTags($tagId) 74 | { 75 | $url = 'https://api.weixin.qq.com/cgi-bin/tags/delete?access_token=ACCESS_TOKEN'; 76 | return $this->callPostApi($url, ['tag' => ['id' => $tagId]]); 77 | } 78 | 79 | /** 80 | * 批量为用户打标签 81 | * @param array $openids 82 | * @param integer $tagId 83 | * @return array 84 | * @throws Exceptions\InvalidResponseException 85 | * @throws Exceptions\LocalCacheException 86 | */ 87 | public function batchTagging(array $openids, $tagId) 88 | { 89 | $url = 'https://api.weixin.qq.com/cgi-bin/tags/members/batchtagging?access_token=ACCESS_TOKEN'; 90 | return $this->callPostApi($url, ['openid_list' => $openids, 'tagid' => $tagId]); 91 | } 92 | 93 | /** 94 | * 批量为用户取消标签 95 | * @param array $openids 96 | * @param integer $tagId 97 | * @return array 98 | * @throws Exceptions\InvalidResponseException 99 | * @throws Exceptions\LocalCacheException 100 | */ 101 | public function batchUntagging(array $openids, $tagId) 102 | { 103 | $url = 'https://api.weixin.qq.com/cgi-bin/tags/members/batchuntagging?access_token=ACCESS_TOKEN'; 104 | return $this->callPostApi($url, ['openid_list' => $openids, 'tagid' => $tagId]); 105 | } 106 | 107 | /** 108 | * 获取用户身上的标签列表 109 | * @param string $openid 110 | * @return array 111 | * @throws Exceptions\InvalidResponseException 112 | * @throws Exceptions\LocalCacheException 113 | */ 114 | public function getUserTagId($openid) 115 | { 116 | $url = 'https://api.weixin.qq.com/cgi-bin/tags/getidlist?access_token=ACCESS_TOKEN'; 117 | return $this->callPostApi($url, ['openid' => $openid]); 118 | } 119 | } -------------------------------------------------------------------------------- /WeChat/Template.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, ['industry_id1' => $industryId1, 'industry_id2' => $industryId2]); 40 | } 41 | 42 | /** 43 | * 获取设置的行业信息 44 | * @return array 45 | * @throws Exceptions\InvalidResponseException 46 | * @throws Exceptions\LocalCacheException 47 | */ 48 | public function getIndustry() 49 | { 50 | $url = "https://api.weixin.qq.com/cgi-bin/template/get_industry?access_token=ACCESS_TOKEN"; 51 | return $this->callGetApi($url); 52 | } 53 | 54 | /** 55 | * 获得模板ID 56 | * @param string $templateIdShort 板库中模板的编号,有“TM**”和“OPENTMTM**”等形式 57 | * @param array $keywordNameList 选用的类目模板的关键词 58 | * @return array 59 | * @throws Exceptions\InvalidResponseException 60 | * @throws Exceptions\LocalCacheException 61 | */ 62 | public function addTemplate($templateIdShort, $keywordNameList = []) 63 | { 64 | $url = "https://api.weixin.qq.com/cgi-bin/template/api_add_template?access_token=ACCESS_TOKEN"; 65 | return $this->callPostApi($url, ['template_id_short' => $templateIdShort, 'keyword_name_list' => $keywordNameList]); 66 | } 67 | 68 | /** 69 | * 获取模板列表 70 | * @return array 71 | * @throws Exceptions\InvalidResponseException 72 | * @throws Exceptions\LocalCacheException 73 | */ 74 | public function getAllPrivateTemplate() 75 | { 76 | $url = "https://api.weixin.qq.com/cgi-bin/template/get_all_private_template?access_token=ACCESS_TOKEN"; 77 | return $this->callGetApi($url); 78 | } 79 | 80 | /** 81 | * 删除模板ID 82 | * @param string $tplId 公众帐号下模板消息ID 83 | * @return array 84 | * @throws Exceptions\InvalidResponseException 85 | * @throws Exceptions\LocalCacheException 86 | */ 87 | public function delPrivateTemplate($tplId) 88 | { 89 | $url = "https://api.weixin.qq.com/cgi-bin/template/del_private_template?access_token=ACCESS_TOKEN"; 90 | return $this->callPostApi($url, ['template_id' => $tplId]); 91 | } 92 | 93 | /** 94 | * 发送模板消息 95 | * @param array $data 96 | * @return array 97 | * @throws Exceptions\InvalidResponseException 98 | * @throws Exceptions\LocalCacheException 99 | */ 100 | public function send(array $data) 101 | { 102 | $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=ACCESS_TOKEN"; 103 | return $this->callPostApi($url, $data); 104 | } 105 | } -------------------------------------------------------------------------------- /WeMini/Image.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, ['img_url' => $img_url, 'img' => $img], true); 41 | } 42 | 43 | /** 44 | * 本接口提供基于小程序的条码/二维码识别的API 45 | * @param string $img_url 要检测的图片 url,传这个则不用传 img 参数。 46 | * @param string $img form-data 中媒体文件标识,有filename、filelength、content-type等信息,传这个则不用穿 img_url 47 | * @return array 48 | * @throws \WeChat\Exceptions\InvalidResponseException 49 | * @throws \WeChat\Exceptions\LocalCacheException 50 | */ 51 | public function scanQRCode($img_url, $img) 52 | { 53 | $url = "https://api.weixin.qq.com/cv/img/qrcode?img_url=ENCODE_URL&access_token=ACCESS_TOKEN"; 54 | return $this->callPostApi($url, ['img_url' => $img_url, 'img' => $img], true); 55 | } 56 | 57 | /** 58 | * 本接口提供基于小程序的图片高清化能力 59 | * @param string $img_url 要检测的图片 url,传这个则不用传 img 参数 60 | * @param string $img form-data 中媒体文件标识,有filename、filelength、content-type等信息,传这个则不用穿 img_url 61 | * @return array 62 | * @throws \WeChat\Exceptions\InvalidResponseException 63 | * @throws \WeChat\Exceptions\LocalCacheException 64 | */ 65 | public function superresolution($img_url, $img) 66 | { 67 | $url = "https://api.weixin.qq.com/cv/img/qrcode?img_url=ENCODE_URL&access_token=ACCESS_TOKEN"; 68 | return $this->callPostApi($url, ['img_url' => $img_url, 'img' => $img], true); 69 | } 70 | } -------------------------------------------------------------------------------- /WeMini/Market.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $data, true); 39 | } 40 | 41 | /** 42 | * 获取服务市场返回的数据 43 | * @param array $data 44 | * @return array 45 | * @throws \WeChat\Exceptions\InvalidResponseException 46 | * @throws \WeChat\Exceptions\LocalCacheException 47 | */ 48 | public function retrieve($data) 49 | { 50 | $url = 'https://api.weixin.qq.com/wxa/servicemarketretrieve?access_token=ACCESS_TOKEN'; 51 | return $this->callPostApi($url, $data, true); 52 | } 53 | 54 | 55 | } -------------------------------------------------------------------------------- /WeMini/Media.php: -------------------------------------------------------------------------------- 1 | callGetApi($url); 41 | } 42 | 43 | /** 44 | * 新增图片素材 45 | * @param array $data 46 | * @return array 47 | * @throws \WeChat\Exceptions\InvalidResponseException 48 | * @throws \WeChat\Exceptions\LocalCacheException 49 | */ 50 | public function upload($filename) 51 | { 52 | $url = 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=image'; 53 | return $this->callPostApi($url, ['media' => Tools::createCurlFile($filename)], false); 54 | } 55 | } -------------------------------------------------------------------------------- /WeMini/Message.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $data, true); 39 | } 40 | 41 | /** 42 | * 动态消息,修改被分享的动态消息 43 | * @param array $data 44 | * @return array 45 | * @throws \WeChat\Exceptions\InvalidResponseException 46 | * @throws \WeChat\Exceptions\LocalCacheException 47 | */ 48 | public function setUpdatableMsg($data) 49 | { 50 | $url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/updatablemsg/send?access_token=ACCESS_TOKEN'; 51 | return $this->callPostApi($url, $data, true); 52 | } 53 | 54 | /** 55 | * 下发小程序和公众号统一的服务消息 56 | * @param array $data 57 | * @return array 58 | * @throws \WeChat\Exceptions\InvalidResponseException 59 | * @throws \WeChat\Exceptions\LocalCacheException 60 | */ 61 | public function uniformSend($data) 62 | { 63 | $url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/uniform_send?access_token=ACCESS_TOKEN'; 64 | return $this->callPostApi($url, $data, true); 65 | } 66 | } -------------------------------------------------------------------------------- /WeMini/Ocr.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $data, false); 39 | } 40 | 41 | /** 42 | * 本接口提供基于小程序的营业执照 OCR 识别 43 | * @param array $data 44 | * @return array 45 | * @throws \WeChat\Exceptions\InvalidResponseException 46 | * @throws \WeChat\Exceptions\LocalCacheException 47 | */ 48 | public function businessLicense($data) 49 | { 50 | $url = 'https://api.weixin.qq.com/cv/ocr/bizlicense?access_token=ACCESS_TOKEN'; 51 | return $this->callPostApi($url, $data, false); 52 | } 53 | 54 | /** 55 | * 本接口提供基于小程序的驾驶证 OCR 识别 56 | * @param array $data 57 | * @return array 58 | * @throws \WeChat\Exceptions\InvalidResponseException 59 | * @throws \WeChat\Exceptions\LocalCacheException 60 | */ 61 | public function driverLicense($data) 62 | { 63 | $url = 'https://api.weixin.qq.com/cv/ocr/drivinglicense?access_token=ACCESS_TOKEN'; 64 | return $this->callPostApi($url, $data, false); 65 | } 66 | 67 | /** 68 | * 本接口提供基于小程序的身份证 OCR 识别 69 | * @param array $data 70 | * @return array 71 | * @throws \WeChat\Exceptions\InvalidResponseException 72 | * @throws \WeChat\Exceptions\LocalCacheException 73 | */ 74 | public function idcard($data) 75 | { 76 | $url = 'https://api.weixin.qq.com/cv/ocr/idcard?access_token=ACCESS_TOKEN'; 77 | return $this->callPostApi($url, $data, false); 78 | } 79 | 80 | /** 81 | * 本接口提供基于小程序的通用印刷体 OCR 识别 82 | * @param array $data 83 | * @return array 84 | * @throws \WeChat\Exceptions\InvalidResponseException 85 | * @throws \WeChat\Exceptions\LocalCacheException 86 | */ 87 | public function printedText($data) 88 | { 89 | $url = 'https://api.weixin.qq.com/cv/ocr/comm?access_token=ACCESS_TOKEN'; 90 | return $this->callPostApi($url, $data, false); 91 | } 92 | 93 | /** 94 | * 本接口提供基于小程序的行驶证 OCR 识别 95 | * @param array $data 96 | * @return array 97 | * @throws \WeChat\Exceptions\InvalidResponseException 98 | * @throws \WeChat\Exceptions\LocalCacheException 99 | */ 100 | public function vehicleLicense($data) 101 | { 102 | $url = 'https://api.weixin.qq.com/cv/ocr/driving?access_token=ACCESS_TOKEN'; 103 | return $this->callPostApi($url, $data, false); 104 | } 105 | } -------------------------------------------------------------------------------- /WeMini/Operation.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $data, true); 40 | } 41 | 42 | /** 43 | * 获取 mediaId 图片 44 | * @param array $data 45 | * @return array 46 | * @throws \WeChat\Exceptions\InvalidResponseException 47 | * @throws \WeChat\Exceptions\LocalCacheException 48 | */ 49 | public function getFeedbackmedia($data) 50 | { 51 | $query = http_build_query($data); 52 | $url = 'https://api.weixin.qq.com/cgi-bin/media/getfeedbackmedia?'. $query .'&access_token=ACCESS_TOKEN'; 53 | return $this->callGetApi($url); 54 | } 55 | 56 | 57 | /** 58 | * 实时日志查询 59 | * @param array $data 60 | * @return array 61 | * @throws \WeChat\Exceptions\InvalidResponseException 62 | * @throws \WeChat\Exceptions\LocalCacheException 63 | */ 64 | public function getFeedback($data) 65 | { 66 | $query = http_build_query($data); 67 | $url = 'https://api.weixin.qq.com/wxaapi/userlog/userlog_search?'.$query.'&access_token=ACCESS_TOKEN'; 68 | return $this->callGetApi($url); 69 | } 70 | } -------------------------------------------------------------------------------- /WeMini/Plugs.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, ['action' => 'apply', 'plugin_appid' => $plugin_appid], true); 39 | } 40 | 41 | /** 42 | * 2.查询已添加的插件 43 | * @return array 44 | * @throws \WeChat\Exceptions\InvalidResponseException 45 | * @throws \WeChat\Exceptions\LocalCacheException 46 | */ 47 | public function getList() 48 | { 49 | $url = 'https://api.weixin.qq.com/wxa/plugin?access_token=ACCESS_TOKEN'; 50 | return $this->callPostApi($url, ['action' => 'list'], true); 51 | } 52 | 53 | /** 54 | * 3.删除已添加的插件 55 | * @param string $plugin_appid 插件appid 56 | * @return array 57 | * @throws \WeChat\Exceptions\InvalidResponseException 58 | * @throws \WeChat\Exceptions\LocalCacheException 59 | */ 60 | public function unbind($plugin_appid) 61 | { 62 | $url = 'https://api.weixin.qq.com/wxa/plugin?access_token=ACCESS_TOKEN'; 63 | return $this->callPostApi($url, ['action' => 'unbind', 'plugin_appid' => $plugin_appid], true); 64 | } 65 | 66 | /** 67 | * 获取当前所有插件使用方 68 | * 修改插件使用申请的状态 69 | * @param array $data 70 | * @return array 71 | * @throws \WeChat\Exceptions\InvalidResponseException 72 | * @throws \WeChat\Exceptions\LocalCacheException 73 | */ 74 | public function devplugin($data) 75 | { 76 | $url = 'https://api.weixin.qq.com/wxa/devplugin?access_token=ACCESS_TOKEN'; 77 | return $this->callPostApi($url, $data, true); 78 | } 79 | 80 | /** 81 | * 4.获取当前所有插件使用方(供插件开发者调用) 82 | * @param integer $page 拉取第page页的数据 83 | * @param integer $num 表示每页num条记录 84 | * @return array 85 | * @throws \WeChat\Exceptions\InvalidResponseException 86 | * @throws \WeChat\Exceptions\LocalCacheException 87 | */ 88 | public function devApplyList($page = 1, $num = 10) 89 | { 90 | $url = 'https://api.weixin.qq.com/wxa/plugin?access_token=ACCESS_TOKEN'; 91 | $data = ['action' => 'dev_apply_list', 'page' => $page, 'num' => $num]; 92 | return $this->callPostApi($url, $data, true); 93 | } 94 | 95 | /** 96 | * 5.修改插件使用申请的状态(供插件开发者调用) 97 | * @param string $action dev_agree:同意申请;dev_refuse:拒绝申请;dev_delete:删除已拒绝的申请者 98 | * @return array 99 | * @throws \WeChat\Exceptions\InvalidResponseException 100 | * @throws \WeChat\Exceptions\LocalCacheException 101 | */ 102 | public function devAgree($action = 'dev_agree') 103 | { 104 | $url = 'https://api.weixin.qq.com/wxa/plugin?access_token=ACCESS_TOKEN'; 105 | return $this->callPostApi($url, ['action' => $action], true); 106 | } 107 | } -------------------------------------------------------------------------------- /WeMini/Poi.php: -------------------------------------------------------------------------------- 1 | $related_name, 'related_credential' => $related_credential, 43 | 'related_address' => $related_address, 'related_proof_material' => $related_proof_material, 44 | ]; 45 | return $this->callPostApi($url, $data, true); 46 | } 47 | 48 | /** 49 | * 查看地点列表 50 | * @param integer $page 起始页id(从1开始计数) 51 | * @param integer $page_rows 每页展示个数(最多1000个) 52 | * @return array 53 | * @throws \WeChat\Exceptions\InvalidResponseException 54 | * @throws \WeChat\Exceptions\LocalCacheException 55 | */ 56 | public function getNearByPoiList($page = 1, $page_rows = 1000) 57 | { 58 | $url = "https://api.weixin.qq.com/wxa/getnearbypoilist?page={$page}&page_rows={$page_rows}&access_token=ACCESS_TOKEN"; 59 | return $this->callGetApi($url); 60 | } 61 | 62 | /** 63 | * 删除地点 64 | * @param string $poi_id 附近地点ID 65 | * @return array 66 | * @throws \WeChat\Exceptions\InvalidResponseException 67 | * @throws \WeChat\Exceptions\LocalCacheException 68 | */ 69 | public function delNearByPoiList($poi_id) 70 | { 71 | $url = "https://api.weixin.qq.com/wxa/delnearbypoi?access_token=ACCESS_TOKEN"; 72 | return $this->callPostApi($url, ['poi_id' => $poi_id], true); 73 | } 74 | 75 | /** 76 | * 展示/取消展示附近小程序 77 | * @param string $poi_id 附近地点ID 78 | * @param string $status 0:取消展示;1:展示 79 | * @return array 80 | * @throws \WeChat\Exceptions\InvalidResponseException 81 | * @throws \WeChat\Exceptions\LocalCacheException 82 | */ 83 | public function setNearByPoiShowStatus($poi_id, $status) 84 | { 85 | $url = "https://api.weixin.qq.com/wxa/setnearbypoishowstatus?access_token=ACCESS_TOKEN"; 86 | return $this->callPostApi($url, ['poi_id' => $poi_id, 'status' => $status], true); 87 | } 88 | } -------------------------------------------------------------------------------- /WeMini/Scheme.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $data, true); 40 | } 41 | 42 | /** 43 | * 查询 URL-Scheme 44 | * @param string $scheme 45 | * @return array 46 | * @throws \WeChat\Exceptions\InvalidResponseException 47 | * @throws \WeChat\Exceptions\LocalCacheException 48 | */ 49 | public function query($scheme) 50 | { 51 | $url = 'https://api.weixin.qq.com/wxa/queryscheme?access_token=ACCESS_TOKEN'; 52 | return $this->callPostApi($url, ['scheme' => $scheme], true); 53 | } 54 | 55 | /** 56 | * 创建 URL-Link 57 | * @param array $data 58 | * @return array 59 | * @throws \WeChat\Exceptions\InvalidResponseException 60 | * @throws \WeChat\Exceptions\LocalCacheException 61 | */ 62 | public function urlLink($data) 63 | { 64 | $url = "https://api.weixin.qq.com/wxa/generate_urllink?access_token=ACCESS_TOKEN"; 65 | return $this->callPostApi($url, $data, true); 66 | } 67 | 68 | /** 69 | * 查询 URL-Link 70 | * @param string $urllink 71 | * @return array 72 | * @throws \WeChat\Exceptions\InvalidResponseException 73 | * @throws \WeChat\Exceptions\LocalCacheException 74 | */ 75 | public function urlQuery($urllink) 76 | { 77 | $url = 'https://api.weixin.qq.com/wxa/query_urllink?access_token=ACCESS_TOKEN'; 78 | return $this->callPostApi($url, ['url_link' => $urllink], true); 79 | } 80 | } -------------------------------------------------------------------------------- /WeMini/Search.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, ['pages' => $pages], true); 39 | } 40 | } -------------------------------------------------------------------------------- /WeMini/Security.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, ['media' => $media], false, ['headers' => ['Content-Type: application/octet-stream']]); 40 | } 41 | 42 | /** 43 | * 异步校验图片/音频是否含有违法违规内容 44 | * @param string $media_url 45 | * @param string $media_type 46 | * @return array 47 | * @throws \WeChat\Exceptions\InvalidResponseException 48 | * @throws \WeChat\Exceptions\LocalCacheException 49 | */ 50 | public function mediaCheckAsync($media_url, $media_type) 51 | { 52 | $url = 'https://api.weixin.qq.com/wxa/media_check_async?access_token=ACCESS_TOKEN'; 53 | return $this->callPostApi($url, ['media_url' => $media_url, 'media_type' => $media_type], true); 54 | } 55 | 56 | /** 57 | * 检查一段文本是否含有违法违规内容 58 | * @param string $content 59 | * @return array 60 | * @throws \WeChat\Exceptions\InvalidResponseException 61 | * @throws \WeChat\Exceptions\LocalCacheException 62 | */ 63 | public function msgSecCheck($content) 64 | { 65 | $url = 'https://api.weixin.qq.com/wxa/msg_sec_check?access_token=ACCESS_TOKEN'; 66 | return $this->callPostApi($url, ['content' => $content], true); 67 | } 68 | } -------------------------------------------------------------------------------- /WeMini/Shipping.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $data, true); 26 | } 27 | 28 | /** 29 | * 发货信息合单录入接口 30 | * @param array $data 31 | * @return array 32 | * @throws \WeChat\Exceptions\InvalidResponseException 33 | * @throws \WeChat\Exceptions\LocalCacheException 34 | */ 35 | public function combined($data) 36 | { 37 | $url = 'https://api.weixin.qq.com/wxa/sec/order/upload_combined_shipping_info?access_token=ACCESS_TOKEN'; 38 | return $this->callPostApi($url, $data, true); 39 | } 40 | 41 | /** 42 | * 查询订单发货状态 43 | * @param array $data 44 | * @return array 45 | * @throws \WeChat\Exceptions\InvalidResponseException 46 | * @throws \WeChat\Exceptions\LocalCacheException 47 | */ 48 | public function query($data) 49 | { 50 | $url = 'https://api.weixin.qq.com/wxa/sec/order/get_order?access_token=ACCESS_TOKEN'; 51 | return $this->callPostApi($url, $data, true); 52 | } 53 | 54 | /** 55 | * 查询订单列表 56 | * @param array $data 57 | * @return array 58 | * @throws \WeChat\Exceptions\InvalidResponseException 59 | * @throws \WeChat\Exceptions\LocalCacheException 60 | */ 61 | public function qlist($data) 62 | { 63 | $url = 'https://api.weixin.qq.com/wxa/sec/order/get_order_list?access_token=ACCESS_TOKEN'; 64 | return $this->callPostApi($url, $data, true); 65 | } 66 | 67 | /** 68 | * 确认收货提醒接口 69 | * @param array $data 70 | * @return array 71 | * @throws \WeChat\Exceptions\InvalidResponseException 72 | * @throws \WeChat\Exceptions\LocalCacheException 73 | */ 74 | public function confirm($data) 75 | { 76 | $url = 'https://api.weixin.qq.com/wxa/sec/order/notify_confirm_receive?access_token=ACCESS_TOKEN'; 77 | return $this->callPostApi($url, $data, true); 78 | } 79 | 80 | /** 81 | * 消息跳转路径设置接口 82 | * @param array $data 83 | * @return array 84 | * @throws \WeChat\Exceptions\InvalidResponseException 85 | * @throws \WeChat\Exceptions\LocalCacheException 86 | */ 87 | public function setJump($data) 88 | { 89 | $url = 'https://api.weixin.qq.com/wxa/sec/order/set_msg_jump_path?access_token=ACCESS_TOKEN'; 90 | return $this->callPostApi($url, $data, true); 91 | } 92 | 93 | /** 94 | * 查询小程序是否已开通发货信息管理服务 95 | * @param array $data 96 | * @return array 97 | * @throws \WeChat\Exceptions\InvalidResponseException 98 | * @throws \WeChat\Exceptions\LocalCacheException 99 | */ 100 | public function isTrade($data) 101 | { 102 | $url = 'https://api.weixin.qq.com/wxa/sec/order/is_trade_managed?access_token=ACCESS_TOKEN'; 103 | return $this->callPostApi($url, $data, true); 104 | } 105 | 106 | /** 107 | * 查询小程序是否已完成交易结算管理确认 108 | * @param array $data 109 | * @return array 110 | * @throws \WeChat\Exceptions\InvalidResponseException 111 | * @throws \WeChat\Exceptions\LocalCacheException 112 | */ 113 | public function isCompleted($data) 114 | { 115 | $url = 'https://api.weixin.qq.com/wxa/sec/order/is_trade_management_confirmation_completed?access_token=ACCESS_TOKEN'; 116 | return $this->callPostApi($url, $data, true); 117 | } 118 | } -------------------------------------------------------------------------------- /WeMini/Shopping.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $data, true); 40 | } 41 | 42 | /** 43 | * 上传物流信息 44 | * @param array $data 45 | * @return array 46 | * @throws \WeChat\Exceptions\InvalidResponseException 47 | * @throws \WeChat\Exceptions\LocalCacheException 48 | */ 49 | public function uploadShippingInfo($data) 50 | { 51 | $url = 'https://api.weixin.qq.com/user-order/orders?access_token=ACCESS_TOKEN'; 52 | return $this->callPostApi($url, $data, true); 53 | } 54 | 55 | /** 56 | * 上传合单购物详情 57 | * @param array $data 58 | * @return array 59 | * @throws \WeChat\Exceptions\InvalidResponseException 60 | * @throws \WeChat\Exceptions\LocalCacheException 61 | */ 62 | public function uploadCombinedShoppingInfo($data) 63 | { 64 | $url = 'https://api.weixin.qq.com/user-order/orders?access_token=ACCESS_TOKEN'; 65 | return $this->callPostApi($url, $data, true); 66 | } 67 | 68 | /** 69 | * 上传合单物流信息 70 | * @param array $data 71 | * @return array 72 | * @throws \WeChat\Exceptions\InvalidResponseException 73 | * @throws \WeChat\Exceptions\LocalCacheException 74 | */ 75 | public function uploadCombinedShippingInfo($data) 76 | { 77 | $url = 'https://api.weixin.qq.com/user-order/orders?access_token=ACCESS_TOKEN'; 78 | return $this->callPostApi($url, $data, true); 79 | } 80 | 81 | /** 82 | * 验证购物订单上传结果 83 | * @param array $data 84 | * @return array 85 | * @throws \WeChat\Exceptions\InvalidResponseException 86 | * @throws \WeChat\Exceptions\LocalCacheException 87 | */ 88 | public function ShoppingInfoVerifyUploadResult($data) 89 | { 90 | $url = 'https://api.weixin.qq.com/user-order/shoppinginfo/verify?access_token=ACCESS_TOKEN'; 91 | return $this->callPostApi($url, $data, true); 92 | } 93 | 94 | 95 | } -------------------------------------------------------------------------------- /WeMini/Soter.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $data, true); 39 | } 40 | } -------------------------------------------------------------------------------- /WeMini/Template.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, ['offset' => '0', 'count' => '20'], true); 39 | } 40 | 41 | /** 42 | * 获取模板库某个模板标题下关键词库 43 | * @param string $template_id 模板标题id,可通过接口获取,也可登录小程序后台查看获取 44 | * @return array 45 | * @throws \WeChat\Exceptions\InvalidResponseException 46 | * @throws \WeChat\Exceptions\LocalCacheException 47 | */ 48 | public function getTemplateLibrary($template_id) 49 | { 50 | $url = 'https://api.weixin.qq.com/cgi-bin/wxopen/template/library/get?access_token=ACCESS_TOKEN'; 51 | return $this->callPostApi($url, ['id' => $template_id], true); 52 | } 53 | 54 | /** 55 | * 组合模板并添加至帐号下的个人模板库 56 | * @param string $template_id 模板标题id,可通过接口获取,也可登录小程序后台查看获取 57 | * @param array $keyword_id_list 开发者自行组合好的模板关键词列表,关键词顺序可以自由搭配(例如[3,5,4]或[4,5,3]),最多支持10个关键词组合 58 | * @return array 59 | * @throws \WeChat\Exceptions\InvalidResponseException 60 | * @throws \WeChat\Exceptions\LocalCacheException 61 | */ 62 | public function addTemplate($template_id, array $keyword_id_list) 63 | { 64 | $url = 'https://api.weixin.qq.com/cgi-bin/wxopen/template/add?access_token=ACCESS_TOKEN'; 65 | return $this->callPostApi($url, ['id' => $template_id, 'keyword_id_list' => $keyword_id_list], true); 66 | } 67 | 68 | /** 69 | * 获取帐号下已存在的模板列表 70 | * @return array 71 | * @throws \WeChat\Exceptions\InvalidResponseException 72 | * @throws \WeChat\Exceptions\LocalCacheException 73 | */ 74 | public function getTemplateList() 75 | { 76 | $url = 'https://api.weixin.qq.com/cgi-bin/wxopen/template/list?access_token=ACCESS_TOKEN'; 77 | return $this->callPostApi($url, ['offset' => '0', 'count' => '20'], true); 78 | } 79 | 80 | /** 81 | * 删除模板消息 82 | * @param string $template_id 要删除的模板id 83 | * @return array 84 | * @throws \WeChat\Exceptions\InvalidResponseException 85 | * @throws \WeChat\Exceptions\LocalCacheException 86 | */ 87 | public function delTemplate($template_id) 88 | { 89 | $url = 'https://api.weixin.qq.com/cgi-bin/wxopen/template/del?access_token=ACCESS_TOKEN'; 90 | return $this->callPostApi($url, ['template_id' => $template_id], true); 91 | } 92 | 93 | /** 94 | * 发送模板消息 95 | * @param array $data 发送的消息对象数组 96 | * @return array 97 | * @throws \WeChat\Exceptions\InvalidResponseException 98 | * @throws \WeChat\Exceptions\LocalCacheException 99 | */ 100 | public function send(array $data) 101 | { 102 | $url = 'https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=ACCESS_TOKEN'; 103 | return $this->callPostApi($url, $data, true); 104 | } 105 | } -------------------------------------------------------------------------------- /WeMini/crypt/errorCode.php: -------------------------------------------------------------------------------- 1 | 6 | *
  • -41001: encodingAesKey 非法
  • 7 | *
  • -41003: aes 解密失败
  • 8 | *
  • -41004: 解密后得到的buffer非法
  • 9 | *
  • -41005: base64加密失败
  • 10 | *
  • -41016: base64解密失败
  • 11 | * 12 | */ 13 | class ErrorCode 14 | { 15 | public static $OK = 0; 16 | public static $IllegalAesKey = -41001; 17 | public static $IllegalIv = -41002; 18 | public static $IllegalBuffer = -41003; 19 | public static $DecodeBase64Error = -41004; 20 | } -------------------------------------------------------------------------------- /WeMini/crypt/wxBizDataCrypt.php: -------------------------------------------------------------------------------- 1 | appid = $appid; 21 | $this->sessionKey = $sessionKey; 22 | include_once __DIR__ . DIRECTORY_SEPARATOR . "errorCode.php"; 23 | } 24 | 25 | /** 26 | * 检验数据的真实性,并且获取解密后的明文. 27 | * @param $encryptedData string 加密的用户数据 28 | * @param $iv string 与用户数据一同返回的初始向量 29 | * @param $data string 解密后的原文 30 | * 31 | * @return int 成功0,失败返回对应的错误码 32 | */ 33 | public function decryptData($encryptedData, $iv, &$data) 34 | { 35 | if (strlen($this->sessionKey) != 24) { 36 | return ErrorCode::$IllegalAesKey; 37 | } 38 | $aesKey = base64_decode($this->sessionKey); 39 | if (strlen($iv) != 24) { 40 | return ErrorCode::$IllegalIv; 41 | } 42 | $aesIV = base64_decode($iv); 43 | $aesCipher = base64_decode($encryptedData); 44 | $result = openssl_decrypt($aesCipher, "AES-128-CBC", $aesKey, 1, $aesIV); 45 | $dataObj = json_decode($result); 46 | if ($dataObj == null) { 47 | return ErrorCode::$IllegalBuffer; 48 | } 49 | // 兼容新版本无 watermark 的情况 50 | if (isset($dataObj->watermark) && $dataObj->watermark->appid != $this->appid) { 51 | return ErrorCode::$IllegalBuffer; 52 | } 53 | $data = $result; 54 | return ErrorCode::$OK; 55 | } 56 | 57 | } 58 | 59 | -------------------------------------------------------------------------------- /WePay/Bill.php: -------------------------------------------------------------------------------- 1 | params->set('sign_type', 'MD5'); 41 | $params = $this->params->merge($options); 42 | $params['sign'] = $this->getPaySign($params, 'MD5'); 43 | $result = Tools::post('https://api.mch.weixin.qq.com/pay/downloadbill', Tools::arr2xml($params)); 44 | if (is_array($jsonData = Tools::xml3arr($result))) { 45 | if ($jsonData['return_code'] !== 'SUCCESS') { 46 | throw new InvalidResponseException($jsonData['return_msg'], '0'); 47 | } 48 | } 49 | return is_null($outType) ? $result : $outType($result); 50 | } 51 | 52 | 53 | /** 54 | * 拉取订单评价数据 55 | * @param array $options 56 | * @return array 57 | * @throws \WeChat\Exceptions\InvalidResponseException 58 | * @throws \WeChat\Exceptions\LocalCacheException 59 | */ 60 | public function comment(array $options) 61 | { 62 | $url = 'https://api.mch.weixin.qq.com/billcommentsp/batchquerycomment'; 63 | return $this->callPostApi($url, $options, true); 64 | } 65 | } -------------------------------------------------------------------------------- /WePay/Coupon.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $options, true, 'MD5'); 39 | } 40 | 41 | /** 42 | * 查询代金券批次 43 | * @param array $options 44 | * @return array 45 | * @throws \WeChat\Exceptions\InvalidResponseException 46 | * @throws \WeChat\Exceptions\LocalCacheException 47 | */ 48 | public function queryStock(array $options) 49 | { 50 | $url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/query_coupon_stock"; 51 | return $this->callPostApi($url, $options, false); 52 | } 53 | 54 | /** 55 | * 查询代金券信息 56 | * @param array $options 57 | * @return array 58 | * @throws \WeChat\Exceptions\InvalidResponseException 59 | * @throws \WeChat\Exceptions\LocalCacheException 60 | */ 61 | public function queryInfo(array $options) 62 | { 63 | $url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/query_coupon_stock"; 64 | return $this->callPostApi($url, $options, false); 65 | } 66 | 67 | } -------------------------------------------------------------------------------- /WePay/Custom.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $options, false, 'MD5', false, false); 40 | } 41 | 42 | /** 43 | * 订单附加信息查询接口 44 | * @param array $options 45 | * @return array 46 | * @throws \WeChat\Exceptions\InvalidResponseException 47 | * @throws \WeChat\Exceptions\LocalCacheException 48 | */ 49 | public function get(array $options = []) 50 | { 51 | $url = 'https://api.mch.weixin.qq.com/cgi-bin/mch/customs/customdeclarequery'; 52 | return $this->callPostApi($url, $options, false, 'MD5', true, false); 53 | } 54 | 55 | 56 | /** 57 | * 订单附加信息重推接口 58 | * @param array $options 59 | * @return array 60 | * @throws \WeChat\Exceptions\InvalidResponseException 61 | * @throws \WeChat\Exceptions\LocalCacheException 62 | */ 63 | public function reset(array $options = []) 64 | { 65 | $url = 'https://api.mch.weixin.qq.com/cgi-bin/mch/newcustoms/customdeclareredeclare'; 66 | return $this->callPostApi($url, $options, false, 'MD5', true, false); 67 | } 68 | 69 | } -------------------------------------------------------------------------------- /WePay/Redpack.php: -------------------------------------------------------------------------------- 1 | params->offsetUnset('appid'); 39 | $this->params->set('wxappid', $this->config->get('appid')); 40 | $url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack"; 41 | return $this->callPostApi($url, $options, true, 'MD5', false); 42 | } 43 | 44 | /** 45 | * 发放裂变红包 46 | * @param array $options 47 | * @return array 48 | * @throws \WeChat\Exceptions\InvalidResponseException 49 | * @throws \WeChat\Exceptions\LocalCacheException 50 | */ 51 | public function groups(array $options) 52 | { 53 | $this->params->offsetUnset('appid'); 54 | $this->params->set('wxappid', $this->config->get('appid')); 55 | $url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack"; 56 | return $this->callPostApi($url, $options, true, 'MD5', false); 57 | } 58 | 59 | /** 60 | * 查询红包记录 61 | * @param string $mchBillno 商户发放红包的商户订单号 62 | * @return array 63 | * @throws \WeChat\Exceptions\InvalidResponseException 64 | * @throws \WeChat\Exceptions\LocalCacheException 65 | */ 66 | public function query($mchBillno) 67 | { 68 | $this->params->offsetUnset('wxappid'); 69 | $this->params->set('appid', $this->config->get('appid')); 70 | $url = "https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo"; 71 | return $this->callPostApi($url, ['mch_billno' => $mchBillno, 'bill_type' => 'MCHT'], true, 'MD5', false); 72 | } 73 | 74 | } -------------------------------------------------------------------------------- /WePay/Refund.php: -------------------------------------------------------------------------------- 1 | callPostApi($url, $options, true); 43 | } 44 | 45 | /** 46 | * 查询退款 47 | * @param array $options 48 | * @return array 49 | * @throws \WeChat\Exceptions\InvalidResponseException 50 | * @throws \WeChat\Exceptions\LocalCacheException 51 | */ 52 | public function query(array $options) 53 | { 54 | $url = 'https://api.mch.weixin.qq.com/pay/refundquery'; 55 | return $this->callPostApi($url, $options); 56 | } 57 | 58 | /** 59 | * 获取退款通知 60 | * @param string|array $xml 61 | * @return array 62 | * @throws \WeChat\Exceptions\InvalidDecryptException 63 | * @throws \WeChat\Exceptions\InvalidResponseException 64 | */ 65 | public function getNotify($xml = '') 66 | { 67 | $data = is_array($xml) ? $xml : Tools::xml2arr(empty($xml) ? Tools::getRawInput() : $xml); 68 | if (!isset($data['return_code']) || $data['return_code'] !== 'SUCCESS') { 69 | throw new InvalidResponseException('获取退款通知XML失败!'); 70 | } 71 | try { 72 | $key = md5($this->config->get('mch_key')); 73 | $decrypt = base64_decode($data['req_info']); 74 | $response = openssl_decrypt($decrypt, 'aes-256-ecb', $key, OPENSSL_RAW_DATA); 75 | $data['result'] = Tools::xml2arr($response); 76 | return $data; 77 | } catch (\Exception $exception) { 78 | throw new InvalidDecryptException($exception->getMessage(), $exception->getCode()); 79 | } 80 | } 81 | } -------------------------------------------------------------------------------- /WePay/Transfers.php: -------------------------------------------------------------------------------- 1 | params->offsetUnset('appid'); 39 | $this->params->offsetUnset('mch_id'); 40 | $this->params->set('mchid', $this->config->get('mch_id')); 41 | $this->params->set('mch_appid', $this->config->get('appid')); 42 | $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; 43 | return $this->callPostApi($url, $options, true, 'MD5', false); 44 | } 45 | 46 | /** 47 | * 查询企业付款到零钱 48 | * @param string $partnerTradeNo 商户调用企业付款API时使用的商户订单号 49 | * @return array 50 | * @throws \WeChat\Exceptions\InvalidResponseException 51 | * @throws \WeChat\Exceptions\LocalCacheException 52 | */ 53 | public function query($partnerTradeNo) 54 | { 55 | $this->params->offsetUnset('mchid'); 56 | $this->params->offsetUnset('mch_appid'); 57 | $this->params->set('appid', $this->config->get('appid')); 58 | $this->params->set('mch_id', $this->config->get('mch_id')); 59 | $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gettransferinfo'; 60 | return $this->callPostApi($url, ['partner_trade_no' => $partnerTradeNo], true, 'MD5', false); 61 | } 62 | 63 | } -------------------------------------------------------------------------------- /WePayV3/Cert.php: -------------------------------------------------------------------------------- 1 | doRequest('GET', '/v3/certificates'); 47 | if (empty($result['data']) && !empty($result['message'])) { 48 | throw new InvalidResponseException($result['message']); 49 | } 50 | $decrypt = new DecryptAes($this->config['mch_v3_key']); 51 | foreach ($result['data'] as $vo) { 52 | $certs[$vo['serial_no']] = [ 53 | 'expire' => strtotime($vo['expire_time']), 54 | 'serial' => $vo['serial_no'], 55 | 'content' => $decrypt->decryptToString( 56 | $vo['encrypt_certificate']['associated_data'], 57 | $vo['encrypt_certificate']['nonce'], 58 | $vo['encrypt_certificate']['ciphertext'] 59 | ) 60 | ]; 61 | } 62 | $this->tmpFile("{$this->config['mch_id']}_certs", $certs); 63 | } catch (\Exception $exception) { 64 | throw new InvalidResponseException($exception->getMessage(), $exception->getCode()); 65 | } 66 | } 67 | } -------------------------------------------------------------------------------- /WePayV3/Contracts/DecryptAes.php: -------------------------------------------------------------------------------- 1 | aesKey = $aesKey; 45 | } 46 | 47 | /** 48 | * Decrypt AEAD_AES_256_GCM ciphertext 49 | * @param string $associatedData AES GCM additional authentication data 50 | * @param string $nonceStr AES GCM nonce 51 | * @param string $ciphertext AES GCM cipher text 52 | * @return string|bool Decrypted string on success or FALSE on failure 53 | * @throws \WeChat\Exceptions\InvalidDecryptException 54 | */ 55 | public function decryptToString($associatedData, $nonceStr, $ciphertext) 56 | { 57 | $ciphertext = \base64_decode($ciphertext); 58 | if (strlen($ciphertext) <= self::AUTH_TAG_LENGTH_BYTE) { 59 | return false; 60 | } 61 | try { 62 | // ext-sodium (default installed on >= PHP 7.2) 63 | if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) { 64 | return \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey); 65 | } 66 | // ext-libsodium (need install libsodium-php 1.x via pecl) 67 | if (function_exists('\Sodium\crypto_aead_aes256gcm_is_available') && \Sodium\crypto_aead_aes256gcm_is_available()) { 68 | return \Sodium\crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, $this->aesKey); 69 | } 70 | // openssl (PHP >= 7.1 support AEAD) 71 | if (PHP_VERSION_ID >= 70100 && in_array('aes-256-gcm', \openssl_get_cipher_methods())) { 72 | $ctext = substr($ciphertext, 0, -self::AUTH_TAG_LENGTH_BYTE); 73 | $authTag = substr($ciphertext, -self::AUTH_TAG_LENGTH_BYTE); 74 | return \openssl_decrypt($ctext, 'aes-256-gcm', $this->aesKey, \OPENSSL_RAW_DATA, $nonceStr, $authTag, $associatedData); 75 | } 76 | } catch (\Exception $exception) { 77 | throw new InvalidDecryptException($exception->getMessage(), $exception->getCode()); 78 | } catch (\SodiumException $exception) { 79 | throw new InvalidDecryptException($exception->getMessage(), $exception->getCode()); 80 | } 81 | throw new InvalidDecryptException('AEAD_AES_256_GCM 需要 PHP 7.1 以上或者安装 libsodium-php'); 82 | } 83 | } -------------------------------------------------------------------------------- /WePayV3/ProfitSharing.php: -------------------------------------------------------------------------------- 1 | config['appid']; 37 | return $this->doRequest('POST', '/v3/profitsharing/orders', json_encode($options, JSON_UNESCAPED_UNICODE), true); 38 | } 39 | 40 | /** 41 | * 查询分账结果 42 | * @param string $outOrderNo 商户分账单号 43 | * @param string $transactionId 微信订单号 44 | * @return array 45 | * @throws \WeChat\Exceptions\InvalidResponseException 46 | */ 47 | public function query($outOrderNo, $transactionId) 48 | { 49 | $pathinfo = "/v3/profitsharing/orders/{$outOrderNo}?&transaction_id={$transactionId}"; 50 | return $this->doRequest('GET', $pathinfo, '', true); 51 | } 52 | 53 | /** 54 | * 解冻剩余资金 55 | * @param array $options 56 | * @return array 57 | * @throws \WeChat\Exceptions\InvalidResponseException 58 | */ 59 | public function unfreeze(array $options) 60 | { 61 | return $this->doRequest('POST', '/v3/profitsharing/orders/unfreeze', json_encode($options, JSON_UNESCAPED_UNICODE), true); 62 | } 63 | 64 | /** 65 | * 查询剩余待分金额 66 | * @param string $transactionId 微信订单号 67 | * @return array 68 | * @throws \WeChat\Exceptions\InvalidResponseException 69 | */ 70 | public function amounts($transactionId) 71 | { 72 | $pathinfo = "/v3/profitsharing/transactions/{$transactionId}/amounts"; 73 | return $this->doRequest('GET', $pathinfo, '', true); 74 | } 75 | 76 | /** 77 | * 添加分账接收方 78 | * @param array $options 79 | * @return array 80 | * @throws \WeChat\Exceptions\InvalidDecryptException 81 | * @throws \WeChat\Exceptions\InvalidResponseException 82 | */ 83 | public function addReceiver(array $options) 84 | { 85 | $options['appid'] = $this->config['appid']; 86 | if (isset($options['name'])) { 87 | $options['name'] = $this->rsaEncode($options['name']); 88 | } 89 | return $this->doRequest('POST', "/v3/profitsharing/receivers/add", json_encode($options, JSON_UNESCAPED_UNICODE), true); 90 | } 91 | 92 | /** 93 | * 删除分账接收方 94 | * @param array $options 95 | * @return array 96 | * @throws \WeChat\Exceptions\InvalidResponseException 97 | */ 98 | public function deleteReceiver(array $options) 99 | { 100 | $options['appid'] = $this->config['appid']; 101 | return $this->doRequest('POST', "/v3/profitsharing/receivers/delete", json_encode($options, JSON_UNESCAPED_UNICODE), true); 102 | } 103 | 104 | /** 105 | * 请求分账回退 106 | * @param array $options 107 | * @return array 108 | * @throws \WeChat\Exceptions\InvalidResponseException 109 | */ 110 | public function backspace(array $options) 111 | { 112 | $options['appid'] = $this->config['appid']; 113 | return $this->doRequest('POST', "/v3/profitsharing/return-orders", json_encode($options, JSON_UNESCAPED_UNICODE), true); 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /WePayV3/Refund.php: -------------------------------------------------------------------------------- 1 | config)->createRefund($data); 40 | // return $this->doRequest('POST', '/v3/ecommerce/refunds/apply', json_encode($data, JSON_UNESCAPED_UNICODE), true); 41 | } 42 | 43 | /** 44 | * 退款订单查询 45 | * @param string $refundNo 退款单号 46 | * @return array 47 | * @throws \WeChat\Exceptions\InvalidResponseException 48 | * @throws \WeChat\Exceptions\LocalCacheException 49 | */ 50 | public function query($refundNo) 51 | { 52 | return Order::instance($this->config)->queryRefund($refundNo); 53 | // $pathinfo = "/v3/ecommerce/refunds/out-refund-no/{$refundNo}"; 54 | // return $this->doRequest('GET', "{$pathinfo}?sub_mchid={$this->config['mch_id']}", '', true); 55 | } 56 | 57 | /** 58 | * 获取退款通知 59 | * @param mixed $xml 60 | * @return array 61 | * @throws \WeChat\Exceptions\InvalidDecryptException 62 | * @throws \WeChat\Exceptions\InvalidResponseException 63 | * @throws \WeChat\Exceptions\LocalCacheException 64 | */ 65 | public function notify($xml = []) 66 | { 67 | return Order::instance($this->config)->notify($xml); 68 | // $data = Tools::xml2arr(empty($xml) ? Tools::getRawInput() : $xml); 69 | // if (!isset($data['return_code']) || $data['return_code'] !== 'SUCCESS') { 70 | // throw new InvalidResponseException('获取退款通知XML失败!'); 71 | // } 72 | // try { 73 | // $key = md5($this->config['mch_v3_key']); 74 | // $decrypt = base64_decode($data['req_info']); 75 | // $response = openssl_decrypt($decrypt, 'aes-256-ecb', $key, OPENSSL_RAW_DATA); 76 | // $data['result'] = Tools::xml2arr($response); 77 | // return $data; 78 | // } catch (\Exception $exception) { 79 | // throw new InvalidDecryptException($exception->getMessage(), $exception->getCode()); 80 | // } 81 | } 82 | } -------------------------------------------------------------------------------- /_test/alipay-app.php: -------------------------------------------------------------------------------- 1 | apply([ 31 | 'out_trade_no' => strval(time()), // 商户订单号 32 | 'total_amount' => '1', // 支付金额 33 | 'subject' => '支付宝订单标题', // 支付订单描述 34 | ]); 35 | echo $result . PHP_EOL .'

    '. PHP_EOL; 36 | 37 | // 请求关闭订单 38 | $result = $pay->close([ 39 | 'out_trade_no' => strval(time()) 40 | ]); 41 | echo PHP_EOL . PHP_EOL . $result; 42 | } catch (\Exception $e) { 43 | echo $e->getMessage(); 44 | } 45 | 46 | 47 | -------------------------------------------------------------------------------- /_test/alipay-bill.php: -------------------------------------------------------------------------------- 1 | apply([ 40 | 'bill_date' => date('Y-m-d', strtotime('-1 month')), // 账单时间(日账单yyyy-MM-dd,月账单 yyyy-MM) 41 | 'bill_type' => 'trade', 42 | ]); 43 | echo '
    ';
    44 |     var_export($result);
    45 | } catch (Exception $e) {
    46 |     echo $e->getMessage();
    47 | }
    
    
    --------------------------------------------------------------------------------
    /_test/alipay-notify.php:
    --------------------------------------------------------------------------------
     1 | notify();
    30 |     if (in_array($data['trade_status'], ['TRADE_SUCCESS', 'TRADE_FINISHED'])) {
    31 |         // @todo 更新订单状态,支付完成
    32 |         file_put_contents('notify.txt', "收到来自支付宝的异步通知\r\n", FILE_APPEND);
    33 |         file_put_contents('notify.txt', '订单号:' . $data['out_trade_no'] . "\r\n", FILE_APPEND);
    34 |         file_put_contents('notify.txt', '订单金额:' . $data['total_amount'] . "\r\n\r\n", FILE_APPEND);
    35 |     } else {
    36 |         file_put_contents('notify.txt', "收到异步通知\r\n", FILE_APPEND);
    37 |     }
    38 | } catch (\Exception $e) {
    39 |     // 异常处理
    40 |     echo $e->getMessage();
    41 | }
    42 | 
    
    
    --------------------------------------------------------------------------------
    /_test/alipay-pos.php:
    --------------------------------------------------------------------------------
     1 | apply([
    31 |         'out_trade_no' => '4312412343', // 订单号
    32 |         'total_amount' => '13', // 订单金额,单位:元
    33 |         'subject'      => '订单商品标题', // 订单商品标题
    34 |         'auth_code'    => '123456', // 授权码
    35 |     ]);
    36 | 
    37 |     echo '
    ';
    38 |     var_export($result);
    39 | } catch (Exception $e) {
    40 |     echo $e->getMessage();
    41 | }
    42 | 
    43 | 
    44 | 
    
    
    --------------------------------------------------------------------------------
    /_test/alipay-refund.php:
    --------------------------------------------------------------------------------
     1 | refund($out_trade_no, $refund_fee);
    36 | 
    37 |     echo '
    ';
    38 |     var_export($result);
    39 | } catch (Exception $e) {
    40 |     echo $e->getMessage();
    41 | }
    
    
    --------------------------------------------------------------------------------
    /_test/alipay-scan.php:
    --------------------------------------------------------------------------------
     1 | apply([
    31 |         'out_trade_no' => '14321412', // 订单号
    32 |         'total_amount' => '13', // 订单金额,单位:元
    33 |         'subject'      => '订单商品标题', // 订单商品标题
    34 |     ]);
    35 | 
    36 |     echo '
    ';
    37 |     var_export($result);
    38 | } catch (Exception $e) {
    39 |     echo $e->getMessage();
    40 | }
    41 | 
    42 | 
    43 | 
    
    
    --------------------------------------------------------------------------------
    /_test/alipay-transfer-account.php:
    --------------------------------------------------------------------------------
     1 | queryAccount([
    31 |         'alipay_user_id'     => $config['appid'], // 订单号
    32 |         'account_scene_code' => 'SCENE_000_000_000',
    33 |     ]);
    34 |     echo '
    ';
    35 |     var_export($result);
    36 | } catch (Exception $e) {
    37 |     echo $e->getMessage();
    38 | }
    39 | 
    40 | 
    
    
    --------------------------------------------------------------------------------
    /_test/alipay-transfer-create.php:
    --------------------------------------------------------------------------------
     1 | create([
    31 |         'out_biz_no'   => time(), // 订单号
    32 |         'trans_amount' => '10', // 转账金额
    33 |         'product_code' => 'TRANS_ACCOUNT_NO_PWD',
    34 |         'biz_scene'    => 'DIRECT_TRANSFER',
    35 |         'payee_info'   => [
    36 |             'identity'      => 'zoujingli@qq.com',
    37 |             'identity_type' => 'ALIPAY_LOGON_ID',
    38 |             'name'          => '邹景立',
    39 |         ],
    40 |     ]);
    41 |     echo '
    ';
    42 |     var_export($result);
    43 | } catch (Exception $e) {
    44 |     echo $e->getMessage();
    45 | }
    46 | 
    47 | 
    
    
    --------------------------------------------------------------------------------
    /_test/alipay-transfer-query.php:
    --------------------------------------------------------------------------------
     1 | queryResult([
    31 |         'out_biz_no'   => '201808080001', // 订单号
    32 |         'product_code' => 'TRANS_ACCOUNT_NO_PWD',
    33 |         'biz_scene'    => 'DIRECT_TRANSFER',
    34 |     ]);
    35 |     echo '
    ';
    36 |     var_export($result);
    37 | } catch (Exception $e) {
    38 |     echo $e->getMessage();
    39 | }
    40 | 
    41 | 
    
    
    --------------------------------------------------------------------------------
    /_test/alipay-transfer.php:
    --------------------------------------------------------------------------------
     1 | apply([
    31 |         'out_biz_no'      => time(), // 订单号
    32 |         'payee_type'      => 'ALIPAY_LOGONID', // 收款方账户类型(ALIPAY_LOGONID | ALIPAY_USERID)
    33 |         'payee_account'   => 'yvvfcr3065@sandbox.com', // 收款方账户
    34 |         'amount'          => '10', // 转账金额
    35 |         'payer_show_name' => '未寒', // 付款方姓名
    36 |         'payee_real_name' => 'yvvfcr3065', // 收款方真实姓名
    37 |         'remark'          => '张三', // 转账备注
    38 |     ]);
    39 | 
    40 |     echo '
    ';
    41 |     var_export($result);
    42 | } catch (Exception $e) {
    43 |     echo $e->getMessage();
    44 | }
    45 | 
    46 | 
    
    
    --------------------------------------------------------------------------------
    /_test/alipay-wap.php:
    --------------------------------------------------------------------------------
     1 | apply([
    34 |         'out_trade_no' => time(), // 商户订单号
    35 |         'total_amount' => '1', // 支付金额
    36 |         'subject'      => '支付订单描述', // 支付订单描述
    37 |     ]);
    38 | 
    39 |     echo $result;
    40 | } catch (Exception $e) {
    41 |     echo $e->getMessage();
    42 | }
    43 | 
    44 | 
    45 | 
    
    
    --------------------------------------------------------------------------------
    /_test/alipay-web.php:
    --------------------------------------------------------------------------------
     1 | apply([
    35 |         'out_trade_no' => time(), // 商户订单号
    36 |         'total_amount' => '1', // 支付金额
    37 |         'subject'      => '支付订单描述', // 支付订单描述
    38 |     ]);
    39 | 
    40 |     echo $result;
    41 | } catch (Exception $e) {
    42 |     echo $e->getMessage();
    43 | }
    44 | 
    45 | 
    46 | 
    
    
    --------------------------------------------------------------------------------
    /_test/alipay/alipayPublicCert.crt:
    --------------------------------------------------------------------------------
     1 | -----BEGIN CERTIFICATE-----
     2 | MIIDszCCApugAwIBAgIQICMFBicVvB1uC0Lc3VFbITANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UE
     3 | BhMCQ04xGzAZBgNVBAoMEkFudCBGaW5hbmNpYWwgdGVzdDElMCMGA1UECwwcQ2VydGlmaWNhdGlv
     4 | biBBdXRob3JpdHkgdGVzdDE+MDwGA1UEAww1QW50IEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1
     5 | dGhvcml0eSBDbGFzcyAyIFIxIHRlc3QwHhcNMjMwNTA2MDYwMTA3WhcNMjQwNTA1MDYwMTA3WjCB
     6 | hDELMAkGA1UEBhMCQ04xHzAdBgNVBAoMFndtaWFrdTY3NDlAc2FuZGJveC5jb20xDzANBgNVBAsM
     7 | BkFsaXBheTFDMEEGA1UEAww65pSv5LuY5a6dKOS4reWbvSnnvZHnu5zmioDmnK/mnInpmZDlhazl
     8 | j7gtMjA4ODcyMTAwMjg0MzQxNDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALkO9F4+
     9 | AB7CLI47hSthHsZFFQxnOiggc4R8pbeb24BkyRc6xJVekYtzuJ8cLSsy1spEX4zguTPc+b7eza5k
    10 | nN1j2pdAfNkzbdEg1Tt4A0b5xbMAfaQtVhwU0aohhLF+i6TTgospMmBwJnN2++Eda6LccrTqS7ff
    11 | x8I2bhkraLlEO4C6pxUcGCyorPLVvRWOTRC/RzxDURHEaGlBPMxxOpeIzYuYNg77OK+Sqp0zb5nk
    12 | U3PO2cpSrOCT4UlrJDmqgSZgwHE0e+9MdBuveLSo1ubG5uGvz8Vjld3hBvVywOAnEuoMBxtSrEbv
    13 | nkz7M0MJBDmQk/D8WSekm2lMGbFDuGUCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgTwMA0GCSqGSIb3
    14 | DQEBCwUAA4IBAQC29uyA9W6uQivhMqc3YyGXPvi4LIOThU1ijeOSpovHiRUGVfaO/qIY4eAQ2ivF
    15 | iKIrUEqcJnWdNN8LZwWdWd6UmInyngq2i+Pf4h3a2MLkV3ZufZNZkJP5GZJxbcjkKlnKuCTKFUd5
    16 | wJ0zo369E+mPdNGlrPLvNXw4ziUpUb4KXmEn1yOVAkQMsBP43K6QB2QVIODrtp4O+rEs80KHgUQh
    17 | cmla+PWGyX2nuwHURxUtEeIeJblra+ntyy+bTYfCVVG8jh4BN5bPExDprRa100aZGsqyExO1xtxk
    18 | 4pu0Jag5XRvGyZpmqH27SfQX2oKcsobuDyGCwff/yvYKOZk53JZD
    19 | -----END CERTIFICATE-----
    20 | -----BEGIN CERTIFICATE-----
    21 | MIIDszCCApugAwIBAgIQIBkIGbgVxq210KxLJ+YA/TANBgkqhkiG9w0BAQsFADCBhDELMAkGA1UE
    22 | BhMCQ04xFjAUBgNVBAoMDUFudCBGaW5hbmNpYWwxJTAjBgNVBAsMHENlcnRpZmljYXRpb24gQXV0
    23 | aG9yaXR5IHRlc3QxNjA0BgNVBAMMLUFudCBGaW5hbmNpYWwgQ2VydGlmaWNhdGlvbiBBdXRob3Jp
    24 | dHkgUjEgdGVzdDAeFw0xOTA4MTkxMTE2MDBaFw0yNDA4MDExMTE2MDBaMIGRMQswCQYDVQQGEwJD
    25 | TjEbMBkGA1UECgwSQW50IEZpbmFuY2lhbCB0ZXN0MSUwIwYDVQQLDBxDZXJ0aWZpY2F0aW9uIEF1
    26 | dGhvcml0eSB0ZXN0MT4wPAYDVQQDDDVBbnQgRmluYW5jaWFsIENlcnRpZmljYXRpb24gQXV0aG9y
    27 | aXR5IENsYXNzIDIgUjEgdGVzdDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMh4FKYO
    28 | ZyRQHD6eFbPKZeSAnrfjfU7xmS9Yoozuu+iuqZlb6Z0SPLUqqTZAFZejOcmr07ln/pwZxluqplxC
    29 | 5+B48End4nclDMlT5HPrDr3W0frs6Xsa2ZNcyil/iKNB5MbGll8LRAxntsKvZZj6vUTMb705gYgm
    30 | VUMILwi/ZxKTQqBtkT/kQQ5y6nOZsj7XI5rYdz6qqOROrpvS/d7iypdHOMIM9Iz9DlL1mrCykbBi
    31 | t25y+gTeXmuisHUwqaRpwtCGK4BayCqxRGbNipe6W73EK9lBrrzNtTr9NaysesT/v+l25JHCL9tG
    32 | wpNr1oWFzk4IHVOg0ORiQ6SUgxZUTYcCAwEAAaMSMBAwDgYDVR0PAQH/BAQDAgTwMA0GCSqGSIb3
    33 | DQEBCwUAA4IBAQBWThEoIaQoBX2YeRY/I8gu6TYnFXtyuCljANnXnM38ft+ikhE5mMNgKmJYLHvT
    34 | yWWWgwHoSAWEuml7EGbE/2AK2h3k0MdfiWLzdmpPCRG/RJHk6UB1pMHPilI+c0MVu16OPpKbg5Vf
    35 | LTv7dsAB40AzKsvyYw88/Ezi1osTXo6QQwda7uefvudirtb8FcQM9R66cJxl3kt1FXbpYwheIm/p
    36 | j1mq64swCoIYu4NrsUYtn6CV542DTQMI5QdXkn+PzUUly8F6kDp+KpMNd0avfWNL5+O++z+F5Szy
    37 | 1CPta1D7EQ/eYmMP+mOQ35oifWIoFCpN6qQVBS/Hob1J/UUyg7BW
    38 | -----END CERTIFICATE-----
    39 | 
    
    
    --------------------------------------------------------------------------------
    /_test/alipay/appPublicCert.crt:
    --------------------------------------------------------------------------------
     1 | -----BEGIN CERTIFICATE-----
     2 | MIIDmTCCAoGgAwIBAgIQICMFBmpzKUKQGs/81YT4UDANBgkqhkiG9w0BAQsFADCBkTELMAkGA1UE
     3 | BhMCQ04xGzAZBgNVBAoMEkFudCBGaW5hbmNpYWwgdGVzdDElMCMGA1UECwwcQ2VydGlmaWNhdGlv
     4 | biBBdXRob3JpdHkgdGVzdDE+MDwGA1UEAww1QW50IEZpbmFuY2lhbCBDZXJ0aWZpY2F0aW9uIEF1
     5 | dGhvcml0eSBDbGFzcyAyIFIxIHRlc3QwHhcNMjMwNTA2MDYwMTA3WhcNMjQwNTEwMDYwMTA3WjBr
     6 | MQswCQYDVQQGEwJDTjEfMB0GA1UECgwWd21pYWt1Njc0OUBzYW5kYm94LmNvbTEPMA0GA1UECwwG
     7 | QWxpcGF5MSowKAYDVQQDDCEyMDg4NzIxMDAyODQzNDE0LTIwMjEwMDAxMjI2NjczMDYwggEiMA0G
     8 | CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQCd0fbopV7cjL7wbFXEO4b1miViuoY2bwml2L0atB0z
     9 | zVp3ik/K6XY1U770LYqvprqMrpDDWDLNzBjG2RQLvGgtlRI+mZIfuwfewPqvYHsx/kWytVJrb2Vy
    10 | bX7dSTIWBmNhOTHjmV9suYAUc7M6XRZ8aQxbRKrc3/k4yvTvgTgSdi0At0TeNVAIN/xvOo3eP8rB
    11 | 7t/XQCCW/GKWLYGsUznriyKWpxuInxTXMOZN1m+YSQ/uJr9hWSa3nDeuHtkGhq5u1wz+tUZhcvaF
    12 | A/Cv+mq40JO7sSHVFxZ+lydu7D6A6do3JeY0WZmR42V6BciJ9y6e3UYrprWlfT3RHx4U3cuNAgMB
    13 | AAGjEjAQMA4GA1UdDwEB/wQEAwIE8DANBgkqhkiG9w0BAQsFAAOCAQEAiLA1wk7or0uqxPSD9z31
    14 | BLJRnamf51Uz2YOSDPjUivu9VJrkjf1PsCleK9RSgOcXcpy9QWZSFIIyakFqCCWylgBdjmhSvzAv
    15 | po86ycJXEBrd7klOM/6VFh68BqpmK1CJl0g29JOJ1fNvIKYJ/WS4ue988NSGrpsVhXbNGALhgiBL
    16 | Gqs7KkZQSsIAySx2HNCSknFM5G5xG6IR6wUJ619khba6rMaKOJ3D7mxuv0Vjyu7DrFBsPLOSdjP1
    17 | Jzi5WmutetJGVrbOKayVjL4xDcU7lgOWTrhTs7S54Z6GnxqRLwy8gD7RmDbXtnVyGP/mUcAgnFtE
    18 | BPFZBe7qjqsCCkf+Zw==
    19 | -----END CERTIFICATE-----
    
    
    --------------------------------------------------------------------------------
    /_test/config.php:
    --------------------------------------------------------------------------------
     1 |  function ($name, $value, $expired = 360) {
    26 | //        var_dump(func_get_args());
    27 | //         return $value;
    28 | //    },
    29 | //    'get' => function ($name) {
    30 | //        var_dump(func_get_args());
    31 | //        return $value;
    32 | //    },
    33 | //    'del' => function ($name) {
    34 | //        var_dump(func_get_args());
    35 | //        return true;
    36 | //    },
    37 | //    'put' => function ($name) {
    38 | //        var_dump(func_get_args());
    39 | //        return $filePath;
    40 | //    },
    41 | // ];
    42 | 
    43 | return [
    44 |     'token'          => 'test',
    45 |     'appid'          => 'wx60a43dd8161666d4',
    46 |     'appsecret'      => 'b4e28746f1bd73b5c6684f5e01883c36',
    47 |     'encodingaeskey' => 'BJIUzE0gqlWy0GxfPp4J1oPTBmOrNDIGPNav1YFH5Z5',
    48 |     // 配置缓存目录,需要拥有写权限
    49 |     'cache_path'     => '',
    50 |     // 其他支付参数可以合并在这里
    51 |     // ...
    52 | ];
    
    
    --------------------------------------------------------------------------------
    /_test/mini-login.php:
    --------------------------------------------------------------------------------
     1 |  'wx6bb7b70258da09c6',
    22 |     'appsecret' => '78b7b8d65bd67b078babf951d4342b42',
    23 | ];
    24 | 
    25 | // 解码数据
    26 | $iv = 'ltM/wT7hsAl0TijEBI4v/g==';
    27 | $code = '013LyiTR0TwjC92QjJRR0mEsTR0LyiT3';
    28 | $decode = 'eIoVtIC2YzLCnrwiIs1IBbXMvC0vyL8bo1IhD38fUQIRbk3lgTWa0Hdw/Ty7NTs3iu7YlqqZBti+cxd6dCfeXBUQwTO2QpbHg0WTeDAdrihsHRHm4dCWdfTx8rzDloGbNOIsKdRElIhUH5YFdiTr5AYiufUDb34cwJ4GNWLAUq4bR0dmFeVEi+3nfwe2MAjGYDl4aq719VLsHodOggK6lXZvM5wjoDyuZsK2dPqJr3/Ji30Z0mdyFq32R4uR3rtJH/h+Rj0+/QmE9QYG7Y6Z48hgPE8cpnhRQNwH49jnC/zKZ9wtDkQ/J8J3Ed2i58zcuY01v8IV+pZ8oBUKXfO5ha+APOxtBSTzyHraU/2RGo8UWtOF6h64OQZhd/UQQy362eyc/qoq8sF9JnEFRP0mRmTDJ+u9oyDhxswCu6x8V73ERWaJeEGSCyjiGpep7/DxZ6eSSBq36OB0BWBkJqsq9Q==';
    29 | $sessionKey = 'OetNxl86B/yMpbwG6wtMEw==';
    30 | 
    31 | // $mini = \We::WeMiniCrypt($config);
    32 | // $mini = new WeMini\Crypt($config);
    33 | $mini = \WeMini\Crypt::instance($config);
    34 | 
    35 | echo '
    ';
    36 | //print_r($mini->session($code));
    37 | print_r($mini->decode($iv, $sessionKey, $decode));
    38 | //print_r($mini->userInfo($code, $iv, $decode));
    
    
    --------------------------------------------------------------------------------
    /_test/mini-qrc.php:
    --------------------------------------------------------------------------------
     1 |  'wx6bb7b70258da09c6',
    22 |     'appsecret' => '78b7b8d65bd67b078babf951d4342b42',
    23 | ];
    24 | 
    25 | //We::config($config);
    26 | 
    27 | // $mini = We::WeMiniQrcode($config);
    28 | // $mini = new WeMini\Qrcode($config);
    29 | $mini = \WeMini\Qrcode::instance($config);
    30 | 
    31 | //echo '
    ';
    32 | try {
    33 |     header('Content-type:image/jpeg'); //输出的类型
    34 | //    echo $mini->createDefault('pages/index?query=1');
    35 | //    echo $mini->createMiniScene('432432', 'pages/index/index');
    36 |     echo $mini->createMiniPath('pages/index?query=1');
    37 | } catch (Exception $e) {
    38 |     var_dump($e->getMessage());
    39 | }
    40 | 
    
    
    --------------------------------------------------------------------------------
    /_test/pay-config.php:
    --------------------------------------------------------------------------------
     1 |  function ($name, $value, $expired = 360) {
    26 | //        var_dump(func_get_args());
    27 | //         return $value;
    28 | //    },
    29 | //    'get' => function ($name) {
    30 | //        var_dump(func_get_args());
    31 | //        return $value;
    32 | //    },
    33 | //    'del' => function ($name) {
    34 | //        var_dump(func_get_args());
    35 | //        return true;
    36 | //    },
    37 | //    'put' => function ($name) {
    38 | //        var_dump(func_get_args());
    39 | //        return $filePath;
    40 | //    },
    41 | // ];
    42 | 
    43 | return [
    44 |     'appid'      => 'wx60a43dd8161666d4',
    45 |     // 配置商户支付参数
    46 |     'mch_id'     => "1332187001",
    47 |     'mch_key'    => 'A82DC5BD1F3359081049C568D8502BC5',
    48 |     // 配置商户支付双向证书目录 (p12 | key,cert 二选一,两者都配置时p12优先)
    49 |     'ssl_p12'    => __DIR__ . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . '1332187001_20181030_cert.p12',
    50 |     // 'ssl_key'        => __DIR__ . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . '1332187001_20181030_key.pem',
    51 |     // 'ssl_cer'        => __DIR__ . DIRECTORY_SEPARATOR . 'cert' . DIRECTORY_SEPARATOR . '1332187001_20181030_cert.pem',
    52 |     // 配置缓存目录,需要拥有写权限
    53 |     'cache_path' => '',
    54 | ];
    
    
    --------------------------------------------------------------------------------
    /_test/pay-download-bill.php:
    --------------------------------------------------------------------------------
     1 |  '20171001',
    33 |         'bill_type' => 'ALL',
    34 |     ];
    35 |     $result = $wechat->billDownload($options);
    36 | 
    37 |     var_export($result);
    38 | 
    39 | } catch (Exception $e) {
    40 | 
    41 |     // 出错啦,处理下吧
    42 |     echo $e->getMessage() . PHP_EOL;
    43 | 
    44 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-order-close.php:
    --------------------------------------------------------------------------------
     1 | closeOrder($options);
    33 | 
    34 |     var_export($result);
    35 | 
    36 | } catch (Exception $e) {
    37 | 
    38 |     // 出错啦,处理下吧
    39 |     echo $e->getMessage() . PHP_EOL;
    40 | 
    41 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-order-create.php:
    --------------------------------------------------------------------------------
     1 |  '测试商品',
    33 |         'out_trade_no'     => time(),
    34 |         'total_fee'        => '1',
    35 |         'openid'           => 'o38gpszoJoC9oJYz3UHHf6bEp0Lo',
    36 |         'trade_type'       => 'JSAPI', // JSAPI--JSAPI支付(服务号或小程序支付)、NATIVE--Native 支付、APP--APP支付,MWEB--H5支付
    37 |         'notify_url'       => 'https://a.com/text.html',
    38 |         'spbill_create_ip' => '127.0.0.1',
    39 |     ];
    40 | 
    41 |     // 生成预支付码
    42 |     $result = $wechat->createOrder($options);
    43 | 
    44 |     echo '
    ';
    45 |     if ($options['trade_type'] === 'NATIVE') {
    46 |         echo '

    二维码 NATIVE 支付,直接使用 code_url 生成二维码即可

    '; 47 | var_export($result); 48 | return; 49 | } 50 | 51 | // 创建JSAPI参数签名 52 | $options = $wechat->createParamsForJsApi($result['prepay_id']); 53 | 54 | echo "

    --- 创建 JSAPI 预支付码 ---

    "; 55 | var_export($result); 56 | // array( 57 | // 'return_code' => 'SUCCESS', 58 | // 'return_msg' => 'OK', 59 | // 'result_code' => 'SUCCESS', 60 | // 'mch_id' => '1332187001', 61 | // 'appid' => 'wx60a43dd8161666d4', 62 | // 'nonce_str' => 'YIPDbGWT1jpLLM5R', 63 | // 'sign' => '7EBBA1B5F196CF122C920D10FA768D96', 64 | // 'prepay_id' => 'wx211858080224615a10c2fc9f6c824f0000', 65 | // 'trade_type' => 'JSAPI', 66 | // ) 67 | 68 | echo "

    --- 生成 JSAPI 及 H5 支付参数 ---

    "; 69 | var_export($options); 70 | // array( 71 | // 'appId' => 'wx60a43dd8161666d4', 72 | // 'timeStamp' => '1669028299', 73 | // 'nonceStr' => '5s7h0dyp0nmzylbqytb462fpnb0tmrjg', 74 | // 'package' => 'prepay_id=wx21185819502283c23cca162e9d787f0000', 75 | // 'signType' => 'MD5', 76 | // 'paySign' => 'BBE0F426B8E1EEC9E45AC4459E8AE9D6', 77 | // 'timestamp' => '1669028299', 78 | // ) 79 | 80 | } catch (Exception $exception) { 81 | 82 | // 出错啦,处理下吧 83 | echo $exception->getMessage() . PHP_EOL; 84 | 85 | } -------------------------------------------------------------------------------- /_test/pay-order-notify.php: -------------------------------------------------------------------------------- 1 | getNotify(); 32 | if ($data['return_code'] === 'SUCCESS' && $data['result_code'] === 'SUCCESS') { 33 | // @todo 去更新下原订单的支付状态 34 | $order_no = $data['out_trade_no']; 35 | 36 | // 返回接收成功的回复 37 | ob_clean(); 38 | echo $wechat->getNotifySuccessReply(); 39 | } 40 | 41 | } catch (Exception $e) { 42 | 43 | // 出错啦,处理下吧 44 | echo $e->getMessage() . PHP_EOL; 45 | 46 | } 47 | -------------------------------------------------------------------------------- /_test/pay-order-query.php: -------------------------------------------------------------------------------- 1 | '1008450740201411110005820873', 33 | // 'out_trade_no' => '商户订单号', 34 | ]; 35 | $result = $wechat->queryOrder($options); 36 | 37 | var_export($result); 38 | 39 | } catch (Exception $e) { 40 | 41 | // 出错啦,处理下吧 42 | echo $e->getMessage() . PHP_EOL; 43 | 44 | } -------------------------------------------------------------------------------- /_test/pay-redpack-create.php: -------------------------------------------------------------------------------- 1 | time(), 33 | 're_openid' => 'o38gps3vNdCqaggFfrBRCRikwlWY', 34 | 'send_name' => '商户名称😍', 35 | 'act_name' => '活动名称', 36 | 'total_amount' => '100', 37 | 'total_num' => '1', 38 | 'wishing' => '感谢您参加猜灯谜活动,祝您元宵节快乐!', 39 | 'remark' => '猜越多得越多,快来抢!', 40 | 'client_ip' => '127.0.0.1', 41 | ]; 42 | // 发送红包记录 43 | $result = $wechat->create($options); 44 | echo '
    ';
    45 |     var_export($result);
    46 |     // 查询红包记录
    47 |     $result = $wechat->query($options['mch_billno']);
    48 |     var_export($result);
    49 | 
    50 | } catch (Exception $e) {
    51 | 
    52 |     // 出错啦,处理下吧
    53 |     echo $e->getMessage() . PHP_EOL;
    54 | 
    55 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-refund-create.php:
    --------------------------------------------------------------------------------
     1 |  '1008450740201411110005820873',
    33 |         'out_refund_no'  => '3241251235123',
    34 |         'total_fee'      => '1',
    35 |         'refund_fee'     => '1',
    36 |     ];
    37 |     $result = $wechat->createRefund($options);
    38 | 
    39 |     var_export($result);
    40 | 
    41 | } catch (Exception $e) {
    42 | 
    43 |     // 出错啦,处理下吧
    44 |     echo $e->getMessage() . PHP_EOL;
    45 | 
    46 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-refund-query.php:
    --------------------------------------------------------------------------------
     1 |  '1008450740201411110005820873',
    33 |         // 'out_trade_no'   => '商户订单号',
    34 |         // 'out_refund_no' => '商户退款单号'
    35 |         // 'refund_id' => '微信退款单号',
    36 |     ];
    37 |     $result = $wechat->queryRefund($options);
    38 | 
    39 |     var_export($result);
    40 | 
    41 | } catch (Exception $e) {
    42 | 
    43 |     // 出错啦,处理下吧
    44 |     echo $e->getMessage() . PHP_EOL;
    45 | 
    46 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-transfers-create.php:
    --------------------------------------------------------------------------------
     1 |  time(),
    33 |         'openid'           => 'o38gps3vNdCqaggFfrBRCRikwlWY',
    34 |         'check_name'       => 'NO_CHECK',
    35 |         'amount'           => '100',
    36 |         'desc'             => '企业付款操作说明信息',
    37 |         'spbill_create_ip' => '127.0.0.1',
    38 |     ];
    39 |     $result = $wechat->createTransfers($options);
    40 |     echo '
    ';
    41 |     var_export($result);
    42 |     $result = $wechat->queryTransfers($options['partner_trade_no']);
    43 |     var_export($result);
    44 | 
    45 | } catch (Exception $e) {
    46 | 
    47 |     // 出错啦,处理下吧
    48 |     echo $e->getMessage() . PHP_EOL;
    49 | 
    50 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-transfersbank-create.php:
    --------------------------------------------------------------------------------
     1 |  time(),
    33 |         'enc_bank_no'      => '6212263602037318102',
    34 |         'enc_true_name'    => '邹景立',
    35 |         'bank_code'        => '1002',
    36 |         'amount'           => '100',
    37 |         'desc'             => '打款测试',
    38 |     ];
    39 |     echo '
    ';
    40 |     $result = $wechat->createTransfersBank($options);
    41 |     var_export($result);
    42 | 
    43 | } catch (Exception $e) {
    44 | 
    45 |     // 出错啦,处理下吧
    46 |     echo $e->getMessage() . PHP_EOL;
    47 | 
    48 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-v3-config-cert.php:
    --------------------------------------------------------------------------------
     1 | download();
    27 | 
    28 | } catch (\Exception $exception) {
    29 |     // 出错啦,处理下吧
    30 |     echo $exception->getMessage() . PHP_EOL;
    31 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-v3-config.php:
    --------------------------------------------------------------------------------
     1 |  function ($name, $value, $expired = 360) {
    47 | //        var_dump(func_get_args());
    48 | //        return $value;
    49 | //    },
    50 | //    'get' => function ($name) {
    51 | //        var_dump(func_get_args());
    52 | //        return $value;
    53 | //    },
    54 | //    'del' => function ($name) {
    55 | //        var_dump(func_get_args());
    56 | //        return true;
    57 | //    },
    58 | //    'put' => function ($name) {
    59 | //        var_dump(func_get_args());
    60 | //        return $filePath;
    61 | //    },
    62 | // ];
    63 | 
    64 | return [
    65 |     // 公众号 APPID(可选)
    66 |     'appid'        => 'wx3760xxxxxxxxxxxx',
    67 |     // 微信商户号(必填)
    68 |     'mch_id'       => '15293xxxxxx',
    69 |     // 微信商户 V3 接口密钥(必填)
    70 |     'mch_v3_key'   => '98b7fxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    71 | 
    72 |     // 商户证书序列号(可选):用于请求签名
    73 |     'cert_serial'  => '49055D67B2XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX',
    74 |     // 微信商户证书公钥(必填):可填写证书内容或文件路径,仅用于提取序列号
    75 |     'cert_public'  => $certPublic,
    76 |     // 微信商户证书私钥(必填):可填写证书内容或文件路径,用于请求数据签名
    77 |     'cert_private' => $certPrivate,
    78 | 
    79 |     // 自定义证书包:支持平台证书或支付公钥(可填写文件路径或证书内容)
    80 |     'cert_package' => [
    81 |         'PUB_KEY_ID_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx' => $certPayment
    82 |     ],
    83 | 
    84 |     // 微信平台证书或支付证书序列号(可选)
    85 |     // 'mp_cert_serial'  => 'PUB_KEY_ID_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx',
    86 | 
    87 |     // 微信平台证书或支付证书内容(可选)
    88 |     // 'mp_cert_content' => $certPayment,
    89 | 
    90 |     // 运行时文件缓存路径(可选)
    91 |     'cache_path'   => ''
    92 | ];
    
    
    --------------------------------------------------------------------------------
    /_test/pay-v3-order-app.php:
    --------------------------------------------------------------------------------
     1 | create('app', [
    30 |         'appid'        => $config['appid'],
    31 |         'mchid'        => $config['mch_id'],
    32 |         'description'  => '商品描述',
    33 |         'out_trade_no' => $order,
    34 |         'notify_url'   => 'https://thinkadmin.top',
    35 |         'amount'       => ['total' => 2, 'currency' => 'CNY'],
    36 |     ]);
    37 | 
    38 |     echo '
    ';
    39 |     echo "\n--- 创建支付参数 ---\n";
    40 |     var_export($result);
    41 | 
    42 |     // 创建退款
    43 |     $out_refund_no = strval(time());
    44 |     $result = $payment->createRefund([
    45 |         'out_trade_no'  => $order,
    46 |         'out_refund_no' => $out_refund_no,
    47 |         'amount'        => [
    48 |             'refund'   => 2,
    49 |             'total'    => 2,
    50 |             'currency' => 'CNY'
    51 |         ]
    52 |     ]);
    53 |     echo "\n--- 创建退款订单 ---\n";
    54 |     var_export($result);
    55 | 
    56 |     $result = $payment->queryRefund($out_refund_no);
    57 | 
    58 |     echo "\n--- 查询退款订单 ---\n";
    59 |     var_export($result);
    60 | 
    61 | } catch (\Exception $exception) {
    62 |     // 出错啦,处理下吧
    63 |     echo $exception->getMessage() . PHP_EOL;
    64 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-v3-order-h5.php:
    --------------------------------------------------------------------------------
     1 | create('h5', [
    29 |         'appid'        => $config['appid'],
    30 |         'mchid'        => $config['mch_id'],
    31 |         'description'  => '商品描述',
    32 |         'out_trade_no' => (string)time(),
    33 |         'notify_url'   => 'https://thinkadmin.top',
    34 |         'amount'       => ['total' => 2, 'currency' => 'CNY'],
    35 |         'scene_info'   => [
    36 |             'h5_info'         => [
    37 |                 'type' => 'Wap',
    38 |             ],
    39 |             'payer_client_ip' => '14.23.150.211',
    40 |         ],
    41 |     ]);
    42 | 
    43 |     echo '
    ';
    44 |     echo "\n--- 创建支付参数 ---\n";
    45 |     var_export($result);
    46 | 
    47 | } catch (\Exception $exception) {
    48 |     // 出错啦,处理下吧
    49 |     echo $exception->getMessage() . PHP_EOL;
    50 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-v3-order-jsapi.php:
    --------------------------------------------------------------------------------
     1 | create('jsapi', [
    30 |         'appid'        => $config['appid'],
    31 |         'mchid'        => $config['mch_id'],
    32 |         'description'  => '商品描述',
    33 |         'out_trade_no' => $order,
    34 |         'notify_url'   => 'https://thinkadmin.top',
    35 |         'payer'        => ['openid' => 'o38gps3vNdCqaggFfrBRCRikwlWY'],
    36 |         'amount'       => ['total' => 2, 'currency' => 'CNY'],
    37 |     ]);
    38 | 
    39 |     echo '
    ';
    40 |     echo "\n--- 创建支付参数 ---\n";
    41 |     var_export($result);
    42 | 
    43 | //    array(
    44 | //        'appId'     => 'wx60a43dd8161666d4',
    45 | //        'timeStamp' => '1669027650',
    46 | //        'nonceStr'  => 'dfscg4lm02uqy448kjd1kjs2eo26joom',
    47 | //        'package'   => 'prepay_id=wx211847302881094d83b1917194ca880000',
    48 | //        'signType'  => 'RSA',
    49 | //        'paySign'   => '1wvvi4vmcJmP3GXB0H52mxp8lOhyqE4BtLmyi3Flg8DVKCES4fsb6+0z/L9sYkbp/TNinsnK0k7mUpTe2Yo86P1DLg18fR7zsIn5u1+3tI58boHk3VsAJl4Uhlti9ME3T7kRq1bEb4DGxp16+ixRynOqndkIkYXxrREhsrZIQlsGMfNCV0K1707s7jBTgqIm1vlkpIjNEg8nbcuG88Vzly4dR1a9K6Fux+sm0gu2rMroRwIo2R/0rgHGDANmnAZj6YEfLZlRrGTbr9r0V1+HHQPvV4BJLvTG8KXVJmJSJzBWSgq31PwrLWdOwdtpNKk7wJbY7yoScYUysYqqzM4DTQ==',
    50 | //    );
    51 | 
    52 |     echo "\n\n--- 查询支付参数 ---\n";
    53 |     $result = $payment->query($order);
    54 |     var_export($result);
    55 | 
    56 | //    array(
    57 | //        'amount'           => array('payer_currency' => 'CNY', 'total' => 2),
    58 | //        'appid'            => 'wx60a43dd8161666d4',
    59 | //        'mchid'            => '1332187001',
    60 | //        'out_trade_no'     => '1669027802',
    61 | //        'promotion_detail' => array(),
    62 | //        'scene_info'       => array('device_id' => ''),
    63 | //        'trade_state'      => 'NOTPAY',
    64 | //        'trade_state_desc' => '订单未支付',
    65 | //    );
    66 | 
    67 |     // 创建退款
    68 |     $out_refund_no = strval(time());
    69 |     $result = $payment->createRefund([
    70 |         'out_trade_no'  => $order,
    71 |         'out_refund_no' => $out_refund_no,
    72 |         'amount'        => [
    73 |             'refund'   => 2,
    74 |             'total'    => 2,
    75 |             'currency' => 'CNY'
    76 |         ]
    77 |     ]);
    78 |     echo "\n--- 创建退款订单2 ---\n";
    79 |     var_export($result);
    80 | 
    81 |     $result = $payment->queryRefund($out_refund_no);
    82 | 
    83 |     echo "\n--- 查询退款订单2 ---\n";
    84 |     var_export($result);
    85 | 
    86 | } catch (\Exception $exception) {
    87 |     // 出错啦,处理下吧
    88 |     echo $exception->getMessage() . PHP_EOL;
    89 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-v3-order-native.php:
    --------------------------------------------------------------------------------
     1 | create('native', [
    30 |         'appid'        => $config['appid'],
    31 |         'mchid'        => $config['mch_id'],
    32 |         'description'  => '商品描述',
    33 |         'out_trade_no' => $order,
    34 |         'notify_url'   => 'https://thinkadmin.top',
    35 |         'amount'       => ['total' => 2, 'currency' => 'CNY'],
    36 |     ]);
    37 | 
    38 |     echo '
    ';
    39 |     echo "\n--- 创建支付参数 ---\n";
    40 |     var_export($result);
    41 | 
    42 | //  array('code_url' => 'weixin://wxpay/bizpayurl?pr=cdJXOVDzz');
    43 | 
    44 | 
    45 |     echo "\n\n--- 查询支付参数 ---\n";
    46 |     $result = $payment->query($order);
    47 |     var_export($result);
    48 | 
    49 | //    array(
    50 | //        'amount'           => array('payer_currency' => 'CNY', 'total' => 2),
    51 | //        'appid'            => 'wx60a43dd8161666d4',
    52 | //        'mchid'            => '1332187001',
    53 | //        'out_trade_no'     => '1669027871',
    54 | //        'promotion_detail' => array(),
    55 | //        'scene_info'       => array('device_id' => ''),
    56 | //        'trade_state'      => 'NOTPAY',
    57 | //        'trade_state_desc' => '订单未支付',
    58 | //    );
    59 | 
    60 |     // 创建退款
    61 |     $out_refund_no = strval(time());
    62 |     $result = $payment->createRefund([
    63 |         'out_trade_no'  => $order,
    64 |         'out_refund_no' => $out_refund_no,
    65 |         'amount'        => [
    66 |             'refund'   => 2,
    67 |             'total'    => 2,
    68 |             'currency' => 'CNY'
    69 |         ]
    70 |     ]);
    71 |     echo "\n--- 创建退款订单2 ---\n";
    72 |     var_export($result);
    73 | 
    74 |     $result = $payment->queryRefund($out_refund_no);
    75 | 
    76 |     echo "\n--- 查询退款订单2 ---\n";
    77 |     var_export($result);
    78 | 
    79 | } catch (\Exception $exception) {
    80 |     // 出错啦,处理下吧
    81 |     echo $exception->getMessage() . PHP_EOL;
    82 | }
    
    
    --------------------------------------------------------------------------------
    /_test/pay-v3-transfer.php:
    --------------------------------------------------------------------------------
     1 | batchs([
    27 |         'out_batch_no'         => 'plfk2020042013',
    28 |         'batch_name'           => '2019年1月深圳分部报销单',
    29 |         'batch_remark'         => '2019年1月深圳分部报销单',
    30 |         'total_amount'         => 100,
    31 |         'transfer_detail_list' => [
    32 |             [
    33 |                 'out_detail_no'   => 'x23zy545Bd5436',
    34 |                 'transfer_amount' => 100,
    35 |                 'transfer_remark' => '2020年4月报销',
    36 |                 'openid'          => 'o-MYE42l80oelYMDE34nYD456Xoy',
    37 |                 'user_name'       => '小小邹'
    38 |             ]
    39 |         ]
    40 |     ]);
    41 | 
    42 |     echo "\n--- 批量打款 ---\n";
    43 |     var_export($result);
    44 | 
    45 | } catch (\Exception $exception) {
    46 |     // 出错啦,处理下吧
    47 |     echo $exception->getMessage() . PHP_EOL;
    48 | }
    
    
    --------------------------------------------------------------------------------
    /_test/wechat-jssdk-sign.php:
    --------------------------------------------------------------------------------
     1 | getJsSign('https://a.com/test.php');
    32 | 
    33 |     var_export($result);
    34 | 
    35 | } catch (Exception $e) {
    36 | 
    37 |     // 出错啦,处理下吧
    38 |     echo $e->getMessage() . PHP_EOL;
    39 | 
    40 | }
    
    
    --------------------------------------------------------------------------------
    /_test/wechat-menu-get.php:
    --------------------------------------------------------------------------------
     1 | get();
    32 | 
    33 |     var_export($result);
    34 | 
    35 | } catch (Exception $e) {
    36 | 
    37 |     // 出错啦,处理下吧
    38 |     echo $e->getMessage() . PHP_EOL;
    39 | 
    40 | }
    
    
    --------------------------------------------------------------------------------
    /_test/wechat-qrcode-create.php:
    --------------------------------------------------------------------------------
     1 | create('场景内容');
    32 |     echo var_export($result, true) . PHP_EOL;
    33 | 
    34 |     // 5. 创建二维码链接
    35 |     $url = $wechat->url($result['ticket']);
    36 |     echo var_export($url, true);
    37 | 
    38 | 
    39 | } catch (Exception $e) {
    40 | 
    41 |     // 出错啦,处理下吧
    42 |     echo $e->getMessage() . PHP_EOL;
    43 | 
    44 | }
    
    
    --------------------------------------------------------------------------------
    /_test/wechat-user-get.php:
    --------------------------------------------------------------------------------
     1 | getUserList();
    32 | 
    33 |     echo '
    ';
    34 |     var_export($result);
    35 | 
    36 |     // 5. 批量获取用户资料
    37 |     foreach (array_chunk($result['data']['openid'], 100) as $item) {
    38 |         $userList = $wechat->getBatchUserInfo($item);
    39 |         var_export($userList);
    40 |     }
    41 | 
    42 | } catch (Exception $e) {
    43 | 
    44 |     // 出错啦,处理下吧
    45 |     echo $e->getMessage() . PHP_EOL;
    46 | 
    47 | }
    
    
    --------------------------------------------------------------------------------
    /_test/work-config.php:
    --------------------------------------------------------------------------------
     1 |  function ($name, $value, $expired = 360) {
    26 | //        var_dump(func_get_args());
    27 | //         return $value;
    28 | //    },
    29 | //    'get' => function ($name) {
    30 | //        var_dump(func_get_args());
    31 | //        return $value;
    32 | //    },
    33 | //    'del' => function ($name) {
    34 | //        var_dump(func_get_args());
    35 | //        return true;
    36 | //    },
    37 | //    'put' => function ($name) {
    38 | //        var_dump(func_get_args());
    39 | //        return $filePath;
    40 | //    },
    41 | // ];
    42 | 
    43 | return [
    44 |     'appid'      => '', // 企业ID
    45 |     'appsecret'  => '', // 应用的凭证密钥
    46 |     'cache_path' => '', // 配置缓存目录
    47 | ];
    
    
    --------------------------------------------------------------------------------
    /_test/work-department.php:
    --------------------------------------------------------------------------------
     1 | callGetApi($url);
    26 |     echo '
    ';
    27 |     print_r(BasicWeWork::instance($config)->config->get());
    28 |     print_r($result);
    29 |     echo '
    '; 30 | } catch (Exception $exception) { 31 | echo $exception->getMessage() . PHP_EOL; 32 | } 33 | -------------------------------------------------------------------------------- /composer.json: -------------------------------------------------------------------------------- 1 | { 2 | "type": "library", 3 | "name": "zoujingli/wechat-developer", 4 | "homepage": "https://thinkadmin.top", 5 | "description": "WeChat and Alipay Platform Development", 6 | "license": "MIT", 7 | "authors": [ 8 | { 9 | "name": "Anyon", 10 | "email": "zoujingli@qq.com", 11 | "homepage": "https://thinkadmin.top" 12 | } 13 | ], 14 | "keywords": [ 15 | "AliPay", 16 | "WeMini", 17 | "WeChat", 18 | "WeChatPay", 19 | "WeChatDeveloper" 20 | ], 21 | "require": { 22 | "php": ">=5.4", 23 | "ext-xml": "*", 24 | "ext-json": "*", 25 | "ext-curl": "*", 26 | "ext-bcmath": "*", 27 | "ext-libxml": "*", 28 | "ext-openssl": "*", 29 | "ext-mbstring": "*", 30 | "ext-simplexml": "*" 31 | }, 32 | "autoload": { 33 | "files": [ 34 | "helper.php" 35 | ], 36 | "classmap": [ 37 | "We.php" 38 | ], 39 | "psr-4": { 40 | "WePay\\": "WePay", 41 | "WeChat\\": "WeChat", 42 | "WeMini\\": "WeMini", 43 | "AliPay\\": "AliPay", 44 | "WePayV3\\": "WePayV3" 45 | } 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /helper.php: -------------------------------------------------------------------------------- 1 | 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | --------------------------------------------------------------------------------