海南旅游SAAS
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.

124 lines
4.1 KiB

4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
4 years ago
  1. <?php
  2. namespace App\Http\Controllers\Api;
  3. use App\Common\OrderStatus as Status;
  4. use App\Common\PayType;
  5. use App\Http\Controllers\Controller;
  6. use App\Models\AdminSetting;
  7. use App\Models\Agent;
  8. use App\Models\AgentProduct;
  9. use App\Models\Order;
  10. use App\Models\User;
  11. use EasyWeChat\Factory;
  12. use EasyWeChat\Kernel\Exceptions\InvalidArgumentException;
  13. use EasyWeChat\Kernel\Exceptions\InvalidConfigException;
  14. use GuzzleHttp\Exception\GuzzleException;
  15. use Illuminate\Support\Facades\Cache;
  16. /**
  17. * 跳转支付
  18. * Class SharePay
  19. * @package App\Http\Controllers\Api
  20. */
  21. class SharePayController extends Controller
  22. {
  23. public function pay()
  24. {
  25. $order_id = request()->input('id');
  26. if (!$order_id) {
  27. return $this->error('无效的ID');
  28. }
  29. $this->user_id = Cache::get(request()->header('Authentication'));
  30. if (!$this->user_id) {
  31. return $this->error('获取用户信息失败');
  32. }
  33. //用户openid
  34. $user_info = User::query()->where('id', $this->user_id)->first(['agent_id', 'openid']); //此处要用where,value()用find有BUG
  35. $openid = $user_info['openid'];
  36. $this->agent_id = $user_info['agent_id'];
  37. $order = Order::with(['agentProduct'])
  38. ->whereRaw('`timeout` >= NOW()')
  39. ->whereIn('status', [Status::UNPAID, Status::PAY_EARNEST])
  40. ->find($order_id);
  41. if (!$order) {
  42. return $this->error('订单已支付或已超时,订单ID:' . $order_id);
  43. }
  44. $order->pay_user_id = $this->user_id;
  45. $order->save();
  46. //如果已经付定金或首付款,则仅支付尾款
  47. if ($order->status == Status::PAY_EARNEST) {
  48. $price = $order->price - $order->paid_money;
  49. } else {
  50. $price = $this->calc($order->price, $order->num, $order->pay_type, $order->agentProduct);
  51. }
  52. $setting = AdminSetting::val(['payee_appid', 'payee_mchid', 'payee_mchkey']);
  53. if (!isset($setting['payee_appid'], $setting['payee_mchid'], $setting['payee_mchkey'])) {
  54. return $this->error('获取系统配置失败');
  55. }
  56. $config = config('wechat.payment.default');
  57. $config = array_merge($config, [
  58. 'app_id' => $setting['payee_appid'],
  59. 'mch_id' => $setting['payee_mchid'],
  60. 'key' => $setting['payee_mchkey'],
  61. ]);
  62. $app = Factory::payment($config);
  63. try {
  64. $result = $app->order->unify([
  65. 'body' => $order->title,
  66. 'out_trade_no' => $order->order_no . '-' . $order->status, //后面加status,主要是为了方便微信支付回调时区分定金(首付款)和尾款支付
  67. 'total_fee' => round($price * 100), //支付金额单位为分
  68. 'notify_url' => route('wxpay_notify', ['agent_id' => $this->agent_id]), // 支付结果通知网址,如果不设置则会使用配置里的默认地址
  69. 'trade_type' => 'JSAPI',
  70. 'openid' => $openid,
  71. 'attach' => $this->user_id, //保存支付用户的user_id
  72. // 'profit_sharing' => 'Y', //Y分账,N不分账,默认不分账,Y大写
  73. ]);
  74. } catch (InvalidArgumentException | InvalidConfigException | GuzzleException $e) {
  75. return ['error' => $e->getMessage(), 'line' => $e->getLine()];
  76. }
  77. if (empty($result['prepay_id'])) {
  78. return $result;
  79. }
  80. $jump_appid = Agent::where('id', $order->agent_id)->value('appid');
  81. $jssdk = $app->jssdk;
  82. $payConfig = $jssdk->bridgeConfig($result['prepay_id'], false) +
  83. ['id' => $order->id, 'order_no' => $order->order_no, 'jump_appid' => $jump_appid]; // 返回数组
  84. return $this->success($payConfig);
  85. }
  86. /**
  87. * 计算最终价格
  88. * @param float $price 订单价格
  89. * @param float $num 购买数量
  90. * @param int $pay_type 支付方式
  91. * @param AgentProduct $agent_product 代理商产品
  92. * @return float
  93. */
  94. private function calc(float $price, float $num, int $pay_type, AgentProduct $agent_product): float
  95. {
  96. /** 修改需要同步修改Order里面的 */
  97. //根据支付方式计算价格
  98. if (in_array($pay_type, [PayType::DEPOSIT_PAY, PayType::EARNEST_PAY, PayType::DOWN_PAYMENT])) {
  99. if ($pay_type == PayType::DEPOSIT_PAY && $agent_product->deposit && $agent_product->deposit_timeout) {
  100. return $agent_product->deposit;
  101. } else if ($pay_type == PayType::EARNEST_PAY && $agent_product->earnest && $agent_product->earnest_timeout) {
  102. return $agent_product->earnest;
  103. }
  104. }
  105. $total_price = $price * $num;
  106. return round($total_price, 2);
  107. }
  108. }