/**
  * Create a discount for the given user.
  *
  * @param  Request  $request
  * @param  string  $userId
  * @return Response
  */
 public function store(Request $request, $userId)
 {
     $user = Spark::user()->where('id', $userId)->firstOrFail();
     $this->validate($request, ['type' => 'required|in:amount,percent', 'value' => 'required|integer', 'duration' => 'required|in:once,forever,repeating', 'months' => 'required_if:duration,repeating']);
     $coupon = StripeCoupon::create(['currency' => 'usd', 'amount_off' => $request->type == 'amount' ? $request->value * 100 : null, 'percent_off' => $request->type == 'percent' ? $request->value : null, 'duration' => $request->duration, 'duration_in_months' => $request->months, 'max_redemptions' => 1], config('services.stripe.secret'));
     $user->applyCoupon($coupon->id);
 }
示例#2
0
 /**
  * Get the current discount for the given user.
  *
  * @param  Request  $request
  * @param  string  $userId
  * @return Response
  */
 public function current(Request $request, $userId)
 {
     $user = Spark::user()->where('id', $userId)->firstOrFail();
     if ($coupon = $this->coupons->forBillable($user)) {
         return response()->json($coupon->toArray());
     }
 }
示例#3
0
 /**
  * Bootstrap any application services.
  *
  * @return void
  */
 public function boot()
 {
     if (method_exists($this, 'customizeSpark')) {
         $this->customizeSpark();
     }
     if (method_exists($this, 'customizeRegistration')) {
         $this->customizeRegistration();
     }
     if (method_exists($this, 'customizeRoles')) {
         $this->customizeRoles();
     }
     if (method_exists($this, 'customizeProfileUpdates')) {
         $this->customizeProfileUpdates();
     }
     if (method_exists($this, 'customizeSubscriptionPlans')) {
         $this->customizeSubscriptionPlans();
     }
     if (method_exists($this, 'customizeSettingsTabs')) {
         $this->customizeSettingsTabs();
     }
     if ($this->twoFactorAuth) {
         Spark::withTwoFactorAuth();
     }
     Spark::generateInvoicesWith($this->invoiceWith);
 }
示例#4
0
 /**
  * {@inheritdoc}
  */
 public function handle($user, $plan, $fromRegistration, array $data)
 {
     $subscription = $user->newSubscription('default', $plan->id);
     // Here we will check if we need to skip trial or set trial days on the subscription
     // when creating it on the provider. By default, we will skip the trial when this
     // interaction is not from egistration since they have already usually trialed.
     if (!$fromRegistration) {
         $subscription->skipTrial();
     } elseif ($plan->trialDays > 0) {
         $subscription->trialDays($plan->trialDays);
     }
     if (isset($data['coupon'])) {
         $subscription->withCoupon($data['coupon']);
     }
     // Next, we need to check if this application is storing billing addresses and if so
     // we will update the billing address in the database so that any tax information
     // on the user will be up to date via the taxPercentage method on the billable.
     if (Spark::collectsBillingAddress()) {
         Spark::call(UserRepository::class . '@updateBillingAddress', [$user, $data]);
     }
     // If this application collects European VAT, we will store the VAT ID that was sent
     // with the request. It is used to determine if the VAT should get charged at all
     // when billing the customer. When it is present, VAT is not typically charged.
     if (Spark::collectsEuropeanVat()) {
         Spark::call(UserRepository::class . '@updateVatId', [$user, array_get($data, 'vat_id')]);
     }
     // Here we will create the actual subscription on the service and fire off the event
     // letting other listeners know a user has subscribed, which will allow any hooks
     // to fire that need to send the subscription data to any external metrics app.
     $subscription->create($data[$this->token]);
     event(new UserSubscribed($user = $user->fresh(), $plan, $fromRegistration));
     return $user;
 }
 /**
  * Handle the event.
  *
  * @param  UserRegistered  $event
  * @return void
  */
 public function handle(UserRegistered $event)
 {
     if (!Spark::trialDays()) {
         return;
     }
     $this->notifications->create($event->user, ['icon' => 'fa-clock-o', 'body' => 'Your trial period will expire on ' . $event->user->trial_ends_at->format('F jS') . '.', 'action_text' => 'Subscribe', 'action_url' => '/settings#/subscription']);
 }
 /**
  * Determine if the authenticated user is a developer.
  *
  * @param  \Illuminate\Http\Request  $request
  * @param  \Closure  $next
  * @return \Illuminate\Http\Response
  */
 public function handle($request, $next)
 {
     if ($request->user() && Spark::developer($request->user()->email)) {
         return $next($request);
     }
     return $request->ajax() || $request->wantsJson() ? response('Unauthorized.', 401) : redirect()->guest('login');
 }
 /**
  * Get the validator for the request.
  *
  * @return \Illuminate\Validation\Validator
  */
 public function validator()
 {
     $validator = Validator::make($this->all(), ['plan' => 'required|in:' . Spark::activePlanIdList()]);
     return $validator->after(function ($validator) {
         $this->validatePlanEligibility($validator);
     });
 }
