ThinkPayの最新WeChat決済公式アカウント決済ドライバー共有
皆様の便宜のために、ThinkPay の WeChat 支払いドライバーを共有しましょう。ご質問がある場合は、105108204 で QQ グループ ディスカッションに参加してください<?php<br />。
// +---------------------------------------------- --- ----------------------------------<br />
// | ゼロクラウド [シンプル、効率的、優れた]<br />
// +---------------------------------------------- --- ----------------------------------<br />
// | 著作権 (c) 2016 http://www.lingyun.net 無断複写・転載を禁じます<br />
// +---------------------------------------------- --- ----------------------------------<br />
// | 著者: jry <598821125@qq.com><br />
// +---------------------------------------------- --- ----------------------------------<br />
名前空間AddonsPayThinkPayPayDriver;<br />
<br />
/**<br />
* WeChat 支払いドライバー<br />
*/<br />
クラス Wxpay は AddonsPayThinkPayPayPay を拡張します<br />
{<br />
保護された $gateway = 'https://api.mch.weixin.qq.com/pay/unifiedorder';<br />
Protected $orderquery = 'https://api.mch.weixin.qq.com/pay/orderquery';<br />
protected $config = array(<br />
'appsecret' =>
「mchid」 => <br>
);<br>
<br>
パブリック関数 check()<br>
{<br>
if (!$this->config['appid'] || !$this->config['appsecret'] || !$this->config['mchid'] || !$this-> config['key']) {<br>
E("WeChat の支払い設定が間違っています!");<br>
}<br>
true を返します;<br>
}<br>
<br>
パブリック関数 buildRequestForm($pay_data)<br>
{<br>
// アプリ支払い<br>
If (C('IS_API')) {<br>
$param = array(<br>
それ以来「appid」
「mch_id」のため
「NonCe_str」から
「本体」のため
'out_trade_no'
'total_fee'
'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],<br>
「Notify_url」から
'trade_type' now);<br>
<br>
$param['sign'] = $this->MakeSign($param);<br>
$result = $this->FromXml($this->postXmlCurl($xml_param, $this->gateway));<br>
If ($result['return_code'] === 'SUCCESS') {<br>
If ($this->CheckSign($result)) {<br>
// Unified Ordering Interfaceは通常のPrepay_idを返し、署名仕様に従って署名を再生し、データをアプリに送信します。 <br>
// 署名フィールドに参加するのは、appid、partnerid、prepayid、noncestr、timestamp、package です。注: パッケージの値の形式は Sign=WXPay です<br>
$prepayparams = array();<br>
$ prepayparams ['appid']
$prepayparams['partnerid'] = $result['mch_id'];<br>
$prepayparams['prepayid'] = $result['prepay_id'];<br>
$prepayparams['noncestr'] = $result['nonce_str'];<br>
$ prepayparams ['package']
$prepayparams['timestamp'] = time();<br>
$ prepayparams ['sign']
$return['json']
戻る
}<br>
}<br>
else {<br>
// ユーザーの openId を取得します。WeChat パブリック アカウント JSAPI 支払いが必要です <br>
$openId = $this->GetOpenid();<br>
$param = array(<br>
それ以来「appid」
「mch_id」のため 'nonce_str' => $this->getNonceStr(),<br>
「本体」 => $pay_data['body'],<br>
「out_trade_no」 => $pay_data['out_trade_no'],<br>
'total_fee' => $pay_data['お金'] * 100,<br>
「spbill_create_ip」 => $_SERVER['REMOTE_ADDR']、<br>
「notify_url」 => $this->config['notify_url'],<br>
'trade_type' => 「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'] === 'SUCCESS') {<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>
関数 jsApiCall()<br>
WeixinJSBridge.invoke(<br>
「getBrandWCPayRequest」、<br>
関数(解像度){<br>
WeixinJSBridge.log(res.err_msg);<br>
//alert(res.err_code+res.err_desc+res.err_msg);
);<br>
<br>
関数 callpay()<br>
If (WeixinJSBridge の種類 == "未定義"){<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>
終わり;<br>
}<br>
- "それ以外
E("WeChat 注文エラー!" . $result['return_msg']);<br>
}<br>
}<br>
}<br>
<br>
/**<br>
* * 非同期通知の検証<br>
*/<br>
パブリック関数 verifyNotify($notify)<br>
{<br>
//通知データを取得します<br>
If ($notify['return_code'] === 'SUCCESS') {<br>
If (!array_key_exists("transaction_id", $notify)) {<br>
E("入力パラメータが間違っています!");<br>
}<br>
$param['transaction_id'] = $notify["transaction_id"];<br>
$param['appid']
$ param ['mch_id']スルー
$ param ['nonce_str']
$ param ['sign']
$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>
$ this-&gt; info
true を返す;<br>
}<br>
else {<br>
E('通知エラー');<br>
}<br>
}<br>
<br>
/**<br>
*<br>
* jsapi Paymentのパラメータを取得します<br>
* @param array $UnifiedOrderResult 統合支払いインターフェースによって返されるデータ<br>
* @throws WxPayException<br> *<br>
* @return jsonデータ、js関数数をパラメータとして直接入力可能<br>
*/<br>
パブリック関数 GetJsApiParameters($UnifiedOrderResult)<br>
{<br>
if (!array_key_exists("appid", $UnifiedOrderResult)<br>
|| !array_key_exists("prepay_id", $UnifiedOrderResult)<br>
|| $UnifiedOrderResult['prepay_id'] == "") {<br>
E("パラメータ错误");<br>
}<br>
$jsapi['appId'] = $UnifiedOrderResult["appid"];<br>
$jsapi['timeStamp'] = (文字列) time();<br>
$jsapi['nonceStr'] = $this->getNonceStr();<br>
$jsapi['appId'] = $UnifiedOrderResult["appid"];<br>
$jsapi['package'] = 「prepay_id=」。 $UnifiedOrderResult['prepay_id'];<br>
$jsapi['signType'] = 'MD5';<br>
$jsapi['paySign'] = $this->MakeSign($jsapi);<br>
$parameters = json_encode($jsapi);<br>
$パラメータを返す;<br>
}<br>
<br>
/**<br>
* 投稿モードで対応するインターフェイス URL に XML を送信します<br>
*<br>
* @param string $xml 投稿にはXMLデータが必要です<br>
* @param string $url URL<br>
* @param bool $useCert 証明書が必要かどうか、デフォルトでは不要<br>
* @param int $sec URL 実行タイムアウト、デフォルトは 30 秒<br>
* @throws WxPayException<br>
*/<br>
private static function postXmlCurl($xml, $url, $useCert = false, $sec = 30)<br>
{<br>
$ch = curl_init();<br>
//設置超時間<br>
curl_setopt($ch, CURLOPT_TIMEOUT, $秒);<br>
<br>
//結果があれば配置代理人この里就配置代理人<br>
// if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"<br>
// && WxPayConfig::CURL_PROXY_PORT != 0){<br>
// curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);<br>
// curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);<br>
// }<br>
curl_setopt($ch, CURLOPT_URL, $url);<br>
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);<br>
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2); //严格校验<br>
//ヘッダーを設置します<br>
curl_setopt($ch, CURLOPT_HEADER, false);<br>
//要求結果は文字列であり、画面上に出力されます<br>curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);<br>
<br>
if ($useCert == true) {<br>
証明書を設定するには<br>
//証明書を使用します: 証明書とキーはそれぞれ 2 つの .pem ファイルに属します<br>
curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');<br>
curl_setopt($ch, CURLOPT_SSLCERT, WxPayConfig::SSLCERT_PATH);<br>
curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');<br>
curl_setopt($ch, CURLOPT_SSLKEY, WxPayConfig::SSLKEY_PATH);<br>
}<br>
// 投稿方法<br>
curl_setopt($ch, CURLOPT_POST, true);<br>
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);<br>
//カールを実行します<br>
$data =curl_exec($ch);<br>
//結果を返す<br>
if ($data) {<br>
curl_close($ch);<br>
return $data;<br>
else {<br>
$error =curl_errno($ch);<br>
curl_close($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>
$str
for ($i = 0; $i
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);<br>
}<br>
$ Str を返します。
}<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 . $this->config['key'];<br>
//署名ステップ 3: MD5 暗号化<br>
$string = md5($string);<br>
//署名ステップ 4: すべての文字を大文字に変換します<br>
$result = strtoupper($string);<br>
$ の結果を返します。
}<br>
<br>
/**<br>
*<br> * 检测签名<br>
*/<br>
公開関数CheckSign($param)<br>
{<br>
$sign = $this->MakeSign($param);<br>
if ($param['sign'] == $sign) {<br>
true を返します;<br>
} else {<br>
E("签名错误!");<br>
}<br>
}<br>
<br>
/**<br>
*<br>
* * 署名文字列を接続しています<br>
* @param 配列 $urlObj<br>
*<br>
* @return 連結された文字列を返します<br>
*/<br>
パブリック関数ToUrlParams($param)<br>
{<br>
$buff = "";<br>
foreach ($param as $k => $v) {<br>
if ($k != "sign" && $v != "" && !is_array($v)) {<br>
$buff .= $k . 「=」 $v 。 "&";<br>
}<br>
}<br>
<br>
$buff = trim($buff, "&");<br>
$buff を返します;<br>
}<br>
<br>
/**<br>
* XML文字を出力します <br>
* @throws WxPayException<br>
**/<br>
パブリック関数ToXml($param)<br>
{<br>
if (!is_array($param)<br>
|| count($param)
E("数组データベース异常!");<br>
}<br>
<br>
$xml = "<xml>";<br>
foreach ($param as $key => $val) {<br>
if (is_numeric($val)) {<br>
$xml .= "<" 。 $key 。 「>」 。 $val 。 「</」 。 $key 。 ">";<br />
} else {<br />
$xml .= "<" 。 $key 。 "><![CDATA[" . $val 。 「]]></」 $key 。 ">";<br />
}<br />
}<br />
$xml .= "</xml>";<br>
$xml を返す;<br>
}<br>
<br>
/**<br>
* XMLを配列に変換します<br>
* * @param string $xml<br>
* @throws 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->values;<br>
}<br>
<br>
/**<br>
*<br>
* ジャンプを通じてユーザーの openid を取得します。ジャンプのプロセスは次のとおりです。
* 1. コールバックに必要な URL およびその他のパラメータを設定し、WeChat サーバーにジャンプします https://open.weixin.qq.com/connect/oauth2/authorize<br>
* 2. WeChat サービスの処理が完了すると、ユーザーの redirect_uri アドレスに戻ります。このとき、code<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>
$ url
Header("場所: $url");<br>
exit();<br>
else {<br>
//openid を取得するコードを取得します<br>
$コード
$openid = $this->getOpenidFromMp($code);<br>
return $openid;<br>
}<br>
}<br>
<br>
/**<br>
*<br>
* コードを通じて作業プラットフォームから openid machine access_token を取得します<br>
* @param string $code WeChatによって持ち帰られたコード<br>
*<br>
* * @return openid<br>
*/<br>
パブリック関数 GetOpenidFromMp($code)<br>
{<br>
$url = $this->__CreateOauthUrlForOpenid($code);<br>
//curlを初期化します<br>
$ch =curl_init();<br>
//タイムアウトを設定します<br>
curl_setopt($ch, CURLOPT_TIMEOUT, $this->curl_timeout);<br>
curl_setopt($ch, CURLOPT_URL, $url);<br>
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);<br>
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);<br>
curl_setopt($ch, CURLOPT_HEADER, false);<br>
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);<br>
///if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0"<br>
curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST);<br> // curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT);<br>
// }<br>
//カールを実行し、結果をジェイソン形式で返します<br>
$res = curl_exec($ch);<br>
curl_close($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["スコープ"] = "snsapi_base";<br>
$urlObj["状態"] = "#wechat_redirect";<br>
$bizString = $this->ToUrlParams($urlObj);<br>
return 「https://open.weixin.qq.com/connect/oauth2/authorize?」 。 $bizString;<br>
}<br>
<br>
/**<br>
*<br>
* openとaccess_tokeのURLアドレスを取得する構築<br>
* @param string $code、WeChat ジャンプによって戻されたコード<br>
*<br>
* @return リクエストされた URL <br>
*/<br>
プライベート関数 __CreateOauthUrlForOpenid($code)<br>
{<br>
$urlObj["appid"] = $this->config['appid'];<br>
$urlObj["secret"] = $this->config['appsecret'];<br>
$urlObj["コード"] = $code;<br>
$urlObj["grant_type"] = "authorization_code";<br>
$bizString = $this->ToUrlParams($urlObj);<br>
return 「https://api.weixin.qq.com/sns/oauth2/access_token?」 。 $bizString;<br>
}<br>
}</xml>