ホームページ  >  記事  >  バックエンド開発  >  PHPはWeChat決済機能開発コードシェアリングを実装

PHPはWeChat決済機能開発コードシェアリングを実装

小云云
小云云オリジナル
2018-03-09 16:53:086501ブラウズ

この記事は主に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 をダウンロードします。 ファイル ディレクトリは次のとおりです。

PHPはWeChat決済機能開発コードシェアリングを実装

PHPはWeChat決済機能開発コードシェアリングを実装

WeChat Payment SDK の Cert ディレクトリと Lib ディレクトリを Thinkphp に置きます。ディレクトリは

PHPはWeChat決済機能開発コードシェアリングを実装 です

次に、WeChat 支払い承認ディレクトリの問題を紹介します。まず、WeChat 支払い開発構成で支払い承認ディレクトリを入力し、次に JS インターフェイス セキュリティを入力します。分野。

PHPはWeChat決済機能開発コードシェアリングを実装

最後にWeb認証を設定します

PHPはWeChat決済機能開発コードシェアリングを実装

PHPはWeChat決済機能開発コードシェアリングを実装

これらの設定が完了したら、設定したディレクトリとthinkphp内のディレクトリに注意してください。

PHPはWeChat決済機能開発コードシェアリングを実装

4. WeChat支払い設定

PHPはWeChat決済機能開発コードシェアリングを実装

関連する設定を正しく入力します。




[php]ビュー 無地コピー


  1. /**

  2. * アカウント情報を設定します

  3. */

  4. WxPayConfig ===========================
  5. //
  6. /**

  7. * TODO: ここで設定を変更して、自分で申請した販売者情報を適用します

    * WeChat 公開アカウント情報の設定
  8. *
  9. * APPID: 支払いにバインドされたAPPID (構成が必要、アカウント開設メールで確認できます)
  10. * 表示)
  11. *
  12. * 設定アドレス: https://pay.weixin.qq.com/index.php/account/api_cert

  13. * パブリックプラットフォームにログインし、開発者センターに入ってセットアップしてください)、

  14. * アドレスを取得: https://mp.weixin.qq.com/advanced/advanced?action=dev&t=advanced/dev&token=2005451881&lang=zh_CN

  15. * @varstring

  16. */

  17. const APPID = '';

    const
  18. MCHID =

    ''; const

  19. KEY =
  20. ''; const

  21. APPSECRET =
  22. ''

  23. //========[証明書パス設定]================================ =====

  24. /**

  25. *TODO: 販売者証明書のパスを設定します

  26. *証明書のパスは絶対パスであることに注意してください。パスを入力する必要があります (注文を返金またはキャンセルする場合にのみ必要です。販売者プラットフォームにログインしてダウンロードできます。

    )
  27. * API証明書のダウンロードアドレス: https://pay.weixin.qq.com/index.php/account/api_cert、ダウンロードする前に加盟店運営証明書をインストールする必要があります)

  28. * @var path

  29. */

  30. const SSLCERT_PATH = '../cert/apiclient_cert.

  31. const SSLKEY_PATH = '../cert/apiclient_key.pem'; プロキシ設定】=== ===================== ==========

  32. /**

  33. * TODO: ここでプロキシ マシンを設定します。プロキシが必要ない場合は、0.0.0.0 と 0

  34. *このルーチンは、curl を使用します。HTTP POST メソッドを使用して、プロキシ サーバーをここで変更できます。

  35. * デフォルトの CURL_PROXY_HOST=0.0.0.0 および CURL_PROXY_PORT=0 では、プロキシは現時点ではオンになっていません (設定されています)。必要に応じて)

  36. * @varknown_type

  37. */

  38. const CURL_PROXY_HOST = "0.0.0.0";//"10.152.18.220";

  39. const CURL_PROXY_PORT = 0;/ /8080;

  40. //=======【レポート情報構成】================= = ==================

  41. /**

  42. * TODO: インターフェイス呼び出しのレポートレベル、デフォルトのエラーレポート (注: レポートのタイムアウトは [1 秒]、成功または失敗に関係なくレポート [例外をスローしない]、

  43. *インターフェイス呼び出しプロセスには影響しません)。レポートを有効にした後、WeChat がリクエスト呼び出しの品質を監視すると便利です。少なくとも

  44. * をオンにすることをお勧めします。

  45. * レポートレベル、0. レポートを閉じる; 1. エラーのみがレポートされる; 2. 完全なレポート

  46. * @var int

  47. */

  48. const

    REPORT_LEVENL = 1

  49. }

