weixin_public.class.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152
  1. <?php
  2. /**
  3. * 微信支付服务器端下单
  4. * 微信APP支付文档地址: https://pay.weixin.qq.com/wiki/doc/api/app.php?chapter=8_6
  5. * 使用示例
  6. * 构造方法参数
  7. * 'appid' => //填写微信分配的公众账号ID
  8. * 'mch_id' => //填写微信支付分配的商户号
  9. * 'notify_url'=> //填写微信支付结果回调地址
  10. * 'key' => //填写微信商户支付密钥
  11. * );
  12. * 统一下单方法
  13. * $WechatAppPay = new wechatAppPay($options);
  14. * $params['body'] = '商品描述'; //商品描述
  15. * $params['out_trade_no'] = '1217752501201407'; //自定义的订单号,不能重复
  16. * $params['total_fee'] = '100'; //订单金额 只能为整数 单位为分
  17. * $params['trade_type'] = 'APP'; //交易类型 JSAPI | NATIVE |APP | WAP
  18. * $wechatAppPay->unifiedOrder( $params );
  19. */
  20. class weixin_public
  21. {
  22. private $appid;
  23. private $seceret;
  24. private $uri;
  25. public function __construct($appid, $seceret, $uri)
  26. {
  27. $this->appid = $appid;
  28. $this->seceret = $seceret;
  29. $this->uri = $uri;
  30. }
  31. //获取code
  32. public function redirectWithCode()
  33. {
  34. $url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$this->appid
  35. ."&redirect_uri=".urlencode($this->uri)
  36. ."&response_type=code&scope=snsapi_userinfo&state=".time()."#wechat_redirect";
  37. return $url;
  38. }
  39. private function getAcessTokenAndOpenId($code)
  40. {
  41. $url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid
  42. ."&secret=".$this->seceret."&code=".$code."&grant_type=authorization_code";
  43. $jsonInfo = file_get_contents($url);
  44. return json_decode($jsonInfo, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP 变量
  45. }
  46. private function getBaseToken()
  47. {
  48. $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$this->appid."&secret=".$this->seceret;
  49. $jsonInfo = file_get_contents($url);
  50. return json_decode($jsonInfo, true);
  51. }
  52. private function getJsTicket($access_token)
  53. {
  54. $url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=".$access_token."&type=jsapi"; // 两小时有效
  55. $jsonInfo = file_get_contents($url);
  56. return json_decode($jsonInfo,true);
  57. }
  58. private function createNonceStr($length = 16) {
  59. $chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
  60. $str = "";
  61. for ($i = 0; $i < $length; $i++) {
  62. $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
  63. }
  64. return $str;
  65. }
  66. private function getSignPackage($jsToken, $jsUrl) {
  67. // 注意 URL 一定要动态获取,不能 hardcode.
  68. $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
  69. //$jsUrl = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
  70. //$jsUrl = "$protocol$_SERVER[HTTP_HOST]/front-page/fission-page.html";
  71. $nonceStr = self::createNonceStr();
  72. $timestamp = time();
  73. // 这里参数的顺序要按照 key 值 ASCII 码升序排序
  74. $string = "jsapi_ticket=$jsToken&noncestr=$nonceStr&timestamp=$timestamp&url=$jsUrl";
  75. $signature = sha1($string);
  76. $signPackage = array(
  77. "appId" => $this->appid,
  78. "nonceStr" => $nonceStr,
  79. "timestamp" => $timestamp,
  80. "url" => $jsUrl,
  81. "signature" => $signature,
  82. "rawString" => $string
  83. );
  84. return $signPackage;
  85. }
  86. public function getAllInfo($code, $jsUrl)
  87. {
  88. $reader = array();
  89. $info = self::getAcessTokenAndOpenId($code);
  90. if (empty($info['access_token']) || empty($info['openid'])) {
  91. return $reader;
  92. }
  93. $baseTokenInfo = self::getBaseToken();
  94. if (empty($baseTokenInfo['access_token'])) {
  95. return $baseTokenInfo;
  96. }
  97. $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=".$baseTokenInfo['access_token']."&openid=".$info['openid']."&lang=zh_CN";
  98. $jsonInfo = file_get_contents($url);
  99. //$jsonInfo = iconv('ISO-8859-1', 'UTF-8', $jsonInfo);
  100. $rs = json_decode($jsonInfo, true); //接受一个 JSON 格式的字符串并且把它转换为 PHP 变量
  101. if(empty($rs['openid'])) {
  102. return $rs;
  103. }
  104. $attr['country'] = $rs['country'];
  105. $attr['province'] = $rs['province'];
  106. $attr['city'] = $rs['city'];
  107. $attr['headimgurl'] = $rs['headimgurl'];
  108. $attr['openid'] = $rs['openid'];
  109. $attr['nickname'] = $rs['nickname'];
  110. $attr['sex'] = $rs['sex'];
  111. $attr['subscribe'] = $rs['subscribe'];
  112. $attr['subscribe_time'] = $rs['subscribe_time'];
  113. $reader = Reader::getInfoByOpenId($info['openid']);
  114. Reader::addOrUpdate($reader['id'], $attr);
  115. $reader = Reader::getInfoByOpenId($info['openid']);
  116. $jsTokenInfo = self::getJsTicket($baseTokenInfo['access_token']);
  117. if (empty($jsTokenInfo['ticket'])) {
  118. return $jsTokenInfo;
  119. }
  120. $signPackage = self::getSignPackage($jsTokenInfo['ticket'], $jsUrl);
  121. $reader['js_sign'] = $signPackage;
  122. return $reader;
  123. }
  124. }