1、話不多說找到文檔下載PHP版本的sdk
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
2、目前的壓縮包名為:WxpayAPI_php_v3,下載完畢后,解壓到桌面,里面一共含有5個文件夾
SDK目錄結構
|-- lib
|-- logs
`-- example
cert //可以自己新建 證書存放路徑,證書可以登錄商戶平台https://pay.weixin.qq.com/index.php/account/api_cert
lib API接口封裝代碼
WxPay.Api.php 包括所有微信支付API接口的封裝
WxPay.Config.Interface.php 商戶配置 , 業務需要從這里繼承(請注意保管自己的密鑰/證書等)
WxPay.Data.php 輸入參數封裝
WxPay.Exception.php 異常類
WxPay.Notify.php 回調通知基類
doc 官方文檔
log 日志文件
example 官方示例文件夾
快速搭建指南
①、建SDK解壓到網站根目錄
②、修改lib/WxPay.Config.php為自己申請的商戶號的信息(配置詳見說明)
③、下載證書替換cert下的文件
搭建完成
圖是網上的,本地環境被谷歌自己添加的https證書攔住進不去了
在這里我們選擇掃碼支付
將API放到YII2 vender/wxpay目錄下
然后找到對應的 方法 下面是我們用微信掃碼支付的模式二 獲取支付的二維碼
require_once '../../vendor/wxpay/lib/WxPay.Api.php'; require_once '../../vendor/wxpay/example/phpqrcode/phpqrcode.php'; require_once "../../vendor/wxpay/example/WxPay.NativePay.php"; use Yii; class WxPayMent{ public static function getQcCode($price,$user_id){ $notify = new \NativePay(); $price = $price*100; // //模式二 /** * 流程: * 1、調用統一下單,取得code_url,生成二維碼 * 2、用戶掃描二維碼,進行支付 * 3、支付完成之后,微信服務器會通知支付成功 * 4、在支付成功通知中需要查單確認是否真正支付成功(見:notify.php) */ $order_sn = Payment::createOrderSn(); //支付模型 創建訂單號 $input = new \WxPayUnifiedOrder(); $input->SetBody("原創文檔充值"); //商品描述 $input->SetAttach($user_id); //自定義數據 $input->SetOut_trade_no($order_sn); //訂單號 $input->SetTotal_fee($price); //支付的錢 單位是分!! $input->SetTime_start(date("YmdHis")); $input->SetGoods_tag("原創文檔充值"); $input->SetNotify_url("http://www.***.com/personal-center/notify"); //異步通知地址 來修改我們后台數據庫 $input->SetTrade_type("NATIVE"); $input->SetProduct_id($order_sn); $result = $notify->GetPayUrl($input); if($result['return_code'] == 'FAIL'){ Yii::warning(date('Y-m-d h:i:s',time()).'錯誤:'.$result['return_msg'],'wxpay'); return ['error'=>1,'msg'=>'獲取二維碼失敗']; } $url = $result["code_url"]; $file_name = Payment::createOrderSn().'.png'; $QrCodeUrl = 'QrCodeUrl'; if(!file_exists($QrCodeUrl)){ mkdir($QrCodeUrl,0777); } $file_name = $QrCodeUrl.'/'.$file_name; if(substr($url, 0, 6) == "weixin"){ \QRcode::png($url,$file_name,'','',true); }else{ header('HTTP/1.1 404 Not Found'); } $file_name = Yii::$app->request->hostInfo.'/'.$file_name; $order = ['error'=>0,'qc_code' => $file_name,'order_sn' => $order_sn]; return $order; } }
這里返回二維碼跟訂單號 用戶掃碼支付
異步處理:
/** * 微信支付 * 微信異步修改數據庫 * @Author WangSai * @DateTime 2020-03-14 * @version [version] * @return [type] [description] */ public function actionNotify() { $testxml = file_get_contents("php://input"); $jsonxml = json_encode(simplexml_load_string($testxml, 'SimpleXMLElement', LIBXML_NOCDATA)); if(!file_exists("../logs/")){ mkdir("../logs/",0777); } $result = json_decode($jsonxml, true);//轉成數組 if($result){ //如果成功返回了 $out_trade_no = $result['out_trade_no']; $is_pay = UserPay::find()->where(['out_trade_no' => $out_trade_no])->orWhere(['trade_no' => $result['transaction_id']])->asArray()->one(); //這里是我保存交易記錄的地方輪訓修改的地方,如果修改過則不用再進入下面的循環 if($is_pay){ die; } if($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS'){ //執行業務邏輯 } } }
我們在前台可以用訂單號輪訓來查看 支付情況
data () { return { timer: null, timerNum:60, } }, methods: { cx(){ this.$axios .get('pay-ment/wx-pay-order-query',{ params:{ orderSn:this.orderSn, } }) .then(res => { if(res.data.code == 200){ this.timerNum = 0; } }) }, getStatus() { this.loading(); // 啟動定時器 this.timer = setInterval(() => { //創建定時器 if (this.timerNum === 0) { // 設置的定時器時間為0后執行的操作 this.timer && this.clearTimer(); // 關閉定時器 } else { this.cx(); this.loading(); } }, 1000); }, loading() { // 啟動定時器 this.timerNum -= 1; // 定時器減1 }, clearTimer() {//清除定時器 clearInterval(this.timer); this.timer = null; }, }, // 最后在beforeDestroy()生命周期內清除定時器: beforeDestroy() { clearInterval(this.timer); this.timer = null; },
后台接口查詢
/** * [actionOrderQuery 輪詢微信查詢接口查看是否支付] * @Author WangSai * @DateTime 2020-03-20 * @version [version] * @return [array] [返回查詢結果] */ public function actionWxPayOrderQuery(){ $order_sn = Yii::$app->getRequest()->get('orderSn'); require_once "../../vendor/wxpay/lib/WxPay.Api.php"; require_once "../../vendor/wxpay/example/WxPay.Config.php"; // $user_account = UserAccount::find()->where(['user_id' => $this->user_id])->asArray()->one(); if(isset($order_sn) && $order_sn != ""){ $input = new \WxPayOrderQuery(); $input->SetOut_trade_no($order_sn); $config = new \WxPayConfig(); $order_type = \WxPayApi::orderQuery($config, $input); // $order_type['total_price'] = $user_account['price']; // return $this->msg('200',$order_type); } if($order_type['trade_state'] == 'SUCCESS'){ return $this->msg('200',$order_type); }else{ return $this->msg('201'); } }