status) { throw new BizException('该会员卡已关闭'); } $user_vip = $user->vips()->create([ 'vip_id' => $vip->id, 'name' => $vip->name, 'price' => $vip->price, 'times' => $vip->times, 'gift' => $vip->gift, ]); return $user_vip; } public function pay(UserVip $userVip, $pay_way = '') { if (!$pay_way) { $pay_way = PayWay::WxpayMiniProgram->value; } if ($userVip->status == 2) { throw new BizException('支付处理中,请勿重复操作'); } $userVip->update([ 'status' => 2 ]); $pay_log = PayLog::create([ 'payable_type' => UserVip::class, 'payable_id' => $userVip->id, 'pay_sn' => serial_number(), 'pay_way' => $pay_way ]); $money = $userVip->price; $debug = config('app.debug'); if ($debug) { $money = 1; } $user = $userVip->user; // 微信小程序支付 if ($pay_log->pay_way === PayWay::WxpayMiniProgram) { $openid = $user->socialites()->where('socialite_type', SocialiteType::WechatMiniProgram)->value('socialite_id'); if (!$openid && $debug) { $openid = 'oU7xS5UspzVvpPEBqKZuW6N9WXDg'; } if (!$openid) { throw new BizException('未找到用户的微信授权信息, 无法使用微信支付'); } $params = [ 'body' => app_settings('app.app_name').'-会员-' . $userVip->name, 'out_trade_no' => $pay_log->pay_sn, 'total_fee' => $money * 100, 'trade_type' => WxpayTradeType::JSAPI->value, 'openid' => $openid, ]; return ['pay_way' => $pay_way, 'data' => (new WxpayService())->pay($params)]; } throw new BizException('未知的支付方式'); } /** * 购买成功 * @param UserVip $userVip 购买记录 * @param array $params {'pay_at':'购买时间'} */ public function success(UserVip $userVip, array $params = null) { $userVip->update([ 'status' => 1, 'success_time' => data_get($params, 'pay_at', now()) ]); $user = $userVip->user; $vip_expired = $this->convertTimes(data_get($userVip->times, 'num'), data_get($userVip->times, 'unit'), $user->vip_expired); $userVip->user->update([ 'vip_expired' => $vip_expired ]); $this->gift($userVip); } /** * 发放赠品 * @param UserVip $userVip 购买记录 */ public function gift(UserVip $userVip) { if ($userVip->status != 1) { throw new BizException('请先购买'); } $user = $userVip->user; $gift = $userVip->gift; // 优惠券 if (isset($gift['coupon'])) { $coupon_service = new CouponService(); foreach(Coupon::whereIn('id', $gift['coupon'])->get() as $item) { try { $coupon_service->sendCoupon($user, $item); } catch (BizException $e) { } } } } /** * 延长时限 * * @param int $num 数量 * @param string $unit 单位 * @return Carbon */ public function convertTimes(int $num, string $unit, Carbon $start = null) { if (!$start) { $start = now(); } switch ($unit) { case Vip::TIME_YEAR: $start->addYears($num); break; case Vip::TIME_MONTH: $start->addMonths($num); break; case Vip::TIME_DAY: $start->addDays($num); break; default: throw new BizException('未知的时间单位'); } return $start; } }