示例#8
0
 /**
  * Verify the incoming request's user belongs to team.
  *
  * @param  \Illuminate\Http\Request  $request
  * @param  \Closure  $next
  * @return \Illuminate\Http\Response
  */
 public function handle($request, $next)
 {
     if (Spark::usesTeams() && $request->user() && !$request->user()->hasTeams()) {
         return redirect('missing-team');
     }
     return $next($request);
 }
示例#9
0
 /**
  * {@inheritdoc}
  */
 public function handle($team, $plan, array $data)
 {
     $subscription = $team->newSubscription('default', $plan->id);
     // Here we will fill the trial days for this team subscription. We will also set any
     // coupon on the subscription so that the team can receive a discount on the team
     // subscription. Then we will almost be ready to create the final subscription.
     $subscription->trialDays($plan->trialDays);
     if (isset($data['coupon'])) {
         $subscription->withCoupon($data['coupon']);
     }
     // Next, we need to check if this application is storing billing addresses and if so
     // we will update the billing address in the database so that any tax information
     // on the team will be up to date via the taxPercentage method on the billable.
     if (Spark::collectsBillingAddress()) {
         Spark::call(TeamRepository::class . '@updateBillingAddress', [$team, $data]);
     }
     // If this application collects European VAT, we will store the VAT ID that was sent
     // with the request. It is used to determine if the VAT should get charged at all
     // when billing the customer. When it is present, VAT is not typically charged.
     if (Spark::collectsEuropeanVat()) {
         Spark::call(TeamRepository::class . '@updateVatId', [$team, array_get($data, 'vat_id')]);
     }
     // Here we will create the actual subscription on the service and fire off the event
     // letting other listeners know a team has subscribed, which will allow any hooks
     // to fire that need to send the subscription data to any external metrics app.
     $subscription->create($data[$this->token]);
     event(new TeamSubscribed($team = $team->fresh(), $plan));
     return $team;
 }
 /**
  * Handle the event.
  *
  * @param  TeamCreated  $event
  * @return void
  */
 public function handle(TeamCreated $event)
 {
     if (!Spark::teamTrialDays()) {
         return;
     }
     $this->notifications->create($event->team->owner, ['icon' => 'fa-clock-o', 'body' => "The " . $event->team->name . " team's trial period will expire on " . $event->team->trial_ends_at->format('F jS') . '.', 'action_text' => 'Subscribe', 'action_url' => '/settings/teams/' . $event->team->id . '#/subscription']);
 }
 /**
  * Get the validator for the request.
  *
  * @return \Illuminate\Validation\Validator
  */
 public function validator()
 {
     $validator = $this->registerValidator(['stripe_token']);
     if (Spark::collectsBillingAddress() && $this->hasPaidPlan()) {
         $this->validateBillingAddress($validator);
     }
     return $validator;
 }
示例#12
0
 /**
  * Configure the valdiator to validate the token abilities.
  *
  * @param  \Illuminate\Validation\Validator  $validator
  * @return \Illuminate\Validation\Validator
  */
 protected function validateAbilities($validator)
 {
     $abilities = implode(',', array_keys(Spark::tokensCan()));
     $validator->sometimes('abilities', 'required|array|in:' . $abilities, function () {
         return count(Spark::tokensCan()) > 0;
     });
     return $validator;
 }
 /**
  * Send an invoice notification e-mail.
  *
  * @param  mixed  $billable
  * @param  \Laravel\Cashier\Invoice
  * @return void
  */
 protected function sendInvoiceNotification($billable, $invoice)
 {
     $invoiceData = Spark::invoiceDataFor($billable);
     $data = compact('billable', 'invoice', 'invoiceData');
     Mail::send($this->emailView, $data, function ($message) use($billable, $invoice, $invoiceData) {
         $this->buildInvoiceMessage($message, $billable, $invoice, $invoiceData);
     });
 }