今すぐコードの投稿を開始してください:




[php] view プレーンコピー


  1. 名前空間WechatController

  2. use
  3. ThinkContローラー;

    /**
  4. * 親クラスコントローラー、継承する必要があります
  5. * @file ParentController.class.php
  6. * @著者ゲイリー
  7. * @date August 4, 2015
  8. * @todu
  9. */
  10. classParentController extendsController {

  11. protected$options = 配列 (

  12. 'トークン' => '', // 暗号化用の EncodingAESKey を入力します

  13. 'appid' => 「アプリシークレット」 => '',

    // 高度な呼び出し機能のキーを入力します
  14. 'デバッグ' => false、

  15. 'logcallback' => ''

  16. );   

  17. public $errCode = 40001;   

  18. public $errMsg = 「アクセス禁止」;   

  19. /**

  20. * 获取access_token

  21. * @return mixed|boolean|unknown

  22.  */

  23. 公開 関数 getToken(){

  24. $cache_token = S('exp_wechat_pay_token');  

  25. if(!($cache_token)){

  26. return $cache_token;  

  27. }

  28. $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s &secret=%s ';  

  29. $url = sprintf($url,$this->options['appid'], $this-> ;オプション['アプリシークレット']);   

  30. $result = $this->http_get($url);  

  31. $result = json_decode($result,true);   

  32. if(($結果)){

  33. return false;  

  34. }

  35. S('exp_wechat_pay_token',$result['access_token' ]、配列('タイプ' =>'ファイル','有効期限'=>3600));  

  36. return $result['access_token'];  

  37. }

  38. /**

  39. * カスタマーサービスメッセージを送信する

  40. * @param array $data メッセージ構造 {"touser":"OPENID","msgtype":"news","news": { ...}}

  41. */

  42. public function sendCustomMessage( $data){

  43. $token = $this->getToken();  

  44. if (($token)) return false;   

  45. $url = 'https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s';  

  46. $url = sprintf($url,$token);  

  47. $result = $this->http_post($url,self::json_encode($data) ));  

  48. if ($result)

  49. {

  50. $json = json_decode($result,true) ;  

    ???
  51. $this->errCode = $json['errcode'];  

    $this
  52. ->errMsg =

    $json['errmsg'];  

    return
  53. false;  

    } return

  54. $json

    ;  

  55. }
  56. return

    false;   }

  57. /**

  58. * テンプレートメッセージを送信

  59. * @param 不明 $data

  60. * @return boolean|unknown

  61. */

  62. public function sendTemplateMessage($data) ){

  63. $トークン = $this->getToken();  

  64. if (($token)) return false;  

  65. $url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=%s";  

  66.  $url = sprintf($url,$token);  

  67.  $result = $this->http_post($url,self::json_encode($data));  

  68.  if ($result)  

  69.  {  

  70.  $json = json_decode($result,true);  

    ???
  71. $this->errCode = $json['errcode'];  

    $this
  72. ->errMsg =

    $json['errmsg'];  

    return
  73. false;  

    } return

  74. $json

    ;  

  75. }
  76. return

    false;   }

  77.   

  78.  public function getFileCache($name){  

  79. return S($name);  

  80. }

  81. /**

  82. * WeChat API は中国語のエスケープされた JSON 構造をサポートしていません

  83. * @param array $arr

  84. */

  85. static function json_encode( $arr) {

  86. $parts = array ();  

  87. $is_list = false;  

  88. //指定された配列が数値配列かどうかを調べます

  89. $keys = array_keys ( $arr );  

  90. $max_length = count ( $arr ) - 1;  

  91. if (($keys [0] === 0) && ($keys [$max_length] === $max_length )) { //最初のキーが 0 で、最後のキーの長さが - 1 であるかどうかを確認します

  92. $is_list = true;  

  93. for($i = 0; $i カウント ( $keys ); $i ++) { //各キーがその位置に対応しているかどうかを確認します

  94. if ($i != $keys [$i]) { //位置チェックでキーが失敗しました。

  95. $is_list = false; //これは連想配列です。

  96. break;  

  97. }

  98. }

  99. }

  100. foreach ( $arr as $key => $value ) {

  101. if ( is_array ( $value )) { //配列のカスタム処理

  102. if () $is_list)

  103. $parts [] = self::json_encode ( $value ); /* :RECURSION: */

  104. else

  105. $parts [] = '"' . $key . '":' . self::json_encode ( $value ); /* :RECURSION: */

  106. } else {

  107. $str = ;  

  108. if (! $is_list)

  109. $str = '"' . $key . '":';  

  110. //複数のデータタイプのカスタム処理

  111. if (!is_string ( $value ) && is_numeric ( $value ) && $value

  112. $str .= $value//数字

  113. elseif ($value === false)

  114. $str .= 'false' //ブール値

  115. elseif ($value === true)

  116. $str .= 'true' ;  

  117. else

  118. $str .= '"' . スラッシュを追加します ( $value ) . //その他すべてのこと

  119. //:TODO: 他に注意すべきデータタイプはありますか? (オブジェクト?)

  120. $parts

    [] = $str;  

  121. }
  122. }
  123. $json

    = 内破 ( ',' $パーツ );  

  124. if

    ($is_list)

  125. return '[' . $json']'//数値のJSONを返します ;

  126. 戻る
  127. '{' . '}'} /**

  128. +------------------------------------------------------------- -------------

  129. * ランダムな文字列を生成

  130. +---- ------------- ------------------------- ----

  131. * @param int $length 生成するランダム文字列の長さ

  132. * @param string $type ランダムコードタイプ: 0、数字 + 大文字と小文字;1、数字 2、小文字; 3、大文字、4、特殊文字、-1、数字 + 大文字と小文字 + 特殊文字

  133. +------------------------------------------ --------------

  134. * @return string

  135. +--------------- -------------------------------------------

  136. */

  137. static public function randCode($length = 5、$type = 2){

  138. $arr = array(1 => "0123456789", 2 => "abcdefghijklmnopqrstuv wxyz", 3 => "ABCDEFGHIJKLMNOPQRSTUVWXYZ" , 4 => "~@#$%^&*(){}[]|");  

  139. if ($type == 0) {

  140. array_pop($arr);  

  141. $string = implode("", $arr);  

  142. } elseif ($type == "-1") {

  143. $string = 爆破("" $arr);  

  144. } else {

  145. $string = $arr[ $タイプ];  

  146. }

  147. $count = strlen($string) - 1;  

  148. $code = '';  

  149. for ($i = 0; $i $length; $i ++) {

  150. $code .= $string[rand(0, $count)];  

  151. }

  152. return $code;  

  153. }

  154. /**

  155. * GET 请求

  156. * @param string $url

  157. */

  158. プライベート 機能 http_get($url){

  159. $oCurl = curl_init();  

  160. if(ストライポ($url,"https://")!==FALSE){

  161. curl_setopt ($oCurl、CURLOPT_SSL_VERIFYPEER、FALSE);  

  162. curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, FALSE);  

  163. curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1

  164. }

  165. curl_setopt($oCurl, CURLOPT_URL, $url);  

  166. curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );  

  167. $sContent = curl_exec($oCurl);  

  168. $aStatus = curl_getinfo($oCurl);  

  169. curl_close($oCurl);  

  170. if(intval($aStatus["http_code"])==200){

  171. 戻る $sコンテンツ;  

  172. }else{

  173. return false;  

  174. }

  175. }

  176. /**

  177. * POSTリクエスト

  178. * @param string $url

  179. * @ param array $param

  180. * @param boolean $post_file ファイルがアップロードされているかどうか。*/

  181. プライベート

  182. 機能 http_post($url,

  183. $param
  184. ,$post_file=false){ $oCurl = curl_init();  

  185. if(stripos($url,"https://")!==FALSE){

  186. curl_setopt($ oCurl、CURLOPT_SSL_VERIFYPEER、FALSE);  

  187. curl_setopt($oCurl, CURLOPT_SSL_VERIFYHOST, false);  

  188. curl_setopt($oCurl, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1

  189. }

  190. if (is_string) ($param) || $post_file) {

  191. $strPOST = $param;  

  192. } else {

  193. $aPOST = array();  

  194. foreach($param as $key=>$val ){

  195. $aPOST [] = $key."=".urlencode($val);  

  196. }

  197. $strPOST = join("&", $aPOST);  

  198. }

  199. curl_setopt($oCurl, CURLOPT_URL, $url);  

  200. curl_setopt($oCurl, CURLOPT_RETURNTRANSFER, 1 );  

  201. curl_setopt($oCurl, CURLOPT_POST,true);  

  202. curl_setopt($oCurl, CURLOPT_POSTFIELDS,$strPOST);  

  203. $sContent = curl_exec($oCurl);  

  204. $aStatus = curl_getinfo($oCurl);  

  205. curl_close($oCurl);  

  206. if(intval($aStatus["http_code"])==200){

  207. 戻る $sコンテンツ;  

  208. }else{

  209. return false;  

  210. }

  211. }

  212. }




