PaymentController.php 33 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864
  1. <?php
  2. namespace App\Http\Controllers\Admin;
  3. use App\Events\UserUpdateCreditsEvent;
  4. use App\Http\Controllers\Controller;
  5. use App\Models\InvoiceSettings;
  6. use App\Models\PartnerDiscount;
  7. use App\Models\Payment;
  8. use App\Models\ShopProduct;
  9. use App\Models\Settings;
  10. use App\Models\User;
  11. use App\Notifications\InvoiceNotification;
  12. use App\Notifications\ConfirmPaymentNotification;
  13. use Exception;
  14. use Illuminate\Contracts\Foundation\Application;
  15. use Illuminate\Contracts\View\Factory;
  16. use Illuminate\Contracts\View\View;
  17. use Illuminate\Http\JsonResponse;
  18. use Illuminate\Http\RedirectResponse;
  19. use Illuminate\Http\Request;
  20. use Illuminate\Support\Facades\Auth;
  21. use Illuminate\Support\Facades\DB;
  22. use Illuminate\Support\Facades\Log;
  23. use Illuminate\Support\Facades\Storage;
  24. use LaravelDaily\Invoices\Classes\Buyer;
  25. use LaravelDaily\Invoices\Classes\InvoiceItem;
  26. use LaravelDaily\Invoices\Classes\Party;
  27. use LaravelDaily\Invoices\Invoice;
  28. use PayPalCheckoutSdk\Core\PayPalHttpClient;
  29. use PayPalCheckoutSdk\Core\ProductionEnvironment;
  30. use PayPalCheckoutSdk\Core\SandboxEnvironment;
  31. use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
  32. use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
  33. use PayPalHttp\HttpException;
  34. use Stripe\Stripe;
  35. use Symfony\Component\Intl\Currencies;
  36. class PaymentController extends Controller
  37. {
  38. /**
  39. * @return Application|Factory|View
  40. */
  41. public function index()
  42. {
  43. return view('admin.payments.index')->with([
  44. 'payments' => Payment::paginate(15)
  45. ]);
  46. }
  47. /**
  48. * @param Request $request
  49. * @param ShopProduct $shopProduct
  50. * @return Application|Factory|View
  51. */
  52. public function checkOut(Request $request, ShopProduct $shopProduct)
  53. {
  54. return view('store.checkout')->with([
  55. 'product' => $shopProduct,
  56. 'discountpercent' => PartnerDiscount::getDiscount(),
  57. 'discountvalue' => PartnerDiscount::getDiscount() * $shopProduct->price/100,
  58. 'discountedprice' => $shopProduct->getPriceAfterDiscount(),
  59. 'taxvalue' => $shopProduct->getTaxValue(),
  60. 'taxpercent' => $shopProduct->getTaxPercent(),
  61. 'total' => $shopProduct->getTotalPrice()
  62. ]);
  63. }
  64. /**
  65. * @param Request $request
  66. * @param ShopProduct $shopProduct
  67. * @return RedirectResponse
  68. */
  69. public function FreePay(Request $request, ShopProduct $shopProduct)
  70. {
  71. //dd($shopProduct);
  72. //check if the product is really free or the discount is 100%
  73. if($shopProduct->getTotalPrice()>0) return redirect()->route('home')->with('error', __('An error ocured. Please try again.'));
  74. //give product
  75. /** @var User $user */
  76. $user = Auth::user();
  77. //not updating server limit
  78. //update User with bought item
  79. if ($shopProduct->type=="Credits") {
  80. $user->increment('credits', $shopProduct->quantity);
  81. }elseif ($shopProduct->type=="Server slots"){
  82. $user->increment('server_limit', $shopProduct->quantity);
  83. }
  84. //skipped the referral commission, because the user did not pay anything.
  85. //not giving client role
  86. //store payment
  87. $payment = Payment::create([
  88. 'user_id' => $user->id,
  89. 'payment_id' => uniqid(),
  90. 'payment_method' => 'free',
  91. 'type' => $shopProduct->type,
  92. 'status' => 'paid',
  93. 'amount' => $shopProduct->quantity,
  94. 'price' => $shopProduct->price - ($shopProduct->price*PartnerDiscount::getDiscount()/100),
  95. 'tax_value' => $shopProduct->getTaxValue(),
  96. 'tax_percent' => $shopProduct->getTaxPercent(),
  97. 'total_price' => $shopProduct->getTotalPrice(),
  98. 'currency_code' => $shopProduct->currency_code,
  99. 'shop_item_product_id' => $shopProduct->id,
  100. ]);
  101. event(new UserUpdateCreditsEvent($user));
  102. //not sending an invoice
  103. //redirect back to home
  104. return redirect()->route('home')->with('success', __('Your credit balance has been increased!'));
  105. }
  106. /**
  107. * @param Request $request
  108. * @param ShopProduct $shopProduct
  109. * @return RedirectResponse
  110. */
  111. public function PaypalPay(Request $request, ShopProduct $shopProduct)
  112. {
  113. 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.'));
  114. $request = new OrdersCreateRequest();
  115. $request->prefer('return=representation');
  116. $request->body = [
  117. "intent" => "CAPTURE",
  118. "purchase_units" => [
  119. [
  120. "reference_id" => uniqid(),
  121. "description" => $shopProduct->display . (PartnerDiscount::getDiscount()?(" (" . __('Discount') . " " . PartnerDiscount::getDiscount() . '%)'):""),
  122. "amount" => [
  123. "value" => $shopProduct->getTotalPrice(),
  124. 'currency_code' => strtoupper($shopProduct->currency_code),
  125. 'breakdown' => [
  126. 'item_total' =>
  127. [
  128. 'currency_code' => strtoupper($shopProduct->currency_code),
  129. 'value' => $shopProduct->getPriceAfterDiscount(),
  130. ],
  131. 'tax_total' =>
  132. [
  133. 'currency_code' => strtoupper($shopProduct->currency_code),
  134. 'value' => $shopProduct->getTaxValue(),
  135. ]
  136. ]
  137. ]
  138. ]
  139. ],
  140. "application_context" => [
  141. "cancel_url" => route('payment.Cancel'),
  142. "return_url" => route('payment.PaypalSuccess', ['product' => $shopProduct->id]),
  143. 'brand_name' => config('app.name', 'Laravel'),
  144. 'shipping_preference' => 'NO_SHIPPING'
  145. ]
  146. ];
  147. try {
  148. // Call API with your client and get a response for your call
  149. $response = $this->getPayPalClient()->execute($request);
  150. return redirect()->away($response->result->links[1]->href);
  151. // If call returns body in response, you can get the deserialized version from the result attribute of the response
  152. } catch (HttpException $ex) {
  153. echo $ex->statusCode;
  154. dd(json_decode($ex->getMessage()));
  155. }
  156. }
  157. /**
  158. * @return PayPalHttpClient
  159. */
  160. protected function getPayPalClient()
  161. {
  162. $environment = env('APP_ENV') == 'local'
  163. ? new SandboxEnvironment($this->getPaypalClientId(), $this->getPaypalClientSecret())
  164. : new ProductionEnvironment($this->getPaypalClientId(), $this->getPaypalClientSecret());
  165. return new PayPalHttpClient($environment);
  166. }
  167. /**
  168. * @return string
  169. */
  170. protected function getPaypalClientId()
  171. {
  172. return env('APP_ENV') == 'local' ? config("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_CLIENT_ID") : config("SETTINGS::PAYMENTS:PAYPAL:CLIENT_ID");
  173. }
  174. /**
  175. * @return string
  176. */
  177. protected function getPaypalClientSecret()
  178. {
  179. return env('APP_ENV') == 'local' ? config("SETTINGS::PAYMENTS:PAYPAL:SANDBOX_SECRET") : config("SETTINGS::PAYMENTS:PAYPAL:SECRET");
  180. }
  181. /**
  182. * @param Request $laravelRequest
  183. */
  184. public function PaypalSuccess(Request $laravelRequest)
  185. {
  186. /** @var ShopProduct $shopProduct */
  187. $shopProduct = ShopProduct::findOrFail($laravelRequest->input('product'));
  188. /** @var User $user */
  189. $user = Auth::user();
  190. $request = new OrdersCaptureRequest($laravelRequest->input('token'));
  191. $request->prefer('return=representation');
  192. try {
  193. // Call API with your client and get a response for your call
  194. $response = $this->getPayPalClient()->execute($request);
  195. if ($response->statusCode == 201 || $response->statusCode == 200) {
  196. //update server limit
  197. if (config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
  198. if ($user->server_limit < config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
  199. $user->update(['server_limit' => config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
  200. }
  201. }
  202. //update User with bought item
  203. if ($shopProduct->type=="Credits") {
  204. $user->increment('credits', $shopProduct->quantity);
  205. }elseif ($shopProduct->type=="Server slots"){
  206. $user->increment('server_limit', $shopProduct->quantity);
  207. }
  208. //give referral commission always
  209. if((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both") && $shopProduct->type=="Credits" && config("SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION") == "true"){
  210. if($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', $user->id)->first()){
  211. $ref_user = User::findOrFail($ref_user->referral_id);
  212. $increment = number_format($shopProduct->quantity*(PartnerDiscount::getCommission($ref_user->id))/100,0,"","");
  213. $ref_user->increment('credits', $increment);
  214. //LOGS REFERRALS IN THE ACTIVITY LOG
  215. activity()
  216. ->performedOn($user)
  217. ->causedBy($ref_user)
  218. ->log('gained '. $increment.' '.config("SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME").' for commission-referral of '.$user->name.' (ID:'.$user->id.')');
  219. }
  220. }
  221. //update role give Referral-reward
  222. if ($user->role == 'member') {
  223. $user->update(['role' => 'client']);
  224. //give referral commission only on first purchase
  225. if((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both") && $shopProduct->type=="Credits" && config("SETTINGS::REFERRAL::ALWAYS_GIVE_COMMISSION") == "false"){
  226. if($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', $user->id)->first()){
  227. $ref_user = User::findOrFail($ref_user->referral_id);
  228. $increment = number_format($shopProduct->quantity*(PartnerDiscount::getCommission($ref_user->id))/100,0,"","");
  229. $ref_user->increment('credits', $increment);
  230. //LOGS REFERRALS IN THE ACTIVITY LOG
  231. activity()
  232. ->performedOn($user)
  233. ->causedBy($ref_user)
  234. ->log('gained '. $increment.' '.config("SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME").' for commission-referral of '.$user->name.' (ID:'.$user->id.')');
  235. }
  236. }
  237. }
  238. //store payment
  239. $payment = Payment::create([
  240. 'user_id' => $user->id,
  241. 'payment_id' => $response->result->id,
  242. 'payment_method' => 'paypal',
  243. 'type' => $shopProduct->type,
  244. 'status' => 'paid',
  245. 'amount' => $shopProduct->quantity,
  246. 'price' => $shopProduct->price - ($shopProduct->price*PartnerDiscount::getDiscount()/100),
  247. 'tax_value' => $shopProduct->getTaxValue(),
  248. 'tax_percent' => $shopProduct->getTaxPercent(),
  249. 'total_price' => $shopProduct->getTotalPrice(),
  250. 'currency_code' => $shopProduct->currency_code,
  251. 'shop_item_product_id' => $shopProduct->id,
  252. ]);
  253. event(new UserUpdateCreditsEvent($user));
  254. //only create invoice if SETTINGS::INVOICE:ENABLED is true
  255. if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
  256. $this->createInvoice($user, $payment, 'paid', $shopProduct->currency_code);
  257. }
  258. //redirect back to home
  259. return redirect()->route('home')->with('success', __('Your credit balance has been increased!'));
  260. }
  261. // If call returns body in response, you can get the deserialized version from the result attribute of the response
  262. if (env('APP_ENV') == 'local') {
  263. dd($response);
  264. } else {
  265. abort(500);
  266. }
  267. } catch (HttpException $ex) {
  268. if (env('APP_ENV') == 'local') {
  269. echo $ex->statusCode;
  270. dd($ex->getMessage());
  271. } else {
  272. abort(422);
  273. }
  274. }
  275. }
  276. /**
  277. * @param Request $request
  278. */
  279. public function Cancel(Request $request)
  280. {
  281. return redirect()->route('store.index')->with('success', 'Payment was Canceled');
  282. }
  283. /**
  284. * @param Request $request
  285. * @param ShopProduct $shopProduct
  286. * @return RedirectResponse
  287. */
  288. public function StripePay(Request $request, ShopProduct $shopProduct)
  289. {
  290. if(!$this->checkAmount($shopProduct->getTotalPrice(), strtoupper($shopProduct->currency_code), "stripe")) 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.'));
  291. $stripeClient = $this->getStripeClient();
  292. $request = $stripeClient->checkout->sessions->create([
  293. 'line_items' => [
  294. [
  295. 'price_data' => [
  296. 'currency' => $shopProduct->currency_code,
  297. 'product_data' => [
  298. 'name' => $shopProduct->display . (PartnerDiscount::getDiscount()?(" (" . __('Discount') . " " . PartnerDiscount::getDiscount() . '%)'):""),
  299. 'description' => $shopProduct->description,
  300. ],
  301. 'unit_amount_decimal' => round($shopProduct->getPriceAfterDiscount() * 100, 2),
  302. ],
  303. 'quantity' => 1,
  304. ],
  305. [
  306. 'price_data' => [
  307. 'currency' => $shopProduct->currency_code,
  308. 'product_data' => [
  309. 'name' => __('Tax'),
  310. 'description' => $shopProduct->getTaxPercent() . "%",
  311. ],
  312. 'unit_amount_decimal' => round($shopProduct->getTaxValue(), 2) * 100,
  313. ],
  314. 'quantity' => 1,
  315. ]
  316. ],
  317. 'mode' => 'payment',
  318. "payment_method_types" => str_getcsv(config("SETTINGS::PAYMENTS:STRIPE:METHODS")),
  319. 'success_url' => route('payment.StripeSuccess', ['product' => $shopProduct->id]) . '&session_id={CHECKOUT_SESSION_ID}',
  320. 'cancel_url' => route('payment.Cancel'),
  321. ]);
  322. return redirect($request->url, 303);
  323. }
  324. /**
  325. * @param Request $request
  326. */
  327. public function StripeSuccess(Request $request)
  328. {
  329. /** @var ShopProduct $shopProduct */
  330. $shopProduct = ShopProduct::findOrFail($request->input('product'));
  331. /** @var User $user */
  332. $user = Auth::user();
  333. $stripeClient = $this->getStripeClient();
  334. try {
  335. //get stripe data
  336. $paymentSession = $stripeClient->checkout->sessions->retrieve($request->input('session_id'));
  337. $paymentIntent = $stripeClient->paymentIntents->retrieve($paymentSession->payment_intent);
  338. //get DB entry of this payment ID if existing
  339. $paymentDbEntry = Payment::where('payment_id', $paymentSession->payment_intent)->count();
  340. // check if payment is 100% completed and payment does not exist in db already
  341. if ($paymentSession->status == "complete" && $paymentIntent->status == "succeeded" && $paymentDbEntry == 0) {
  342. //update server limit
  343. if (config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
  344. if ($user->server_limit < config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
  345. $user->update(['server_limit' => config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
  346. }
  347. }
  348. //update User with bought item
  349. if ($shopProduct->type=="Credits") {
  350. $user->increment('credits', $shopProduct->quantity);
  351. }elseif ($shopProduct->type=="Server slots"){
  352. $user->increment('server_limit', $shopProduct->quantity);
  353. }
  354. //update role give Referral-reward
  355. if ($user->role == 'member') {
  356. $user->update(['role' => 'client']);
  357. if((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both") && $shopProduct->type=="Credits"){
  358. if($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', $user->id)->first()){
  359. $ref_user = User::findOrFail($ref_user->referral_id);
  360. $increment = number_format($shopProduct->quantity/100*config("SETTINGS::REFERRAL:PERCENTAGE"),0,"","");
  361. $ref_user->increment('credits', $increment);
  362. //LOGS REFERRALS IN THE ACTIVITY LOG
  363. activity()
  364. ->performedOn($user)
  365. ->causedBy($ref_user)
  366. ->log('gained '. $increment.' '.config("SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME").' for commission-referral of '.$user->name.' (ID:'.$user->id.')');
  367. }
  368. }
  369. }
  370. //store paid payment
  371. $payment = Payment::create([
  372. 'user_id' => $user->id,
  373. 'payment_id' => $paymentSession->payment_intent,
  374. 'payment_method' => 'stripe',
  375. 'type' => $shopProduct->type,
  376. 'status' => 'paid',
  377. 'amount' => $shopProduct->quantity,
  378. 'price' => $shopProduct->price - ($shopProduct->price*PartnerDiscount::getDiscount()/100),
  379. 'tax_value' => $shopProduct->getTaxValue(),
  380. 'total_price' => $shopProduct->getTotalPrice(),
  381. 'tax_percent' => $shopProduct->getTaxPercent(),
  382. 'currency_code' => $shopProduct->currency_code,
  383. 'shop_item_product_id' => $shopProduct->id,
  384. ]);
  385. //payment notification
  386. $user->notify(new ConfirmPaymentNotification($payment));
  387. event(new UserUpdateCreditsEvent($user));
  388. //only create invoice if SETTINGS::INVOICE:ENABLED is true
  389. if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
  390. $this->createInvoice($user, $payment, 'paid', $shopProduct->currency_code);
  391. }
  392. //redirect back to home
  393. return redirect()->route('home')->with('success', __('Your credit balance has been increased!'));
  394. } else {
  395. if ($paymentIntent->status == "processing") {
  396. //store processing payment
  397. $payment = Payment::create([
  398. 'user_id' => $user->id,
  399. 'payment_id' => $paymentSession->payment_intent,
  400. 'payment_method' => 'stripe',
  401. 'type' => $shopProduct->type,
  402. 'status' => 'processing',
  403. 'amount' => $shopProduct->quantity,
  404. 'price' => $shopProduct->price,
  405. 'tax_value' => $shopProduct->getTaxValue(),
  406. 'total_price' => $shopProduct->getTotalPrice(),
  407. 'tax_percent' => $shopProduct->getTaxPercent(),
  408. 'currency_code' => $shopProduct->currency_code,
  409. 'shop_item_product_id' => $shopProduct->id,
  410. ]);
  411. //only create invoice if SETTINGS::INVOICE:ENABLED is true
  412. if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
  413. $this->createInvoice($user, $payment, 'paid', $shopProduct->currency_code);
  414. }
  415. //redirect back to home
  416. return redirect()->route('home')->with('success', __('Your payment is being processed!'));
  417. }
  418. if ($paymentDbEntry == 0 && $paymentIntent->status != "processing") {
  419. $stripeClient->paymentIntents->cancel($paymentIntent->id);
  420. //redirect back to home
  421. return redirect()->route('home')->with('success', __('Your payment has been canceled!'));
  422. } else {
  423. abort(402);
  424. }
  425. }
  426. } catch (HttpException $ex) {
  427. if (env('APP_ENV') == 'local') {
  428. echo $ex->statusCode;
  429. dd($ex->getMessage());
  430. } else {
  431. abort(422);
  432. }
  433. }
  434. }
  435. /**
  436. * @param Request $request
  437. */
  438. protected function handleStripePaymentSuccessHook($paymentIntent)
  439. {
  440. try {
  441. // Get payment db entry
  442. $payment = Payment::where('payment_id', $paymentIntent->id)->first();
  443. $user = User::where('id', $payment->user_id)->first();
  444. if ($paymentIntent->status == 'succeeded' && $payment->status == 'processing') {
  445. //update server limit
  446. if (config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE') !== 0) {
  447. if ($user->server_limit < config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')) {
  448. $user->update(['server_limit' => config('SETTINGS::USER:SERVER_LIMIT_AFTER_IRL_PURCHASE')]);
  449. }
  450. }
  451. //update User with bought item
  452. if ($shopProduct->type=="Credits") {
  453. $user->increment('credits', $shopProduct->quantity);
  454. }elseif ($shopProduct->type=="Server slots"){
  455. $user->increment('server_limit', $shopProduct->quantity);
  456. }
  457. //update role give Referral-reward
  458. if ($user->role == 'member') {
  459. $user->update(['role' => 'client']);
  460. if((config("SETTINGS::REFERRAL:MODE") == "commission" || config("SETTINGS::REFERRAL:MODE") == "both")&& $shopProduct->type=="Credits"){
  461. if($ref_user = DB::table("user_referrals")->where('registered_user_id', '=', $user->id)->first()){
  462. $ref_user = User::findOrFail($ref_user->referral_id);
  463. $increment = number_format($shopProduct->quantity/100*config("SETTINGS::REFERRAL:PERCENTAGE"),0,"","");
  464. $ref_user->increment('credits', $increment);
  465. //LOGS REFERRALS IN THE ACTIVITY LOG
  466. activity()
  467. ->performedOn($user)
  468. ->causedBy($ref_user)
  469. ->log('gained '. $increment.' '.config("SETTINGS::SYSTEM:CREDITS_DISPLAY_NAME").' for commission-referral of '.$user->name.' (ID:'.$user->id.')');
  470. }
  471. }
  472. }
  473. //update payment db entry status
  474. $payment->update(['status' => 'paid']);
  475. //payment notification
  476. $user->notify(new ConfirmPaymentNotification($payment));
  477. event(new UserUpdateCreditsEvent($user));
  478. //only create invoice if SETTINGS::INVOICE:ENABLED is true
  479. if (config('SETTINGS::INVOICE:ENABLED') == 'true') {
  480. $this->createInvoice($user, $payment, 'paid', strtoupper($paymentIntent->currency));
  481. }
  482. }
  483. } catch (HttpException $ex) {
  484. abort(422);
  485. }
  486. }
  487. /**
  488. * @param Request $request
  489. */
  490. public function StripeWebhooks(Request $request)
  491. {
  492. \Stripe\Stripe::setApiKey($this->getStripeSecret());
  493. try {
  494. $payload = @file_get_contents('php://input');
  495. $sig_header = $request->header('Stripe-Signature');
  496. $event = null;
  497. $event = \Stripe\Webhook::constructEvent(
  498. $payload,
  499. $sig_header,
  500. $this->getStripeEndpointSecret()
  501. );
  502. } catch (\UnexpectedValueException $e) {
  503. // Invalid payload
  504. abort(400);
  505. } catch (\Stripe\Exception\SignatureVerificationException $e) {
  506. // Invalid signature
  507. abort(400);
  508. }
  509. // Handle the event
  510. switch ($event->type) {
  511. case 'payment_intent.succeeded':
  512. $paymentIntent = $event->data->object; // contains a \Stripe\PaymentIntent
  513. $this->handleStripePaymentSuccessHook($paymentIntent);
  514. break;
  515. default:
  516. echo 'Received unknown event type ' . $event->type;
  517. }
  518. }
  519. /**
  520. * @return \Stripe\StripeClient
  521. */
  522. protected function getStripeClient()
  523. {
  524. return new \Stripe\StripeClient($this->getStripeSecret());
  525. }
  526. /**
  527. * @return string
  528. */
  529. protected function getStripeSecret()
  530. {
  531. return env('APP_ENV') == 'local'
  532. ? config("SETTINGS::PAYMENTS:STRIPE:TEST_SECRET")
  533. : config("SETTINGS::PAYMENTS:STRIPE:SECRET");
  534. }
  535. /**
  536. * @return string
  537. */
  538. protected function getStripeEndpointSecret()
  539. {
  540. return env('APP_ENV') == 'local'
  541. ? config("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_TEST_SECRET")
  542. : config("SETTINGS::PAYMENTS:STRIPE:ENDPOINT_SECRET");
  543. }
  544. protected function createInvoice($user, $payment, $paymentStatus, $currencyCode)
  545. {
  546. $shopProduct = ShopProduct::where('id', $payment->shop_item_product_id)->first();
  547. //create invoice
  548. $lastInvoiceID = \App\Models\Invoice::where("invoice_name", "like", "%" . now()->format('mY') . "%")->count("id");
  549. $newInvoiceID = $lastInvoiceID + 1;
  550. $logoPath = storage_path('app/public/logo.png');
  551. $seller = new Party([
  552. 'name' => config("SETTINGS::INVOICE:COMPANY_NAME"),
  553. 'phone' => config("SETTINGS::INVOICE:COMPANY_PHONE"),
  554. 'address' => config("SETTINGS::INVOICE:COMPANY_ADDRESS"),
  555. 'vat' => config("SETTINGS::INVOICE:COMPANY_VAT"),
  556. 'custom_fields' => [
  557. 'E-Mail' => config("SETTINGS::INVOICE:COMPANY_MAIL"),
  558. "Web" => config("SETTINGS::INVOICE:COMPANY_WEBSITE")
  559. ],
  560. ]);
  561. $customer = new Buyer([
  562. 'name' => $user->name,
  563. 'custom_fields' => [
  564. 'E-Mail' => $user->email,
  565. 'Client ID' => $user->id,
  566. ],
  567. ]);
  568. $item = (new InvoiceItem())
  569. ->title($shopProduct->description)
  570. ->pricePerUnit($shopProduct->price);
  571. $notes = [
  572. __("Payment method") . ": " . $payment->payment_method,
  573. ];
  574. $notes = implode("<br>", $notes);
  575. $invoice = Invoice::make()
  576. ->template('controlpanel')
  577. ->name(__("Invoice"))
  578. ->buyer($customer)
  579. ->seller($seller)
  580. ->discountByPercent(PartnerDiscount::getDiscount())
  581. ->taxRate(floatval($shopProduct->getTaxPercent()))
  582. ->shipping(0)
  583. ->addItem($item)
  584. ->status(__($paymentStatus))
  585. ->series(now()->format('mY'))
  586. ->delimiter("-")
  587. ->sequence($newInvoiceID)
  588. ->serialNumberFormat(config("SETTINGS::INVOICE:PREFIX") . '{DELIMITER}{SERIES}{SEQUENCE}')
  589. ->currencyCode($currencyCode)
  590. ->currencySymbol(Currencies::getSymbol($currencyCode))
  591. ->notes($notes);
  592. if (file_exists($logoPath)) {
  593. $invoice->logo($logoPath);
  594. }
  595. //Save the invoice in "storage\app\invoice\USER_ID\YEAR"
  596. $invoice->filename = $invoice->getSerialNumber() . '.pdf';
  597. $invoice->render();
  598. Storage::disk("local")->put("invoice/" . $user->id . "/" . now()->format('Y') . "/" . $invoice->filename, $invoice->output);
  599. \App\Models\Invoice::create([
  600. 'invoice_user' => $user->id,
  601. 'invoice_name' => $invoice->getSerialNumber(),
  602. 'payment_id' => $payment->payment_id,
  603. ]);
  604. //Send Invoice per Mail
  605. $user->notify(new InvoiceNotification($invoice, $user, $payment));
  606. }
  607. public function checkAmount($amount, $currencyCode, $payment_method)
  608. {
  609. $minimums = [
  610. "USD" => [
  611. "paypal" => 0,
  612. "stripe" => 0.5
  613. ],
  614. "AED" => [
  615. "paypal" => 0,
  616. "stripe" => 2
  617. ],
  618. "AUD" => [
  619. "paypal" => 0,
  620. "stripe" => 0.5
  621. ],
  622. "BGN" => [
  623. "paypal" => 0,
  624. "stripe" => 1
  625. ],
  626. "BRL" => [
  627. "paypal" => 0,
  628. "stripe" => 0.5
  629. ],
  630. "CAD" => [
  631. "paypal" => 0,
  632. "stripe" => 0.5
  633. ],
  634. "CHF" => [
  635. "paypal" => 0,
  636. "stripe" => 0.5
  637. ],
  638. "CZK" => [
  639. "paypal" => 0,
  640. "stripe" => 15
  641. ],
  642. "DKK" => [
  643. "paypal" => 0,
  644. "stripe" => 2.5
  645. ],
  646. "EUR" => [
  647. "paypal" => 0,
  648. "stripe" => 0.5
  649. ],
  650. "GBP" => [
  651. "paypal" => 0,
  652. "stripe" => 0.3
  653. ],
  654. "HKD" => [
  655. "paypal" => 0,
  656. "stripe" => 4
  657. ],
  658. "HRK" => [
  659. "paypal" => 0,
  660. "stripe" => 0.5
  661. ],
  662. "HUF" => [
  663. "paypal" => 0,
  664. "stripe" => 175
  665. ],
  666. "INR" => [
  667. "paypal" => 0,
  668. "stripe" => 0.5
  669. ],
  670. "JPY" => [
  671. "paypal" => 0,
  672. "stripe" => 0.5
  673. ],
  674. "MXN" => [
  675. "paypal" => 0,
  676. "stripe" => 10
  677. ],
  678. "MYR" => [
  679. "paypal" => 0,
  680. "stripe" => 2
  681. ],
  682. "NOK" => [
  683. "paypal" => 0,
  684. "stripe" => 3
  685. ],
  686. "NZD" => [
  687. "paypal" => 0,
  688. "stripe" => 0.5
  689. ],
  690. "PLN" => [
  691. "paypal" => 0,
  692. "stripe" => 2
  693. ],
  694. "RON" => [
  695. "paypal" => 0,
  696. "stripe" => 2
  697. ],
  698. "SEK" => [
  699. "paypal" => 0,
  700. "stripe" => 3
  701. ],
  702. "SGD" => [
  703. "paypal" => 0,
  704. "stripe" => 0.5
  705. ],
  706. "THB" => [
  707. "paypal" => 0,
  708. "stripe" => 10
  709. ]
  710. ];
  711. return $amount >= $minimums[$currencyCode][$payment_method];
  712. }
  713. /**
  714. * @return JsonResponse|mixed
  715. * @throws Exception
  716. */
  717. public function dataTable()
  718. {
  719. $query = Payment::with('user');
  720. return datatables($query)
  721. ->editColumn('user', function (Payment $payment) {
  722. return
  723. ($payment->user)?'<a href="'.route('admin.users.show', $payment->user->id).'">'.$payment->user->name.'</a>':__('Unknown user');
  724. })
  725. ->editColumn('price', function (Payment $payment) {
  726. return $payment->formatToCurrency($payment->price);
  727. })
  728. ->editColumn('tax_value', function (Payment $payment) {
  729. return $payment->formatToCurrency($payment->tax_value);
  730. })
  731. ->editColumn('tax_percent', function (Payment $payment) {
  732. return $payment->tax_percent . ' %';
  733. })
  734. ->editColumn('total_price', function (Payment $payment) {
  735. return $payment->formatToCurrency($payment->total_price);
  736. })
  737. ->editColumn('created_at', function (Payment $payment) {
  738. return $payment->created_at ? $payment->created_at->diffForHumans() : '';
  739. })
  740. ->addColumn('actions', function (Payment $payment) {
  741. return '<a data-content="' . __("Download") . '" data-toggle="popover" data-trigger="hover" data-placement="top" href="' . route('admin.invoices.downloadSingleInvoice', "id=" . $payment->payment_id) . '" class="btn btn-sm text-white btn-info mr-1"><i class="fas fa-file-download"></i></a>';
  742. })
  743. ->rawColumns(['actions', 'user'])
  744. ->make(true);
  745. }
  746. }