示例#14
0
 /**
  * Execute the given interaction.
  *
  * This performs the common validate and handle flow of some interactions.
  *
  * @param  Request  $request
  * @param  string  $interaction
  * @param  array  $parameters
  * @return void
  */
 public function interaction(Request $request, $interaction, array $parameters)
 {
     $validator = Spark::interact($interaction . '@validator', $parameters);
     if ($validator->fails()) {
         $this->throwValidationException($request, $validator);
     }
     return Spark::interact($interaction, $parameters);
 }
示例#15
0
 /**
  * Subscribe the given user to a subscription plan.
  *
  * @param  RegisterRequest  $request
  * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
  * @return \Illuminate\Contracts\Auth\Authenticatable
  */
 protected function subscribe($request, $user)
 {
     if (!$request->hasPaidPlan()) {
         return $user;
     }
     Spark::interact(Subscribe::class, [$user, $request->plan(), true, $request->all()]);
     return $user;
 }
示例#16
0
 /**
  * Notify the given user about a new invoice.
  *
  * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
  * @param  \Laravel\Cashier\Invoice  $invoice
  * @return void
  */
 public function notify(Authenticatable $user, Invoice $invoice)
 {
     $invoiceData = array_merge(['vendor' => 'Vendor', 'product' => 'Product', 'vat' => new ViewExpression(nl2br(e($user->extra_billing_info)))], Spark::generateInvoicesWith());
     $data = compact('user', 'invoice', 'invoiceData');
     Mail::send('spark::emails.billing.invoice', $data, function ($message) use($user, $invoice, $invoiceData) {
         $message->to($user->email, $user->name)->subject('Your ' . $invoiceData['product'] . ' Invoice')->attachData($invoice->pdf($invoiceData), 'invoice.pdf');
     });
 }
 /**
  * Get the validator for the request.
  *
  * @return \Illuminate\Validation\Validator
  */
 public function validator()
 {
     $validator = $this->baseValidator(['stripe_token' => 'required', 'vat_id' => 'max:50|vat_id']);
     if (Spark::collectsBillingAddress()) {
         $this->validateBillingAddress($validator);
     }
     return $validator;
 }
示例#18
0
 /**
  * Get all of the available roles that may be assigned to team members.
  *
  * @return \Illuminate\Http\Response
  */
 public function getTeamRoles()
 {
     $roles = [];
     foreach (Spark::roles() as $key => $value) {
         $roles[] = ['value' => $key, 'text' => $value];
     }
     return response()->json($roles);
 }
 /**
  * Get the validator for the request.
  *
  * @return \Illuminate\Validation\Validator
  */
 public function validator()
 {
     $validator = Validator::make($this->all(), ['stripe_token' => 'required']);
     if (Spark::collectsBillingAddress()) {
         $this->validateBillingAddress($validator);
     }
     return $validator;
 }
 /**
  * Customize the tabs on the settings screen.
  *
  * @return void
  */
 protected function customizeSettingsTabs()
 {
     Spark::settingsTabs()->configure(function ($tabs) {
         return [$tabs->profile(), $tabs->teams(), $tabs->security(), $tabs->subscription()];
     });
     Spark::teamSettingsTabs()->configure(function ($tabs) {
         return [$tabs->owner(), $tabs->membership()];
     });
 }
示例#21
0
 /**
  * {@inheritdoc}
  */
 public function handle($team, $email)
 {
     $invitedUser = Spark::user()->where('email', $email)->first();
     $this->emailInvitation($invitation = $this->createInvitation($team, $email, $invitedUser));
     if ($invitedUser) {
         event(new UserInvitedToTeam($team, $invitedUser));
     }
     return $invitation;
 }
示例#22
0
 /**
  * Get the tax percentage to apply to the subscription.
  *
  * @return int
  */
 public function taxPercentage()
 {
     if (!Spark::collectsEuropeanVat()) {
         return 0;
     }
     $vatCalculator = new VatCalculator();
     $vatCalculator->setBusinessCountryCode(Spark::homeCountry());
     return $vatCalculator->getTaxRateForCountry($this->card_country, !empty($this->vat_id)) * 100;
 }
示例#23
0
 /**
  * Create a new team for the given user and data.
  *
  * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
  * @param  array  $data
  * @return \Laravel\Spark\Teams\Team
  */
 public function create($user, array $data)
 {
     $class = Spark::model('teams', Team::class);
     $team = new $class(['name' => $data['name']]);
     $team->owner_id = $user->id;
     $team->save();
     $team = $user->teams()->attach($team, ['role' => 'owner']);
     return $team;
 }
示例#24
0
 /**
  * Show the settings dashboard.
  *
  * @param  \Illuminate\Http\Request  $request
  * @return \Illuminate\Http\Response
  */
 public function show(Request $request)
 {
     $data = ['activeTab' => $request->get('tab', Spark::firstSettingsTabKey()), 'invoices' => [], 'user' => $this->users->getCurrentUser()];
     if (Auth::user()->stripe_id) {
         $data['invoices'] = Cache::remember('spark:invoices:' . Auth::id(), 30, function () {
             return Auth::user()->invoices();
         });
     }
     return view('spark::settings.dashboard', $data);
 }
 /**
  * Call the custom plan eligibility checker callback.
  *
  * @param  \Illuminate\Validation\Validator  $validator
  * @param  \Laravel\Spark\Plan  $plan
  * @return void
  */
 protected function callCustomCallback($validator, $plan)
 {
     try {
         if (!Spark::eligibleForTeamPlan($this->route('team'), $plan)) {
             $validator->errors()->add('plan', 'This team is not eligible for this plan.');
         }
     } catch (IneligibleForPlan $e) {
         $validator->errors()->add('plan', $e->getMessage());
     }
 }
示例#26
0
 /**
  * {@inheritdoc}
  */
 public function handle(array $data)
 {
     if (!Spark::hasSupportAddress()) {
         throw new RuntimeException("No customer support request recipient is defined.");
     }
     Mail::raw($data['message'], function ($m) use($data) {
         $m->to(Spark::supportAddress())->subject('Support Request: ' . $data['subject']);
         $m->replyTo($data['from']);
     });
 }
示例#27
0
 /**
  * Get the team matching the given ID.
  *
  * @param  Request  $request
  * @param  string  $teamId
  * @return Response
  */
 public function show(Request $request, $teamId)
 {
     $team = Spark::interact(TeamRepository::class . '@find', [$teamId]);
     abort_unless($request->user()->onTeam($team), 404);
     if ($request->user()->ownsTeam($team)) {
         $team->load('subscriptions');
         $team->shouldHaveOwnerVisibility();
     }
     return $team;
 }
示例#28
0
 /**
  * Attach a user to a given team based on their invitation.
  *
  * @param  string  $invitationId
  * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
  * @return void
  */
 public function attachUserToTeamByInvitation($invitationId, $user)
 {
     $userModel = get_class($user);
     $inviteModel = get_class((new $userModel())->invitations()->getQuery()->getModel());
     $invitation = (new $inviteModel())->where('token', $invitationId)->first();
     if ($invitation) {
         $invitation->team->users()->attach([$user->id], ['role' => Spark::defaultRole()]);
         $user->switchToTeam($invitation->team);
         $invitation->delete();
     }
 }
 /**
  * Redeem the given coupon code.
  *
  * @param  Request  $request
  * @return Response
  */
 public function redeem(Request $request)
 {
     $this->validate($request, ['coupon' => 'required']);
     // We will verify that the coupon can actually be redeemed. In some cases even
     // valid coupons can not get redeemed by an existing user if this coupon is
     // running as a promotion for brand new registrations to the application.
     if (!$this->coupons->canBeRedeemed($request->coupon)) {
         return response()->json(['coupon' => ['This coupon code is invalid.']], 422);
     }
     Spark::interact(RedeemCoupon::class, [$request->user(), $request->coupon]);
 }
 /**
  * Create the subscription on Stripe.
  *
  * @param  \Illuminate\Http\Request  $request
  * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
  * @return void
  */
 protected function createSubscriptionOnStripe(Request $request, $user)
 {
     $plan = Spark::plans()->find($request->plan);
     $subscription = $user->subscription($plan->id);
     if ($plan->hasTrial()) {
         $subscription->trialFor(Carbon::now()->addDays($plan->trialDays));
     }
     if ($request->coupon) {
         $subscription->withCoupon($request->coupon);
     }
     $subscription->create($request->stripe_token, ['email' => $user->email]);
 }