QQ扫一扫联系
config.php
<?php // 微信支付配置 $wechatConfig = [ 'mchid' => '商户号',// 商户号 'appid' => '公众号appid',// 公众号appid 'appKey' => '公众号APPSECRET',// 公众号APPSECRET 'apiKey' => '商户API密钥'// 商户API密钥 ]; // 自动获取当前域名 $domain = ($_SERVER['SERVER_PORT'] == 443 ? 'https://' : 'http://') . $_SERVER['HTTP_HOST']; $alipayConfig['returnUrl'] = $domain . '/return.php'; $alipayConfig['notifyUrl'] = $domain . '/notify.php'; $wechatConfig['notifyUrl'] = $domain . '/wx_notify.php'; // 开启错误报告 error_reporting(E_ALL); ini_set('display_errors', 1); ?>
index.php
<?php require_once 'config.php'; require_once 'functions.php'; $amount = isset($_GET['amount']) ? floatval($_GET['amount']) : 0.01; class WxpayService { protected $mchid; protected $appid; protected $apiKey; public function __construct($mchid, $appid, $key) { $this->mchid = $mchid; $this->appid = $appid; $this->apiKey = $key; } public function createH5BizPackage($totalFee, $outTradeNo, $orderName, $notifyUrl, $timestamp, $sceneInfo = []) { // 金额验证 if ($totalFee <= 0) { die('支付金额必须大于0'); } // 金额转换为分(微信支付单位为分) $totalFeeInCent = intval(floatval($totalFee) * 100); if ($totalFeeInCent <= 0) { die('支付金额转换错误'); } $config = [ 'mch_id' => $this->mchid, 'appid' => $this->appid, 'key' => $this->apiKey, ]; $unified = [ 'appid' => $config['appid'], 'attach' => 'pay', 'body' => $orderName, 'mch_id' => $config['mch_id'], 'nonce_str' => self::createNonceStr(), 'notify_url' => $notifyUrl, 'out_trade_no' => $outTradeNo, 'spbill_create_ip' => $_SERVER['REMOTE_ADDR'], 'total_fee' => $totalFeeInCent, // 使用整数分 'trade_type' => 'MWEB', ]; // 添加H5支付场景信息 if (!empty($sceneInfo)) { $unified['scene_info'] = json_encode($sceneInfo); } $unified['sign'] = self::getSign($unified, $config['key']); $responseXml = self::curlPost('https://api.mch.weixin.qq.com/pay/unifiedorder', self::arrayToXml($unified)); $unifiedOrder = simplexml_load_string($responseXml, 'SimpleXMLElement', LIBXML_NOCDATA); if ($unifiedOrder === false) { die('parse xml error'); } if ($unifiedOrder->return_code != 'SUCCESS') { die($unifiedOrder->return_msg); } if ($unifiedOrder->result_code != 'SUCCESS') { die($unifiedOrder->err_code); } return [ 'mweb_url' => (string)$unifiedOrder->mweb_url, 'prepay_id' => (string)$unifiedOrder->prepay_id ]; } public static function curlGet($url = '', $options = []) { $ch = curl_init($url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_TIMEOUT, 30); if (!empty($options)) curl_setopt_array($ch, $options); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public static function curlPost($url = '', $postData = '', $options = []) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postData); curl_setopt($ch, CURLOPT_TIMEOUT, 30); if (!empty($options)) curl_setopt_array($ch, $options); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $data = curl_exec($ch); curl_close($ch); return $data; } public static function createNonceStr($length = 16) { $chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789'; $str = ''; for ($i = 0; $i < $length; $i++) { $str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1); } return $str; } public static function arrayToXml($arr) { $xml = "<xml>"; foreach ($arr as $key => $val) { if (is_numeric($val)) { $xml .= "<" . $key . ">" . $val . "</" . $key . ">"; } else { $xml .= "<" . $key . "><![CDATA[" . $val . "]]></" . $key . ">"; } } $xml .= "</xml>"; return $xml; } public static function getSign($params, $key) { ksort($params, SORT_STRING); $unSignParaString = self::formatQueryParaMap($params, false); return strtoupper(md5($unSignParaString . "&key=" . $key)); } protected static function formatQueryParaMap($paraMap, $urlEncode = false) { $buff = ""; ksort($paraMap); foreach ($paraMap as $k => $v) { if (null != $v && "null" != $v) { if ($urlEncode) $v = urlencode($v); $buff .= $k . "=" . $v . "&"; } } $reqPar = ''; if (strlen($buff) > 0) $reqPar = substr($buff, 0, strlen($buff) - 1); return $reqPar; } } // 初始化微信支付服务 $wxPay = new WxpayService($wechatConfig['mchid'], $wechatConfig['appid'], $wechatConfig['apiKey']); // 生成订单号 $outTradeNo = uniqid(); $orderName = '商品支付'; $payTime = time(); // H5支付场景信息(可选) $sceneInfo = [ 'h5_info' => [ 'type' => 'Wap', 'wap_url' => 'https://你的网站域名.com', // 替换为您的网站URL 'wap_name' => '你的网站名称' // 替换为您的网站名称 ] ]; // 创建H5支付请求 $h5PayResult = $wxPay->createH5BizPackage($amount, $outTradeNo, $orderName, $wechatConfig['notifyUrl'], $payTime, $sceneInfo); // 获取H5支付链接 $mwebUrl = $h5PayResult['mweb_url']; // 如果需要添加回调页面参数 $redirectUrl = urlencode('https://您的网站域名.com/pay_result.php?out_trade_no='.$outTradeNo); $mwebUrl .= '&redirect_url='.$redirectUrl; ?> <!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <title>微信支付</title> <style> body { font-family: Arial, sans-serif; text-align: center; padding: 20px; } .pay-container { max-width: 400px; margin: 0 auto; padding: 20px; background-color: #f9f9f9; border-radius: 8px; box-shadow: 0 2px 10px rgba(0,0,0,0.1); } .amount { font-size: 24px; color: #f56c6c; margin: 20px 0; } .order-info { margin: 20px 0; text-align: left; padding: 15px; background-color: #fff; border-radius: 5px; } #payButton { width: 200px; height: 40px; background-color: #07C160; color: white; border: none; border-radius: 4px; font-size: 16px; margin: 20px auto; cursor: pointer; } .loading { margin: 30px 0; color: #888; } </style> <script type="text/javascript"> function startPayment() { // 跳转到微信H5支付页面 window.location.href = "<?php echo $mwebUrl; ?>"; } // 页面加载后自动跳转支付 window.onload = function() { // 可以设置延迟跳转,让用户看到订单信息 setTimeout(startPayment, 1000); // 也可以不自动跳转,让用户点击按钮 // document.getElementById('payButton').style.display = 'block'; }; </script> </head> <body> <div class="pay-container"> <h2>微信支付</h2> <div class="amount">¥<?php echo number_format($amount, 2); ?></div> <div class="order-info"> <p><strong>订单号:</strong><?php echo $outTradeNo; ?></p> <p><strong>商品名称:</strong><?php echo $orderName; ?></p> </div> <div class="loading">正在跳转到微信支付...</div> <button id="payButton" onclick="startPayment()" style="display:none;">立即支付</button> </div> </body> </html>