PaymentController.php 33 KB

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