微信小程序支付+php后端


  最近在做自有項目后端用的是thinkphp5.1框架,閑話不說直接上代碼

  小程序代碼

  

 1 wxpay: function(e){
 2     let thisid = e.currentTarget.dataset.id;       這個是訂單的id
 3     var that = this;
 4     wx.request({
 5       url: URL +'need/requestPay',       這個是往后台傳的地址
 6       data:{
 7         id : thisid
 8       },
 9       method:'post',
10       success(res){
11         var data = res.data;
12         console.log(data)
13         if (data.error == 0){
14           app.mistake(data.msg,'../../../');
15           return false;
16         }
17         wx.requestPayment({         //調起支付
18           //下邊參數具體看微信小程序官方文檔
19           timeStamp: data.data.timeStamp,
20           nonceStr: data.data.nonceStr,
21           package: data.data.package,
22           signType: data.data.signType,
23           paySign: data.data.paySign,
24           success(res) {
25             if (res.errMsg == "requestPayment:ok"){
26               wx.request({      //這個是支付成功后改變訂單狀態的代碼
27                 url: URL+'need/payok',
28                 data:{
29                   id : thisid
30                 },
31                 method:'post',
32                 success(r){
33                   console.log(r);
34                   if(r.data.error == 1){
35                     app.ok('支付成功', '../../../');     這個是支付成功后的彈窗
36                     that.onLoad();
37                   }
38                 }
39               })
40             }
41           },
42           fail(res) { }
43         })
44       }
45     })
46   }        

后台代碼

  使用前先引入WeixinPay.php

 1 public function requestPay()
 2     {
 3         if(!Request::instance()->isPost()){
 4             return $this -> re(0,'請用POST獲取數據');
 5         }
 6         $id = input('id');
 7         $rs = Db::name('表名') -> field('id,openid,order_amount,order_payment,order_number') -> where(['id' => $id,'order_payment' => 1]) -> find();
 8         if(empty($rs)){
 9             return $this -> re(0,'未找到此訂單');
10         }
11         // halt($rs);
12         $a = new WeixinPay($rs['openid'],$rs['order_number'],'訂單支付',$rs['order_amount']);
13         $pay = $a -> pay();  //下單獲取返回值
14         // halt($pay);
15         return $this -> re(1,'下單成功',$pay);
16     }
17 
18     //支付成功
19     public function payok()
20     {
21         if(!Request::instance()->isPost()){
22             return $this -> re(0,'請用POST獲取數據');
23         }
24         $id = input('id');
25         $rs = Db::name('表名') -> where('id',$id) -> update(['order_payment' => 0,'order_fi' => 3]);    //修改表中字段狀態
26         if(empty($rs)){
27             return $this -> re(0,'失敗');
28         }else{
29             return $this -> re(1,'成功');
30         }
31     }

WeixinPay.php

  1 <?php 
  2 namespace app\library;
  3   
  4 /* 
  5  * 小程序微信支付 
  6  */
  7   
  8   
  9 class WeixinPay { 
 10   
 11   
 12   /*protected $appid; 
 13   protected $mch_id; 
 14   protected $key; 
 15   protected $openid; 
 16   protected $out_trade_no; 
 17   protected $body; 
 18   protected $total_fee; */
 19   function __construct($openid,$out_trade_no,$body,$total_fee) { 
 20     $this->appid = 'wx0aaaaaaaaa';//你的小程序appid 
 21     $this->openid = $openid;   //用戶的openid我是直接存在表中的,若是你沒有存,請百度查詢如何獲取用戶openid
 22     // 商戶號
 23     $this->mch_id = '888888';   //你的商戶號。找不到的在你的小程序里邊的微信支付里邊找,前提是你必須先開啟你的微信支付
 24     // 支付秘鑰
 25     $this->key = '5555555555555';   //這個是你商戶號的api秘鑰,在產品中心里邊找,
 26     //訂單號
 27     $this->out_trade_no = $out_trade_no;   //這個我是用的我后台的訂單號
 28     // 內容
 29     $this->body = $body;         //支付時顯示的提示
 30     //金額
 31     $this->total_fee = floatval($total_fee)*100;    //這個塊使用分為單位的所有要乘100
 32   } 
 33   
 34   
 35   public function pay() { 
 36     //統一下單接口 
 37     $return = $this->weixinapp(); 
 38     return $return; 
 39   } 
 40   
 41   
 42   //統一下單接口 
 43   private function unifiedorder() { 
 44     $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; 
 45     $parameters = array( 
 46       'appid' => $this->appid, //小程序ID 
 47       'mch_id' => $this->mch_id, //商戶號 
 48       'nonce_str' => $this->createNoncestr(), //隨機字符串  
 49       'body' => $this->body, //商品描述  
 50       'out_trade_no'=> $this->out_trade_no, //商戶訂單號 
 51       'total_fee' => $this->total_fee, //總金額 單位 分 
 52       'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], //終端IP 
 53       'notify_url' => 'http://www.weixin.qq.com/wxpay/pay.php', //通知地址 確保外網能正常訪問 
 54       'openid' => $this->openid, //用戶id 
 55       'trade_type' => 'JSAPI'//交易類型       //要是返回該產品權限未開通請在產品中心開通jsAPi他包含的小程序支付
 56     ); 
 57     //統一下單簽名 
 58     $parameters['sign'] = $this->getSign($parameters); 
 59     $xmlData = $this->arrayToXml($parameters); 
 60     $return = $this->xmlToArray($this->postXmlCurl($xmlData, $url, 60)); 
 61     return $return; 
 62   } 
 63   
 64   
 65   private static function postXmlCurl($xml, $url, $second = 30)  
 66   { 
 67     $ch = curl_init(); 
 68     //設置超時 
 69     curl_setopt($ch, CURLOPT_TIMEOUT, $second); 
 70     curl_setopt($ch, CURLOPT_URL, $url); 
 71     curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); 
 72     curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //嚴格校驗 
 73     //設置header 
 74     curl_setopt($ch, CURLOPT_HEADER, FALSE); 
 75     //要求結果為字符串且輸出到屏幕上 
 76     curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
 77     //post提交方式 
 78     curl_setopt($ch, CURLOPT_POST, TRUE); 
 79     curl_setopt($ch, CURLOPT_POSTFIELDS, $xml); 
 80   
 81   
 82     curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 20); 
 83     curl_setopt($ch, CURLOPT_TIMEOUT, 40); 
 84     set_time_limit(0); 
 85   
 86   
 87     //運行curl 
 88     $data = curl_exec($ch); 
 89     //返回結果 
 90     if ($data) { 
 91       curl_close($ch); 
 92       return $data; 
 93     } else { 
 94       $error = curl_errno($ch); 
 95       curl_close($ch); 
 96       throw new WxPayException("curl出錯,錯誤碼:$error"); 
 97     } 
 98   } 
 99     
