|
|
|
@ -2,31 +2,46 @@ |
|
|
|
|
|
|
|
namespace App\Http\Controllers\Api; |
|
|
|
use App\Http\Controllers\Controller; |
|
|
|
use App\Models\Agent; |
|
|
|
use App\Models\AgentProduct; |
|
|
|
use App\Models\Order; |
|
|
|
use App\Models\Product; |
|
|
|
use App\Models\UserMoneyLog; |
|
|
|
use EasyWeChat\Factory; |
|
|
|
use EasyWeChat\Kernel\Exceptions\Exception; |
|
|
|
use EasyWeChat\Payment\Kernel\Exceptions\InvalidSignException; |
|
|
|
use Illuminate\Support\Facades\DB; |
|
|
|
use App\Service\OrderStatus; |
|
|
|
|
|
|
|
class WxpayController extends Controller |
|
|
|
class WxpayController |
|
|
|
{ |
|
|
|
//微信支付 支付结果通知网址
|
|
|
|
public function notify() |
|
|
|
{ |
|
|
|
// {"sign": "3F99E6044C503B0E0131F95A1410B630", "appid": "wxb35ef055a4dd8ad4", "mch_id": "1606181693", "openid": "oBYj55W0gLv5MYUnsYUuJfzYzmsg", "cash_fee": "1", "fee_type": "CNY", "time_end": "20210623222330", "bank_type": "OTHERS", "nonce_str": "60d343d820e94", "total_fee": "1", "trade_type": "JSAPI", "result_code": "SUCCESS", "return_code": "SUCCESS", "is_subscribe": "N", "out_trade_no": "2842908479209865216", "transaction_id": "4200001210202106237487333085"}
|
|
|
|
|
|
|
|
$agent_id = request()->route('aid'); |
|
|
|
$agent = Agent::find($agent_id); |
|
|
|
|
|
|
|
$config = config('wechat.payment.default'); |
|
|
|
$config = array_merge($config, [ |
|
|
|
'app_id' => $agent->appid, |
|
|
|
'mch_id' => $agent->mchid, |
|
|
|
'key' => $agent->mchkey, |
|
|
|
]); |
|
|
|
$app = Factory::payment($config); |
|
|
|
try { |
|
|
|
$response = $app->handlePaidNotify(function ($message, $fail) { |
|
|
|
// 请求成功
|
|
|
|
if ($message['return_code'] === 'SUCCESS') { |
|
|
|
//订单号带有pay_type后缀,主要是为了区分定金支付和尾款支付,前24位才是真正的订单号
|
|
|
|
$order_no = substr($message['out_trade_no'], 0, 24); |
|
|
|
$order = Order::query() |
|
|
|
->where(['order_no' => $message['out_trade_no']]) |
|
|
|
->where(['order_no' => $order_no]) |
|
|
|
->first(); |
|
|
|
|
|
|
|
//已经处理过的订单直接返回true
|
|
|
|
if ($order && $order->paid_at) { |
|
|
|
if ($order && in_array($order->status, [OrderStatus::PAID, OrderStatus::PAY_RETAINAGE])) { |
|
|
|
return true; |
|
|
|
} |
|
|
|
|
|
|
|
@ -34,27 +49,42 @@ class WxpayController extends Controller |
|
|
|
if ($message['result_code'] === 'SUCCESS') { |
|
|
|
DB::beginTransaction(); |
|
|
|
try { |
|
|
|
//TODO 需要判断尾款和全款
|
|
|
|
$order->status = OrderStatus::PAID; |
|
|
|
$status = $order->status; |
|
|
|
$pay_type = $order->pay_type; |
|
|
|
//定金支付和首付款支付
|
|
|
|
if (in_array($pay_type, [1, 2])) { |
|
|
|
if ($pay_type == OrderStatus::UNPAID) { |
|
|
|
$order->status = OrderStatus::PAY_EARNEST; |
|
|
|
} else if ($status == OrderStatus::PAY_EARNEST) { |
|
|
|
$order->status = OrderStatus::PAY_RETAINAGE; |
|
|
|
} |
|
|
|
} else if ($pay_type == 0) { |
|
|
|
$order->status = OrderStatus::PAID; |
|
|
|
} |
|
|
|
|
|
|
|
$money = $message['total_fee'] / 100; |
|
|
|
$order->paid_at = time(); |
|
|
|
|
|
|
|
$snowflake = resolve('snowflake'); |
|
|
|
$confirmCode = $snowflake->id(); // TODO 这个码太长后续可以找方案搞短些
|
|
|
|
$order->confirm_code = isset($params['platform:']) && $params['platform'] |
|
|
|
? $params['platform:'] . '|' . $confirmCode |
|
|
|
: $confirmCode; |
|
|
|
|
|
|
|
$order->paid_money = DB::raw('`paid_money` + ' . $money); |
|
|
|
$order->save(); |
|
|
|
|
|
|
|
// 计算销量
|
|
|
|
GoodsSpecs::query() |
|
|
|
->where([ |
|
|
|
'id' => $order->goods_specs_id, |
|
|
|
'goods_id' => $order->goods_id, |
|
|
|
]) |
|
|
|
->update([ |
|
|
|
'sold_stock' => DB::raw('sold_stock+' . $order->number . ''), |
|
|
|
]); |
|
|
|
//增加销量,库存在拍下时已经减了
|
|
|
|
AgentProduct::query() |
|
|
|
->where('id', $order->agent_product_id) |
|
|
|
->increment('sale', $order->num); |
|
|
|
Product::query() |
|
|
|
->where('id', $order->product_id) |
|
|
|
->increment('sale', $order->num); |
|
|
|
|
|
|
|
//资金流水
|
|
|
|
UserMoneyLog::query()->create([ |
|
|
|
'user_id' => $order->user_id, |
|
|
|
'agent_id' => $order->agent_id, |
|
|
|
'money' => -$money, |
|
|
|
'order_id' => $order->id, |
|
|
|
'type' => 1, |
|
|
|
'desc' => '购买产品:' . $order->title, |
|
|
|
'created_at' => time(), //模型没有updated_at,无法自动写入时间
|
|
|
|
]); |
|
|
|
|
|
|
|
DB::commit(); |
|
|
|
return true; |
|
|
|
@ -62,12 +92,8 @@ class WxpayController extends Controller |
|
|
|
DB::rollBack(); |
|
|
|
$fail('Unknown error'); |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} // 支付失败
|
|
|
|
elseif ($message['result_code'] === 'FAIL') { |
|
|
|
$order->state = UserGoodsOrder::PAID_FAIL; |
|
|
|
$order->save(); |
|
|
|
else if ($message['result_code'] === 'FAIL') { |
|
|
|
return true; |
|
|
|
} |
|
|
|
} |
|
|
|
@ -75,12 +101,13 @@ class WxpayController extends Controller |
|
|
|
// 希望微信重试
|
|
|
|
$fail('Order not exists.'); |
|
|
|
}); |
|
|
|
} catch (Exception $e) { |
|
|
|
} catch (InvalidSignException | \Exception $e) { |
|
|
|
$time = time(); |
|
|
|
$filename = storage_path('/wxpay/notify/') . date('Y-m-d-H', $time) . '.log'; |
|
|
|
$filename = storage_path('logs/wxpay_notify_') . date('Y-m-d-H', $time) . '.log'; |
|
|
|
$data = '[' . date('Y-m-d H:i:s', $time) . ']' . PHP_EOL; |
|
|
|
$data .= '[message]:' . $e->getMessage() . PHP_EOL . PHP_EOL; |
|
|
|
$data .= '[message]:' . $e->getMessage() . $e->getFile() . $e->getLine() . PHP_EOL . PHP_EOL; |
|
|
|
file_put_contents($filename, $data, FILE_APPEND); |
|
|
|
return 'error'; |
|
|
|
} |
|
|
|
|
|
|
|
return $response; |
|
|
|
@ -99,8 +126,10 @@ class WxpayController extends Controller |
|
|
|
file_put_contents(storage_path('/wxpay/refund'.date('Y-m-d-H').'.log'), date('Y-m-d H:i:s').PHP_EOL.json_encode($message).PHP_EOL.json_encode($reqInfo), FILE_APPEND); |
|
|
|
// 请求成功
|
|
|
|
if ($message['return_code'] === 'SUCCESS') { |
|
|
|
$order = UserGoodsOrder::query() |
|
|
|
->where(['order_sn' => $reqInfo['out_trade_no']]) |
|
|
|
//订单号带有pay_type后缀,主要是为了区分定金支付和尾款支付,前24位才是真正的订单号
|
|
|
|
$order_no = substr($message['out_trade_no'], 0, 24); |
|
|
|
$order = Order::query() |
|
|
|
->where(['order_sn' => $order_no]) |
|
|
|
->first(); |
|
|
|
|
|
|
|
// 退款成功
|
|
|
|
|