<?php
namespace app\index\controller;
use app\common\controller\Frontend;
use app\admin\model\Order;
use app\admin\model\Product;
use think\Log;
use addons\epay\library\Service as EpayService;
class Pay extends Frontend
{
protected $noNeedLogin = '*';
protected $noNeedRight = '*';
protected $layout = '';
/**
* 发起支付
*/
public function submit()
{
$id = $this->request->param('id');
$weight = $this->request->param('weight');
$type = $this->request->param('type', 'alipay'); // alipay 或 wxpay
if (!$id || !$weight) {
$this->error('参数错误');
}
$product = Product::get($id);
if (!$product) {
$this->error('商品不存在');
}
$price = $product['price'];
$amount = bcmul($price, $weight, 2);
$isWechat = strpos($this->request->server('HTTP_USER_AGENT'), 'MicroMessenger') !== false;
$payType = $type == 'wxpay' ? 'wechat' : 'alipay';
$openid = '';
// 微信内并且选择微信支付时,通过 third 插件获取 openid
if ($isWechat && $payType == 'wechat') {
$user = $this->auth->getUserinfo();
if ($user) {
// 已经登录,尝试获取 third 表中的 openid
$third = \addons\third\model\Third::where('user_id', $user['id'])->where('platform', 'wechat')->find();
if ($third) {
$openid = $third['openid'];
}
}
if (!$openid) {
// 如果没有 openid,跳转到 third 插件授权登录,登录后会跳回当前链接继续支付流程
$url = $this->request->url(true); // 当前发起支付的完整URL
$this->redirect(addon_url('third/index/connect', [':platform' => 'wechat', 'url' => $url]));
return;
}
}
// 创建订单
$order = new Order();
$order->sn = date('YmdHis') . mt_rand(1000, 9999);
$order->product_id = $id;
$order->product_name = $product['title'];
$order->weight = $weight;
$order->amount = $amount;
$order->pay_type = $type;
$order->createtime = time();
$order->status = 'created';
$order->save();
// 根据设备类型决定发起支付的 method
$method = 'web';
if ($payType == 'alipay' && $this->request->isMobile()) {
$method = 'wap';
}
// 构造回调链接
$notifyurl = request()->domain() . '/index/pay/notify/paytype/' . $payType;
$returnurl = request()->domain() . '/index/pay/return_url/paytype/' . $payType . '/out_trade_no/' . $order->sn;
// 发起支付
$response = EpayService::submitOrder($amount, $order->sn, $payType, $product['title'], $notifyurl, $returnurl, $method, $openid);
return $response;
}
/**
* 支付异步回调
*/
public function notify()
{
$paytype = $this->request->param('paytype');
$pay = EpayService::checkNotify($paytype);
if (!$pay) {
echo "fail";
return;
}
// 获取回调数据,V3和V2的回调接收不同
$data = EpayService::isVersionV3() ? $pay->callback() : $pay->verify();
try {
// 微信支付V3返回和V2不同
if (EpayService::isVersionV3() && $paytype === 'wechat') {
$data = $data['resource']['ciphertext'];
$data['total_fee'] = $data['amount']['total'];
}
// 记录回调日志
Log::info('Pay Notify: ' . json_encode($data));
$out_trade_no = $data['out_trade_no'];
// 支付宝是 trade_no,微信是 transaction_id
$trade_no = $paytype == 'alipay' ? ($data['trade_no'] ?? '') : ($data['transaction_id'] ?? '');
$order = Order::where('sn', $out_trade_no)->find();
if ($order && $order['status'] == 'created') {
$order->status = 'paid';
$order->paytime = time();
$order->trade_id = $trade_no; // 记录流水号
$order->save();
// 更新商品已筹重量和参与人次
$product = Product::get($order->product_id);
if ($product) {
$product->current_weight += $order->weight;
$product->participant_count += 1;
$product->save();
}
}
} catch (\Exception $e) {
Log::error('Pay Notify Error: ' . $e->getMessage());
}
// 下面这句必须要执行,且在此之前不能有任何输出
if (EpayService::isVersionV3()) {
return $pay->success()->getBody()->getContents();
} else {
return $pay->success()->send();
}
}
/**
* 支付同步回调
*/
public function return_url()
{
$paytype = $this->request->param('paytype');
$out_trade_no = $this->request->param('out_trade_no');
$order = Order::where('sn', $out_trade_no)->find();
if ($order) {
if ($order['status'] == 'paid') {
$this->success('支付成功', 'index/ok');
} else {
// 尝试主动查询订单状态进行补单
try {
$config = EpayService::getConfig($paytype);
$pay = $paytype == 'wechat' ? \Yansongda\Pay\Pay::wechat($config) : \Yansongda\Pay\Pay::alipay($config);
$result = EpayService::isVersionV3() ? $pay->find(['out_trade_no' => $out_trade_no]) : $pay->find($out_trade_no);
$isPaid = false;
$trade_no = '';
if ($paytype == 'alipay') {
if (in_array($result['trade_status'] ?? '', ['TRADE_SUCCESS', 'TRADE_FINISHED'])) {
$isPaid = true;
$trade_no = $result['trade_no'] ?? '';
}
} else {
if (isset($result['trade_state']) && $result['trade_state'] == 'SUCCESS') {
$isPaid = true;
$trade_no = $result['transaction_id'] ?? '';
}
}
if ($isPaid) {
$order->status = 'paid';
$order->paytime = time();
$order->trade_id = $trade_no;
$order->save();
// 更新商品数据
$product = Product::get($order->product_id);
if ($product) {
$product->current_weight += $order->weight;
$product->participant_count += 1;
$product->save();
}
$this->success('支付成功', 'index/ok');
} else {
// 尚未支付完成
$this->error('支付尚未完成', 'index/index');
}
} catch (\Exception $e) {
$this->success('支付成功或正在处理中', 'index/ok');
}
}
} else {
$this->error('订单不存在', 'index/index');
}
}
}
发表评论 取消回复