微信小程序或微信支付相關操作支付退款訂單查詢退款查詢支付成功,進行回調退款成功 進行回調用到的方法
支付
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
|
/** * 預支付請求接口(POST) * @param string $openid openid * @param string $body 商品簡單描述 * @param string $order_sn 訂單編號 * @param string $total_fee 金額 * @return json的數據 */ public function prepay() { tp_log( '預支付請求數據===>' . json_encode( $_POST ), 'prepay' , request()->controller()); $goods_user = db( 'tf_goods_user' )->where( array ( 'order_no' => $_POST [ 'order_no' ]))->find(); $goods = db( 'tf_goods' )->where( array ( 'id' => $goods_user [ 'goods_id' ]))->find(); //判斷產品的數量 if (( $goods [ 'sales_initial' ] - $goods [ 'sales_actual' ]) <= 0) { $return [ 'status' ] = 0; $return [ 'info' ] = '此產品已售完' ; exit (json_encode( $return )); } $order_no = $_POST [ 'order_no' ]; //訂單號 $is_sale = $_POST [ 'is_sale' ]; $openid = $_POST [ 'openid' ]; $goods_name = $_POST [ 'goods_name' ]; $pay_price = $_POST [ 'price' ]; $attach [ 'is_sale' ] = $_POST [ 'is_sale' ]; $attach [ 'sale_id' ] = $_POST [ 'sale_id' ]; $nonce_str = $this ->nonce_str(); //隨機字符串 $order_no_ssh = $this ->get_orderssh(); //商戶訂單號 //組裝支付數據 $data = [ 'appid' => config( 'pay.APPID' ), 'mch_id' => config( 'pay.MCHID' ), 'nonce_str' => $nonce_str , 'body' => $goods_name , //商品名稱組合 'attach' => json_encode( $attach ), 'out_trade_no' => $order_no_ssh , //$order_no, //訂單號 商戶訂單號 'total_fee' => intval ( $pay_price * 100), 'spbill_create_ip' => $_SERVER [ 'REMOTE_ADDR' ], 'notify_url' => config( 'pay.NOTIFY_URL' ), 'trade_type' => 'JSAPI' , 'openid' => $openid ]; //訂單支付表創建訂單支付數據 $p_o_data [ 'createtime' ] = time(); $p_o_data [ 'order_no' ] = $order_no ; $p_o_data [ 'order_no_ssh' ] = $order_no_ssh ; $p_o_data [ 'ready' ] = json_encode( $data ); $p_o_return = db( 'tf_pay_order' )->insert( $p_o_data ); if (! $p_o_return ){ //失敗 $return [ 'status' ] = -1; $return [ 'info' ] = $p_o_data ; exit (json_encode( $return )); } // 獲取簽名 $sign = $this ->makeSign( $data ); $data [ 'sign' ] = $sign ; $xml = $this ->toXml( $data ); $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder' ; //發起支付接口鏈接 //發起預支付請求 $prepay_return_reslut_xml = $this ->http_request( $url , $xml ); $xml_to_arr = $this ->fromXml( $prepay_return_reslut_xml ); $return_result = json_encode( $xml_to_arr , true); tp_log( '預支付請求返回數據array===>' . $return_result , 'prepay' , request()->controller()); //記錄預支付返回信息 db( 'tf_goods_order' )->where( array ( 'order_no' => $order_no )) ->update( array ( 'go_pay' => $return_result , 'updatetime' => time(), 'updateuser' => $openid )); if ( $xml_to_arr [ 'return_code' ] == 'SUCCESS' && $xml_to_arr [ 'result_code' ] == 'SUCCESS' ){ //成功 $time = time(); //臨時數組用于簽名 $tmp = [ 'appId' => config( 'pay.APPID' ), 'nonceStr' => $nonce_str , 'package' => 'prepay_id=' . $xml_to_arr [ 'prepay_id' ], 'signType' => 'MD5' , 'timeStamp' => "$time" , ]; $data [ 'timeStamp' ] = "$time" ; //時間戳 $data [ 'nonceStr' ] = $nonce_str ; //隨機字符串 $data [ 'signType' ] = 'MD5' ; //簽名算法,暫支持 MD5 $data [ 'package' ] = 'prepay_id=' . $xml_to_arr [ 'prepay_id' ]; //統一下單接口返回的 prepay_id 參數值,提交格式如:prepay_id=* $data [ 'paySign' ] = $this ->makeSign( $tmp ); //簽名,具體簽名方案參見微信公眾號支付幫助文檔;$data['out_trade_no'] = $out_trade_no; $return [ 'status' ] = 1; $return [ 'info' ] = $data ; } else { //失敗 $return [ 'status' ] = -1; $return [ 'info' ] = $xml_to_arr ; } exit (json_encode( $return )); } //curl請求 public function http_request( $url , $data = null, $headers = array ()) { $curl = curl_init(); if ( count ( $headers ) >= 1) { curl_setopt( $curl , CURLOPT_HTTPHEADER, $headers ); } curl_setopt( $curl , CURLOPT_URL, $url ); curl_setopt( $curl , CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt( $curl , CURLOPT_SSL_VERIFYHOST, FALSE); if (! empty ( $data )) { curl_setopt( $curl , CURLOPT_POST, 1); curl_setopt( $curl , CURLOPT_POSTFIELDS, $data ); } curl_setopt( $curl , CURLOPT_RETURNTRANSFER, 1); $output = curl_exec( $curl ); curl_close( $curl ); return $output ; } |
退款
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
|
/** * 申請退款API * @param $transaction_id * @param double $total_fee 賬單總金額 * @param double $refund_fee 退款金額 * @return bool * @throws BaseException */ public function refund() { $transaction_id = '4200000712202007274705432240' ; $total_fee = '0.01' ; $refund_fee = '0.01' ; // 當前時間 $time = time(); // 生成隨機字符串 $nonceStr = md5( $time . $transaction_id . $total_fee . $refund_fee ); // API參數 $params = [ 'appid' => config( 'pay.APPID' ), 'mch_id' => config( 'pay.MCHID' ), 'nonce_str' => $nonceStr , 'transaction_id' => $transaction_id , 'out_refund_no' => $time , 'total_fee' => $total_fee * 100, 'refund_fee' => $refund_fee * 100, 'notify_url' => config( 'pay.NOTIFY_URL_REFUND' ), //退款回調地址 ]; // 生成簽名 $params [ 'sign' ] = $this ->makeSign( $params ); tp_log( '退款請求數據===>' . json_encode( $params ), 'refund' , request()->controller()); // 請求API $url = 'https://api.mch.weixin.qq.com/secapi/pay/refund' ; $result = $this ->post( $url , $this ->toXml( $params ), true, $this ->getCertPem()); $prepay = $this ->fromXml( $result ); // 請求失敗 if ( empty ( $result )) { throw new BaseException([ 'msg' => '微信退款api請求失敗' ]); } // 格式化返回結果 $prepay = $this ->fromXml( $result ); tp_log( '退款返回數據===>' . json_encode( $prepay ), 'refund' , request()->controller()); // 請求失敗 // if ($prepay['return_code'] === 'FAIL') { // throw new BaseException(['msg' => 'return_msg: ' . $prepay['return_msg']]); // } // if ($prepay['result_code'] === 'FAIL') { // throw new BaseException(['msg' => 'err_code_des: ' . $prepay['err_code_des']]); // } return true; } /** * 模擬POST請求 * @param $url * @param array $data * @param bool $useCert * @param array $sslCert * @return mixed */ public function post( $url , $data = [], $useCert = false, $sslCert = []) { $header = [ 'Content-type: application/json;' ]; $curl = curl_init(); //如果有配置代理這里就設置代理 // if(WxPayConfig::CURL_PROXY_HOST != "0.0.0.0" // && WxPayConfig::CURL_PROXY_PORT != 0){ // curl_setopt($ch,CURLOPT_PROXY, WxPayConfig::CURL_PROXY_HOST); // curl_setopt($ch,CURLOPT_PROXYPORT, WxPayConfig::CURL_PROXY_PORT); // } curl_setopt( $curl , CURLOPT_URL, $url ); curl_setopt( $curl , CURLOPT_HTTPHEADER, $header ); curl_setopt( $curl , CURLOPT_HEADER, false); curl_setopt( $curl , CURLOPT_RETURNTRANSFER, 1); curl_setopt( $curl , CURLOPT_SSL_VERIFYPEER, false); curl_setopt( $curl , CURLOPT_POST, TRUE); curl_setopt( $curl , CURLOPT_POSTFIELDS, $data ); if ( $useCert == true) { // 設置證書:cert 與 key 分別屬于兩個.pem文件 curl_setopt( $curl , CURLOPT_SSLCERTTYPE, 'PEM' ); curl_setopt( $curl , CURLOPT_SSLCERT, $sslCert [ 'certPem' ]); curl_setopt( $curl , CURLOPT_SSLKEYTYPE, 'PEM' ); curl_setopt( $curl , CURLOPT_SSLKEY, $sslCert [ 'keyPem' ]); } $result = curl_exec( $curl ); curl_close( $curl ); return $result ; } |
訂單查詢
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
|
/** * 訂單查詢 * @param $out_trade_no * @return mixed * @throws BaseException */ public function orderquery() { $transaction_id = '4200000712202007274705432240' ; //微信訂單號 // 當前時間 $time = time(); // 生成隨機字符串 $nonce_str = md5( $time . mt_rand(00000,99999)); //API參數 $params = [ 'appid' => config( 'pay.APPID' ), //公眾號ID 'mch_id' => config( 'pay.MCHID' ), //商戶號 'transaction_id' => $transaction_id , //商戶訂單號 'nonce_str' => $nonce_str , // 隨機字符串 ]; //生成簽名 $params [ 'sign' ] = $this ->makeSign( $params ); //請求API $url = 'https://api.mch.weixin.qq.com/pay/orderquery' ; $result = $this ->post( $url , $this ->toXml( $params )); $prepay = $this ->fromXml( $result ); // 請求失敗 if ( $prepay [ 'return_code' ] === 'FAIL' ) { throw new BaseException([ 'msg' => $prepay [ 'return_msg' ], 'code' => 0]); } if ( $prepay [ 'result_code' ] === 'FAIL' ) { throw new BaseException([ 'msg' => $prepay [ 'err_code_des' ], 'code' => 0]); } return $prepay ; } |
退款查詢
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
/** * 退款查詢 * @param $out_trade_no * @return mixed * @throws BaseException */ public function refundquery() { $transaction_id = '4200000712202007274705432240' ; //微信訂單號 // 當前時間 $time = time(); // 生成隨機字符串 $nonce_str = md5( $time . mt_rand(00000,99999)); //API參數 $params = [ 'appid' => config( 'pay.APPID' ), //公眾號ID 'mch_id' => config( 'pay.MCHID' ), //商戶號 'transaction_id' => $transaction_id , //商戶訂單號 'nonce_str' => $nonce_str , // 隨機字符串 ]; //生成簽名 $params [ 'sign' ] = $this ->makeSign( $params ); //請求API $url = 'https://api.mch.weixin.qq.com/pay/refundquery' ; $result = $this ->post( $url , $this ->toXml( $params )); $prepay = $this ->fromXml( $result ); dump( $prepay ); die ; // 請求失敗 if ( $prepay [ 'return_code' ] === 'FAIL' ) { throw new BaseException([ 'msg' => $prepay [ 'return_msg' ], 'code' => 0]); } if ( $prepay [ 'result_code' ] === 'FAIL' ) { throw new BaseException([ 'msg' => $prepay [ 'err_code_des' ], 'code' => 0]); } return $prepay ; } |
支付成功,進行回調
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
public function index() { $data = file_get_contents ( 'php://input' ); $data = $this ->FromXml( $data ); tp_log( '支付回調數據===>' . json_encode( $data ), 'index' , request()->controller()); // 保存微信服務器返回的簽名sign $data_sign = $data [ 'sign' ]; // sign不參與簽名算法 unset( $data [ 'sign' ]); $sign = $this ->makeSign( $data ); //回調驗證簽名 $str_success = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>' ; $str_error = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[簽名失敗]]></return_msg></xml>' ; if (( $sign === $data_sign ) && ( $data [ 'return_code' ] == 'SUCCESS' ) && ( $data [ 'result_code' ] == 'SUCCESS' )) { // 支付成功 進行你的邏輯處理 } echo $str_success ; //str_error 告知微信 你已的邏輯處理完畢 不用再推送或再次推送你結果 } |
退款成功 進行回調
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
|
/* * 小程序 退款結果通知 */ public function refund(){ $data = file_get_contents ( 'php://input' ); $data = $this ->FromXml( $data ); tp_log( '退款回調數據===>' . json_encode( $data ), 'refund' , request()->controller()); //對加密的字符串解密 $req_info_xml = openssl_decrypt( base64_decode ( $data [ 'req_info' ]), 'aes-256-ecb' , md5(config( 'pay.KEY' )),OPENSSL_RAW_DATA); $req_info = $this ->FromXml( $req_info_xml ); // // 保存微信服務器返回的簽名sign // $data_sign = $data['sign']; // // sign不參與簽名算法 // unset($data['sign']); // $sign = $this->makeSign($data);//回調驗證簽名 // // $str_success = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'; // $str_error = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[簽名失敗]]></return_msg></xml>'; // // // // if (($sign === $data_sign) && ($data['return_code'] == 'SUCCESS') && ($data['result_code'] == 'SUCCESS')) { // tp_log('退款成功===>', 'refund', request()->controller()); // //去修改訂單的狀態 和支付回調的一樣 修改成功 告知微信 不在推送 // } } |
用到的方法
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
|
/** * 生成簽名 * @param $values * @return string 本函數不覆蓋sign成員變量,如要設置簽名需要調用SetSign方法賦值 */ private function makeSign( $values ) { //簽名步驟一:按字典序排序參數 ksort( $values ); $string = $this ->toUrlParams( $values ); //簽名步驟二:在string后加入KEY $string = $string . '&key=' . config( 'pay.KEY' ); //簽名步驟三:MD5加密 $string = md5( $string ); //簽名步驟四:所有字符轉為大寫 $result = strtoupper ( $string ); return $result ; } private function ToUrlParams( $array ) { $buff = "" ; foreach ( $array as $k => $v ) { if ( $k != "sign" && $v != "" && ! is_array ( $v )) { $buff .= $k . "=" . $v . "&" ; } } $buff = trim( $buff , "&" ); return $buff ; } /** * 輸出xml字符 * @param $values * @return bool|string */ private function toXml( $values ) { if (! is_array ( $values ) || count ( $values ) <= 0 ) { return false; } $xml = "<xml>" ; foreach ( $values as $key => $val ) { if ( is_numeric ( $val )) { $xml .= "<" . $key . ">" . $val . "</" . $key . ">" ; } else { $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">" ; } } $xml .= "</xml>" ; return $xml ; } /** * 將xml轉為array * @param $xml * @return mixed */ private function fromXml( $xml ) { // 禁止引用外部xml實體 libxml_disable_entity_loader(true); return json_decode(json_encode(simplexml_load_string( $xml , 'SimpleXMLElement' , LIBXML_NOCDATA)), true); } /** * 獲取cert證書文件 * @return array * @throws BaseException */ private function getCertPem() { // if (empty($this->config['cert_pem']) || empty($this->config['key_pem'])) { // throw new BaseException(['msg' => '請先到后臺小程序設置填寫微信支付證書文件']); // } // cert目錄 $filePath = EXTEND_PATH. 'wxpay/cert/' ; return [ 'certPem' => $filePath . 'apiclient_cert.pem' , 'keyPem' => $filePath . 'apiclient_key.pem' ]; } /** * 生成商戶訂單號 */ public function get_orderssh() { return date ( "YmdHis" ) . mt_rand(10000000, 99999999); } |
證書路徑
config配置
總結
到此這篇關于基于thinkphp5框架實現微信小程序支付 退款 訂單查詢 退款查詢的文章就介紹到這了,更多相關微信小程序支付 退款 訂單查詢 退款查詢內容請搜索服務器之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持服務器之家!
原文鏈接:https://blog.csdn.net/qq_37468919/article/details/107617288