100     
101     
102   //數組轉換成xml 
103   private function arrayToXml($arr) { 
104     $xml = "<root>"; 
105     foreach ($arr as $key => $val) { 
106       if (is_array($val)) { 
107         $xml .= "<" . $key . ">" . arrayToXml($val) . "</" . $key . ">"; 
108       } else { 
109         $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; 
110       } 
111     } 
112     $xml .= "</root>"; 
113     return $xml; 
114   } 
115   
116   
117   //xml轉換成數組 
118   private function xmlToArray($xml) { 
119   
120   
121     //禁止引用外部xml實體  
122   
123   
124     libxml_disable_entity_loader(true); 
125   
126   
127     $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); 
128   
129   
130     $val = json_decode(json_encode($xmlstring), true); 
131   
132   
133     return $val; 
134   } 
135   
136   
137   //微信小程序接口 
138   private function weixinapp() { 
139     //統一下單接口 
140     $unifiedorder = $this->unifiedorder(); 
141     //print_r($unifiedorder);
142     // halt($unifiedorder);
143     // if($unifiedorder['err_code_des'] == '201 商戶訂單號重復'){
144     //   return ''
145     // }
146     $parameters = array( 
147       'appId' => $this->appid, //小程序ID 
148       'timeStamp' => '' . time() . '', //時間戳 
149       'nonceStr' => $this->createNoncestr(), //隨機串 
150       'package' => 'prepay_id=' . $unifiedorder['prepay_id'], //數據包         要是返回201則要修改訂單號,這個問題測試中容易出現,上線了基本不出現問題
151       'signType' => 'MD5'//簽名方式 
152     ); 
153     //簽名 
154     $parameters['paySign'] = $this->getSign($parameters); 
155     return $parameters;
156   } 
157   
158   
159   //作用:產生隨機字符串,不長於32位 
160   private function createNoncestr($length = 32) { 
161     $chars = "abcdefghijklmnopqrstuvwxyz0123456789"; 
162     $str = ""; 
163     for ($i = 0; $i < $length; $i++) { 
164       $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); 
165     } 
166     return $str; 
167   } 
168   
169   
170   //作用:生成簽名 
171   private function getSign($Obj) { 
172     foreach ($Obj as $k => $v) { 
173       $Parameters[$k] = $v; 
174     } 
175     //簽名步驟一:按字典序排序參數 
176     ksort($Parameters); 
177     $String = $this->formatBizQueryParaMap($Parameters, false); 
178     //簽名步驟二:在string后加入KEY 
179     $String = $String . "&key=" . $this->key; 
180     //簽名步驟三:MD5加密 
181     $String = md5($String);
182     //簽名步驟四:所有字符轉為大寫 
183     $result_ = strtoupper($String); 
184     return $result_; 
185   } 
186   
187   
188   ///作用:格式化參數,簽名過程需要使用 
189   private function formatBizQueryParaMap($paraMap, $urlencode) { 
190     $buff = ""; 
191     ksort($paraMap); 
192     foreach ($paraMap as $k => $v) { 
193       if ($urlencode) { 
194         $v = urlencode($v); 
195       } 
196       $buff .= $k . "=" . $v . "&"; 
197     } 
198     $reqPar; 
199     if (strlen($buff) > 0) { 
200       $reqPar = substr($buff, 0, strlen($buff) - 1); 
201     } 
202     return $reqPar; 
203   } 
204   
205   
206 } 

 

  然后微信支付基本上就這些問題了,若是還有其他的問題請留言,我看到會回復 的,轉載請標明出處,謝謝


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM