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 = $userVip->pay()->create([ 'pay_sn' => serial_number(), 'pay_way' => $pay_way ]); $money = $userVip->price; if ($money <= 0) { $this->success($userVip); return ['status' => 1]; } $debug = config('app.debug'); if ($debug) { $money = 0.01; } $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), 'status' => 0]; } 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; $success_time = $userVip->success_time; $start = $user->vip_expired; if ($success_time->gt($start)) { $start = $success_time; } $vip_expired = $this->convertTimes(data_get($userVip->times, 'num'), data_get($userVip->times, 'unit'), $start); $userVip->update([ 'expired' => $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']) && $gift['coupon']) { $coupon_service = new CouponService(); $couponId = array_column($gift['coupon'], 'id'); $couponList = Coupon::whereIn('id', $couponId)->get(); foreach($gift['coupon'] as $item) { try { $coupon = $couponList->firstWhere('id', $item['id']); $amount = data_get($item, 'amount', 1); if ($amount > 0 && $coupon) { $coupon_service->sendCoupon($user, $coupon, $amount); } } 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; } }