EasyWeChat 是一个优秀的 PHP 微信 SDK,同时也支持支付宝支付。下面我将介绍如何在 Laravel 框架中封装这两种支付方式。
首先安装 EasyWeChat 包:
composer require overtrue/wechat -vvv
在 config/services.php
中添加微信支付配置:
'wechat_payment' => [
'app_id' => env('WECHAT_PAYMENT_APPID'),
'mch_id' => env('WECHAT_PAYMENT_MCH_ID'),
'key' => env('WECHAT_PAYMENT_KEY'),
'cert_path' => env('WECHAT_PAYMENT_CERT_PATH', 'path/to/cert/apiclient_cert.pem'),
'key_path' => env('WECHAT_PAYMENT_KEY_PATH', 'path/to/cert/apiclient_key.pem'),
'notify_url' => env('WECHAT_PAYMENT_NOTIFY_URL', 'your.domain.com/wechat/notify'),
],
同样在 config/services.php
中添加:
'alipay' => [
'app_id' => env('ALIPAY_APP_ID'),
'ali_public_key' => env('ALIPAY_PUBLIC_KEY'),
'private_key' => env('ALIPAY_PRIVATE_KEY'),
'notify_url' => env('ALIPAY_NOTIFY_URL', 'your.domain.com/alipay/notify'),
'return_url' => env('ALIPAY_RETURN_URL', 'your.domain.com/alipay/return'),
'log' => [
'file' => storage_path('logs/alipay.log'),
],
],
创建一个 PaymentService
类来封装支付逻辑:
<?php
namespace App\Services;
use EasyWeChat\Factory;
use EasyWeChat\Payment\Application as PaymentApp;
use EasyWeChat\Pay\Application as PayApp;
class PaymentService
{
protected $wechatPayment;
protected $alipay;
public function __construct()
{
// 初始化微信支付
$this->wechatPayment = Factory::payment(config('services.wechat_payment'));
// 初始化支付宝支付
$this->alipay = Factory::alipay(config('services.alipay'));
}
/**
* 微信支付 - JSAPI支付
*/
public function wechatJsapiPay(array $orderData)
{
$result = $this->wechatPayment->order->unify([
'body' => $orderData['body'],
'out_trade_no' => $orderData['out_trade_no'],
'total_fee' => $orderData['total_fee'], // 单位:分
'trade_type' => 'JSAPI',
'openid' => $orderData['openid'],
'notify_url' => config('services.wechat_payment.notify_url'),
]);
if ($result['return_code'] === 'SUCCESS' && $result['result_code'] === 'SUCCESS') {
$config = $this->wechatPayment->jssdk->bridgeConfig($result['prepay_id']);
return $config;
}
throw new \Exception('微信支付下单失败: '.json_encode($result));
}
/**
* 支付宝支付 - 网页支付
*/
public function alipayWebPay(array $orderData)
{
$order = [
'out_trade_no' => $orderData['out_trade_no'],
'total_amount' => $orderData['total_amount'], // 单位:元
'subject' => $orderData['subject'],
'product_code' => 'FAST_INSTANT_TRADE_PAY',
];
return $this->alipay->web->pay($order);
}
/**
* 处理微信支付回调
*/
public function handleWechatNotify()
{
$response = $this->wechatPayment->handlePaidNotify(function($message, $fail) {
// 你的业务逻辑
$order = Order::where('order_no', $message['out_trade_no'])->first();
if (!$order) {
return $fail('订单不存在');
}
if ($order->paid_at) {
return true; // 已经处理过了
}
// 支付成功
if ($message['result_code'] === 'SUCCESS') {
$order->paid_at = now();
$order->status = 'paid';
$order->save();
// 其他业务逻辑...
return true;
}
return $fail('支付失败');
});
return $response;
}
/**
* 处理支付宝回调
*/
public function handleAlipayNotify()
{
$data = $this->alipay->verify();
try {
$order = Order::where('order_no', $data->out_trade_no)->first();
if (!$order) {
throw new \Exception('订单不存在');
}
if ($order->paid_at) {
return true; // 已经处理过了
}
// 交易状态
if (in_array($data->trade_status, ['TRADE_SUCCESS', 'TRADE_FINISHED'])) {
$order->paid_at = now();
$order->status = 'paid';
$order->save();
// 其他业务逻辑...
return true;
}
} catch (\Exception $e) {
// 记录错误日志
\Log::error('支付宝回调处理失败: '.$e->getMessage());
return false;
}
return $this->alipay->success();
}
}
<?php
namespace App\Http\Controllers;
use App\Services\PaymentService;
use Illuminate\Http\Request;
class PaymentController extends Controller
{
protected $paymentService;
public function __construct(PaymentService $paymentService)
{
$this->paymentService = $paymentService;
}
/**
* 微信JSAPI支付
*/
public function wechatJsapiPay(Request $request)
{
$orderData = [
'body' => '测试商品',
'out_trade_no' => time().rand(1000, 9999),
'total_fee' => 100, // 1元
'openid' => $request->user()->wechat_openid,
];
try {
$config = $this->paymentService->wechatJsapiPay($orderData);
return view('payment.wechat', compact('config'));
} catch (\Exception $e) {
return back()->withErrors($e->getMessage());
}
}
/**
* 支付宝网页支付
*/
public function alipayWebPay(Request $request)
{
$orderData = [
'out_trade_no' => time().rand(1000, 9999),
'total_amount' => 0.01, // 0.01元测试
'subject' => '测试商品',
];
try {
return $this->paymentService->alipayWebPay($orderData);
} catch (\Exception $e) {
return back()->withErrors($e->getMessage());
}
}
/**
* 微信支付回调
*/
public function wechatNotify()
{
return $this->paymentService->handleWechatNotify();
}
/**
* 支付宝回调
*/
public function alipayNotify()
{
return $this->paymentService->handleAlipayNotify();
}
}
在 routes/web.php
中添加:
Route::middleware('auth')->group(function () {
Route::post('/payment/wechat/jsapi', [PaymentController::class, 'wechatJsapiPay']);
Route::post('/payment/alipay/web', [PaymentController::class, 'alipayWebPay']);
});
// 支付回调路由
Route::post('/payment/wechat/notify', [PaymentController::class, 'wechatNotify']);
Route::post('/payment/alipay/notify', [PaymentController::class, 'alipayNotify']);
<!-- resources/views/payment/wechat.blade.php -->
<!DOCTYPE html>
<html>
<head>
<title>微信支付</title>
<script src="https://res.wx.qq.com/open/js/jweixin-1.6.0.js"></script>
</head>
<body>
<button id="payButton">支付</button>
<script>
document.getElementById('payButton').addEventListener('click', function() {
wx.chooseWXPay({
timestamp: '{{ $config["timestamp"] }}',
nonceStr: '{{ $config["nonceStr"] }}',
package: '{{ $config["package"] }}',
signType: '{{ $config["signType"] }}',
paySign: '{{ $config["paySign"] }}',
success: function (res) {
alert('支付成功');
// 跳转到成功页面
window.location.href = '/payment/success';
},
fail: function (res) {
alert('支付失败: ' + JSON.stringify(res));
}
});
});
</script>
</body>
</html>
支付宝支付会直接返回一个表单,自动提交跳转到支付宝页面,无需额外处理。
通过以上步骤,你可以在 Laravel 中轻松集成微信支付和支付宝支付功能。根据实际业务需求,你可以进一步扩展 PaymentService 类,添加更多支付方式和功能。