


Wie kann ich einheitliche Bestellungen per WeChat-Zahlung mit PHP aufgeben? (Vollst?ndiger Code)
Jul 26, 2018 am 09:29 AMWas soll ich tun, wenn bei der H5-Zahlung ein ?Signaturfehler“ auftritt? Beachten Sie, dass der Benutzer nach dem Aufrufen der ?Unified Order“-Schnittstelle von WeChat und der Rückgabe von pre_pay_id erneut signieren und zu HTML zurückkehren muss. ?Das Zahlungsverzeichnis ist nicht autorisiert“. Geben Sie einfach die Hintergrundeinstellungen für die WeChat-H?ndlerverwaltung ein.
1. Modellebene, Wxpay.php
<?php namespace app\common\model; class Wxpay { private $appid = 'wxe8*****d4'; //微信公眾號appid private $secret = '37c4*******5f0'; //微信公眾號appsecret private $mchid = '13******02'; //商家號 private $key = '5363e******49e8'; //支付密鑰 private $sslcert_path = 'apiclient_cert.pem'; //證書所在絕對路徑 private $sslkey_path = 'apiclient_key.pem'; //證書所在絕對路徑 public function __construct($appid = '', $secret = '', $mchid = '', $key = '') { if(!empty($appid)) $this->appid = $appid; if(!empty($secret)) $this->secret = $secret; if(!empty($mchid)) $this->mchid = $mchid; if(!empty($key)) $this->key= $key; } /* * 微信內(nèi)H5調(diào)起支付 * @params string $openid : 微信用戶openid * @params string $out_trade_no : 商家生成的訂單號(唯一性) * @params int $total_fee : 支付金額,單位分 * return array $ret : 返回支付時所需要的數(shù)據(jù) * */ public function payForWeixin($openid,$out_trade_no,$total_fee,$attach='微信支付',$body='微信支付') { //支付數(shù)據(jù) $data['openid'] = $openid; $data['out_trade_no'] = $out_trade_no; $data['total_fee'] = $total_fee*100; $data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"]; $data['attach'] = $attach; $data['body'] = $body; $data['appid'] = $this->appid; $data['mch_id'] = $this->mchid; $data['nonce_str'] = random(12); $data['trade_type'] = "JSAPI"; $data['notify_url'] = "http://****.com/home/wxpaynofiy/notify.html"; $sign = $this->getParam($data); $dataXML = "<xml> <appid>".$data['appid']."</appid> <attach>".$data['attach']."</attach> <body>".$data['body']."</body> <mch_id>".$data['mch_id']."</mch_id> <nonce_str>".$data['nonce_str']."</nonce_str> <notify_url>".$data['notify_url']."</notify_url> <openid>".$data['openid']."</openid> <out_trade_no>".$data['out_trade_no']."</out_trade_no> <spbill_create_ip>".$data['spbill_create_ip']."</spbill_create_ip> <total_fee>".$data['total_fee']."</total_fee> <trade_type>".$data['trade_type']."</trade_type> <sign>".$sign."</sign> </xml>"; $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; $result = $this->https_post($url,$dataXML); $ret = $this->xmlToArray($result); if($ret['return_code'] == 'SUCCESS' && $ret['return_msg'] == 'OK') { return array( 'appId' => $this->appid, 'timeStamp' => time(), 'nonceStr' => $data['nonce_str'], 'package' => 'prepay_id='.$ret['prepay_id'], 'signType' => 'MD5', 'paySign' => $sign ); } else { $this->errorLog("微信支付失敗,",$ret); return null; } } /* * 微信二維碼支付 * @params string $openid : 用戶的openid * @params string $out_trade_no : 商戶訂單號 * @params number $total_fee : 訂單金額,單位分 * return string $code_url : 二維碼URL鏈接 */ public function payForQrcode($out_trade_no,$total_fee,$body="魔盒CMS",$attach="微信支付") { //支付數(shù)據(jù) $data['out_trade_no'] = $out_trade_no; $data['total_fee'] = $total_fee*100; $data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"]; $data['attach'] = $attach; $data['body'] = $body; $data['appid'] = $this->appid; $data['mch_id'] = $this->mchid; $data['nonce_str'] = random(12); $data['trade_type'] = "NATIVE"; $data['notify_url'] = "http://****.com/home/wxpaynofiy/notify.html"; $sign = $this->getParam($data); $dataXML = "<xml> <appid>".$data['appid']."</appid> <attach>".$data['attach']."</attach> <body>".$data['body']."</body> <mch_id>".$data['mch_id']."</mch_id> <nonce_str>".$data['nonce_str']."</nonce_str> <notify_url>".$data['notify_url']."</notify_url> <out_trade_no>".$data['out_trade_no']."</out_trade_no> <spbill_create_ip>".$data['spbill_create_ip']."</spbill_create_ip> <total_fee>".$data['total_fee']."</total_fee> <trade_type>".$data['trade_type']."</trade_type> <sign>".$sign."</sign> </xml>"; $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; $result = $this->https_post($url,$dataXML); $ret = $this->xmlToArray($result); if($ret['return_code'] == 'SUCCESS' && $ret['return_msg'] == 'OK') { return $ret['code_url']; } else { $this->errorLog("獲取微信支付二維碼失敗,",$ret); return null; } } /* * 訂單查詢 * @params string $transaction_id : 微信訂單號 * @params string $out_trade_no : 商家訂單號(與微信訂單號二選一) * */ public function findOrder($out_trade_no) { $data['appid'] = $this->appid; $data['mch_id'] = $this->mchid; $data['nonce_str'] = random(12); $data['out_trade_no'] = $out_trade_no; $sign = $this->getParam($data); $dataXML = "<xml> <appid>".$data['appid']."</appid> <mch_id>".$data['mch_id']."</mch_id> <nonce_str>".$data['nonce_str']."</nonce_str> <out_trade_no>".$data['out_trade_no']."</out_trade_no> <sign>".$sign."</sign> </xml>"; $url = 'https://api.mch.weixin.qq.com/pay/orderquery'; $result = $this->https_post($url,$dataXML); $ret = $this->xmlToArray($result); if($ret['return_code'] == 'SUCCESS' && $ret['return_msg'] == 'OK') { return $ret; } else { $this->errorLog("查詢微信支付訂單失敗,",$ret); return null; } } /* * 退款訂單查詢 * @params string $transaction_id : 微信訂單號 * @params string $out_trade_no : 商家訂單號(與微信訂單號二選一) * */ public function findRefundOrder($out_trade_no) { $data['appid'] = $this->appid; $data['mch_id'] = $this->mchid; $data['nonce_str'] = random(12); $data['out_trade_no'] = $out_trade_no; $sign = $this->getParam($data); $dataXML = "<xml> <appid>".$data['appid']."</appid> <mch_id>".$data['mch_id']."</mch_id> <nonce_str>".$data['nonce_str']."</nonce_str> <out_trade_no>".$data['out_trade_no']."</out_trade_no> <sign>".$sign."</sign> </xml>"; $url = 'https://api.mch.weixin.qq.com/pay/refundquery'; $result = $this->https_post($url,$dataXML); $ret = $this->xmlToArray($result); if($ret['return_code'] == 'SUCCESS' && $ret['return_msg'] == 'OK') { return $ret; } else { $this->errorLog("查詢微信支付退款訂單失敗,",$ret); return $ret['err_code_des']; } } /* * 申請退款 * @params string $out_trade_no : 商戶訂單號 * @params string $out_refund_no : 商戶退款單號 * @params int $total_fee : 訂單金額 * @params int $refund_fee : 退款金額 * @params string $refund_desc : 退款原因 * */ public function refund($out_trade_no,$out_refund_no,$total_fee,$refund_fee,$refund_desc='退款') { $data['appid'] = $this->appid; $data['mch_id'] = $this->mchid; $data['nonce_str'] = random(12); $data['out_trade_no'] = $out_trade_no; $data['out_refund_no'] = $out_refund_no; $data['total_fee'] = $total_fee*100; $data['refund_fee'] = $refund_fee*100; $data['refund_desc'] = $refund_desc; $data['notify_url'] = "http://*****.com/home/wxpaynofiy/refund.html"; $sign = $this->getParam($data); $dataXML = "<xml> <appid>".$data['appid']."</appid> <mch_id>".$data['mch_id']."</mch_id> <nonce_str>".$data['nonce_str']."</nonce_str> <out_trade_no>".$data['out_trade_no']."</out_trade_no> <out_refund_no>".$data['out_refund_no']."</out_refund_no> <total_fee>".$data['total_fee']."</total_fee> <refund_fee>".$data['refund_fee']."</refund_fee> <refund_desc>".$data['refund_desc']."</refund_desc> <notify_url>".$data['notify_url']."</notify_url> <sign>".$sign."</sign> </xml>"; $url = 'https://api.mch.weixin.qq.com/secapi/pay/refund'; $result = $this->https_post($url,$dataXML,true); $ret = $this->xmlToArray($result); if($ret['return_code'] == 'SUCCESS' && $ret['return_msg'] == 'OK') { return $ret; } else { $this->errorLog("微信退款失敗,",$ret); return null; } } /* * 企業(yè)付款至用戶零錢 * @params string $openid : 用戶openid * @params int $total_fee : 付款金額,單位分 * @params string $out_trade_no : 商家訂單號 * @params string $username : 微信用戶名稱(注意微信昵稱若為空時支付會出錯) * @params string $desc : 付款描述 * @params string $check_name : 是否檢測用戶名 * */ public function payForUser($openid,$total_fee,$out_trade_no,$username='魔盒CMS',$desc='魔盒CMS付款給用戶',$check_name='NO_CHECK') { $data['amount'] = $total_fee*100; $data['check_name'] = $check_name; $data['desc'] = $desc; $data['mch_appid'] = $this->appid; $data['mchid'] = $this->mchid; $data['nonce_str'] = random(12); $data['openid'] = $openid; $data['partner_trade_no'] = $out_trade_no; $data['re_user_name'] = $username; $data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"]; $sign = $this->getParam($data); $dataXML="<xml> <mch_appid>".$data['mch_appid']."</mch_appid> <mchid>".$data['mchid']."</mchid> <nonce_str>".$data['nonce_str']."</nonce_str> <partner_trade_no>".$data['partner_trade_no']."</partner_trade_no> <openid>".$data['openid']."</openid> <check_name>".$data['check_name']."</check_name> <re_user_name>".$data['re_user_name']."</re_user_name> <amount>".$data['amount']."</amount> <desc>".$data['desc']."</desc> <spbill_create_ip>".$data['spbill_create_ip']."</spbill_create_ip> <sign>".$sign."</sign> </xml>"; $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/promotion/transfers'; $result = $this->https_post($url,$dataXML,true); $ret = $this->xmlToArray($result); if($ret['return_code']=='SUCCESS' && $ret['result_code'] == 'SUCCESS') { //支付成功返回商戶訂單號、微信訂單號、微信支付成功時間 $result['partner_trade_no'] = $ret['partner_trade_no']; $result['payment_no'] = $ret['payment_no']; $result['payment_time'] = $ret['payment_time']; return $ret; } else { $this->errorLog('付款給用戶失敗',$ret); return null; } } /* * 普通紅包 * @params string $out_trade_no : 商家訂單號 * @params string $openid : 接收紅包用戶的openid * @params int $total_fee : 紅包金額,單位分 * @params int $total_num : 紅包發(fā)放總?cè)藬?shù) * @params string $wishing : 紅包祝福語 * @params string $act_name : 活動名稱 * @params string $remark : 備注 * @params string $scene_id :場景值ID。發(fā)放紅包使用場景,紅包金額大于200或者小于1元時必傳。PRODUCT_1:商品促銷、PRODUCT_2:抽獎、PRODUCT_3:虛擬物品兌獎 、PRODUCT_4:企業(yè)內(nèi)部福利、PRODUCT_5:渠道分潤、PRODUCT_6:保險回饋、PRODUCT_7:彩票派獎、PRODUCT_8:稅務(wù)刮獎 * */ public function redPack($openid,$total_fee,$out_trade_no,$total_num = 1,$wishing = '感謝您光臨***平臺進行購物',$act_name='***購物發(fā)紅包',$remark = '購物領(lǐng)紅包') { $data['mch_billno'] = $out_trade_no; $data['mch_id'] = $this->mchid; $data['wxappid'] = $this->appid; $data['send_name'] = '發(fā)送紅包者的名稱'; $data['re_openid'] = $openid; $data['total_amount'] = $total_fee; $data['total_num'] = $total_num; $data['wishing'] = $wishing; $data['client_ip'] = $_SERVER["REMOTE_ADDR"]; $data['act_name'] = $act_name; $data['remark'] = $remark; $data['nonce_str'] = random(12); $sign = $this->getParam($data); $dataXML="<xml> <sign>".$sign."</sign> <mch_billno>".$data['mch_billno']."</mch_billno> <mch_id>".$data['mch_id']."</mch_id> <wxappid>".$data['wxappid']."</wxappid> <send_name>".$data['send_name']."</send_name> <re_openid>".$data['re_openid']."</re_openid> <total_amount>".$data['total_amount']."</total_amount> <total_num>".$data['total_num']."</total_num> <wishing>".$data['wishing']."</wishing> <client_ip>".$data['client_ip']."</client_ip> <act_name>".$data['act_name']."</act_name> <remark>".$data['remark']."</remark> <nonce_str>".$data['nonce_str']."</nonce_str> </xml>"; $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendredpack'; $result = $this->https_post($url,$dataXML,true); $ret = $this->xmlToArray($result); if($ret['return_code']=='SUCCESS' && $ret['result_code'] == 'SUCCESS') { return $ret; } else { $this->errorLog('發(fā)放普通紅包失敗',$ret); return $ret['err_code_des']; } } /* * 裂變紅包:一次可以發(fā)放一組紅包。首先領(lǐng)取的用戶為種子用戶,種子用戶領(lǐng)取一組紅包當(dāng)中的一個,并可以通過社交分享將剩下的紅包給其他用戶。 * 裂變紅包充分利用了人際傳播的優(yōu)勢。 * @params string $out_trade_no : 商家訂單號 * @params string $openid : 接收紅包用戶的openid * @params int $total_fee : 紅包金額,單位分 * @params int $total_num : 紅包發(fā)放總?cè)藬?shù) * @params string $wishing : 紅包祝福語 * @params string $act_name : 活動名稱 * @params string $remark : 備注 * @params string $scene_id :場景值ID。發(fā)放紅包使用場景,紅包金額大于200或者小于1元時必傳。PRODUCT_1:商品促銷、PRODUCT_2:抽獎、PRODUCT_3:虛擬物品兌獎 、PRODUCT_4:企業(yè)內(nèi)部福利、PRODUCT_5:渠道分潤、PRODUCT_6:保險回饋、PRODUCT_7:彩票派獎、PRODUCT_8:稅務(wù)刮獎 * */ public function redPackGroup($openid,$total_fee,$out_trade_no,$total_num,$wishing = '感謝您光臨***進行購物',$act_name='**購物發(fā)紅包',$remark = '購物領(lǐng)紅包') { $data['mch_billno'] = $out_trade_no; $data['mch_id'] = $this->mchid; $data['wxappid'] = $this->appid; $data['send_name'] = '發(fā)送紅包者的名稱'; $data['re_openid'] = $openid; $data['total_amount'] = $total_fee; $data['amt_type'] = 'ALL_RAND'; //ALL_RAND—全部隨機,商戶指定總金額和紅包發(fā)放總?cè)藬?shù),由微信支付隨機計算出各紅包金額 $data['total_num'] = $total_num; $data['wishing'] = $wishing; $data['client_ip'] = $_SERVER["REMOTE_ADDR"]; $data['act_name'] = $act_name; $data['remark'] = $remark; $data['nonce_str'] = random(12); $sign = $this->getParam($data); $dataXML="<xml> <sign>".$sign."</sign> <mch_billno>".$data['mch_billno']."</mch_billno> <mch_id>".$data['mch_id']."</mch_id> <wxappid>".$data['wxappid']."</wxappid> <send_name>".$data['send_name']."</send_name> <re_openid>".$data['re_openid']."</re_openid> <total_amount>".$data['total_amount']."</total_amount> <amt_type>".$data['amt_type']."</amt_type> <total_num>".$data['total_num']."</total_num> <wishing>".$data['wishing']."</wishing> <client_ip>".$data['client_ip']."</client_ip> <act_name>".$data['act_name']."</act_name> <remark>".$data['remark']."</remark> <nonce_str>".$data['nonce_str']."</nonce_str> </xml>"; $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/sendgroupredpack'; $result = $this->https_post($url,$dataXML,true); $ret = $this->xmlToArray($result); if($ret['return_code']=='SUCCESS' && $ret['result_code'] == 'SUCCESS') { return $ret; } else { $this->errorLog('發(fā)放裂變紅包失敗',$ret); return $ret['err_code_des']; } } /* * 查詢紅包記錄 * @params string $out_trade_no : 商家訂單號 * */ public function findRedPack($out_trade_no) { $data['mch_billno'] = $out_trade_no; $data['mch_id'] = $this->mchid; $data['appid'] = $this->appid; $data['bill_type'] = 'MCHT'; //MCHT:通過商戶訂單號獲取紅包信息。 $data['nonce_str'] = random(12); $sign = $this->getParam($data); $dataXML="<xml> <sign>".$sign."</sign> <mch_billno>".$data['mch_billno']."</mch_billno> <mch_id>".$data['mch_id']."</mch_id> <appid>".$data['appid']."</appid> <bill_type>".$data['bill_type']."</bill_type> <nonce_str>".$data['nonce_str']."</nonce_str> </xml>"; $url = 'https://api.mch.weixin.qq.com/mmpaymkttransfers/gethbinfo'; $result = $this->https_post($url,$dataXML,true); $ret = $this->xmlToArray($result); if($ret['return_code']=='SUCCESS' && $ret['result_code'] == 'SUCCESS') { return $ret; } else { $this->errorLog('查詢紅包記錄失敗',$ret); return $ret['err_code_des']; } } /* * 獲取用戶微信的OPENID * */ public function openid($c=false) { if($_GET['state']!="zgm"){ $t = $c ? "snsapi_userinfo" : "snsapi_base"; $url=urlencode(get_url()); $url="https://open.weixin.qq.com/connect/oauth2/authorize?appid=".$this->appid."&redirect_uri=".$url."&response_type=code&scope=".$t."&state=zgm#wechat_redirect"; echo "<html><script>window.location.href='$url';</script></html>"; exit; } if($_GET['code']){ $url="https://api.weixin.qq.com/sns/oauth2/access_token?appid=".$this->appid."&secret=".$this->secret."&code=".$_GET['code']."&grant_type=authorization_code"; $wx_db=json_decode($this->https_get($url)); if($c){ $url_2="https://api.weixin.qq.com/sns/userinfo?access_token=".$wx_db->access_token."&openid=".$wx_db->openid."&lang=zh_CN"; $db=json_decode($this->https_get($url_2)); return $db; }else{ return $wx_db->openid; } } } /* * 發(fā)起網(wǎng)絡(luò)GET請求 * @params string $url : URL鏈接 */ private function https_get($url) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($curl, CURLOPT_HEADER, FALSE) ; curl_setopt($curl, CURLOPT_TIMEOUT,60); if (curl_errno($curl)) { return 'Errno'.curl_error($curl); } else{$result=curl_exec($curl);} curl_close($curl); return $result; } //對參數(shù)排序,生成MD5加密簽名 private function getParam($paramArray, $isencode=false) { $paramStr = ''; ksort($paramArray); $i = 0; foreach ($paramArray as $key => $value) { if ($key == 'Signature'){ continue; } if ($i == 0){ $paramStr .= ''; }else{ $paramStr .= '&'; } $paramStr .= $key . '=' . ($isencode?urlencode($value):$value); ++$i; } $stringSignTemp=$paramStr."&key=".$this->key; $sign=strtoupper(md5($stringSignTemp)); return $sign; } //POST提交數(shù)據(jù) private function https_post($url,$data,$ssl = false) { $ch = curl_init (); curl_setopt ( $ch, CURLOPT_URL, $url ); curl_setopt ( $ch, CURLOPT_CUSTOMREQUEST, "POST" ); curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE ); curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE ); if($ssl) { curl_setopt ( $ch,CURLOPT_SSLCERT,$this->sslcert_path); curl_setopt ( $ch,CURLOPT_SSLKEY,$this->sslkey_path); } curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 ); curl_setopt ( $ch, CURLOPT_AUTOREFERER, 1 ); curl_setopt ( $ch, CURLOPT_POSTFIELDS, $data ); curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true ); $result = curl_exec($ch); if (curl_errno($ch)) { return 'Errno: '.curl_error($ch); } curl_close($ch); return $result; } /* * XML轉(zhuǎn)array * @params xml $xml : xml 數(shù)據(jù) * return array $data : 轉(zhuǎn)義后的array數(shù)組 */ private function xmlToArray($xml) { libxml_disable_entity_loader(true); $xmlstring = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); $val = json_decode(json_encode($xmlstring),true); return $val; } /* * 記錄日志 * @params string $msg : 提示語句 * @params array $ret : 錯誤結(jié)果 */ private function errorLog($msg,$ret) { file_put_contents(ROOT_PATH . 'runtime/error/wxpay.log', "[" . date('Y-m-d H:i:s') . "] ".$msg."," .json_encode($ret).PHP_EOL, FILE_APPEND); } }
2. Controller-Ebene, Test.php
<?php namespace app\goods\controller; use app\common\model\Wxpay; class Test { /* * 調(diào)用微信支付 * 一、獲取微信用戶的openid; * 二、調(diào)用微信支付接口 * 三、生成H5中使用的簽名內(nèi)容 */ public function wx() { $wxpay = new Wxpay(); $openid = $wxpay->openid(); $pay = $wxpay->payForWeixin($openid,date('YmdHis').rand(1,5),'0.1'); $paySign =strtoupper(MD5('appId='.$pay['appId'].'&nonceStr='.$pay['nonceStr'].'&package='.$pay['package'].'&signType=MD5&timeStamp='.$pay['timeStamp'].'&key=536*****9e8')); $h5 = array( 'appId' => $pay['appId'], 'timeStamp' => $pay['timeStamp'], 'nonceStr' => $pay['nonceStr'], 'package' => $pay['package'], 'signType' => $pay['signType'], 'paySign' => $paySign ); $this->assign('wxpay',$h5); return view(); } }
3. WeChat-Zahlung in HTML aufrufen, wx.html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>訂單示例</title> </head> <body> <script type="text/javascript"> function onBridgeReady(){ WeixinJSBridge.invoke( 'getBrandWCPayRequest', { "appId":"{$wxpay['appId']}", "timeStamp":"{$wxpay['timeStamp']}", "nonceStr":"{$wxpay['nonceStr']}", "package":"{$wxpay['package']}", "signType":"MD5", "paySign":"{$wxpay['paySign']}" }, function(res){ if(res.err_msg == "get_brand_wcpay_request:ok" ){ // 使用以上方式判斷前端返回,微信團隊鄭重提示: //res.err_msg將在用戶支付成功后返回ok,但并不保證它絕對可靠。 } }); } if (typeof WeixinJSBridge == "undefined"){ if( document.addEventListener ){ document.addEventListener('WeixinJSBridgeReady', onBridgeReady, false); }else if (document.attachEvent){ document.attachEvent('WeixinJSBridgeReady', onBridgeReady); document.attachEvent('onWeixinJSBridgeReady', onBridgeReady); } }else{ onBridgeReady(); } </script> </body> </html>
4. Erhalten Sie das WeChat-Zahlungsrückgabeergebnis und legen Sie den notify_url-Wert w?hrend der Zahlung fest, um sicherzustellen, dass auf diesen Link vom externen Netzwerk aus zugegriffen werden kann. wxpaynofiy.php
<?php namespace app\home\controller; class Wxpaynofiy { public function notify() { $xml = isset($GLOBALS["HTTP_RAW_POST_DATA"]) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input"); $data = xmlToArray($xml); if($data['return_code'] == 'SUCCESS' && $data['result_code'] == 'SUCCESS'){ if($this->checkSign($data)) { $transaction_id = $data['transaction_id']; //微信支付訂單號 $out_trade_no = $data['out_trade_no']; //商家訂單號 $this->errorLog('微信支付返回結(jié)果,微信支付訂單號:'.$transaction_id.',商家訂單號:'.$out_trade_no,[]); } else { $this->errorLog('微信支付返回結(jié)果簽名驗證失敗',$data); } } else { $this->errorLog('微信支付返回結(jié)果',$data); } echo '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>'; } /* * 驗證簽名 * @params array $result : 微信支付成功返回的結(jié)果數(shù)組 * return bool $ret : 成功true,失敗false * */ private function checkSign(array $data) { $str = ''; ksort($data); foreach ($data as $k => $v) { if($k != 'sign') $str .= $k.'='.$v.'&'; } $temp = $str . 'key=5363******49e8'; //key:商戶支付密鑰 $sign = strtoupper(md5($temp)); return $sign == $data['sign'] ? true : false; } private function errorLog($msg,$ret) { file_put_contents(ROOT_PATH . 'runtime/error/wxpaynofiy.log', "[" . date('Y-m-d H:i:s') . "] ".$msg."," .json_encode($ret).PHP_EOL, FILE_APPEND); } }
Video-Tutorial: PHP WeChat-Schnittstellenentwicklung praktisches Projekt Chatbot + WeChat-Zahlung
Das obige ist der detaillierte Inhalt vonWie kann ich einheitliche Bestellungen per WeChat-Zahlung mit PHP aufgeben? (Vollst?ndiger Code). Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Hei?e KI -Werkzeuge

Undress AI Tool
Ausziehbilder kostenlos

Undresser.AI Undress
KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover
Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Clothoff.io
KI-Kleiderentferner

Video Face Swap
Tauschen Sie Gesichter in jedem Video mühelos mit unserem v?llig kostenlosen KI-Gesichtstausch-Tool aus!

Hei?er Artikel

Hei?e Werkzeuge

Notepad++7.3.1
Einfach zu bedienender und kostenloser Code-Editor

SublimeText3 chinesische Version
Chinesische Version, sehr einfach zu bedienen

Senden Sie Studio 13.0.1
Leistungsstarke integrierte PHP-Entwicklungsumgebung

Dreamweaver CS6
Visuelle Webentwicklungstools

SublimeText3 Mac-Version
Codebearbeitungssoftware auf Gottesniveau (SublimeText3)

PhpisstillrelevantinMoDernEnterpriseEnvironments.1.ModerPhp (7.xand8.x) Angebote, strenge, jitkompilation und moderne Syntax, machte ma?geschneiderte Foreiglableforlarge-ScaleApplikationen

Um einen flexiblen PHP -Microservice zu erstellen, müssen Sie Rabbitmq verwenden, um eine asynchrone Kommunikation zu erreichen. 1. Decken Sie den Dienst über Nachrichtenwarteschlangen ab, um Kaskadenfehler zu vermeiden. 2. Konfigurieren Sie persistente Warteschlangen, anhaltende Nachrichten, Freigabebest?tigung und manuelles ACK, um die Zuverl?ssigkeit zu gew?hrleisten. 3.. Verwenden Sie exponentielle Backoff -Wiederholung, TTL und Dead Letter -Warteschlangenverarbeitungsfehler; 4. Verwenden Sie Tools wie Supervisford, um Verbraucherprozesse zu schützen und Herzschlagmechanismen zu erm?glichen, um die Gesundheit der Service zu gew?hrleisten. und letztendlich die F?higkeit des Systems erkennen, kontinuierlich in Fehlern zu arbeiten.

Vermeiden Sie N 1 Abfrageprobleme, reduzieren Sie die Anzahl der Datenbankabfragen, indem Sie die zugeh?rigen Daten im Voraus laden. 2. W?hlen Sie nur die erforderlichen Felder aus, um das Laden vollst?ndiger Entit?ten zu vermeiden, um Speicher und Bandbreite zu sparen. 3.. Verwenden Sie Cache-Strategien vernünftigerweise, z. 4. Optimieren Sie den Lebenszyklus der Entit?t und rufen Sie Clear () regelm??ig an, um den Speicher freizugeben, um den Speicherüberlauf zu verhindern. 5. Stellen Sie sicher, dass der Datenbankindex die generierten SQL -Anweisungen existiert und analysiert, um ineffiziente Abfragen zu vermeiden. 6. Deaktivieren Sie die automatische ?nderungsverfolgung in Szenarien, in denen ?nderungen nicht erforderlich sind, und verwenden Sie Arrays oder Leichtgewichtsmodi, um die Leistung zu verbessern. Die korrekte Verwendung von ORM erfordert die Kombination der SQL -überwachung, -gespeicherung, der Stapelverarbeitung und der geeigneten Optimierung, um die Anwendungsleistung zu gew?hrleisten und gleichzeitig die Entwicklungseffizienz beizubehalten.

Die Verwendung des richtigen PHP-Basisbildes und die Konfiguration einer sicheren, leistungsoptimierten Docker-Umgebung ist der Schlüssel zum Erreichen der Produktion. 1. W?hlen Sie PHP: 8,3-FPM-Alpine als Grundbild, um die Angriffsfl?che zu reduzieren und die Leistung zu verbessern. 2. Deaktivieren Sie gef?hrliche Funktionen über benutzerdefinierte Php.ini, deaktivieren Sie die Fehleranzeige und aktivieren Sie Opcache und JIT, um die Sicherheit und Leistung zu verbessern. 3.. Verwenden Sie Nginx als Reverse Proxy, um den Zugriff auf sensible Dateien einzuschr?nken und die PHP-Anforderungen korrekt an PHP-FPM weiterzuleiten. 4. Verwenden Sie mehrstufige Optimierungsbilder, um Entwicklungsabh?ngigkeiten zu entfernen, und richten Sie nicht Root-Benutzer auf, um Container auszuführen. 5. optionaler Aufsichtsbeh?rde zum Verwalten mehrerer Prozesse wie Cron; 6. überprüfen

Verwenden Sie Subprozess.run (), um die Befehle von Shell sicher auszuführen und die Ausgabe zu erfassen. Es wird empfohlen, Parameter in Listen zu übergeben, um Einspritzrisiken zu vermeiden. 2. Wenn die Shell -Eigenschaften erforderlich sind, k?nnen Sie Shell = True einstellen, aber achten Sie auf die Befehlsinjektion. 3. verwenden subprocess.popen, um die Echtzeit-Ausgangsverarbeitung zu realisieren. 4. Setzen Sie check = true, um Ausnahmen zu werfen, wenn der Befehl fehlschl?gt. 5. Sie k?nnen direkt Ketten anrufen, um die Ausgabe in einem einfachen Szenario zu erhalten. Sie sollten Subprozess vorrangig machen. Die obigen Methoden überschreiben die Kernverwendung der Ausführung von Shell -Befehlen in Python.

Die Datei "Settings.JSON" befindet sich auf dem Pfad auf Benutzerebene oder Arbeitsbereichsebene und wird verwendet, um die VSCODE-Einstellungen anzupassen. 1. Benutzer-Level-Pfad: Windows ist C: \ Benutzer \\ AppData \ Roaming \ Code \ User \ Settings.json, MacOS is /users//library/applicationsupport/code/user/settings.json, Linux is /home/.config/code/usser/setings.json; 2. Pfad auf Arbeitsbereichsebene: .VSCODE/Einstellungen im Projekt Root Directory

Der Müllsammlung von PHP basiert auf der Referenzz?hlung, aber kreisf?rmige Referenzen müssen von einem periodischen kreisf?rmigen Müllsammler verarbeitet werden. 1. Die Referenzzahl gibt den Speicher sofort frei, wenn keine Referenz auf die Variable vorhanden ist. 2. Referenzreferenz bewirkt, dass Speicher nicht automatisch freigegeben werden kann, und es h?ngt davon ab, dass GC ihn erfasst und reinigt. 3.. GC wird ausgel?st, wenn das "m?gliche Wurzel" den Schwellenwert erreicht oder manuell gc_collect_cycles () aufruft; 4. Langzeit laufende PHP-Anwendungen sollten gc_status () überwachen und rechtzeitig gc_collect () aufrufen, um Speicherleckage zu vermeiden. 5. Zu den Best Practices geh?rt die Vermeidung von kreisf?rmigen Referenzen, die Verwendung von gc_disable () zur Optimierung der Leistungsschlüsselbereiche und Dereference -Objekte über die Clear () -Methode des ORM.

Mit Bref erm?glicht es PHP-Entwicklern, skalierbare, kostengünstige Anwendungen zu erstellen, ohne Server zu verwalten. 1.Bref bringt Php nach AWSLambda, indem er eine optimierte PHP -Laufzeitschicht bereitstellt, Php8.3 und andere Versionen unterstützt und sich nahtlos in Frameworks wie Laravel und Symfony integriert. 2.. 3. Führen Sie den Befehl ServerlessDeploy aus, um die Bereitstellung abzuschlie?en, apiCateway automatisch zu konfigurieren und Zugriffs -URLs zu generieren. 4. Für Lambda -Beschr?nkungen bietet BREF L?sungen.
