>php教程 >php手册 >ThinkPay의 최신 WeChat 결제 공식 계정 결제 드라이버 공유

ThinkPay의 최신 WeChat 결제 공식 계정 결제 드라이버 공유

WBOY
WBOY원래의
2016-12-01 00:00:171433검색

ThinkPay의 최신 WeChat 결제 공식 계정 결제 드라이버 공유
모두의 편의를 위해 ThinkPay의 WeChat 결제 드라이버를 공유해 보겠습니다. 궁금한 점이 있으면 QQ 그룹 토론 105108204<?php<br />에 참여하세요. // +--------------------- --- ----------<br /> // | 제로 클라우드 [간단하고 효율적이며 우수함]<br /> // +--------------------- --- ----------<br /> // | Copyright (c) 2016 http://www.lingyun.net All Rights Reserved.<br /> // +--------------------- --- ----------<br /> // | 작성자: jry <598821125@qq.com><br> // +--------------------- --- ----------<br> 네임스페이스 AddonsPayThinkPayPayDriver;<br> <br> /**<br> * 위챗 결제 드라이버<br> ​*/<br> 클래스 Wxpay는 AddonsPayThinkPayPayPay를 확장합니다<br> {<br> protected $gateway = 'https://api.mch.weixin.qq.com/pay/unifiedorder';<br> 보호된 $orderquery = 'https://api.mch.weixin.qq.com/pay/orderquery';<br> 보호된 $config = 배열(<br> >                                                  'appsecret' => '',<br> 'mchid' => '',<br> '열쇠' );<br> <br> 공개함수 확인()<br> {<br> if (!$this->config['appid'] || !$this->config['appsecret'] || !$this->config['mchid'] || !$this-> config['키']) {<br> E("위챗 결제 설정이 잘못되었습니다!");<br>         }<br>          true를 반환합니다.<br> }<br> <br> 공개 함수 buildRequestForm($pay_data)<br> {<br>              // 앱 결제<br> If (C('IS_API')) {<br>              $param = 배열(<br> > >      > 한 번도 없었습니다.” 'Mch_id' = & gt; $ this- & gt; config ['mchid'], <br> ~ ~                          왜냐면 ~                                                                                              왜냐하면 'OUT_TRADE_NO' = & GT; $ Pay_data ['OUT_TRADE_NO'], <br> ~                                                                                                                                      'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],<br> 'Notify_url' = & gt; $ this-& gt; config ['notify_url'], <br>               'trade_type'                                                                                       ~                        );<br> <br> // 서명              $param['sign'] = $this->MakeSign($param);<br> ~                                           $result = $this->FromXml($this->postXmlCurl($xml_param, $this->gateway));<br> If ($result['return_code'] === '성공') {<br> If ($this->CheckSign($result)) {<br> // 주문 인터페이스를 통일하여 일반 prepay_id를 반환한 다음 서명 사양에 따라 서명을 다시 생성하고 데이터를 앱으로 전송합니다. <br> // 참여하는 서명 필드는 Appid, Partnerid, Prepayid, Noncestr, Timestamp, Package입니다. 참고: 패키지의 값 형식은 Sign=WXPay<br>입니다. $prepayparams = 배열();<br> ~                                                                       $prepayparams['partnerid'] = $result['mch_id'];<br>                     $prepayparams['prepayid'] = $result['prepay_id'];<br>                     $prepayparams['noncestr'] = $result['nonce_str'];<br> ~                                                                    $prepayparams['timestamp'] = time();<br> ~ ~                          $ Return ['json'] = json_encode ($ prepayparams) <br>                       $return 반환;<br>                 }<br>             }<br>            } else {<br>                             // 사용자 openId 획득, WeChat 공개 계정 JSAPI 결제는 <br>이어야 합니다.               $openId = $this->GetOpenid();<br>                 $param = 배열(<br> 'Appid' = & gt; $ this-& gt; config ['appid'], <br> 'Mch_id' = & gt; $ this- & gt; config ['mchid'], <br>                'nonce_str'        => $this->getNonceStr(),<br>                 '본문'             => $pay_data['몸'],<br>                 'out_trade_no'     => $pay_data['out_trade_no'],<br>                 'total_fee'        => $pay_data['money'] * 100,<br>                 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],<br>                 'notify_url'       => $this->config['notify_url'],<br>                 '무역 유형'       => 'JSAPI',<br>                 'openid'           => $openId,<br>             );<br> <br>             // 설명<br>             $param['sign'] = $this->MakeSign($param);<br>             $xml_param     = $this->ToXml($param);<br>             $result        = $this->FromXml($this->postXmlCurl($xml_param, $this->gateway));<br>             if ($result['return_code'] === '성공') {<br>                 if ($this->CheckSign($result)) {<br>                     // 获取JSAPI所需参数<br>                     $jsApiParameters = $this->GetJsApiParameters($result);<br>                     $pay_page        = <<<EOF<br />                         <html><br>                             <br>                                 <meta http-equiv="content-type" content="text/html;charset=utf-8"/><br>                                 <meta name="viewport" content="width=device-width, initial-scale=1"/><br>                                 <title>微信支付</title> <br>                                 <script type="text/javascript"><br>//WeChat JS API 결제 호출<br> 함수 jsApiCall()<br> ~ WeixinJSBridge.invoke(<br> 'getBrandWCPayRequest',<br> ~ 함수(res){<br> WeixinJSBridge.log(res.err_msg);<br> >                            } <br>                                                      ~ ~                                                 } <br> 함수 callpay()<br> ~ If (WeixinJSBridge 유형 == "정의되지 않음"){<br> If(document.addEventListener){<br> document.addEventListener('WeixinJSBridgeReady', jsApiCall, false);<br> } Else if (document.attachevent) {<br>                                             document.attachEvent('WeixinJSBridgeReady', jsApiCall);<br>                                             document.attachEvent('onWeixinJSBridgeReady', jsApiCall);<br>                                         }<br>                                     }else{<br>                                         jsApiCall();<br>                                     }<br>                                 }<br>                                 </script><br>                             </head><br>                             <body><br>                                 <br/><br>                                 <font color="#9ACD32"><b>该笔订单支付金额为<span style="color:#f00;font-size:50px">{$pay_data['money']}</span>元</b></font><br/><br/><br>                                 <div align="center"><br>                                     <button style="width:210px; height:50px; border-radius: 15px;background-color:#FE6714; border:0px #FE6714 solid; cursor: pointer; color:white; font-size:16px;" type="button" onclick="callpay()" >立即支付</button><br>                                 </div><br> ~ ~ EOF;<br> $ pay_page 반환 <br>                 }<br>                                                      그 외 {<br> E("위챗 주문 오류!" . $result['return_msg']);<br>             }<br>         }<br> }<br> <br> /**<br> * * 비동기 알림 확인<br> ​​*/<br> 공개 함수 verifyNotify($notify)<br> {<br> ​​​​ //알림 데이터 가져오기<br> If ($notify['return_code'] === '성공') {<br> If (!array_key_exists("transaction_id", $notify)) {<br> E("입력 매개변수가 올바르지 않습니다!");<br>             }<br>              $param['transaction_id'] = $notify["transaction_id"];<br> ~ ~                           를 통해 ~ ~                            를 통해 > ~ $param['sign'] = $this->MakeSign($param);<br> >                                                      $result = $this->FromXml($this->postXmlCurl($xml_param, $this->orderquery));<br> If ($this->CheckSign($result)) {<br>               $result['status'] = ($result['result_code'] == 'SUCCESS') ? true : false;<br>                $result['money'] = $result['total_fee'] / 100;<br> ~ ~                         true를 반환합니다.<br>             }<br>            } else {<br> E('오류 알림');<br>         }<br> }<br> <br> /**<br> *<br> * jsapi 결제 매개변수 가져오기<br> * @param array $UnifiedOrderResult 통합 결제 인터페이스에서 반환된 데이터<br> * @WxPayException 발생<br>*<br> * @return json 데이터, js 함수에 매개변수로 직접 입력할 수 있음 <br> */<br> 공용 함수 GetJsApiParameters($UnifiedOrderResult)<br> {<br> If (!array_key_exists("appid", $UnifiedOrderResult)<br> >                    || $UnifiedOrderResult['prepay_id'] == "") {<br> E("매개변수 오류");<br>         }<br>         $jsapi['appId']                                                                                       $jsapi['timeStamp'] = (문자열) 시간();<br>          $jsapi['nonceStr'] = $this->getNonceStr();<br> >             $jsapi['package'] = "prepay_id=" . $UnifiedOrderResult['prepay_id'];<br>          $jsapi['signType'] = 'MD5';<br> >                    $parameters = json_encode($jsapi);<br>           $매개변수를 반환합니다.<br> }<br> <br> /**<br> * 포스트 모드에서 해당 인터페이스 URL에 xml을 제출하세요<br> *<br> * @param string $xml 게시에 필요한 XML 데이터<br> * @param 문자열 $url url<br> * @param bool $useCert 인증서 필수 여부, 기본적으로 필수 아님<br> * @param int $second URL 실행 시간 초과, 기본값은 30초<br> * @WxPayException 발생<br> ​​*/<br> 비공개 정적 함수 postXmlCurl($xml, $url, $useCert = false, $second = 30)<br> {<br>          $ch = 컬_init();<br> ​​​​ //시간 초과 설정<br>         cur_setopt($ch, CURLOPT_TIMEOUT, $second);<br> <br> ​​​​ //프록시가 구성되어 있으면 여기서 프록시를 설정하세요<br>             // if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"<br> ~ ~                              cur_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);<br>                                  curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);<br> |         컬_setopt($ch, CURLOPT_URL, $url);<br> 컬_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);<br>         cur_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2) //엄격한 검증<br> ​​​​ //헤더 설정<br>         cur_setopt($ch, CURLOPT_HEADER, false);<br> ​​​​ //결과를 문자열로 요구하고 화면에 출력합니다<br>컬_setopt($ch, CURLOPT_RETURNTRANSFER, true);<br> <br> If ($useCert == true) {<br> > 인증서를 설정하려면 <br>                   //인증서 사용: 인증서와 키는 각각 두 개의 .pem 파일에 속합니다 <br>             cur_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');<br>             cur_setopt($ch, CURLOPT_SSLCERT, WxPayConfig::SSLCERT_PATH);<br>              cur_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');<br>             cur_setopt($ch, CURLOPT_SSLKEY, WxPayConfig::SSLKEY_PATH);<br>         }<br> ​​​​ //포스트 제출 방법<br>         cur_setopt($ch, CURLOPT_POST, true);<br>         컬_setopt($ch, CURLOPT_POSTFIELDS, $xml);<br> ​​​​ //컬 실행<br>         $data = 컬_exec($ch);<br>                //결과 반환<br>           if ($data) {<br>                컬_닫기($ch);<br>                 $data 반환;<br>            } else {<br>                $error = 컬_errno($ch);<br>                컬_닫기($ch);<br> E("컬 오류, 오류 코드: $error");<br>         }<br> }<br> <br> /*<br> * 32자 이하의 임의 문자열을 생성합니다. <br> * @param int $length<br> * * @return 무작위 문자열 생성 <br> */<br> 공용 정적 함수 getNonceStr($length = 32)<br> {<br>          $chars = "abcdefghijklmnopqrstuvwxyz0123456789";<br> ~                                         for ($i = 0; $i < $length; $i++) {<br />               $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);<br />         }<br />          $str 반환<br /> }<br /> <br /> /**<br /> * 서명 생성<br /> * @return Signature, 이 함수는 sign 멤버 변수를 포함하지 않습니다. 서명을 설정하려면 SetSign 메서드를 호출하여 값을 할당해야 합니다. <br /> ​​*/<br /> 공용 함수 MakeSign($param)<br /> {<br /> ​​​​ //서명 1단계: 사전순으로 매개변수 정렬<br />          ksort($param);<br />          $string = $this->ToUrlParams($param);<br> ​​​​ //서명 2단계: 문자열 뒤에 KEY<br> 추가 $string = $string . "&key=" . $this->config['key'];<br> ​​​​ //서명 3단계: MD5 암호화<br>         $string = md5($string);<br> ​​​​ //서명 4단계: 모든 문자를 대문자로 변환<br>         $result = strtoupper($string);<br>           $result 반환<br> }<br> <br> /**<br> *<br>     * 检测签명<br>      */<br>     공개 함수 CheckSign($param)<br>     {<br>         $sign = $this->MakeSign($param);<br>         if ($param['sign'] == $sign) {<br>             true를 반환합니다.<br>         } 그밖에 {<br>             E("签name错误!");<br>         }<br>     }<br> <br>     /**<br> *<br> * * 서명문자열 접합<br> * @param 배열 $urlObj<br> *<br> * @return 연결된 문자열을 반환합니다 <br> ​​*/<br>     공개 함수 ToUrlParams($param)<br>     {<br>         $buff = "";<br>         foreach($param은 $k =>$v) {<br>             if ($k != "sign" && $v != "" && !is_array($v)) {<br>                 $버프 .= $k . "=" . $v . "&";<br>             }<br>         }<br> <br>         $buff = trim($buff, "&");<br>         $buff 반환;<br>     }<br> <br>     /**<br> * XML 문자 출력 <br> * @WxPayException 발생<br> **/<br>     공개 함수 ToXml($param)<br>     {<br>         if (!is_array($param)<br>             || 개수($param) <= 0) {<br />             E("数组数据异常!");<br />         }<br /> <br />         $xml = "<xml>";<br>         foreach($param은 $key로 =>$val) {<br>             if (is_numeric($val)) {<br>                 $xml .= "<" . $키 . ">" . $발 . "</" . $키 . ">";<br>             } 그밖에 {<br>                 $xml .= "<" . $키 . "><![CDATA[" . $발 . "]]></" . $키 . ">";<br>             }<br>         }<br>         $xml .= "</xml>";<br>         $xml 반환<br>     }<br> <br>     /**<br> * XML을 배열로 변환<br> * @param 문자열 $xml<br> * @WxPayException 발생<br> ​​*/<br>     공개 함수 FromXml($xml)<br>     {<br>         if (!$xml) {<br>             E("xml数据异常!");<br>         }<br>​​​​ //XML을 배열로 변환<br> ​​​​ //외부 XML 엔터티 참조는 금지됩니다<br> ​​​​libxml_disable_entity_loader(true);<br>          $this->values ​​​​= json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);<br>           $this->값 반환<br> }<br> <br> /**<br> *<br> * 점프를 통해 사용자의 openid를 가져옵니다. <br> * 1. 콜백에 필요한 URL 및 기타 매개변수를 설정하고 WeChat 서버 https://open.weixin.qq.com/connect/oauth2/authorize<br>로 이동합니다. * 2. WeChat 서비스 처리가 완료되면 사용자 리디렉션_uri 주소로 다시 이동합니다. 이때 다음과 같은 일부 매개변수가 가져옵니다.<br> *<br> * @return 사용자의 openid<br> ​​*/<br> 공개 함수 GetOpenid()<br> {<br> ​​​​ //코드를 통해 openid 얻기<br> If (!isset($_GET['code'])) {<br> //WeChat 반환 코드 실행<br> $baseUrl = urlencode('http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI']);<br> >                                            Header("위치: $url");<br> 종료();<br>            } else {<br> // Openid를 얻기 위한 코드를 얻습니다 <br> $code = $_GET['코드'];<br>              $openid = $this->getOpenidFromMp($code);<br>                  $openid 반환;<br>         }<br> }<br> <br> /**<br> *<br> * 코드를 통해 작업 플랫폼에서 openid 머신 access_token을 가져옵니다<br> * @param string $code 위챗에서 가져온 코드<br> *<br> * @return openid<br> ​​*/<br> 공개 함수 GetOpenidFromMp($code)<br> {<br>          $url = $this->__CreateOauthUrlForOpenid($code);<br> ​​​​ //컬 초기화<br>          $ch = 컬_init();<br> ​​​​ //시간 초과 설정<br>         컬_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);<br>         컬_setopt($ch, CURLOPT_URL, $url);<br>         cur_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);<br>         cur_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);<br>         cur_setopt($ch, CURLOPT_HEADER, false);<br> 컬_setopt($ch, CURLOPT_RETURNTRANSFER, true);<br>             // if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"<br> ~ ~                              cur_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);<br>        //             curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);<br>         //         }<br>         //运行curl,结果以jason형式返回<br>         $res = curl_exec($ch);<br>         컬_닫기($ch);<br>         //출출openid<br>         $data       = json_decode($res, true);<br>         $this->data = $data;<br>         $openid     = $data['openid'];<br>         $openid 반환;<br>     }<br> <br>     /**<br> *<br> * 코드를 얻으려면 URL 연결을 구성하세요<br> * @param string $redirectUrl WeChat 서버가 반송하는 URL, URL 인코딩이 필요합니다 <br> *<br> * @return 생성된 URL을 반환합니다<br> ​​*/<br>     비공개 함수 __CreateOauthUrlForCode($redirectUrl)<br>     {<br>         $urlObj["appid"]         = $this->config['appid'];<br>         $urlObj["redirect_uri"]  = "$redirectUrl";<br>         $urlObj["response_type"] = "코드";<br>         $urlObj["scope"]         = "snsapi_base";<br>         $urlObj["state"]         = "#wechat_redirect";<br>         $bizString              = $this->ToUrlParams($urlObj);<br>         "https://open.weixin.qq.com/connect/oauth2/authorize?"를 반환합니다. . $bizString;<br>     }<br> <br>     /**<br> *<br> * open 및 access_toke의 URL 주소를 얻기 위한 구성<br> * @param string $code, 위챗 점프에서 가져온 코드<br> *<br> * @return 요청 URL<br> ​​*/<br>     비공개 함수 __CreateOauthUrlForOpenid($code)<br>     {<br>         $urlObj["appid"]      = $this->config['appid'];<br>         $urlObj["secret"]     = $this->config['appsecret'];<br>         $urlObj["code"]       = $code;<br>         $urlObj["grant_type"] = "authorization_code";<br>         $bizString            = $this->ToUrlParams($urlObj);<br>         "https://api.weixin.qq.com/sns/oauth2/access_token?"을 반환합니다. . $bizString;<br>     }<br> }

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.