您好,登录后才能下订单哦!
密码登录
登录注册
点击 登录注册 即表示同意《亿速云用户服务条款》
# PHP如何实现微信支付
微信支付作为国内主流的移动支付方式,其API接入是Web开发中的常见需求。本文将全面讲解PHP环境下微信支付的完整实现流程,涵盖从前期准备到代码实现的各个环节。
## 一、微信支付接入前准备
### 1.1 申请微信支付商户号
在开始开发前,您需要:
1. 注册微信支付商户平台账号
2. 提交企业资质材料(营业执照、法人身份证等)
3. 完成账户验证(对公账户打款验证)
4. 获取以下关键信息:
- 商户号(MCHID)
- API密钥(32位随机字符串)
- 申请对应的支付产品(如Native支付、JSAPI支付等)
### 1.2 配置服务器环境
PHP环境要求:
- PHP 5.6+(推荐7.0以上版本)
- 开启cURL扩展
- 服务器需要支持HTTPS(微信支付要求全站HTTPS)
- 设置好服务器IP白名单(在商户平台配置)
```php
// 检查PHP环境
if (version_compare(PHP_VERSION, '5.6.0', '<')) {
die("需要PHP 5.6.0或更高版本");
}
if (!function_exists('curl_init')) {
die("需要启用cURL扩展");
}
创建配置文件wxpay_config.php
:
<?php
// 微信支付配置
define('WXPAY_APPID', '您的公众号APPID');
define('WXPAY_MCHID', '商户号');
define('WXPAY_KEY', '商户支付密钥');
define('WXPAY_APPSECRET', '公众号APPSECRET'); // JSAPI支付需要
define('WXPAY_NOTIFY_URL', 'https://您的域名.com/notify.php'); // 支付结果通知地址
define('WXPAY_CERT_PATH', __DIR__.'/cert/apiclient_cert.pem'); // 证书路径
define('WXPAY_KEY_PATH', __DIR__.'/cert/apiclient_key.pem'); // 密钥路径
require_once 'wxpay_config.php';
require_once 'WxPay.Api.php';
require_once 'WxPay.NativePay.php';
$notify = new NativePay();
$input = new WxPayUnifiedOrder();
$input->SetBody("测试商品"); // 商品描述
$input->SetAttach("附加数据"); // 附加数据
$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis")); // 商户订单号
$input->SetTotal_fee("1"); // 支付金额(单位:分)
$input->SetTime_start(date("YmdHis")); // 交易起始时间
$input->SetTime_expire(date("YmdHis", time() + 600)); // 交易结束时间
$input->SetGoods_tag("测试"); // 商品标记
$input->SetNotify_url(WxPayConfig::NOTIFY_URL); // 通知地址
$input->SetTrade_type("NATIVE"); // 交易类型
$input->SetProduct_id("123456789"); // 商品ID
$result = $notify->GetPayUrl($input);
$url2 = $result["code_url"]; // 获取支付二维码链接
使用PHP QR Code库生成二维码:
include 'phpqrcode/phpqrcode.php';
QRcode::png($url2, false, QR_ECLEVEL_L, 10); // 输出二维码图片
// 在微信授权回调页面获取openid
if (!isset($_GET['code'])) {
$redirectUrl = urlencode('https://您的域名.com/getOpenid.php');
$url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=".WXPAY_APPID."&redirect_uri={$redirectUrl}&response_type=code&scope=snsapi_base&state=123#wechat_redirect";
header("Location: $url");
exit();
} else {
$code = $_GET['code'];
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid=".WXPAY_APPID."&secret=".WXPAY_APPSECRET."&code={$code}&grant_type=authorization_code";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
curl_close($ch);
$data = json_decode($response, true);
$openid = $data['openid']; // 获取到的用户openid
}
$input = new WxPayUnifiedOrder();
$input->SetBody("测试商品");
$input->SetAttach("附加数据");
$input->SetOut_trade_no(WxPayConfig::MCHID.date("YmdHis"));
$input->SetTotal_fee("1");
$input->SetTime_start(date("YmdHis"));
$input->SetTime_expire(date("YmdHis", time() + 600));
$input->SetGoods_tag("测试");
$input->SetNotify_url(WxPayConfig::NOTIFY_URL);
$input->SetTrade_type("JSAPI");
$input->SetOpenid($openid); // 设置用户openid
$order = WxPayApi::unifiedOrder($input);
$jsApiParameters = $tools->GetJsApiParameters($order);
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 注入配置
wx.config({
debug: false, // 开启调试模式
appId: '<?php echo WXPAY_APPID; ?>',
timestamp: <?php echo time(); ?>,
nonceStr: '随机字符串',
signature: '签名',
jsApiList: ['chooseWXPay']
});
// 调用支付
wx.chooseWXPay({
timestamp: <?php echo $order['timestamp']; ?>,
nonceStr: '<?php echo $order['nonce_str']; ?>',
package: '<?php echo $order['prepay_id']; ?>',
signType: 'MD5',
paySign: '<?php echo $order['sign']; ?>',
success: function(res) {
alert('支付成功');
},
fail: function(res) {
alert('支付失败: ' + JSON.stringify(res));
}
});
});
</script>
require_once "wxpay_config.php";
require_once "WxPay.Api.php";
require_once "WxPay.Notify.php";
class PayNotifyCallBack extends WxPayNotify
{
// 重写回调处理函数
public function NotifyProcess($data, &$msg)
{
// 1. 验证签名
if(!array_key_exists("transaction_id", $data)){
$msg = "输入参数不正确";
return false;
}
// 2. 查询订单,判断订单真实性
$query = new WxPayOrderQuery();
$query->SetTransaction_id($data["transaction_id"]);
$result = WxPayApi::orderQuery($query);
if(array_key_exists("return_code", $result)
&& array_key_exists("result_code", $result)
&& $result["return_code"] == "SUCCESS"
&& $result["result_code"] == "SUCCESS")
{
// 3. 处理业务逻辑
$out_trade_no = $data['out_trade_no'];
$total_fee = $data['total_fee'] / 100; // 转换为元
// TODO: 更新订单状态、发货等业务逻辑
return true;
}
return false;
}
}
// 处理通知
$notify = new PayNotifyCallBack();
$notify->Handle(false);
function queryOrder($transaction_id)
{
$input = new WxPayOrderQuery();
$input->SetTransaction_id($transaction_id);
try {
$result = WxPayApi::orderQuery($input);
if($result["return_code"] == "SUCCESS"
&& $result["result_code"] == "SUCCESS")
{
// 支付成功
return [
'status' => true,
'data' => $result
];
} else {
return [
'status' => false,
'msg' => $result["return_msg"]
];
}
} catch(Exception $e) {
return [
'status' => false,
'msg' => $e->getMessage()
];
}
}
function applyRefund($transaction_id, $total_fee, $refund_fee)
{
$input = new WxPayRefund();
$input->SetTransaction_id($transaction_id);
$input->SetTotal_fee($total_fee);
$input->SetRefund_fee($refund_fee);
$input->SetOut_refund_no(WxPayConfig::MCHID.date("YmdHis"));
$input->SetOp_user_id(WxPayConfig::MCHID);
try {
$result = WxPayApi::refund($input);
if($result["return_code"] == "SUCCESS"
&& $result["result_code"] == "SUCCESS")
{
return [
'status' => true,
'data' => $result
];
} else {
return [
'status' => false,
'msg' => $result["err_code_des"] ?? $result["return_msg"]
];
}
} catch(Exception $e) {
return [
'status' => false,
'msg' => $e->getMessage()
];
}
}
try {
// 微信支付API调用
$result = WxPayApi::unifiedOrder($input);
} catch (WxPayException $e) {
// 捕获微信支付异常
error_log("微信支付异常: ".$e->getMessage());
return [
'status' => false,
'msg' => '支付系统繁忙,请稍后再试'
];
} catch (Exception $e) {
// 其他异常
error_log("系统异常: ".$e->getMessage());
return [
'status' => false,
'msg' => '系统错误,请联系客服'
];
}
class WxPayLogger
{
public static function write($content, $type = 'INFO')
{
$logFile = __DIR__.'/logs/'.date('Y-m-d').'.log';
$content = "[".date('Y-m-d H:i:s')."] [$type] ".$content.PHP_EOL;
file_put_contents($logFile, $content, FILE_APPEND);
}
}
// 使用示例
WxPayLogger::write("创建支付订单,订单号:".$outTradeNo);
错误代码 | 说明 | 解决方案 |
---|---|---|
NOAUTH | 商户无此接口权限 | 检查商户号配置和支付产品权限 |
NOTENOUGH | 用户账户余额不足 | 提示用户充值或更换支付方式 |
ORDERPD | 订单已支付 | 检查订单状态,避免重复支付 |
ORDERCLOSED | 订单已关闭 | 重新创建订单 |
SYSTEMERROR | 系统错误 | 重试或联系微信支付客服 |
本文详细介绍了PHP环境下微信支付的完整实现流程,包括:
通过以上步骤,开发者可以构建一个安全、稳定的微信支付系统。在实际开发中,还需要根据具体业务需求进行调整和优化,特别是要做好异常处理和日志记录,确保支付系统的可靠性。
扩展阅读: - 微信支付官方文档 - PHP cURL高级用法 - 支付系统设计原则
附录:示例代码下载 点击下载完整示例项目 “`
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。