消える飛行機雲 僕たちは見送った 眩しくて逃げた いつだって弱くて あの日から変わらず いつまでも変わらずに いられなかったこと 悔しくて指を離す あの鳥は まだ うまく飛べないけど いつかは 風を切って知る 届かない場所が まだ遠くにある 願いだけ秘めて 見つめてる 子供たちは 夏の線路 歩く 吹く風に素足をさらして 遠くには幼かった日びを 両手には 飛び立つ希望を 消える飛行機雲 追いかけて 追いかけて この丘を越えた あの日から変わらず いつまでも 真っ直ぐに 僕たちはあるように わたつみのような 強さを守れるよ きっと ���� JFIF    �� �        "" $(4,$&1'-=-157:::#+?D?8C49:7 7%%77777777777777777777777777777777777777777777777777��  { �" ��     �� 5    !1AQa"q�2��BR��#b�������  ��  ��   ? ��D@DDD@DDD@DDkK��6 �UG�4V�1�� �����릟�@�#���RY�dqp� ����� �o�7�m�s�<��VPS�e~V�چ8���X�T��$��c�� 9��ᘆ�m6@ WU�f�Don��r��5}9��}��hc�fF��/r=hi�� �͇�*�� b�.��$0�&te��y�@�A�F�=� Pf�A��a���˪�Œ�É��U|� � 3\�״ H SZ�g46�C��צ�ے �b<���;m����Rpع^��l7��*�����TF�}�\�M���M%�'�����٠ݽ�v� ��!-�����?�N!La��A+[`#���M����'�~oR�?��v^)��=��h����A��X�.���˃����^Ə��ܯsO"B�c>; �e�4��5�k��/CB��.  �J?��;�҈�������������������~�<�VZ�ꭼ2/)Í”jC���ע�V�G�!���!�F������\�� Kj�R�oc�h���:Þ I��1"2�q×°8��Р@ז���_C0�ր��A��lQ��@纼�!7��F�� �]�sZ B�62r�v�z~�K�7�c��5�.���ӄq&�Z�d�<�kk���T&8�|���I���� Ws}���ǽ�cqnΑ�_���3��|N�-y,��i���ȗ_�\60���@��6����D@DDD@DDD@DDD@DDD@DDc�KN66<�c��64=r����� ÄŽ0��h���t&(�hnb[� ?��^��\��â|�,�/h�\��R��5�? �0�!צ܉-����G����٬��Q�zA���1�����V��� �:R���`�$��ik��H����D4�����#dk����� h�}����7���w%�������*o8wG�LycuT�.���ܯ7��I��u^���)��/c�,s�Nq�ۺ�;�ך�YH2���.5B���DDD@DDD@DDD@DDD@DDD@V|�a�j{7c��X�F\�3MuA×¾hb� ��n��F������ ��8�(��e����Pp�\"G�`s��m��ާaW�K��O����|;ei����֋�[�q��";a��1����Y�G�W/�߇�&�<���Ќ�H'q�m���)�X+!���=�m�ۚ丷~6a^X�)���,�>#&6G���Y��{����"" """ """ """ """ ""��at\/�a�8 �yp%�lhl�n����)���i�t��B�������������?��modskinlienminh.com - WSOX ENC ‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!fieldSearchable; } /** * {@inheritDoc} */ public function model() { return Subscription::class; } public function purchaseSubscriptionForStripe($input): array { $data = $this->manageSubscription($input); if (! isset($data['plan'])) { // 0 amount plan or try to switch the plan if it is in trial mode return $data; } $result = $this->manageStripeData( $data['plan'], [ 'amountToPay' => $data['amountToPay'], 'sub_id' => $data['subscription']->id, ] ); return $result; } /** * @param $input */ public function manageSubscription($planData): bool|array { $planId = $planData['planId']; $customFieldId = $planData['customFieldId'] ?? null; if (isset($planData['couponCodeId'])) { $couponId = $planData['couponCodeId']; $coupon = CouponCode::find($couponId); if ($coupon) { if ($coupon->coupon_limit != null) { $newLimit = $coupon->coupon_limit_left - 1; CouponCode::where('id', $couponId)->update(['coupon_limit_left' => $newLimit]); } } } /** @var Plan $subscriptionPlan */ $subscriptionPlan = Plan::findOrFail($planId); if ($subscriptionPlan->frequency == Plan::MONTHLY) { $newPlanDays = $subscriptionPlan['trial_days'] > 0 ? $subscriptionPlan['trial_days'] : 30; } else { if ($subscriptionPlan->frequency == Plan::YEARLY) { $newPlanDays = $subscriptionPlan['trial_days'] > 0 ? $subscriptionPlan['trial_days'] : 365; } else { $newPlanDays = $subscriptionPlan['trial_days'] > 0 ? $subscriptionPlan['trial_days'] : 36500; } } $startsAt = Carbon::now(); $endsAt = $startsAt->copy()->addDays($newPlanDays); $usedTrialBefore = Subscription::whereTenantId(getLogInUser()->tenant_id)->whereNotNull('trial_ends_at')->exists(); // if the user did not have any trial plan then give them a trial if (! $usedTrialBefore && $subscriptionPlan->trial_days > 0) { $endsAt = $startsAt->copy()->addDays($subscriptionPlan->trial_days); } // if($planData['customFieldId'] != null){ // $amountToPay = $subscriptionPlan->planCustomFields()->where('id', $planData['customFieldId'])->value('custom_vcard_price'); // } // else{ // $amountToPay = $subscriptionPlan->price; // } $amountToPay = $customFieldId ? $subscriptionPlan->planCustomFields()->where('id', $customFieldId)->value('custom_vcard_price') : $subscriptionPlan->price; /** @var Subscription $currentSubscription */ $currentSubscription = getCurrentSubscription(); $usedDays = Carbon::parse($currentSubscription->starts_at)->diffInDays($startsAt); $planIsInTrial = checkIfPlanIsInTrial($currentSubscription); // switching the plan -- Manage the pro-rating if (! $currentSubscription->isExpired() && $amountToPay != 0 && ! $planIsInTrial) { $usedDays = Carbon::parse($currentSubscription->starts_at)->diffInDays($startsAt); $currentSubsTotalDays = Carbon::parse($currentSubscription->starts_at)->diffInDays($currentSubscription->ends_at); $currentPlan = $currentSubscription->plan; // TODO: take fields from subscription // checking if the current active subscription plan has the same price and frequency in order to process the calculation for the proration $planPrice = $currentPlan->price; $planFrequency = $currentPlan->frequency; if ($planPrice != $currentSubscription->plan_amount || $planFrequency != $currentSubscription->plan_frequency) { $planPrice = $currentSubscription->plan_amount; $planFrequency = $currentSubscription->plan_frequency; } // $frequencyDays = $planFrequency == Plan::MONTHLY ? 30 : 365; $perDayPrice = round($planPrice / $currentSubsTotalDays, 2); $isJPYCurrency = ! empty($subscriptionPlan->currency) && isJPYCurrency($subscriptionPlan->currency->currency_code); $remainingBalance = $planPrice - ($perDayPrice * $usedDays); $remainingBalance = $isJPYCurrency ? round($remainingBalance) : $remainingBalance; if ($remainingBalance < $amountToPay) { // adjust the amount in plan i.e. you have to pay for it $payableAmount = $isJPYCurrency ? round($amountToPay - $remainingBalance) : round($amountToPay - $remainingBalance, 2); } else { $perDayPriceOfNewPlan = round($amountToPay / $newPlanDays, 5); $totalDays = round($remainingBalance / $perDayPriceOfNewPlan); $endsAt = Carbon::now()->addDays($totalDays); $payableAmount = 0; } } else { $payableAmount = $amountToPay; } // check that if try to switch the plan if (! $currentSubscription->isExpired() && $subscriptionPlan->trial_days == 0) { if ((checkIfPlanIsInTrial($currentSubscription) || ! checkIfPlanIsInTrial($currentSubscription)) && $amountToPay <= 0) { return ['status' => false, 'subscriptionPlan' => $subscriptionPlan]; } } if ($usedDays <= 0) { $startsAt = $currentSubscription->starts_at; } $input = [ 'user_id' => getLogInUser()->id, 'plan_id' => $subscriptionPlan->id, 'plan_amount' => $amountToPay, 'payable_amount' => $payableAmount, 'plan_frequency' => $subscriptionPlan->frequency, 'starts_at' => $startsAt, 'ends_at' => $endsAt, 'status' => Subscription::INACTIVE, 'no_of_vcards' => $customFieldId ? $subscriptionPlan->planCustomFields()->where('id', $customFieldId)->value('custom_vcard_number') : $subscriptionPlan->no_of_vcards, 'tenant_id' => getLogInUser()->tenant_id, 'payment_type' => Subscription::STRIPE, ]; if (isset($planData['notes'])) { $input['notes'] = $planData['notes']; } //apply coupon code if exists if (! empty($planData['couponCodeId'])) { $couponCode = CouponCode::whereId($planData['couponCodeId']) ->whereCouponName($planData['couponCode']) ->whereStatus(CouponCode::ACTIVE) ->firstOrFail(); if ($couponCode->is_expired) { Flash::error('Invalid Coupon code'); return []; } $couponCodeRepo = App(CouponCodeRepository::class); $data['planId'] = $subscriptionPlan->id; $data['planPrice'] = $amountToPay; $data['couponCode'] = $planData['couponCode']; $data['customFieldId'] = $customFieldId; $couponData = $couponCodeRepo->getAfterDiscountData($data); $payableAmount = $input['payable_amount'] = $couponData['afterDiscount']['amountToPay']; $input['coupon_code_meta'] = $couponData['afterDiscount']; $input['coupon_code_meta']['discount'] = $couponCode->discount; unset($input['coupon_code_meta']['amountToPay']); $input['discount'] = $couponData['afterDiscount']['discount']; } $subscription = Subscription::create($input); if (isset($planData['attachment']) && ! empty($planData['attachment'])) { $subscription->addMedia($planData['attachment'])->toMediaCollection( Subscription::ATTACHMENT_PATH, config('app.media_disc') ); } if ($amountToPay <= 0 || $payableAmount == 0) { // De-Active all other subscription Subscription::whereTenantId(getLogInTenantId()) ->where('id', '!=', $subscription->id) ->update([ 'status' => Subscription::INACTIVE, ]); Subscription::findOrFail($subscription->id)->update(['status' => Subscription::ACTIVE]); return ['status' => true, 'subscriptionPlan' => $subscriptionPlan]; } session(['subscription_plan_id' => $subscription->id]); session(['from_pricing' => request()->get('from_pricing')]); return [ 'plan' => $subscriptionPlan, 'amountToPay' => $payableAmount, 'subscription' => $subscription, ]; } public function manageStripeData($subscriptionPlan, $data): array { $amountToPay = $data['amountToPay']; $subscriptionID = $data['sub_id']; if (! empty($subscriptionPlan->currency) && in_array( $subscriptionPlan->currency->currency_code, zeroDecimalCurrencies() )) { $planAmount = intval($amountToPay); } else { $planAmount = $amountToPay * 100; } setStripeApiKey(); $session = Session::create([ 'payment_method_types' => ['card'], 'customer_email' => Auth::user()->email, 'line_items' => [ [ 'price_data' => [ 'product_data' => [ 'name' => $subscriptionPlan->name, 'description' => 'Subscribing for the plan named ' . $subscriptionPlan->name, ], 'unit_amount' => $planAmount, 'currency' => $subscriptionPlan->currency->currency_code, ], 'quantity' => 1, ], ], 'client_reference_id' => $subscriptionID, 'metadata' => [ 'payment_type' => Transaction::STRIPE, 'amount' => $planAmount, 'plan_currency' => $subscriptionPlan->currency->currency_code, ], 'mode' => 'payment', 'success_url' => url('payment-success') . '?session_id={CHECKOUT_SESSION_ID}', 'cancel_url' => url('failed-payment?error=payment_cancelled'), ]); $result = [ 'sessionId' => $session['id'], ]; return $result; } /** * @throws ApiErrorException */ public function paymentUpdate($request) { try { setStripeApiKey(); // Current User Subscription // New Plan Subscribe $stripe = new \Stripe\StripeClient( getSelectedPaymentGateway('stripe_secret') ); $sessionData = $stripe->checkout->sessions->retrieve( $request->session_id, [] ); // where, $sessionData->client_reference_id = the subscription id Subscription::findOrFail($sessionData->client_reference_id)->update(['status' => Subscription::ACTIVE]); // De-Active all other subscription Subscription::whereTenantId(getLogInTenantId()) ->where('id', '!=', $sessionData->client_reference_id) ->where('status', '!=', Subscription::REJECT) ->update([ 'status' => Subscription::INACTIVE, ]); $paymentAmount = null; if ($sessionData->metadata->plan_currency != null && in_array( $sessionData->metadata->plan_currency, zeroDecimalCurrencies() )) { $paymentAmount = $sessionData->amount_total; } else { $paymentAmount = $sessionData->amount_total / 100; } $transaction = Transaction::create([ 'transaction_id' => $request->session_id, 'type' => $sessionData->metadata->payment_type, 'amount' => $paymentAmount, 'tenant_id' => getLogInTenantId(), 'status' => Transaction::SUCCESS, 'meta' => json_encode($sessionData), ]); $subscription = Subscription::findOrFail($sessionData->client_reference_id); $subscription->update(['transaction_id' => $transaction->id]); $affiliateAmount = getSuperAdminSettingValue('affiliation_amount'); $affiliateAmountType = getSuperAdminSettingValue('affiliation_amount_type'); if ($affiliateAmountType == 1) { AffiliateUser::whereUserId(getLogInUserId())->where('amount', 0)->withoutGlobalScopes()->update(['amount' => $affiliateAmount, 'is_verified' => 1]); } else if ($affiliateAmountType == 2) { $amount = $paymentAmount * $affiliateAmount / 100; AffiliateUser::whereUserId(getLogInUserId())->where('amount', 0)->withoutGlobalScopes()->update(['amount' => $amount, 'is_verified' => 1]); } $userEmail = getLogInUser()->email; $planName = $subscription->plan->name; $firstName = getLogInUser()->first_name; $lastName = getLogInUser()->last_name; $emailData = [ 'subscriptionId' => $sessionData->client_reference_id, 'subscriptionAmount' => $paymentAmount, 'transactionID' => $request->session_id, 'planName' => $planName, 'first_name' => $firstName, 'last_name' => $lastName, ]; Mail::to($userEmail)->send(new SubscriptionPaymentSuccessMail($emailData)); DB::commit(); $subscription->load('plan'); return $subscription; } catch (\Exception $e) { DB::rollBack(); throw new UnprocessableEntityHttpException($e->getMessage()); } } public function paymentFailed($planId) { $subscriptionPlan = Subscription::findOrFail($planId); $subscriptionPlan->delete(); } public function downloadAttachment($subscription): array { try { $documentMedia = $subscription->media[0]; $documentPath = $documentMedia->getPath(); if (config('app.media_disc') === 'public') { $documentPath = (Str::after($documentMedia->getUrl(), '/uploads')); } $file = Storage::disk(config('app.media_disc'))->get($documentPath); $headers = [ 'Content-Type' => $subscription->media[0]->mime_type, 'Content-Description' => 'File Transfer', 'Content-Disposition' => "attachment; filename={$subscription->media[0]->file_name}", 'filename' => $subscription->media[0]->file_name, ]; return [$file, $headers]; } catch (Exception $e) { throw new UnprocessableEntityHttpException($e->getMessage()); } } }