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>