From 4041955296724849da8273342ce37e6370be8e5d Mon Sep 17 00:00:00 2001 From: IceToast <> Date: Tue, 3 Jan 2023 13:49:37 +0100 Subject: [PATCH 01/22] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20Extension=20r?= =?UTF-8?q?outes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- routes/extensions.php | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 routes/extensions.php diff --git a/routes/extensions.php b/routes/extensions.php new file mode 100644 index 00000000..c97f3eec --- /dev/null +++ b/routes/extensions.php @@ -0,0 +1,13 @@ + 'extensions'], function () { + $extensions = glob(app_path() . '/Extensions/*', GLOB_ONLYDIR); + foreach ($extensions as $extension) { + $routesFile = $extension . '/routes.php'; + if (file_exists($routesFile)) { + include_once $routesFile; + } + } +}); \ No newline at end of file From 16a7391372290875eb8d51ebef094b732281cb46 Mon Sep 17 00:00:00 2001 From: IceToast <> Date: Tue, 3 Jan 2023 18:31:21 +0100 Subject: [PATCH 02/22] =?UTF-8?q?feat:=20=E2=9C=A8=20Fixed=20extension=20r?= =?UTF-8?q?outes=20&=20Added=20PayPal=20Extension=20Routes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PaymentGateways/PayPal/routes.php | 6 ++++ app/Helpers/ExtensionHelper.php | 32 ++++++++++++++++++ .../PaymentGateways}/paypal_logo.png | Bin .../PaymentGateways}/stripe_logo.png | Bin routes/extensions.php | 13 +++++-- routes/web.php | 5 +-- 6 files changed, 52 insertions(+), 4 deletions(-) create mode 100644 app/Extensions/PaymentGateways/PayPal/routes.php create mode 100644 app/Helpers/ExtensionHelper.php rename public/images/{ => Extensions/PaymentGateways}/paypal_logo.png (100%) rename public/images/{ => Extensions/PaymentGateways}/stripe_logo.png (100%) diff --git a/app/Extensions/PaymentGateways/PayPal/routes.php b/app/Extensions/PaymentGateways/PayPal/routes.php new file mode 100644 index 00000000..7ec92f81 --- /dev/null +++ b/app/Extensions/PaymentGateways/PayPal/routes.php @@ -0,0 +1,6 @@ +name('payment.PayPalPay'); +Route::get('payment/PayPalSuccess', [PaymentController::class, 'PaypalSuccess'])->name('payment.PaypalSuccess'); diff --git a/app/Helpers/ExtensionHelper.php b/app/Helpers/ExtensionHelper.php new file mode 100644 index 00000000..f0cd7e4a --- /dev/null +++ b/app/Helpers/ExtensionHelper.php @@ -0,0 +1,32 @@ + 'extensions'], function () { - $extensions = glob(app_path() . '/Extensions/*', GLOB_ONLYDIR); + + // get all extensions that are inside App/Extensions + // It is important that the extensions are inside a folder with the name of the extension + // while those folders are inside Folders with the name of the type of extension like PaymentGateways, Themes, etc. + $extensionNamespaces = glob(app_path() . '/Extensions/*', GLOB_ONLYDIR); + $extensions = []; + foreach ($extensionNamespaces as $extensionNamespace) { + $extensions = array_merge($extensions, glob($extensionNamespace . '/*', GLOB_ONLYDIR)); + } + foreach ($extensions as $extension) { $routesFile = $extension . '/routes.php'; if (file_exists($routesFile)) { include_once $routesFile; } - } + } }); \ No newline at end of file diff --git a/routes/web.php b/routes/web.php index db124a34..2e86a556 100644 --- a/routes/web.php +++ b/routes/web.php @@ -85,8 +85,7 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () { #payments Route::get('checkout/{shopProduct}', [PaymentController::class, 'checkOut'])->name('checkout'); - Route::get('payment/PaypalPay/{shopProduct}', [PaymentController::class, 'PaypalPay'])->name('payment.PaypalPay'); - Route::get('payment/PaypalSuccess', [PaymentController::class, 'PaypalSuccess'])->name('payment.PaypalSuccess'); + Route::get('payment/pay', [PaymentController::class, 'pay'])->name('payment.pay'); Route::get('payment/StripePay/{shopProduct}', [PaymentController::class, 'StripePay'])->name('payment.StripePay'); Route::get('payment/StripeSuccess', [PaymentController::class, 'StripeSuccess'])->name('payment.StripeSuccess'); Route::get('payment/Cancel', [PaymentController::class, 'Cancel'])->name('payment.Cancel'); @@ -214,3 +213,5 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () { Route::get('/home', [HomeController::class, 'index'])->name('home'); }); + +require __DIR__ . '/extensions.php'; From 23cb226196d85610133a91b3e4274d2f5f22d159 Mon Sep 17 00:00:00 2001 From: IceToast <> Date: Tue, 3 Jan 2023 21:17:25 +0100 Subject: [PATCH 03/22] =?UTF-8?q?feat:=20=E2=9C=A8=20Added=20payment.pay?= =?UTF-8?q?=20route=20and=20enhanced=20checkOut=20route=20controller=20to?= =?UTF-8?q?=20serve=20gateways=20to=20view?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Controllers/Admin/PaymentController.php | 224 +++--------------- routes/web.php | 2 +- 2 files changed, 28 insertions(+), 198 deletions(-) diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php index 30f03085..bb2d3960 100644 --- a/app/Http/Controllers/Admin/PaymentController.php +++ b/app/Http/Controllers/Admin/PaymentController.php @@ -35,6 +35,8 @@ use PayPalCheckoutSdk\Orders\OrdersCreateRequest; use PayPalHttp\HttpException; use Stripe\Stripe; use Symfony\Component\Intl\Currencies; +use App\Helpers\ExtensionHelper; + class PaymentController extends Controller @@ -57,6 +59,23 @@ class PaymentController extends Controller */ public function checkOut(Request $request, ShopProduct $shopProduct) { + // get all payment gateway extensions + $extensions = glob(app_path() . '/Extensions/PaymentGateways/*', GLOB_ONLYDIR); + + // build a paymentgateways array that contains the routes for the payment gateways and the image path for the payment gateway which lays in public/images/Extensions/PaymentGateways with the extensionname in lowercase + $paymentGateways = []; + foreach ($extensions as $extension) { + $extensionName = basename($extension); + $config = ExtensionHelper::getExtensionConfig($extensionName, 'PaymentGateways'); + if ($config) { + $payment = new \stdClass(); + $payment->name = $config['name']; + $payment->image = asset('images/Extensions/PaymentGateways/' . strtolower($extensionName) . '_logo.png'); + $paymentGateways[] = $payment; + } + } + + return view('store.checkout')->with([ 'product' => $shopProduct, 'discountpercent' => PartnerDiscount::getDiscount(), @@ -64,210 +83,21 @@ class PaymentController extends Controller 'discountedprice' => $shopProduct->getPriceAfterDiscount(), 'taxvalue' => $shopProduct->getTaxValue(), 'taxpercent' => $shopProduct->getTaxPercent(), - 'total' => $shopProduct->getTotalPrice() + 'total' => $shopProduct->getTotalPrice(), + 'paymentGateways' => $paymentGateways, + ]); } - /** - * @param Request $request - * @param ShopProduct $shopProduct - * @return RedirectResponse - */ - public function PaypalPay(Request $request, ShopProduct $shopProduct) + public function pay(Request $request) { - $request = new OrdersCreateRequest(); - $request->prefer('return=representation'); - $request->body = [ - "intent" => "CAPTURE", - "purchase_units" => [ - [ - "reference_id" => uniqid(), - "description" => $shopProduct->display . (PartnerDiscount::getDiscount()?(" (" . __('Discount') . " " . PartnerDiscount::getDiscount() . '%)'):""), - "amount" => [ - "value" => $shopProduct->getTotalPrice(), - 'currency_code' => strtoupper($shopProduct->currency_code), - 'breakdown' => [ - 'item_total' => - [ - 'currency_code' => strtoupper($shopProduct->currency_code), - 'value' => $shopProduct->getPriceAfterDiscount(), - ], - 'tax_total' => - [ - 'currency_code' => strtoupper($shopProduct->currency_code), - 'value' => $shopProduct->getTaxValue(), - ] - ] - ] - ] - ], - "application_context" => [ - "cancel_url" => route('payment.Cancel'), - "return_url" => route('payment.PaypalSuccess', ['product' => $shopProduct->id]), - 'brand_name' => config('app.name', 'Laravel'), - 'shipping_preference' => 'NO_SHIPPING' - ] + $product = ShopProduct::find($request->product_id); + $paymentGateway = $request->payment_method; - - ]; - - - try { - // Call API with your client and get a response for your call - $response = $this->getPayPalClient()->execute($request); - return redirect()->away($response->result->links[1]->href); - - // If call returns body in response, you can get the deserialized version from the result attribute of the response - } catch (HttpException $ex) { - echo $ex->statusCode; - dd(json_decode($ex->getMessage())); - } - } - - /** - * @return PayPalHttpClient - */ - protected function getPayPalClient() - { - $environment = env('APP_ENV') == 'local' - ? new SandboxEnvironment($this->getPaypalClientId(), $this->getPaypalClientSecret()) - : new ProductionEnvironment($this->getPaypalClientId(), $this->getPaypalClientSecret()); - - return new PayPalHttpClient($environment); - } - - /** - * @return string - */ - protected function getPaypalClientId() - { - return env('APP_ENV') == 'local' ? config("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID") : config("SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID"); - } - - /** - * @return string - */ - protected function getPaypalClientSecret() - { - return env('APP_ENV') == 'local' ? config("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET") : config("SETTINGS::PAYMENTS:PAYPAL:SECRET"); - } - - /** - * @param Request $laravelRequest - */ - public function PaypalSuccess(Request $laravelRequest) - { - /** @var ShopProduct $shopProduct */ - $shopProduct = ShopProduct::findOrFail($laravelRequest->input('product')); - - /** @var User $user */ - $user = Auth::user(); - - $request = new OrdersCaptureRequest($laravelRequest->input('token')); - $request->prefer('return=representation'); - try { - // Call API with your client and get a response for your call - $response = $this->getPayPalClient()->execute($request); - if ($response->statusCode == 201 || $response->statusCode == 200) { - - //update server limit - if (config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) { - if ($user->server_limit < config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) { - $user->update(['server_limit' => config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]); - } - } - - //update User with bought item - if ($shopProduct->type=="Credits") { - $user->increment('credits', $shopProduct->quantity); - }elseif ($shopProduct->type=="Server slots"){ - $user->increment('server_limit', $shopProduct->quantity); - } - - //give referral commission always - if((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both") && $shopProduct->type=="Credits" && config("SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION") == "true"){ - if($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', $user->id)->first()){ - $ref_user = User::findOrFail($ref_user->referral_id); - $increment = number_format($shopProduct->quantity*(PartnerDiscount::getCommission($ref_user->id))/100,0,"",""); - $ref_user->increment('credits', $increment); - - //LOGS REFERRALS IN THE ACTIVITY LOG - activity() - ->performedOn($user) - ->causedBy($ref_user) - ->log('gained '. $increment.' '.config("SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME").' for commission-referral of '.$user->name.' (ID:'.$user->id.')'); - } - - } - - //update role give Referral-reward - if ($user->role == 'member') { - $user->update(['role' => 'client']); - - //give referral commission only on first purchase - if((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both") && $shopProduct->type=="Credits" && config("SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION") == "false"){ - if($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', $user->id)->first()){ - $ref_user = User::findOrFail($ref_user->referral_id); - $increment = number_format($shopProduct->quantity*(PartnerDiscount::getCommission($ref_user->id))/100,0,"",""); - $ref_user->increment('credits', $increment); - - //LOGS REFERRALS IN THE ACTIVITY LOG - activity() - ->performedOn($user) - ->causedBy($ref_user) - ->log('gained '. $increment.' '.config("SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME").' for commission-referral of '.$user->name.' (ID:'.$user->id.')'); - } - - } - - } - - //store payment - $payment = Payment::create([ - 'user_id' => $user->id, - 'payment_id' => $response->result->id, - 'payment_method' => 'paypal', - 'type' => $shopProduct->type, - 'status' => 'paid', - 'amount' => $shopProduct->quantity, - 'price' => $shopProduct->price - ($shopProduct->price*PartnerDiscount::getDiscount()/100), - 'tax_value' => $shopProduct->getTaxValue(), - 'tax_percent' => $shopProduct->getTaxPercent(), - 'total_price' => $shopProduct->getTotalPrice(), - 'currency_code' => $shopProduct->currency_code, - 'shop_item_product_id' => $shopProduct->id, - ]); - - - event(new UserUpdateCreditsEvent($user)); - - //only create invoice if SETTINGS::INVOICE:ENABLED is true - if (config('SETTINGS::INVOICE:ENABLED') == 'true') { - $this->createInvoice($user, $payment, 'paid', $shopProduct->currency_code); - } - - - //redirect back to home - return redirect()->route('home')->with('success', __('Your credit balance has been increased!')); - } - - - // If call returns body in response, you can get the deserialized version from the result attribute of the response - if (env('APP_ENV') == 'local') { - dd($response); - } else { - abort(500); - } - } catch (HttpException $ex) { - if (env('APP_ENV') == 'local') { - echo $ex->statusCode; - dd($ex->getMessage()); - } else { - abort(422); - } - } + return redirect()->route('payment.' . $paymentGateway . 'Pay', ['shopProduct' => $product->id]); } + /** * @param Request $request diff --git a/routes/web.php b/routes/web.php index 2e86a556..a638898b 100644 --- a/routes/web.php +++ b/routes/web.php @@ -85,7 +85,7 @@ Route::middleware(['auth', 'checkSuspended'])->group(function () { #payments Route::get('checkout/{shopProduct}', [PaymentController::class, 'checkOut'])->name('checkout'); - Route::get('payment/pay', [PaymentController::class, 'pay'])->name('payment.pay'); + Route::post('payment/pay', [PaymentController::class, 'pay'])->name('payment.pay'); Route::get('payment/StripePay/{shopProduct}', [PaymentController::class, 'StripePay'])->name('payment.StripePay'); Route::get('payment/StripeSuccess', [PaymentController::class, 'StripeSuccess'])->name('payment.StripeSuccess'); Route::get('payment/Cancel', [PaymentController::class, 'Cancel'])->name('payment.Cancel'); From 10f7e2688e9e8b7e53566c111c70aa568d088484 Mon Sep 17 00:00:00 2001 From: IceToast <> Date: Sat, 14 Jan 2023 22:37:23 +0100 Subject: [PATCH 04/22] =?UTF-8?q?feat:=20=E2=9C=A8=20Create=20PaymentEvent?= =?UTF-8?q?=20/=20Listener?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Events/PaymentEvent.php | 29 ++++++++++++++++++++++++ app/Listeners/PaymentListener.php | 31 ++++++++++++++++++++++++++ app/Providers/EventServiceProvider.php | 5 +++++ 3 files changed, 65 insertions(+) create mode 100644 app/Events/PaymentEvent.php create mode 100644 app/Listeners/PaymentListener.php diff --git a/app/Events/PaymentEvent.php b/app/Events/PaymentEvent.php new file mode 100644 index 00000000..3157de69 --- /dev/null +++ b/app/Events/PaymentEvent.php @@ -0,0 +1,29 @@ +payment = $payment; + } +} diff --git a/app/Listeners/PaymentListener.php b/app/Listeners/PaymentListener.php new file mode 100644 index 00000000..af7ab63d --- /dev/null +++ b/app/Listeners/PaymentListener.php @@ -0,0 +1,31 @@ +payment->user; + + // create invoice using the trait + $this->createInvoice($user, $event->payment); + } + } +} diff --git a/app/Providers/EventServiceProvider.php b/app/Providers/EventServiceProvider.php index b4befadf..a63efdd5 100644 --- a/app/Providers/EventServiceProvider.php +++ b/app/Providers/EventServiceProvider.php @@ -2,7 +2,9 @@ namespace App\Providers; +use App\Events\PaymentEvent; use App\Events\UserUpdateCreditsEvent; +use App\Listeners\PaymentListener; use App\Listeners\UnsuspendServers; use App\Listeners\Verified; use Illuminate\Auth\Events\Registered; @@ -25,6 +27,9 @@ class EventServiceProvider extends ServiceProvider UserUpdateCreditsEvent::class => [ UnsuspendServers::class, ], + PaymentEvent::class => [ + PaymentListener::class, + ], SocialiteWasCalled::class => [ // ... other providers 'SocialiteProviders\\Discord\\DiscordExtendSocialite@handle', From 8a03a7b16b9a134f0f8ca4d5f27b85871cf39f1a Mon Sep 17 00:00:00 2001 From: IceToast <> Date: Sat, 14 Jan 2023 22:38:13 +0100 Subject: [PATCH 05/22] =?UTF-8?q?feat:=20=E2=9C=A8=20Create=20Invoiceable?= =?UTF-8?q?=20Trait=20&=20Fix=20routing=20Extension?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/Extensions/PaymentGateways/PayPal/index.php | 8 +++----- app/Extensions/PaymentGateways/PayPal/routes.php | 2 +- app/Traits/Invoiceable.php | 8 ++++---- 3 files changed, 8 insertions(+), 10 deletions(-) diff --git a/app/Extensions/PaymentGateways/PayPal/index.php b/app/Extensions/PaymentGateways/PayPal/index.php index 6e505b73..fe8958b3 100644 --- a/app/Extensions/PaymentGateways/PayPal/index.php +++ b/app/Extensions/PaymentGateways/PayPal/index.php @@ -1,5 +1,6 @@ $shopProduct->id, ]); event(new UserUpdateCreditsEvent($user)); - //only create invoice if SETTINGS::INVOICE:ENABLED is true - if (config('SETTINGS::INVOICE:ENABLED') == 'true') { - // use the createInvoice method that is defined in the Invoiceable trait - $payment->createInvoice($user, $payment, 'paid', $shopProduct->currency_code); - } + event(new PaymentEvent($payment)); + //redirect back to home return redirect()->route('home')->with('success', __('Your credit balance has been increased!')); } diff --git a/app/Extensions/PaymentGateways/PayPal/routes.php b/app/Extensions/PaymentGateways/PayPal/routes.php index 7ec92f81..bbafa314 100644 --- a/app/Extensions/PaymentGateways/PayPal/routes.php +++ b/app/Extensions/PaymentGateways/PayPal/routes.php @@ -3,4 +3,4 @@ use Illuminate\Support\Facades\Route; Route::get('payment/PayPalPay/{shopProduct}', [PaymentController::class, 'PaypalPay'])->name('payment.PayPalPay'); -Route::get('payment/PayPalSuccess', [PaymentController::class, 'PaypalSuccess'])->name('payment.PaypalSuccess'); +Route::get('payment/PayPalSuccess', [PaymentController::class, 'PaypalSuccess'])->name('payment.PayPalSuccess'); diff --git a/app/Traits/Invoiceable.php b/app/Traits/Invoiceable.php index a4c91d08..4618215e 100644 --- a/app/Traits/Invoiceable.php +++ b/app/Traits/Invoiceable.php @@ -14,7 +14,7 @@ use Symfony\Component\Intl\Currencies; trait Invoiceable { - public function createInvoice($user, $payment, $paymentStatus, $currencyCode) + public function createInvoice($user, $payment) { $shopProduct = ShopProduct::where('id', $payment->shop_item_product_id)->first(); //create invoice @@ -60,13 +60,13 @@ trait Invoiceable ->taxRate(floatval($shopProduct->getTaxPercent())) ->shipping(0) ->addItem($item) - ->status(__($paymentStatus)) + ->status(__($payment->status)) ->series(now()->format('mY')) ->delimiter("-") ->sequence($newInvoiceID) ->serialNumberFormat(config("SETTINGS::INVOICE:PREFIX") . '{DELIMITER}{SERIES}{SEQUENCE}') - ->currencyCode($currencyCode) - ->currencySymbol(Currencies::getSymbol($currencyCode)) + ->currencyCode($payment->currency_code) + ->currencySymbol(Currencies::getSymbol($payment->currency_code)) ->notes($notes); if (file_exists($logoPath)) { From 69dd7a68550eec8e34e230dbe0a51ac436b4142c Mon Sep 17 00:00:00 2001 From: IceToast <> Date: Sat, 14 Jan 2023 23:33:30 +0100 Subject: [PATCH 06/22] =?UTF-8?q?fix:=20=F0=9F=90=9B=20Removed=20PayPal=20?= =?UTF-8?q?Routes=20->=20to=20own=20extension?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../PaymentGateways/PayPal/routes.php | 11 +- app/Helpers/ExtensionHelper.php | 15 ++ .../Controllers/Admin/PaymentController.php | 249 +----------------- 3 files changed, 27 insertions(+), 248 deletions(-) diff --git a/app/Extensions/PaymentGateways/PayPal/routes.php b/app/Extensions/PaymentGateways/PayPal/routes.php index bbafa314..714dfe9a 100644 --- a/app/Extensions/PaymentGateways/PayPal/routes.php +++ b/app/Extensions/PaymentGateways/PayPal/routes.php @@ -1,6 +1,13 @@ name('payment.PayPalPay'); -Route::get('payment/PayPalSuccess', [PaymentController::class, 'PaypalSuccess'])->name('payment.PayPalSuccess'); +Route::get('payment/PayPalPay/{shopProduct}', function () { + PaypalPay(request()); +})->name('payment.PayPalPay'); + +Route::get('payment/PayPalSuccess', function () { + PaypalSuccess(request()); +} +)->name('payment.PayPalSuccess'); diff --git a/app/Helpers/ExtensionHelper.php b/app/Helpers/ExtensionHelper.php index f0cd7e4a..d302f248 100644 --- a/app/Helpers/ExtensionHelper.php +++ b/app/Helpers/ExtensionHelper.php @@ -29,4 +29,19 @@ class ExtensionHelper return $config; } + + public static function getPayMethod($extensionName, $nameSpace) + { + // return the payment method of the extension to be used elsewhere + // for example in the payment controller + // the function starts with the name of the extension and ends with Pay + + $config = self::getExtensionConfig($extensionName, $nameSpace); + + if ($config == null) { + return null; + } + + return $config['payMethod']; + } } \ No newline at end of file diff --git a/app/Http/Controllers/Admin/PaymentController.php b/app/Http/Controllers/Admin/PaymentController.php index 97395f9a..6bd11122 100644 --- a/app/Http/Controllers/Admin/PaymentController.php +++ b/app/Http/Controllers/Admin/PaymentController.php @@ -6,11 +6,9 @@ use App\Events\UserUpdateCreditsEvent; use App\Http\Controllers\Controller; use App\Models\PartnerDiscount; use App\Models\Payment; -use App\Models\Settings; -use App\Models\ShopProduct; use App\Models\User; +use App\Models\ShopProduct; use App\Notifications\ConfirmPaymentNotification; -use App\Notifications\InvoiceNotification; use Exception; use Illuminate\Contracts\Foundation\Application; use Illuminate\Contracts\View\Factory; @@ -20,20 +18,11 @@ use Illuminate\Http\RedirectResponse; use Illuminate\Http\Request; use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\DB; -use Illuminate\Support\Facades\Log; -use Illuminate\Support\Facades\Storage; -use LaravelDaily\Invoices\Classes\Buyer; -use LaravelDaily\Invoices\Classes\InvoiceItem; -use LaravelDaily\Invoices\Classes\Party; -use LaravelDaily\Invoices\Invoice; use PayPalCheckoutSdk\Core\PayPalHttpClient; use PayPalCheckoutSdk\Core\ProductionEnvironment; use PayPalCheckoutSdk\Core\SandboxEnvironment; -use PayPalCheckoutSdk\Orders\OrdersCaptureRequest; -use PayPalCheckoutSdk\Orders\OrdersCreateRequest; use PayPalHttp\HttpException; use Stripe\Stripe; -use Symfony\Component\Intl\Currencies; use App\Helpers\ExtensionHelper; @@ -54,7 +43,7 @@ class PaymentController extends Controller * @param ShopProduct $shopProduct * @return Application|Factory|View */ - public function checkOut(Request $request, ShopProduct $shopProduct) + public function checkOut(ShopProduct $shopProduct) { // get all payment gateway extensions $extensions = glob(app_path() . '/Extensions/PaymentGateways/*', GLOB_ONLYDIR); @@ -90,7 +79,7 @@ class PaymentController extends Controller * @param ShopProduct $shopProduct * @return RedirectResponse */ - public function FreePay(Request $request, ShopProduct $shopProduct) + public function FreePay(ShopProduct $shopProduct) { //dd($shopProduct); //check if the product is really free or the discount is 100% @@ -137,60 +126,6 @@ class PaymentController extends Controller return redirect()->route('home')->with('success', __('Your credit balance has been increased!')); } - /** - * @param Request $request - * @param ShopProduct $shopProduct - * @return RedirectResponse - */ - public function PaypalPay(Request $request, ShopProduct $shopProduct) - { - if(!$this->checkAmount($shopProduct->getTotalPrice(), strtoupper($shopProduct->currency_code), "paypal")) return redirect()->route('home')->with('error', __('The product you chose can´t be purchased with this payment method. The total amount is too small. Please buy a bigger amount or try a different payment method.')); - $request = new OrdersCreateRequest(); - $request->prefer('return=representation'); - $request->body = [ - 'intent' => 'CAPTURE', - 'purchase_units' => [ - [ - 'reference_id' => uniqid(), - 'description' => $shopProduct->display.(PartnerDiscount::getDiscount() ? (' ('.__('Discount').' '.PartnerDiscount::getDiscount().'%)') : ''), - 'amount' => [ - 'value' => $shopProduct->getTotalPrice(), - 'currency_code' => strtoupper($shopProduct->currency_code), - 'breakdown' => [ - 'item_total' => [ - 'currency_code' => strtoupper($shopProduct->currency_code), - 'value' => $shopProduct->getPriceAfterDiscount(), - ], - 'tax_total' => [ - 'currency_code' => strtoupper($shopProduct->currency_code), - 'value' => $shopProduct->getTaxValue(), - ], - ], - ], - ], - ], - 'application_context' => [ - 'cancel_url' => route('payment.Cancel'), - 'return_url' => route('payment.PaypalSuccess', ['product' => $shopProduct->id]), - 'brand_name' => config('app.name', 'Laravel'), - 'shipping_preference' => 'NO_SHIPPING', - ], - - ]; - - try { - // Call API with your client and get a response for your call - $response = $this->getPayPalClient()->execute($request); - - return redirect()->away($response->result->links[1]->href); - - // If call returns body in response, you can get the deserialized version from the result attribute of the response - } catch (HttpException $ex) { - echo $ex->statusCode; - dd(json_decode($ex->getMessage())); - } - } - /** * @return PayPalHttpClient */ @@ -225,114 +160,8 @@ class PaymentController extends Controller $product = ShopProduct::find($request->product_id); $paymentGateway = $request->payment_method; - - return redirect()->route('payment.' . $paymentGateway . 'Pay', ['shopProduct' => $product->id]); } - - - /** - */ - public function PaypalSuccess(Request $laravelRequest) - { - $request = new OrdersCaptureRequest($laravelRequest->input('token')); - $request->prefer('return=representation'); - try { - // Call API with your client and get a response for your call - $response = $this->getPayPalClient()->execute($request); - if ($response->statusCode == 201 || $response->statusCode == 200) { - - //update server limit - if (config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) { - if ($user->server_limit < config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) { - $user->update(['server_limit' => config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]); - } - } - - //update User with bought item - if ($shopProduct->type == 'Credits') { - $user->increment('credits', $shopProduct->quantity); - } elseif ($shopProduct->type == 'Server slots') { - $user->increment('server_limit', $shopProduct->quantity); - } - - //give referral commission always - if ((config('SETTINGS::REFERRAL:MODE') == 'commission' || config('SETTINGS::REFERRAL:MODE') == 'both') && $shopProduct->type == 'Credits' && config('SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION') == 'true') { - if ($ref_user = DB::table('user_referrals')->where('registered_user_id', '=', $user->id)->first()) { - $ref_user = User::findOrFail($ref_user->referral_id); - $increment = number_format($shopProduct->quantity * (PartnerDiscount::getCommission($ref_user->id)) / 100, 0, '', ''); - $ref_user->increment('credits', $increment); - - //LOGS REFERRALS IN THE ACTIVITY LOG - activity() - ->performedOn($user) - ->causedBy($ref_user) - ->log('gained '.$increment.' '.config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME').' for commission-referral of '.$user->name.' (ID:'.$user->id.')'); - } - } - - //update role give Referral-reward - if ($user->role == 'member') { - $user->update(['role' => 'client']); - - //give referral commission only on first purchase - if ((config('SETTINGS::REFERRAL:MODE') == 'commission' || config('SETTINGS::REFERRAL:MODE') == 'both') && $shopProduct->type == 'Credits' && config('SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION') == 'false') { - if ($ref_user = DB::table('user_referrals')->where('registered_user_id', '=', $user->id)->first()) { - $ref_user = User::findOrFail($ref_user->referral_id); - $increment = number_format($shopProduct->quantity * (PartnerDiscount::getCommission($ref_user->id)) / 100, 0, '', ''); - $ref_user->increment('credits', $increment); - - //LOGS REFERRALS IN THE ACTIVITY LOG - activity() - ->performedOn($user) - ->causedBy($ref_user) - ->log('gained '.$increment.' '.config('SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME').' for commission-referral of '.$user->name.' (ID:'.$user->id.')'); - } - } - } - - //store payment - $payment = Payment::create([ - 'user_id' => $user->id, - 'payment_id' => $response->result->id, - 'payment_method' => 'paypal', - 'type' => $shopProduct->type, - 'status' => 'paid', - 'amount' => $shopProduct->quantity, - 'price' => $shopProduct->price - ($shopProduct->price * PartnerDiscount::getDiscount() / 100), - 'tax_value' => $shopProduct->getTaxValue(), - 'tax_percent' => $shopProduct->getTaxPercent(), - 'total_price' => $shopProduct->getTotalPrice(), - 'currency_code' => $shopProduct->currency_code, - 'shop_item_product_id' => $shopProduct->id, - ]); - - event(new UserUpdateCreditsEvent($user)); - - //only create invoice if SETTINGS::INVOICE:ENABLED is true - if (config('SETTINGS::INVOICE:ENABLED') == 'true') { - $this->createInvoice($user, $payment, 'paid', $shopProduct->currency_code); - } - - //redirect back to home - return redirect()->route('home')->with('success', __('Your credit balance has been increased!')); - } - - // If call returns body in response, you can get the deserialized version from the result attribute of the response - if (env('APP_ENV') == 'local') { - dd($response); - } else { - abort(500); - } - } catch (HttpException $ex) { - if (env('APP_ENV') == 'local') { - echo $ex->statusCode; - dd($ex->getMessage()); - } else { - abort(422); - } - } - } /** * @param Request $request @@ -644,78 +473,6 @@ class PaymentController extends Controller : config('SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET'); } - protected function createInvoice($user, $payment, $paymentStatus, $currencyCode) - { - $shopProduct = ShopProduct::where('id', $payment->shop_item_product_id)->first(); - //create invoice - $lastInvoiceID = \App\Models\Invoice::where('invoice_name', 'like', '%'.now()->format('mY').'%')->count('id'); - $newInvoiceID = $lastInvoiceID + 1; - $logoPath = storage_path('app/public/logo.png'); - - $seller = new Party([ - 'name' => config('SETTINGS::INVOICE:COMPANY_NAME'), - 'phone' => config('SETTINGS::INVOICE:COMPANY_PHONE'), - 'address' => config('SETTINGS::INVOICE:COMPANY_ADDRESS'), - 'vat' => config('SETTINGS::INVOICE:COMPANY_VAT'), - 'custom_fields' => [ - 'E-Mail' => config('SETTINGS::INVOICE:COMPANY_MAIL'), - 'Web' => config('SETTINGS::INVOICE:COMPANY_WEBSITE'), - ], - ]); - - $customer = new Buyer([ - 'name' => $user->name, - 'custom_fields' => [ - 'E-Mail' => $user->email, - 'Client ID' => $user->id, - ], - ]); - $item = (new InvoiceItem()) - ->title($shopProduct->description) - ->pricePerUnit($shopProduct->price); - - $notes = [ - __('Payment method').': '.$payment->payment_method, - ]; - $notes = implode('
', $notes); - - $invoice = Invoice::make() - ->template('controlpanel') - ->name(__('Invoice')) - ->buyer($customer) - ->seller($seller) - ->discountByPercent(PartnerDiscount::getDiscount()) - ->taxRate(floatval($shopProduct->getTaxPercent())) - ->shipping(0) - ->addItem($item) - ->status(__($paymentStatus)) - ->series(now()->format('mY')) - ->delimiter('-') - ->sequence($newInvoiceID) - ->serialNumberFormat(config('SETTINGS::INVOICE:PREFIX').'{DELIMITER}{SERIES}{SEQUENCE}') - ->currencyCode($currencyCode) - ->currencySymbol(Currencies::getSymbol($currencyCode)) - ->notes($notes); - - if (file_exists($logoPath)) { - $invoice->logo($logoPath); - } - - //Save the invoice in "storage\app\invoice\USER_ID\YEAR" - $invoice->filename = $invoice->getSerialNumber().'.pdf'; - $invoice->render(); - Storage::disk('local')->put('invoice/'.$user->id.'/'.now()->format('Y').'/'.$invoice->filename, $invoice->output); - - \App\Models\Invoice::create([ - 'invoice_user' => $user->id, - 'invoice_name' => $invoice->getSerialNumber(), - 'payment_id' => $payment->payment_id, - ]); - - //Send Invoice per Mail - $user->notify(new InvoiceNotification($invoice, $user, $payment)); - } - public function checkAmount($amount, $currencyCode, $payment_method) { $minimums = [ From 1f79a1994395d184ce48b5a5ad206f62cf600bb0 Mon Sep 17 00:00:00 2001 From: IceToast <> Date: Sat, 14 Jan 2023 23:34:10 +0100 Subject: [PATCH 07/22] =?UTF-8?q?feat:=20=E2=9C=A8=20Render=20all=20availa?= =?UTF-8?q?ble=20payment=20gateways=20from=20controller?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/default/views/store/checkout.blade.php | 223 ++++++++---------- 1 file changed, 94 insertions(+), 129 deletions(-) diff --git a/themes/default/views/store/checkout.blade.php b/themes/default/views/store/checkout.blade.php index 2e0556ca..749b7c98 100644 --- a/themes/default/views/store/checkout.blade.php +++ b/themes/default/views/store/checkout.blade.php @@ -10,8 +10,7 @@