Files
douyin-card-message/serve/app/PayChannels/WeChatPayNative.php
T
2026-01-13 10:53:26 +08:00

114 lines
3.7 KiB
PHP

<?php
namespace App\PayChannels;
use App\Services\SystemConfig;
use EasyWeChat\Pay\Application;
use Illuminate\Support\Carbon;
use Symfony\Component\HttpFoundation\Response;
use Ugly\Base\Exceptions\ApiCustomError;
use Ugly\Base\Models\Payment;
use Ugly\Base\Traits\ApiResource;
class WeChatPayNative
{
use ApiResource;
private Application $payApp;
private $appid;
private $mchid;
public function __construct()
{
$this->appid = SystemConfig::get('wechat_pay_app_id');
$this->mchid = SystemConfig::get('wechat_pay_mch_id');
if (!empty($this->appid) && !empty(!$this->mchid)) {
$config = [
'appid' => $this->appid,
'mch_id' => $this->mchid,
'secret_key' => SystemConfig::get('wechat_pay_secret_key'),
// 商户证书
'private_key' => SystemConfig::get('wechat_pay_secret_key'),
'certificate' => SystemConfig::get('wechat_pay_certificate'),
/*'platform_certs' => [
storage_path('/certs/wechatpay.pem'),
],*/
'http' => [
'throw' => false,
],
];
} else {
$config = config('services.wechat_pay');
unset($config['platform_certs']);
$this->appid = $config['appid'];
$this->mchid = $config['mch_id'];
}
if (empty($this->appid) || empty($this->mchid)) {
throw new ApiCustomError('请完善支付配置信息!');
}
$this->payApp = new Application($config);
}
// 支付
public function pay($payment, array $data = []): array
{
$payInfo = $this->payApp->getClient()->postJson('v3/pay/transactions/native', [
'appid' => $this->appid,
'mchid' => $this->mchid,
'description' => data_get($data, 'description', ''),
'out_trade_no' => $payment->no,
'notify_url' => config('app.url').'/api/wechat/payment_notify',
'time_expire' => $payment->expired_at->toRfc3339String(),
'amount' => [
'total' => (int) bcmul($payment->amount, 100, 0),
'currency' => 'CNY',
],
])->toArray();
throw_if(
! isset($payInfo['code_url']),
new ApiCustomError(data_get($payInfo, 'message', '微信下单失败!'), Response::HTTP_INTERNAL_SERVER_ERROR, Response::HTTP_INTERNAL_SERVER_ERROR)
);
return [
'no' => $payment->no,
'amount' => $payment->amount,
'desc' => $data['description'] ?? '',
'expired_at' => $payment->expired_at->toDateTimeString(),
'code_url' => $payInfo['code_url'],
];
}
// 成功后通知.
public function notify()
{
$server = $this->payApp->getServer();
// 支付成功
$server->handlePaid(function ($message) {
Payment::success($message['out_trade_no'], [
'notification_no' => $message['transaction_id'],
'notification_data' => $message,
'success_at' => Carbon::parse($message['success_time']),
]);
});
// 退款成功
$server->handleRefunded(function ($message) {
if ($message['refund_status'] === 'SUCCESS') {
Payment::success($message['out_trade_no'], [
'notification_no' => $message['refund_id'],
'notification_data' => $message,
'success_at' => Carbon::parse($message['success_time']),
]);
}
});
return $server->serve();
}
}