You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
126 lines
4.2 KiB
126 lines
4.2 KiB
<?php
|
|
|
|
namespace App\Http\Controllers\Api;
|
|
use App\Common\OrderStatus as Status;
|
|
use App\Common\PayType;
|
|
use App\Http\Controllers\Controller;
|
|
use App\Models\AdminSetting;
|
|
use App\Models\Agent;
|
|
use App\Models\AgentProduct;
|
|
use App\Models\Order;
|
|
use App\Models\User;
|
|
use EasyWeChat\Factory;
|
|
use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
|
|
use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
|
|
use GuzzleHttp\Exception\GuzzleException;
|
|
use Illuminate\Support\Facades\Cache;
|
|
|
|
/**
|
|
* 跳转支付
|
|
* Class SharePay
|
|
* @package App\Http\Controllers\Api
|
|
*/
|
|
class SharePayController extends Controller
|
|
{
|
|
public function pay()
|
|
{
|
|
$order_id = request()->input('id');
|
|
if (!$order_id) {
|
|
return $this->error('无效的ID');
|
|
}
|
|
|
|
$this->user_id = Cache::get(request()->header('Authentication'));
|
|
if (!$this->user_id) {
|
|
return $this->error('获取用户信息失败');
|
|
}
|
|
|
|
//用户openid
|
|
$user_info = User::query()->where('id', $this->user_id)->first(['agent_id', 'openid']); //此处要用where,value()用find有BUG
|
|
$openid = $user_info['openid'];
|
|
$this->agent_id = $user_info['agent_id'];
|
|
|
|
$order = Order::with(['agentProduct'])
|
|
->whereRaw('`timeout` >= NOW()')
|
|
->whereIn('status', [Status::UNPAID, Status::PAY_EARNEST])
|
|
->find($order_id);
|
|
if (!$order) {
|
|
return $this->error('订单已支付或已超时,订单ID:' . $order_id);
|
|
}
|
|
|
|
$order->pay_user_id = $this->user_id;
|
|
$order->save();
|
|
|
|
//如果已经付定金或首付款,则仅支付尾款
|
|
if ($order->status == Status::PAY_EARNEST) {
|
|
$price = bcsub($order->price,$order->paid_money,2);
|
|
} elseif (in_array($order->pay_type, [PayType::DEPOSIT_PAY, PayType::EARNEST_PAY])) {
|
|
$price = $order->prepay_price;
|
|
} else {
|
|
$price = bcmul($order->price,$order->num,2);
|
|
}
|
|
|
|
$setting = AdminSetting::val(['payee_appid', 'payee_mchid', 'payee_mchkey']);
|
|
if (!isset($setting['payee_appid'], $setting['payee_mchid'], $setting['payee_mchkey'])) {
|
|
return $this->error('获取系统配置失败');
|
|
}
|
|
|
|
$config = config('wechat.payment.default');
|
|
$config = array_merge($config, [
|
|
'app_id' => $setting['payee_appid'],
|
|
'mch_id' => $setting['payee_mchid'],
|
|
'key' => $setting['payee_mchkey'],
|
|
]);
|
|
|
|
$app = Factory::payment($config);
|
|
try {
|
|
$result = $app->order->unify([
|
|
'body' => mb_substr(substr($order->title, 0, 127), 0, -1),
|
|
'out_trade_no' => $order->order_no . '-' . $order->status, //后面加status,主要是为了方便微信支付回调时区分定金(首付款)和尾款支付
|
|
'total_fee' => round($price * 100), //支付金额单位为分
|
|
'notify_url' => route('wxpay_notify', ['agent_id' => $this->agent_id]), // 支付结果通知网址,如果不设置则会使用配置里的默认地址
|
|
'trade_type' => 'JSAPI',
|
|
'openid' => $openid,
|
|
'attach' => $this->user_id, //保存支付用户的user_id
|
|
// 'profit_sharing' => 'Y', //Y分账,N不分账,默认不分账,Y大写
|
|
]);
|
|
} catch (InvalidArgumentException | InvalidConfigException | GuzzleException $e) {
|
|
return ['error' => $e->getMessage(), 'line' => $e->getLine()];
|
|
}
|
|
|
|
if (empty($result['prepay_id'])) {
|
|
return $result;
|
|
}
|
|
|
|
$jump_appid = Agent::where('id', $order->agent_id)->value('appid');
|
|
|
|
$jssdk = $app->jssdk;
|
|
$payConfig = $jssdk->bridgeConfig($result['prepay_id'], false) +
|
|
['id' => $order->id, 'order_no' => $order->order_no, 'jump_appid' => $jump_appid]; // 返回数组
|
|
return $this->success($payConfig);
|
|
}
|
|
|
|
/**
|
|
* 计算最终价格
|
|
* @param float $price 订单价格
|
|
* @param float $num 购买数量
|
|
* @param int $pay_type 支付方式
|
|
* @param AgentProduct $agent_product 代理商产品
|
|
* @return float
|
|
*/
|
|
private function calc(float $price, float $num, int $pay_type, AgentProduct $agent_product): float
|
|
{
|
|
/** 修改需要同步修改Order里面的 */
|
|
//根据支付方式计算价格
|
|
if (in_array($pay_type, [PayType::DEPOSIT_PAY, PayType::EARNEST_PAY, PayType::DOWN_PAYMENT])) {
|
|
if ($pay_type == PayType::DEPOSIT_PAY && $agent_product->deposit && $agent_product->deposit_timeout) {
|
|
return $agent_product->deposit;
|
|
} else if ($pay_type == PayType::EARNEST_PAY && $agent_product->earnest && $agent_product->earnest_timeout) {
|
|
return $agent_product->earnest;
|
|
}
|
|
}
|
|
|
|
$total_price = $price * $num;
|
|
|
|
return round($total_price, 2);
|
|
}
|
|
}
|