この記事は主にPHP WeChat決済の開発プロセスを詳しく紹介していますので、興味のある方は参考にしていただければ幸いです。
1. 開発環境
Thinkphp 3.2.3
WeChat: サービスアカウント、認定済み
開発ドメイン名: http://test.paywechat.com (カスタムドメイン名、外部ネットワークからアクセス不可)
2関連するファイルと権限が必要です
WeChat 支払いはアクティベーションを申請する必要があります
WeChat パブリック プラットフォーム開発者ドキュメント: http://mp.weixin.qq.com/wiki/home/index.html
WeChat 支払い開発者ドキュメント: https: // pay.weixin.qq.com/wiki/doc/api/index.html
WeChat Payment SDK のダウンロード アドレス: https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter= 11_1
3. 開発
WeChat Payment PHP バージョンの SDK をダウンロードします。 ファイル ディレクトリは次のとおりです。
WeChat Payment SDK の Cert ディレクトリと Lib ディレクトリを Thinkphp に置きます。ディレクトリは
です
次に、WeChat 支払い承認ディレクトリの問題を紹介します。まず、WeChat 支払い開発構成で支払い承認ディレクトリを入力し、次に JS インターフェイス セキュリティを入力します。分野。
最後にWeb認証を設定します
これらの設定が完了したら、設定したディレクトリとthinkphp内のディレクトリに注意してください。
4. WeChat支払い設定
関連する設定を正しく入力します。
[php]ビュー 無地コピー
/**
* アカウント情報を設定します
*/
WxPayConfig ===========================
//
/**
* WeChat 公開アカウント情報の設定
*
* APPID: 支払いにバインドされたAPPID (構成が必要、アカウント開設メールで確認できます)
* 表示)
*
* 設定アドレス: https://pay.weixin.qq.com/index.php/account/api_cert
* パブリックプラットフォームにログインし、開発者センターに入ってセットアップしてください)、
* アドレスを取得: https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN
* @varstring
*/
const APPID = '';
const''; const
''; const
''
//========[証明書パス設定]================================ =====
/**
*TODO: 販売者証明書のパスを設定します
*証明書のパスは絶対パスであることに注意してください。パスを入力する必要があります (注文を返金またはキャンセルする場合にのみ必要です。販売者プラットフォームにログインしてダウンロードできます。
)* API証明書のダウンロードアドレス: https://pay.weixin.qq.com/index.php/account/api_cert、ダウンロードする前に加盟店運営証明書をインストールする必要があります)
* @var path
*/
const SSLCERT_PATH = '../cert/apiclient_cert.
const SSLKEY_PATH = '../cert/apiclient_key.pem'; プロキシ設定】=== ===================== ==========
/**
* TODO: ここでプロキシ マシンを設定します。プロキシが必要ない場合は、0.0.0.0 と 0
*このルーチンは、curl を使用します。HTTP POST メソッドを使用して、プロキシ サーバーをここで変更できます。
* デフォルトの CURL_PROXY_HOST=0.0.0.0 および CURL_PROXY_PORT=0 では、プロキシは現時点ではオンになっていません (設定されています)。必要に応じて)
* @varknown_type
*/
const CURL_PROXY_HOST = "0.0.0.0";//"10.152.18.220";
const CURL_PROXY_PORT = 0;/ /8080;
//=======【レポート情報構成】================= = ==================
/**
* TODO: インターフェイス呼び出しのレポートレベル、デフォルトのエラーレポート (注: レポートのタイムアウトは [1 秒]、成功または失敗に関係なくレポート [例外をスローしない]、
*インターフェイス呼び出しプロセスには影響しません)。レポートを有効にした後、WeChat がリクエスト呼び出しの品質を監視すると便利です。少なくとも
* をオンにすることをお勧めします。
* レポートレベル、0. レポートを閉じる; 1. エラーのみがレポートされる; 2. 完全なレポート
* @var int
REPORT_LEVENL = 1
今すぐコードの投稿を開始してください:
[php] view プレーンコピー
ThinkContローラー;
/*** 親クラスコントローラー、継承する必要があります
* @file ParentController.class.php
* @著者ゲイリー
* @date August 4, 2015
* @todu
*/
classParentController extendsController {
protected$options = 配列 (
'トークン' => '', // 暗号化用の EncodingAESKey を入力します
'appid' => 「アプリシークレット」 => '',
// 高度な呼び出し機能のキーを入力します'デバッグ' => false、
'logcallback' => ''
);
public $errCode = 40001;
public $errMsg = 「アクセス禁止」;
/**
* 获取access_token
* @return mixed|boolean|unknown
*/
公開 関数 getToken(){
$cache_token = S('exp_wechat_pay_token');
if(!空($cache_token)){
return $cache_token;
}
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s &secret=%s ';
$url = sprintf($url,$this->options['appid'], $this-> ;オプション['アプリシークレット']);
$result = $this->http_get($url);
$result = json_decode($result,true);
if(空($結果)){
return false;
}
S('exp_wechat_pay_token',$result['access_token' ]、配列('タイプ' =>'ファイル','有効期限'=>3600));
return $result['access_token'];
}
/**
* カスタマーサービスメッセージを送信する
* @param array $data メッセージ構造 {"touser":"OPENID","msgtype":"news","news": { ...}}
*/
public function sendCustomMessage( $data){
$token = $this->getToken();
if (空($token)) return false;
$url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s';
$url = sprintf($url,$token);
$result = $this->http_post($url,self::json_encode($data) ));
if ($result)
{
$json = json_decode($result,true) ;
???$this->errCode = $json['errcode'];
$this$json['errmsg'];
return} return
;
false; }
/**
* テンプレートメッセージを送信
* @param 不明 $data
* @return boolean|unknown
*/
public function sendTemplateMessage($data) ){
$トークン = $this->getToken();
if (空($token)) return false;
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";
$url = sprintf($url,$token);
$result = $this->http_post($url,self::json_encode($data));
if ($result)
{
$json = json_decode($result,true);
???$this->errCode = $json['errcode'];
$this$json['errmsg'];
return} return
;
false; }
public function getFileCache($name){
return S($name);
}
/**
* WeChat API は中国語のエスケープされた JSON 構造をサポートしていません
* @param array $arr
*/
static function json_encode( $arr) {
$parts = array ();
$is_list = false;
//指定された配列が数値配列かどうかを調べます
$keys = array_keys ( $arr );
$max_length = count ( $arr ) - 1;
if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //最初のキーが 0 で、最後のキーの長さが - 1 であるかどうかを確認します
$is_list = true;
for($i = 0; $i カウント ( $keys ); $i ++) { //各キーがその位置に対応しているかどうかを確認します
if ($i != $keys [$i]) { //位置チェックでキーが失敗しました。
$is_list = false; //これは連想配列です。
break;
}
}
}
foreach ( $arr as $key => $value ) {
if ( is_array ( $value )) { //配列のカスタム処理
if () $is_list)
$parts [] = self::json_encode ( $value ); /* :RECURSION: */
else
$parts [] = '"' . $key . '":' . self::json_encode ( $value ); /* :RECURSION: */
} else {
$str = 」;
if (! $is_list)
$str = '"' . $key . '":';
//複数のデータタイプのカスタム処理
if (!is_string ( $value ) && is_numeric ( $value ) && $value
$str .= $value; //数字
elseif ($value === false)
$str .= 'false' ; //ブール値
elseif ($value === true)
$str .= 'true' ;
else
$str .= '"' . スラッシュを追加します ( $value ) . ; //その他すべてのこと
[] = $str;
= 内破 ( ',' 、$パーツ );
($is_list)
return '[' . $json']'//数値のJSONを返します ;
'{' . '}'} /**
+------------------------------------------------------------- -------------
* ランダムな文字列を生成
+---- ------------- ------------------------- ----
* @param int $length 生成するランダム文字列の長さ
* @param string $type ランダムコードタイプ: 0、数字 + 大文字と小文字;1、数字 2、小文字; 3、大文字、4、特殊文字、-1、数字 + 大文字と小文字 + 特殊文字
+------------------------------------------ --------------
* @return string
+--------------- -------------------------------------------
*/
static public function randCode($length = 5、$type = 2){
$arr = array(1 => "0123456789", 2 => "abcdefghijklmnopqrstuv wxyz", 3 => "ABCDEFGHIJKLMNOPQRSTUVWXYZ" , 4 => "~@#$%^&*(){}[]|");
if ($type == 0) {
array_pop($arr);
$string = implode("", $arr);
} elseif ($type == "-1") {
$string = 爆破("" 、$arr);
} else {
$string = $arr[ $タイプ];
}
$count = strlen($string) - 1;
$code = '';
for ($i = 0; $i $length; $i ++) {
$code .= $string[rand(0, $count)];
}
return $code;
}
/**
* GET 请求
* @param string $url
*/
プライベート 機能 http_get($url){
$oCurl = curl_init();
if(ストライポ($url,"https://")!==FALSE){
curl_setopt ($oCurl、CURLOPT_SSL_VERIFYPEER、FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
戻る $sコンテンツ;
}else{
return false;
}
}
/**
* POSTリクエスト
* @param string $url
* @ param array $param
* @param boolean $post_file ファイルがアップロードされているかどうか。*/
プライベート
機能 http_post($url,
,$post_file=false){ $oCurl = curl_init();
if(stripos($url,"https://")!==FALSE){
curl_setopt($ oCurl、CURLOPT_SSL_VERIFYPEER、FALSE);
curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1
}
if (is_string) ($param) || $post_file) {
$strPOST = $param;
} else {
$aPOST = array();
foreach($param as $key=>$val ){
$aPOST [] = $key."=".urlencode($val);
}
$strPOST = join("&", $aPOST);
}
curl_setopt($oCurl, CURLOPT_URL, $url);
curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt($oCurl, CURLOPT_POST,true);
curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);
$sContent = curl_exec($oCurl);
$aStatus = curl_getinfo($oCurl);
curl_close($oCurl);
if(intval($aStatus["http_code"])==200){
戻る $sコンテンツ;
}else{
return false;
}
}
}
[php] ビュー plain copy
namespace WechatController;
use WechatControllerParentController;
/**
* WeChat 支払いテストコントローラー
* @file TestController.class.php
* @author Gary
* @date August 4, 2015
* @todu
*/
class TestController extends ParentController {
private $_order_body = 'xxx';
private $_order_goods_tag = 'xxx';
public function __construct(){
parent::__construct();
require_once ROOT_PATH."Api/lib/WxPay.Api.php";
require_once ROOT_PATH."Api/lib/WxPay.JsApiPay.php";
}
public functionindex(){
//①、ユーザーopenidを取得します
$ツール = 新しい JsApiPay();
$openId = $tools->GetOpenid(); //②、統一順序
$input
=WxPayUnifiedOrder(); $input
->->_order_body);
$input->SetAttach('xxx');
$out_trade_no = WxPayConfig::MCHID。 日付
(); $out_trade_no); //合計金額、注文の合計金額は整数のみ、単位はセントです
$input->SetTotal_fee(1);
//トランザクション開始時間
$input ->SetTime_start(日付 (
));
$input->SetTime_expire(date("YmdHis", time() + 600));
//プロダクトマーク$input
$this->_order_goods_tag)
/ /通知アドレス、WeChat 支払いの受信非同期通知コールバック アドレス SITE_URL =http://test.paywechat.com/Charge$notify_url
'/index.php/Test/notify.html' ; $input
->SetNotify_url(); $input-> SAPI");
$order = WxPayApi::unifiedOrder($input); $tools
->GetJsApiParameters(); //共有配送先住所のjs関数パラメータを取得します
$editAddress = $ツール
->GetEditAddressParameters() ; );$this ->assign('jsApiParameters'
,);ドレス'
,);
$this->display();
}
/**
* 非同期通知コールバックメソッド
*/
API/lib/ Notice.php";
$notify = new PayNotifyCallBack();
$notify ->ハンドル(false) //IsSuccess は私がカスタマイズしたメソッドです。参考のためにこのファイルのコードを後で投稿します。
$is_success = $notify
$bdata = $is_success['data'];
( 」 touser' => $bdata[
]、 'ニュース'、
'ニュース' = > 配列 ()
'articles'=> 'title'
' 注文の支払いが完了しました'、
「説明」 => 「支払い金額: {$bdata['total_fee']}n」
「WeChat 注文番号: {$bdata['transaction_id']}n」'picurl' =>
'''url'
」 ) )
) )
//WeChat 支払い通知を送信
$this->sendCustomMessage($news);
}その他 {//支払いに失敗しました
}
}
/**
* 支払い成功ページ
* 信頼性の低いコールバック
* //注文番号
$out_trade_no = I('post.out_trade_no');
//支払い金額
$total_fee = I('post.total_fee');
/*関連ロジック処理*** [xhtml] ビュー プレーン
コピー
>
meta http-equiv="content-type"content="text/html;charset=ut f- 8インチ ; ="width=デバイス幅、初期スケール=1" タイトル> WeChat支払いサンプル -お支払いタイトル> script type="text/javascript"> //WeChat JS API 支払いを呼び出す functionjsApiCall() {$jsApiParameters}, function (res){ WeixinJSBridge.log(res.err_msg); //キャンセルPayment if(res.err_ms g ここで Ajax を使用して送信し、一部の処理を行うことができます。テスト コントローラーの ajax_PaySuccess メソッドなど)。 } 関数 callpay() { if (typeof WeixinJSBridge == "未定義"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', jsApiCall, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', jsApiCall); document.attachEvent('onWeixinJSBridgeReady', jsApiCall); } }else{ jsApiCall(); } } //获取共享地址 f function editAddress() { WeixinJSBridge。 invoke( 'editAddress', {$editAddress}, function(res){ var value1 = res .proviceFirstStageName; var value2 = res.addressCitySecondStageName; var value3 = res.addressCountiesThirdStageName; var value4 = res.addressDetailInfo; var tel = res.telNumber; alert(value1 + value2 + value3 + value4 + ":" + tel); } ); } window.onload = function(){ if (typeof WeixinJSBridge == "未定義"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', editAddress, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', editAddress); document.attachEvent('onWeixinJSBridgeReady', editAddress); } }else{ editAddress(); } }; script> 頭> ボディ> br/> font color="#9ACD32">b> この注文のお支払い金額はです< ;スパンstyle="color:#f00;font-size:50px">1ポイントスパン> お金 b> フォント> p align="中心"> ボタン スタイル= "幅:210px;高さ:50px;border-radius:15px;background-color:#FE6714;border:0px#FE6714solid;カーソル:ポインタ;color:白;font-size:16px;" type="ボタン" onclick="callpay()" >立即支付ボタン> p> body> html> notify.phpファイルコード、ここ公式ドキュメントに新たに追加されたカスタムメソッドがあります。 [php]ビュー
プレーンコピー
require_onceROOT_PATH."Api/lib/WxPay.Api.php"; require_once ROOT_PATH .'Api/lib/WxPay.Notify.php'; //初期化ログ CLogFileHandler(ROOT_PATH. date( 「やあ」). '.log'); $log = Log::Init( $logHandler , 15); protected $para = array('code'=>0,'data'=> '') ; //查询订单 public function Queryorder( $transaction_id) { $input = new WxPayOrderQuery(); $input->SetTransaction_id($transaction_id); $result = WxPayApi::orderQuery($input); Log::DEBUG("query:" . json_encode($result)); if(array_key_exists("return_code", $result) && array_key_exists("result_code ", $result) && $result["return_code"] == "成功" && $result["result_code"] == "SUCCESS") { return true; } $this->para['code'] = 0; $this->para[ 'データ「」 = ''; return false; //コールバック処理関数を書き換える 関数 NotifyProcess($data $msg) { ログ: :DEBUG("コールバック:" . json_encode( )); if(!array_key_exists("transaction_id", $data) )){ $msg = 「入力パラメータが間違っています」 ->para['code'] = 0; $ this 'data'] = return false; // 注文を確認し、注文が本物であるかどうかを判断します if(!$this->Queryorder($data["transaction_id"])){ $メッセージ = 「注文クエリが失敗しました」 ->para['コード'] = 0; $これ->para[ ] = '' $this->para[ ] = 1; $this->para['data'] = $data 本当です IsSuccess(){ $this->para; http://test.paywechat.com/Charge/index.php/Test/index /関連おすすめ:
以上がPHPはWeChat決済機能開発コードシェアリングを実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。