[php] ビュー plain copy


  1. namespace WechatController;  

  2. use WechatControllerParentController;  

  3. /**

  4. * WeChat 支払いテストコントローラー

  5. * @file TestController.class.php

  6. * @author Gary

  7. * @date August 4, 2015

  8. * @todu

  9. */

  10. class TestController extends ParentController {

  11. private $_order_body = 'xxx';  

  12. private $_order_goods_tag = 'xxx';  

  13. public function __construct(){

  14. parent::__construct();  

  15. require_once ROOT_PATH."Api/lib/WxPay.Api.php";  

  16. require_once ROOT_PATH."Api/lib/WxPay.JsApiPay.php";  

  17. }

  18. public functionindex(){

  19. //①、ユーザーopenidを取得します

  20. $ツール = 新しい JsApiPay();

  21. $openId = $tools->GetOpenid(); //②、統一順序

  22. $input

    =
  23. new

    WxPayUnifiedOrder(); $input

    ->
  24. $this

    ->_order_body);

  25. //追加データ。必要なデータを追加できます。WeChat は非同期コールバックを返すときにこのデータを追加します
  26. $input->SetAttach('xxx');

  27. $out_trade_no = WxPayConfig::MCHID。 日付

    (
  28. 「Ymd彼の"

    ); $out_trade_no); //合計金額、注文の合計金額は整数のみ、単位はセントです

  29. $input->SetTotal_fee(1);

  30. //トランザクション開始時間

  31. $input ->SetTime_start(日付 (

  32. "YmdHis"
  33. ));

  34. //トランザクション終了時刻
  35. $input->SetTime_expire(date("YmdHis", time() + 600));

    //プロダクトマーク
  36. $input
  37. ->SetGoods_tag(

    $this->_order_goods_tag)

    / /通知アドレス、WeChat 支払いの受信非同期通知コールバック アドレス SITE_URL =http://test.paywechat.com/Charge
  38. $notify_url
  39. = SITE_URL.

    '/index.php/Test/notify.html' ; $input

    ->SetNotify_url(
  40. $notify_url

    ); $input-> SAPI");

  41. $order = WxPayApi::unifiedOrder($input); $tools

    ->GetJsApiParameters(
  42. $ order

    ); //共有配送先住所のjs関数パラメータを取得します

  43. $editAddress = $ツール

    ->GetEditAddressParameters() ; );
  44. $this ->assign('jsApiParameters'

    ,
  45. $jsApiParameters

    );ドレス'

    ,
  46. $editAddress

    );

  47. $this->display();

  48. }

  49. /**

  50. * 非同期通知コールバックメソッド

  51. */

  52. API/lib/ Notice.php";

  53. $notify = new PayNotifyCallBack();

  54. $notify ->ハンドル(false) //IsSuccess は私がカスタマイズしたメソッドです。参考のためにこのファイルのコードを後で投稿します。

  55. $is_success = $notify

  56. ->IsSuccess();
  57. $bdata = $is_success['data'];

  58. //支払いが成功しました

  59. if

    ( 」 touser' => $bdata[

  60. 'openid'
  61. ]、 'ニュース'

  62. 'ニュース' = > 配列 ()

  63. 'articles'=> 'title'

  64. =>
  65. ' 注文の支払いが完了しました'

  66. 「説明」 => 「支払い金額: {$bdata['total_fee']}n」

    「WeChat 注文番号: {$bdata['transaction_id']}n」
  67. 'picurl' =>

    ''
  68. 'url'

  69. =>
  70. ) )

  71. ) )

  72. //WeChat 支払い通知を送信

  73. $this->sendCustomMessage($news);

  74. }その他 {//支払いに失敗しました

  75. }

  76. }

  77. /**

  78. * 支払い成功ページ

  79. * 信頼性の低いコールバック

  80. * //注文番号

  81. $out_trade_no = I('post.out_trade_no');

  82. //支払い金額

  83. $total_fee = I('post.total_fee');

  84. /*関連ロジック処理*** [xhtml] ビュー プレーン

    コピー
html


>


>

  • 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

  • == 'get_brand_wcpay_request:cancel' ;
  • / *フロントエンドの返品を判断するには、上記の方法を使用してください。WeChatチームは厳粛に次のことを思い出させます。
  • ユーザーが正常に支払った後、res.err_msg は ok を返しますが、絶対に信頼できるという保証はありません
  • ここで 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{

  • edi​​tAddress();  

  • }

  • };  

  • 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]ビュー プレーンコピー


    1. require_onceROOT_PATH."Api/lib/WxPay.Api.php";

    2. require_once ROOT_PATH .'Api/lib/WxPay.Notify.php';

    3. //初期化ログ CLogFileHandler(ROOT_PATH.

      "/logs/"
    4. .

      date( 「やあ」). '.log'); $log = Log::Init( $logHandler , 15);

    5. protected $para = array('code'=>0,'data'=> '') ;  

    6. //查询订单

    7. public function Queryorder( $transaction_id)

    8. {

    9. $input = new WxPayOrderQuery();  

    10. $input->SetTransaction_id($transaction_id);  

    11. $result = WxPayApi::orderQuery($input);  

    12. Log::DEBUG("query:" . json_encode($result));  

    13. if(array_key_exists("return_code", $result)

    14. && array_key_exists("result_code ", $result)

    15. && $result["return_code"] == "成功"

    16. && $result["result_code"] == "SUCCESS")

    17. {

    18. return true;  

    19. }

    20. $this->para['code'] = 0;

    21. $this->para[ 'データ「」 = '';

    22. return false;

    23. //コールバック処理関数を書き換える

    24. 公開
    25. 関数 NotifyProcess($data

    26. , &
    27. $msg) { ログ: :DEBUG("コールバック:" . json_encode(

    28. $data
    29. ));

    30. if(!array_key_exists("transaction_id", $data) )){

    31. $msg = 「入力パラメータが間違っています」

    32. $this

      ->para['code'] = 0; $ this

    33. ->para[
    34. 'data'] = return false;

    35. // 注文を確認し、注文が本物であるかどうかを判断します

    36. if(!$this->Queryorder($data["transaction_id"])){

    37. $メッセージ = 「注文クエリが失敗しました」

    38. $this
    39. ->para['コード'] = 0; $これ->para[

    40. 'data'
    41. ] = ''

      }
    42. $this->para[

    43. 'コード'
    44. ] = 1;

    45. $this->para['data'] = $data

    46. return

      本当です

    47. }
    48. 関数

      IsSuccess(){

    49. return
    50. $this->para;

    51. これは基本的に完了しており、WeChatで開くことができます
    52. http://test.paywechat.com/Charge/index.php/Test/index /関連おすすめ:

    53. Nodejs WeChat決済機能実装の詳細な例

      ThinkphpはWeChat決済機能を統合します

      このWeChat決済機能をPCウェブサイトに追加する方法

    以上がPHPはWeChat決済機能開発コードシェアリングを実装の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

    声明:
    この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。