· 5 years ago · Nov 03, 2020, 03:56 PM
1<?php
2
3namespace Altum\Controllers;
4
5use Altum\Database\Database;
6use Altum\Date;
7use Altum\Logger;
8use Altum\Middlewares\Authentication;
9use Altum\Middlewares\Csrf;
10use Altum\Models\User;
11use Altum\Response;
12use Exception;
13use PayPal\Api\Agreement;
14use PayPal\Api\Amount;
15use PayPal\Api\Currency;
16use PayPal\Api\FlowConfig;
17use PayPal\Api\InputFields;
18use PayPal\Api\Item;
19use PayPal\Api\ItemList;
20use PayPal\Api\MerchantPreferences;
21use PayPal\Api\Patch;
22use PayPal\Api\PatchRequest;
23use PayPal\Api\Payer;
24use PayPal\Api\Payment;
25use PayPal\Api\PaymentDefinition;
26use PayPal\Api\PaymentExecution;
27use PayPal\Api\Plan;
28use PayPal\Api\Presentation;
29use PayPal\Api\RedirectUrls;
30use PayPal\Api\Transaction;
31use PayPal\Api\WebProfile;
32use PayPal\Common\PayPalModel;
33use Midtrans\Snap;
34
35class Pay extends Controller {
36 public $plan_id;
37 public $return_type;
38 public $payment_processor;
39 public $plan;
40 public $plan_taxes;
41 public $applied_taxes_ids = [];
42 public $code;
43
44 public function index() {
45 // echo $_GET['payment_processor'];exit;
46
47 Authentication::guard();
48
49 if(!$this->settings->payment->is_enabled) {
50 redirect();
51 }
52
53 $this->plan_id = isset($this->params[0]) ? $this->params[0] : false;
54 $this->return_type = isset($_GET['return_type']) && in_array($_GET['return_type'], ['success', 'cancel']) ? $_GET['return_type'] : null;
55 $this->payment_processor = isset($_GET['payment_processor']) && in_array($_GET['payment_processor'], ['paypal', 'stripe', 'offline_payment','stripe_gopay','stripe_va','stripe_alfa']) ? $_GET['payment_processor'] : null;
56
57 /* Make sure it is either the trial / free plan or normal plans */
58 switch($this->plan_id) {
59
60 case 'free':
61
62 /* Get the current settings for the free plan */
63 $this->plan = $this->settings->plan_free;
64
65 break;
66
67 case 'trial':
68
69 /* Get the current settings for the trial plan */
70 $this->plan = $this->settings->plan_trial;
71
72 break;
73
74 default:
75
76 $this->plan_id = (int) $this->plan_id;
77
78 /* Check if plan exists */
79 $this->plan = (new \Altum\Models\Plan(['settings' => $this->settings]))->get_plan_by_id($this->plan_id);
80
81 if($this->plan->plan_id == 'custom') {
82 redirect('plan');
83 }
84 }
85
86 /* Make sure the plan is enabled */
87 if(!$this->plan->status) {
88 redirect('plan');
89 }
90
91 /* More checks depending on the user plan and what it has been chosen */
92 if($this->plan_id == 'free') {
93 if($this->user->plan_id == 'free') {
94 $_SESSION['info'][] = $this->language->pay->free->free_already;
95 } else {
96 $_SESSION['info'][] = $this->language->pay->free->other_plan_not_expired;
97 }
98
99 redirect('plan');
100 }
101
102 elseif($this->plan_id == 'trial') {
103 if($this->user->plan_trial_done) {
104 $_SESSION['info'][] = $this->language->pay->trial->trial_done;
105 redirect('plan');
106 }
107 }
108
109 /* Form submission processing */
110 /* Make sure that this only runs on user click submit post and not on callbacks / webhooks */
111 if(!empty($_POST) && !$this->return_type) {
112
113 /* Check for any errors */
114 if(!Csrf::check()) {
115 $_SESSION['error'][] = $this->language->global->error_message->invalid_csrf_token;
116 }
117 // echo $_POST['payment_processor'];exit;
118 switch($this->plan_id) {
119
120 case 'free':
121
122 redirect('pay/' . $this->plan_id);
123
124 break;
125
126 case 'trial':
127
128 if($this->user->plan_trial_done) {
129 redirect('pay/' . $this->plan_id);
130 }
131
132 break;
133
134 default:
135
136 $_POST['payment_frequency'] = Database::clean_string($_POST['payment_frequency']);
137 $_POST['payment_processor'] = Database::clean_string($_POST['payment_processor']);
138 $_POST['payment_type'] = Database::clean_string($_POST['payment_type']);
139
140 /* Make sure the chosen option comply */
141 if(!in_array($_POST['payment_frequency'], ['monthly', 'annual', 'lifetime'])) {
142 redirect('pay/' . $this->plan_id);
143 }
144
145 if(!in_array($_POST['payment_processor'], ['paypal', 'stripe', 'offline_payment','stripe_gopay','stripe_va','stripe_alfa'])) {
146 redirect('pay/' . $this->plan_id);
147 } else {
148
149 /* Make sure the payment processor is active */
150 switch($_POST['payment_processor']) {
151 case 'paypal':
152
153 if(!$this->settings->paypal->is_enabled) {
154 redirect('pay/' . $this->plan_id);
155 }
156
157 break;
158
159 case 'stripe':
160
161 if(!$this->settings->stripe->is_enabled) {
162 redirect('pay/' . $this->plan_id);
163 }
164
165 break;
166
167 case 'stripe_gopay':
168 // echo $this->settings->stripe_gopay->is_enabled;exit;
169 if(!$this->settings->stripe_gopay->is_enabled) {
170 redirect('pay/' . $this->plan_id);
171 }
172
173 break;
174
175 case 'stripe_va':
176 // echo $this->settings->stripe_gopay->is_enabled;exit;
177 if(!$this->settings->stripe_va->is_enabled) {
178 redirect('pay/' . $this->plan_id);
179 }
180
181 break;
182
183 case 'stripe_alfa':
184
185 if(!$this->settings->stripe_alfa->is_enabled) {
186 redirect('pay/' . $this->plan_id);
187 }
188
189 break;
190 }
191
192 }
193
194 if(!in_array($_POST['payment_type'], ['one_time', 'recurring'])) {
195 redirect('pay/' . $this->plan_id);
196 }
197
198 /* Lifetime */
199 if($_POST['payment_frequency'] == 'lifetime') {
200 $_POST['payment_type'] = 'one_time';
201 }
202
203 /* Offline payment */
204 if($_POST['payment_processor'] == 'offline_payment') {
205 $_POST['payment_type'] = 'one_time';
206 }
207
208 break;
209 }
210
211 if(empty($_SESSION['error'])) {
212
213 switch($this->plan_id) {
214
215 case 'trial':
216
217 /* Determine the expiration date of the plan */
218 $plan_expiration_date = (new \DateTime())->modify('+' . $this->plan->days . ' days')->format('Y-m-d H:i:s');
219 $plan_settings = json_encode($this->settings->plan_trial->settings);
220
221 Database::$database->query("UPDATE `users` SET `plan_id` = 'trial', `plan_settings` = '{$plan_settings}', `plan_expiration_date` = '{$plan_expiration_date}', `plan_trial_done` = '1' WHERE `user_id` = {$this->user->user_id}");
222
223 /* Success message and redirect */
224 $this->redirect_pay_thank_you();
225
226 break;
227
228 default:
229
230 /* Check for code usage */
231 $this->code = false;
232
233 if($this->settings->payment->codes_is_enabled && isset($_POST['code'])) {
234
235 $_POST['code'] = Database::clean_string($_POST['code']);
236
237 $this->code = $this->database->query("SELECT `code_id`, `code`, `discount` FROM `codes` WHERE (`plan_id` IS NULL OR `plan_id` = '{$this->plan_id}') AND `code` = '{$_POST['code']}' AND `redeemed` < `quantity` AND `type` = 'discount'")->fetch_object();
238
239 if($this->code && Database::exists('id', 'redeemed_codes', ['user_id' => $this->user->user_id, 'code_id' => $this->code->code_id])) {
240 redirect('pay/' . $this->plan_id);
241 }
242 }
243
244 switch($_POST['payment_processor']) {
245
246 case 'paypal':
247
248 $this->paypal_create();
249
250 break;
251
252 case 'stripe':
253
254 $stripe_session = $this->stripe_create();
255
256 break;
257
258 case 'stripe_gopay':
259
260 $this->stripe_gopay_create();
261
262 break;
263
264 case 'stripe_va':
265
266 $this->stripe_va_create();
267
268 break;
269
270 case 'stripe_alfa':
271
272 $this->stripe_alfa_create();
273
274 break;
275 }
276
277 break;
278
279 }
280
281 }
282
283 }
284
285 /* Include the detection of paypal callbacks processing */
286 $this->paypal_process();
287
288 /* Include the detection of stripe callbacks processing */
289 $this->stripe_process();
290
291 /* Include the detection of stripe callbacks processing */
292 $this->stripe_gopay_process();
293
294 $this->stripe_va_process();
295
296 $this->stripe_alfa_process();
297
298
299
300
301
302
303 /* Prepare the View */
304 $data = [
305 'plan_id' => $this->plan_id,
306 'plan' => $this->plan,
307 'plan_taxes' => $this->plan_taxes,
308 'stripe_session' => $stripe_session ?? false
309 ];
310
311 $view = new \Altum\Views\View('pay/index', (array) $this);
312
313 $this->add_view_content('content', $view->run($data));
314
315 }
316
317 private function paypal_create() {
318
319 /* Initiate paypal */
320 $paypal = new \PayPal\Rest\ApiContext(new \PayPal\Auth\OAuthTokenCredential($this->settings->paypal->client_id, $this->settings->paypal->secret));
321 $paypal->setConfig(['mode' => $this->settings->paypal->mode]);
322
323 /* Payment details */
324 $product = $this->plan->name;
325 $price = $base_amount = (float) $this->plan->{$_POST['payment_frequency'] . '_price'};
326 $shipping = 0;
327 $code = '';
328 $discount_amount = 0;
329
330 /* Check for code usage */
331 if($this->code) {
332
333 /* Discount amount */
334 $discount_amount = number_format(($price * $this->code->discount / 100), 2, '.', '');
335
336 /* Calculate the new price */
337 $price = $price - $discount_amount;
338
339 $code = $this->code->code;
340
341 }
342
343 /* Taxes */
344 // $price = $this->calculate_price_with_taxes($price);
345
346 /* Make sure the price is right depending on the currency */
347 $price = in_array($this->settings->payment->currency, ['JPY', 'TWD', 'HUF']) ? number_format($price, 0, '.', '') : number_format($price, 2, '.', '');
348
349 switch($_POST['payment_type']) {
350 case 'one_time':
351
352 /* Payment experience */
353 $flowConfig = new FlowConfig();
354 $flowConfig->setLandingPageType('Billing');
355 $flowConfig->setUserAction('commit');
356 $flowConfig->setReturnUriHttpMethod('GET');
357
358 $presentation = new Presentation();
359 $presentation->setBrandName($this->settings->payment->brand_name);
360
361 $inputFields = new InputFields();
362 $inputFields->setAllowNote(true)
363 ->setNoShipping(1)
364 ->setAddressOverride(0);
365
366 $webProfile = new WebProfile();
367 $webProfile->setName($this->settings->payment->brand_name . uniqid())
368 ->setFlowConfig($flowConfig)
369 ->setPresentation($presentation)
370 ->setInputFields($inputFields)
371 ->setTemporary(true);
372
373 /* Create the experience profile */
374 try {
375 $createdProfileResponse = $webProfile->create($paypal);
376 } catch (Exception $exception) {
377
378 /* Output errors properly */
379 if (DEBUG) {
380 echo $exception->getCode();
381 echo $exception->getData();
382
383 die();
384 } else {
385
386 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
387 redirect('pay/' . $this->plan_id);
388
389 }
390
391 }
392
393 $payer = new Payer();
394 $payer->setPaymentMethod('paypal');
395
396 $item = new Item();
397 $item->setName($product)
398 ->setCurrency($this->settings->payment->currency)
399 ->setQuantity(1)
400 ->setPrice($price);
401
402 $itemList = new ItemList();
403 $itemList->setItems([$item]);
404
405 $amount = new Amount();
406 $amount->setCurrency($this->settings->payment->currency)
407 ->setTotal($price);
408
409 $transaction = new Transaction();
410 $transaction->setAmount($amount)
411 ->setItemList($itemList)
412 ->setInvoiceNumber(uniqid());
413
414 $redirectUrls = new RedirectUrls();
415 $redirectUrls->setReturnUrl(url('pay/' . $this->plan_id . $this->return_url_parameters('success', $base_amount, $price, $code, $discount_amount)))
416 ->setCancelUrl(url('pay/' . $this->plan_id . $this->return_url_parameters('cancel', $base_amount, $price, $code, $discount_amount)));
417
418 $payment = new Payment();
419 $payment->setIntent('sale')
420 ->setPayer($payer)
421 ->setRedirectUrls($redirectUrls)
422 ->setTransactions([$transaction])
423 ->setExperienceProfileId($createdProfileResponse->getId());
424
425 try {
426 $payment->create($paypal);
427 } catch (Exception $exception) {
428
429 /* Output errors properly */
430 if (DEBUG) {
431 echo $exception->getCode();
432 echo $exception->getData();
433
434 die();
435 } else {
436
437 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
438 redirect('pay/' . $this->plan_id);
439
440 }
441 }
442
443 $payment_url = $payment->getApprovalLink();
444
445 header('Location: ' . $payment_url);
446
447 break;
448
449 case 'recurring':
450
451 $plan = new \PayPal\Api\Plan();
452 $plan->setName($product)
453 ->setDescription($product)
454 ->setType('fixed');
455
456 /* Set billing plan definitions */
457 $payment_definition = new PaymentDefinition();
458 $payment_definition->setName('Regular Payments')
459 ->setType('REGULAR')
460 ->setFrequency($_POST['payment_frequency'] == 'monthly' ? 'Month' : 'Year')
461 ->setFrequencyInterval('1')
462 ->setCycles($_POST['payment_frequency'] == 'monthly' ? '60' : '5')
463 ->setAmount(new Currency(['value' => $price, 'currency' => $this->settings->payment->currency]));
464
465
466 /* Set merchant preferences */
467 $merchant_preferences = new MerchantPreferences();
468 $merchant_preferences->setReturnUrl(url('pay/' . $this->plan_id . $this->return_url_parameters('success', $base_amount, $price, $code, $discount_amount)))
469 ->setCancelUrl(url('pay/' . $this->plan_id . $this->return_url_parameters('cancel', $base_amount, $price, $code, $discount_amount)))
470 ->setAutoBillAmount('yes')
471 ->setInitialFailAmountAction('CONTINUE')
472 ->setMaxFailAttempts('0')
473 ->setSetupFee(new Currency(['value' => $price, 'currency' => $this->settings->payment->currency]));
474
475 $plan->setPaymentDefinitions([$payment_definition]);
476 $plan->setMerchantPreferences($merchant_preferences);
477
478 /* Create the plan */
479 try {
480 $plan = $plan->create($paypal);
481 } catch (Exception $exception) {
482
483 /* Output errors properly */
484 if (DEBUG) {
485 // echo '1';
486 echo $exception->getCode();
487 echo $exception->getData();
488
489 die();
490 } else {
491
492 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
493 redirect('pay/' . $this->plan_id);
494
495 }
496 }
497
498 /* Make sure to activate the plan */
499 try {
500 $patch = new Patch();
501 $value = new PayPalModel('{"state":"ACTIVE"}');
502 $patch->setOp('replace')
503 ->setPath('/')
504 ->setValue($value);
505 $patchRequest = new PatchRequest();
506 $patchRequest->addPatch($patch);
507 $plan->update($patchRequest, $paypal);
508 $plan = Plan::get($plan->getId(), $paypal);
509 } catch (Exception $exception) {
510
511 /* Output errors properly */
512 if (DEBUG) {
513 echo '2';
514 echo $exception->getCode();
515 echo $exception->getData();
516
517 die();
518 } else {
519
520 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
521 redirect('pay/' . $this->plan_id);
522
523 }
524 }
525
526 /* Start creating the agreement */
527 $agreement = new Agreement();
528 $agreement->setName($product)
529 ->setDescription(
530 $this->user->user_id
531 . '!!' . $this->plan_id
532 . '!!' . $base_amount
533 . '!!' . $_POST['payment_frequency']
534 . '!!' . $code
535 . '!!' . $discount_amount
536 . '!!' . json_encode($this->applied_taxes_ids)
537 )
538 ->setStartDate((new \DateTime())->modify($_POST['payment_frequency'] == 'monthly' ? '+30 days' : '+1 year')->format(DATE_ISO8601));
539
540 /* Set the plan id to the agreement */
541 $agreement_plan = new Plan();
542 $agreement_plan->setId($plan->getId());
543 $agreement->setPlan($agreement_plan);
544
545 /* Add Payer */
546 $payer = new Payer();
547 $payer->setPaymentMethod('paypal');
548 $agreement->setPayer($payer);
549
550 /* Create the agreement */
551 try {
552 $agreement = $agreement->create($paypal);
553 } catch (Exception $exception) {
554
555 /* Output errors properly */
556 if (DEBUG) {
557 echo '3';
558 echo $exception->getCode();
559 echo $exception->getData();
560
561 die();
562 } else {
563
564 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
565 redirect('pay/' . $this->plan_id);
566
567 }
568 }
569
570 $payment_url = $agreement->getApprovalLink();
571
572 header('Location: ' . $payment_url);
573
574 break;
575 }
576
577
578 }
579
580 private function paypal_process() {
581
582 /* Initiate paypal */
583 $paypal = new \PayPal\Rest\ApiContext(new \PayPal\Auth\OAuthTokenCredential($this->settings->paypal->client_id, $this->settings->paypal->secret));
584 $paypal->setConfig(['mode' => $this->settings->paypal->mode]);
585
586 /* Return confirmation processing */
587 if($this->return_type && $this->payment_processor && $this->return_type == 'success' && $this->payment_processor = 'paypal' && isset($_GET['payment_frequency'], $_GET['code'])) {
588 $payment_frequency = $_GET['payment_frequency'];
589 $code = $_GET['code'];
590 $discount_amount = $_GET['discount_amount'];
591 $base_amount = $_GET['base_amount'];
592
593 /* Return confirmation processing one time payment */
594 if(isset($_GET['paymentId'], $_GET['PayerID'])) {
595
596 /* Initiate paypal */
597 $paypal = new \PayPal\Rest\ApiContext(new \PayPal\Auth\OAuthTokenCredential($this->settings->paypal->client_id, $this->settings->paypal->secret));
598 $paypal->setConfig(['mode' => $this->settings->paypal->mode]);
599
600 $payment_id = $_GET['paymentId'];
601 $payer_id = $_GET['PayerID'];
602 $payment_type = 'one_time';
603 $subscription_id = '';
604 $payment_subscription_id = '';
605
606 try {
607 $payment = Payment::get($payment_id, $paypal);
608
609 $payer_info = $payment->getPayer()->getPayerInfo();
610 $payer_email = $payer_info->getEmail();
611 $payer_name = $payer_info->getFirstName() . ' ' . $payer_info->getLastName();
612
613 $payment_total = $payment->getTransactions()[0]->getAmount()->getTotal();
614 $payment_currency = $payment->getTransactions()[0]->getAmount()->getCurrency();
615
616 /* Execute the payment */
617 $execute = new PaymentExecution();
618 $execute->setPayerId($payer_id);
619
620 $result = $payment->execute($execute, $paypal);
621
622 /* Get status after execution */
623 $payment_status = $payment->getState();
624
625 } catch (Exception $exception) {
626
627 /* Output errors properly */
628 if (DEBUG) {
629 echo $exception->getCode();
630 echo $exception->getData();
631
632 die();
633 } else {
634
635 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
636 redirect('pay/' . $this->plan_id);
637
638 }
639 }
640
641 /* Make sure the transaction is not already existing */
642 if(Database::exists('id', 'payments', ['payment_id' => $payment_id, 'processor' => 'paypal'])) {
643 redirect('pay/' . $this->plan_id);
644 }
645
646 /* Make sure the payment is approved */
647 if($payment_status != 'approved') {
648 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
649 redirect('pay/' . $this->plan_id);
650 }
651
652 /* Make sure the chosen option comply */
653 if(!in_array($payment_frequency, ['monthly', 'annual', 'lifetime'])) {
654 redirect('pay/' . $this->plan_id);
655 }
656
657 /* Unsubscribe from the previous plan if needed */
658 if(!empty($this->user->payment_subscription_id) && $this->user->payment_subscription_id != $payment_subscription_id) {
659 try {
660 (new User(['settings' => $this->settings, 'user' => $this->user]))->cancel_subscription();
661 } catch (\Exception $exception) {
662
663 /* Output errors properly */
664 if (DEBUG) {
665 echo $exception->getCode() . '-' . $exception->getMessage();
666
667 die();
668 } else {
669 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
670 redirect('pay/' . $this->plan_id);
671 }
672
673 }
674 }
675
676 /* Make sure the code exists */
677 $codes_code = Database::get('*', 'codes', ['code' => $code, 'type' => 'discount']);
678
679 if($codes_code) {
680 $code = $codes_code->code;
681
682 /* Check if we should insert the usage of the code or not */
683 if(!Database::exists('id', 'redeemed_codes', ['user_id' => $this->user->user_id, 'code_id' => $codes_code->code_id])) {
684 /* Update the code usage */
685 $this->database->query("UPDATE `codes` SET `redeemed` = `redeemed` + 1 WHERE `code_id` = {$codes_code->code_id}");
686
687 /* Add log for the redeemed code */
688 Database::insert('redeemed_codes', [
689 'code_id' => $codes_code->code_id,
690 'user_id' => $this->user->user_id,
691 'date' => \Altum\Date::$date
692 ]);
693
694 Logger::users($this->user->user_id, 'codes.redeemed_code=' . $codes_code->code);
695 }
696 }
697
698 /* Add a log into the database */
699 Database::insert(
700 'payments',
701 [
702 'user_id' => $this->user->user_id,
703 'plan_id' => $this->plan_id,
704 'processor' => 'paypal',
705 'type' => $payment_type,
706 'frequency' => $payment_frequency,
707 'code' => $code,
708 'discount_amount' => $discount_amount,
709 'base_amount' => $base_amount,
710 'email' => $payer_email,
711 'payment_id' => $payment_id,
712 'subscription_id' => $subscription_id,
713 'payer_id' => $payer_id,
714 'name' => $payer_name,
715 'billing' => $this->settings->payment->taxes_and_billing_is_enabled && $this->user->billing ? json_encode($this->user->billing) : null,
716 'taxes_ids' => !empty($this->applied_taxes_ids) ? json_encode($this->applied_taxes_ids) : null,
717 'total_amount' => $payment_total,
718 'currency' => $payment_currency,
719 'date' => Date::$date
720 ],
721 false
722 );
723
724 /* Update the user with the new plan */
725 switch($payment_frequency) {
726 case 'monthly':
727 $plan_expiration_date = (new \DateTime())->modify('+30 days')->format('Y-m-d H:i:s');
728 break;
729
730 case 'annual':
731 $plan_expiration_date = (new \DateTime())->modify('+12 months')->format('Y-m-d H:i:s');
732 break;
733
734 case 'lifetime':
735 $plan_expiration_date = (new \DateTime())->modify('+100 years')->format('Y-m-d H:i:s');
736 break;
737 }
738
739 Database::update(
740 'users',
741 [
742 'plan_id' => $this->plan_id,
743 'plan_settings' => json_encode($this->plan->settings),
744 'plan_expiration_date' => $plan_expiration_date
745 ],
746 [
747 'user_id' => $this->user->user_id
748 ]
749 );
750
751 /* Send notification to the user */
752 /* Prepare the email */
753 $email_template = get_email_template(
754 [],
755 $this->language->global->emails->user_payment->subject,
756 [
757 '{{PACKAGE_EXPIRATION_DATE}}' => Date::get($plan_expiration_date, 2),
758 '{{USER_PACKAGE_LINK}}' => url('account-plan'),
759 '{{USER_PAYMENTS_LINK}}' => url('account-payments'),
760 ],
761 $this->language->global->emails->user_payment->body
762 );
763
764 send_mail(
765 $this->settings,
766 $this->user->email,
767 $email_template->subject,
768 $email_template->body
769 );
770
771 /* Send notification to admin if needed */
772 if($this->settings->email_notifications->new_payment && !empty($this->settings->email_notifications->emails)) {
773
774 send_mail(
775 $this->settings,
776 explode(',', $this->settings->email_notifications->emails),
777 sprintf($this->language->global->emails->admin_new_payment_notification->subject, 'paypal', $payment_total, $payment_currency),
778 sprintf($this->language->global->emails->admin_new_payment_notification->body, $payment_total, $payment_currency)
779 );
780
781 }
782
783 /* Success message and redirect */
784 $this->redirect_pay_thank_you();
785
786 }
787
788 /* Return confirmation processing recurring payment */
789 if(isset($_GET['token'], $_GET['payment_type'])) {
790
791 /* Initiate paypal */
792 $paypal = new \PayPal\Rest\ApiContext(new \PayPal\Auth\OAuthTokenCredential($this->settings->paypal->client_id, $this->settings->paypal->secret));
793 $paypal->setConfig(['mode' => $this->settings->paypal->mode]);
794
795 $token = $_GET['token'];
796 $agreement = new \PayPal\Api\Agreement();
797 $payment_type = 'recurring';
798
799 try {
800 $agreement->execute($token, $paypal);
801 } catch (Exception $exception) {
802
803 /* Output errors properly */
804 if (DEBUG) {
805 echo $exception->getCode();
806 echo $exception->getData();
807
808 die();
809 } else {
810
811 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
812 redirect('pay/' . $this->plan_id);
813
814 }
815 }
816
817 /* Get details about the executed agreement */
818 try {
819 $agreement = \PayPal\Api\Agreement::get($agreement->getId(), $paypal);
820 } catch (Exception $exception) {
821
822 /* Output errors properly */
823 if (DEBUG) {
824 echo $exception->getCode();
825 echo $exception->getData();
826
827 die();
828 } else {
829
830 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
831 redirect('pay/' . $this->plan_id);
832
833 }
834 }
835
836 /* Get the needed details from the agreement */
837 $agreement_status = $agreement->getState();
838
839 /* Make sure the payment is approved */
840 if($agreement_status != 'Active' && $agreement_status != 'Pending') {
841 $_SESSION['error'][] = $this->language->pay->error_message->failed_payment;
842 redirect('pay/' . $this->plan_id);
843 }
844
845 /* Success message and redirect */
846 $this->redirect_pay_thank_you();
847
848 }
849
850 }
851
852
853 /* Return confirmation processing if failed */
854 if($this->return_type && $this->payment_processor && $this->return_type == 'cancel' && $this->payment_processor = 'paypal') {
855 $_SESSION['error'][] = $this->language->pay->error_message->canceled_payment;
856 redirect('pay/' . $this->plan_id);
857 }
858
859 }
860
861 private function stripe_create() {
862 // $this->payment_processor = $_GET['payment_processor'];
863 // echo $payment_processor ; exit;
864 // $this->redirect_pay_thank_you();
865 $price = $base_amount = (float) $this->plan->{$_POST['payment_frequency'] . '_price'};
866 $payment_frequency = $_POST['payment_frequency'];
867 if($payment_frequency == 'monthly') $name_detail = 'Pembayaran 1 Bulan Alink.id';
868 elseif($payment_frequency == 'annual') $name_detail = 'Pembayaran 1 Tahun Alink.id';
869 else $name_detail = 'Pembayaran Alink.id Selamanya';
870 $name = $this->user->name;
871 $mail = $this->user->email;
872 // echo $mail;exit;
873
874 // echo $payment_frequency;exit;
875 // echo $price;exit;
876 \Midtrans\Config::$serverKey = 'SB-Mid-server-NzzSoFLl5yluRA2J8tzgtT6Q';
877 // Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
878 \Midtrans\Config::$isProduction = false;
879 // Set sanitization on (default)
880 \Midtrans\Config::$isSanitized = true;
881 // Set 3DS transaction for credit card to true
882 \Midtrans\Config::$is3ds = true;
883
884 $transaction_details = array(
885 'order_id' => rand(),
886 'gross_amount' =>$price, // no decimal allowed for creditcard
887 );
888
889 // Optional
890 $item1_details = array(
891 'id' => rand(),
892 'price' => $price,
893 'quantity' => 1,
894 'name' => $name_detail
895 );
896
897 // Optional
898 $item_details = array ($item1_details);
899
900
901 // Optional
902 $customer_details = array(
903 'first_name' => $name,
904 'email' => $mail
905 // 'phone' => "081122334455",
906 // 'billing_address' => $billing_address,
907 // 'shipping_address' => $shipping_address
908 );
909
910 // Fill SNAP API parameter
911 $params = array(
912 'transaction_details' => $transaction_details,
913 'customer_details' => $customer_details,
914 'item_details' => $item_details,
915 );
916 // echo '1';exit;
917 try {
918 // Get Snap Payment Page URL
919 $paymentUrl = Snap::createTransaction($params)->redirect_url;
920 // echo $paymentUrl;exit;
921 // $gopay = $paymentUrl.'?'.'language=en&gopayMode=deeplink';
922
923 // Redirect to Snap Payment Page
924 header('Location: ' . $paymentUrl);
925 }
926 catch (Exception $e) {
927 echo $e->getMessage();
928 }
929 // redirect('pay/' . $this->plan_id);
930
931 // 'success_url' => url('pay/' . $this->plan_id . $this->return_url_parameters('success', $base_amount, $price, $code, $discount_amount)),
932 // 'cancel_url' => url('pay/' . $this->plan_id . $this->return_url_parameters('cancel', $base_amount, $price, $code, $discount_amount)),
933 }
934
935 private function stripe_process() {
936
937 /* Return confirmation processing if successfuly */
938 if($this->return_type && $this->payment_processor && $this->return_type == 'success' && $this->payment_processor = 'stripe') {
939
940 /* Redirect to the thank you page */
941 $this->redirect_pay_thank_you();
942 }
943
944 /* Return confirmation processing if failed */
945 if($this->return_type && $this->payment_processor && $this->return_type == 'cancel' && $this->payment_processor = 'stripe') {
946 $_SESSION['error'][] = $this->language->pay->error_message->canceled_payment;
947 redirect('pay/' . $this->plan_id);
948 }
949
950 }
951
952 private function stripe_gopay_create() {
953 // echo 'sudah disini';exit;
954 // // $this->payment_processor = $_GET['payment_processor'];
955 // // echo $payment_processor ; exit;
956 // // $this->redirect_pay_thank_you();
957 // $price = $base_amount = (float) $this->plan->{$_POST['payment_frequency'] . '_price'};
958 // // echo $price;exit;
959 // $payment_frequency = $_POST['payment_frequency'];
960 // if($payment_frequency == 'monthly') $name_detail = 'Pembayaran 1 Bulan Alink.id';
961 // elseif($payment_frequency == 'annual') $name_detail = 'Pembayaran 1 Tahun Alink.id';
962 // else $name_detail = 'Pembayaran Alink.id Selamanya';
963 // $name = $this->user->name;
964 // $mail = $this->user->email;
965 $price = $base_amount = $this->plan->{$_POST['payment_frequency'] . '_price'};
966 $code = '';
967 $discount_amount = 0;
968
969 /* Check for code usage */
970 if($this->code) {
971
972 /* Discount amount */
973 $discount_amount = number_format(($price * $this->code->discount / 100), 2, '.', '');
974
975 /* Calculate the new price */
976 $price = $price - $discount_amount;
977
978 $code = $this->code->code;
979
980 }
981 $payment_id = md5($this->user->user_id . $this->plan_id . $_POST['payment_type'] . $_POST['payment_frequency'] . $this->user->email . Date::$date);
982
983 // echo $payment_frequency;exit;
984 // echo $price;exit;
985 \Midtrans\Config::$serverKey = 'SB-Mid-server-NzzSoFLl5yluRA2J8tzgtT6Q';
986 // Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
987 \Midtrans\Config::$isProduction = false;
988 // Set sanitization on (default)
989 \Midtrans\Config::$isSanitized = true;
990 // Set 3DS transaction for credit card to true
991 \Midtrans\Config::$is3ds = true;
992
993 $transaction_details = array(
994 'order_id' => $payment_id,
995 'gross_amount' => $this->plan->{$_POST['payment_frequency'] . '_price'}, // no decimal allowed for creditcard
996 );
997 $item_details = array (
998 array(
999 'id' => $this->plan_id,
1000 'price' => $this->plan->{$_POST['payment_frequency'] . '_price'},
1001 'quantity' => 1,
1002 'name' => $this->plan->name
1003 ),
1004 );
1005 $customer_details = array(
1006 'first_name' => $this->user->name,
1007 'last_name' => '',
1008 'email' => $this->user->email,
1009 'phone' => $this->user->billing->phone,
1010 'billing_address' => '',
1011 'shipping_address' => ''
1012 );
1013 $params = array(
1014 'transaction_details' => $transaction_details,
1015 'customer_details' => $customer_details,
1016 'item_details' => $item_details,
1017 );
1018 try {
1019 Database::insert(
1020 'payments',
1021 [
1022 'user_id' => $this->user->user_id,
1023 'plan_id' => $this->plan_id,
1024 'processor' => 'GoPay / QRIS',
1025 'type' => $_POST['payment_type'],
1026 'frequency' => $_POST['payment_frequency'],
1027 'code' => $code,
1028 'discount_amount' => $discount_amount,
1029 'base_amount' => $base_amount,
1030 'email' => $this->user->email,
1031 'payment_id' => $payment_id,
1032 'subscription_id' => '',
1033 'payer_id' => $this->user->user_id,
1034 'name' => $this->user->name,
1035 'billing' => $this->settings->payment->taxes_and_billing_is_enabled && $this->user->billing ? json_encode($this->user->billing) : null,
1036 'taxes_ids' => !empty($this->applied_taxes_ids) ? json_encode($this->applied_taxes_ids) : null,
1037 'total_amount' => $price,
1038 'currency' => $this->settings->payment->currency,
1039 'payment_proof' => null,
1040 'status' => 0,
1041 'date' => Date::$date
1042 ],
1043 false
1044 );
1045 Database::insert(
1046 'payment_details',
1047 [
1048 'payment_id' => $payment_id,
1049 ],
1050 false
1051 );
1052 $paymentUrl = Snap::createTransaction($params)->redirect_url;
1053 // echo $paymentUrl;exit;
1054 // $gopay = $paymentUrl.'?'.'language=en&gopayMode=deeplink';
1055
1056 // Redirect to Snap Payment Page
1057 header('Location: ' . $paymentUrl.'#/gopay-qris');
1058 }
1059 catch (Exception $e) {
1060 echo $e->getMessage();
1061 }
1062 // // redirect('pay/' . $this->plan_id);
1063
1064 // // 'success_url' => url('pay/' . $this->plan_id . $this->return_url_parameters('success', $base_amount, $price, $code, $discount_amount)),
1065 // // 'cancel_url' => url('pay/' . $this->plan_id . $this->return_url_parameters('cancel', $base_amount, $price, $code, $discount_amount)),
1066 }
1067
1068 private function stripe_gopay_process() {
1069
1070 /* Return confirmation processing if successfuly */
1071 if($this->return_type && $this->payment_processor && $this->return_type == 'success' && $this->payment_processor = 'stripe_gopay') {
1072
1073 /* Redirect to the thank you page */
1074 $this->redirect_pay_thank_you();
1075 }
1076
1077 /* Return confirmation processing if failed */
1078 if($this->return_type && $this->payment_processor && $this->return_type == 'cancel' && $this->payment_processor = 'stripe_gopay') {
1079 $_SESSION['error'][] = $this->language->pay->error_message->canceled_payment;
1080 redirect('pay/' . $this->plan_id);
1081 }
1082
1083 }
1084
1085 private function stripe_va_create() {
1086 // echo 'sudah disini';exit;
1087 // // $this->payment_processor = $_GET['payment_processor'];
1088 // // echo $payment_processor ; exit;
1089 // // $this->redirect_pay_thank_you();
1090 $price = $base_amount = $this->plan->{$_POST['payment_frequency'] . '_price'};
1091 $code = '';
1092 $discount_amount = 0;
1093
1094 /* Check for code usage */
1095 if($this->code) {
1096
1097 /* Discount amount */
1098 $discount_amount = number_format(($price * $this->code->discount / 100), 2, '.', '');
1099
1100 /* Calculate the new price */
1101 $price = $price - $discount_amount;
1102
1103 $code = $this->code->code;
1104
1105 }
1106 $payment_id = md5($this->user->user_id . $this->plan_id . $_POST['payment_type'] . $_POST['payment_frequency'] . $this->user->email . Date::$date);
1107
1108 // echo $payment_frequency;exit;
1109 // echo $price;exit;
1110 \Midtrans\Config::$serverKey = 'SB-Mid-server-NzzSoFLl5yluRA2J8tzgtT6Q';
1111 // Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
1112 \Midtrans\Config::$isProduction = false;
1113 // Set sanitization on (default)
1114 \Midtrans\Config::$isSanitized = true;
1115 // Set 3DS transaction for credit card to true
1116 \Midtrans\Config::$is3ds = true;
1117
1118 $transaction_details = array(
1119 'order_id' => $payment_id,
1120 'gross_amount' => $this->plan->{$_POST['payment_frequency'] . '_price'}, // no decimal allowed for creditcard
1121 );
1122 $item_details = array (
1123 array(
1124 'id' => $this->plan_id,
1125 'price' => $this->plan->{$_POST['payment_frequency'] . '_price'},
1126 'quantity' => 1,
1127 'name' => $this->plan->name
1128 ),
1129 );
1130 $customer_details = array(
1131 'first_name' => $this->user->name,
1132 'last_name' => '',
1133 'email' => $this->user->email,
1134 'phone' => $this->user->billing->phone,
1135 'billing_address' => '',
1136 'shipping_address' => ''
1137 );
1138 $params = array(
1139 'transaction_details' => $transaction_details,
1140 'customer_details' => $customer_details,
1141 'item_details' => $item_details,
1142 );
1143 try {
1144 Database::insert(
1145 'payments',
1146 [
1147 'user_id' => $this->user->user_id,
1148 'plan_id' => $this->plan_id,
1149 'processor' => 'Virtual Account',
1150 'type' => $_POST['payment_type'],
1151 'frequency' => $_POST['payment_frequency'],
1152 'code' => $code,
1153 'discount_amount' => $discount_amount,
1154 'base_amount' => $base_amount,
1155 'email' => $this->user->email,
1156 'payment_id' => $payment_id,
1157 'subscription_id' => '',
1158 'payer_id' => $this->user->user_id,
1159 'name' => $this->user->name,
1160 'billing' => $this->settings->payment->taxes_and_billing_is_enabled && $this->user->billing ? json_encode($this->user->billing) : null,
1161 'taxes_ids' => !empty($this->applied_taxes_ids) ? json_encode($this->applied_taxes_ids) : null,
1162 'total_amount' => $price,
1163 'currency' => $this->settings->payment->currency,
1164 'payment_proof' => null,
1165 'status' => 0,
1166 'date' => Date::$date
1167 ],
1168 false
1169 );
1170 Database::insert(
1171 'payment_details',
1172 [
1173 'payment_id' => $payment_id,
1174 ],
1175 false
1176 );
1177 $paymentUrl = Snap::createTransaction($params)->redirect_url;
1178 // echo $paymentUrl;exit;
1179 // $gopay = $paymentUrl.'?'.'language=en&gopayMode=deeplink';
1180
1181 // Redirect to Snap Payment Page
1182 header('Location: ' . $paymentUrl.'#/bank-transfer');
1183 }
1184 catch (Exception $e) {
1185 echo $e->getMessage();
1186 }
1187 // // redirect('pay/' . $this->plan_id);
1188
1189 // // 'success_url' => url('pay/' . $this->plan_id . $this->return_url_parameters('success', $base_amount, $price, $code, $discount_amount)),
1190 // // 'cancel_url' => url('pay/' . $this->plan_id . $this->return_url_parameters('cancel', $base_amount, $price, $code, $discount_amount)),
1191 }
1192
1193 private function stripe_va_process() {
1194
1195 /* Return confirmation processing if successfuly */
1196 if($this->return_type && $this->payment_processor && $this->return_type == 'success' && $this->payment_processor = 'stripe_va') {
1197
1198 /* Redirect to the thank you page */
1199 $this->redirect_pay_thank_you();
1200 }
1201
1202 /* Return confirmation processing if failed */
1203 if($this->return_type && $this->payment_processor && $this->return_type == 'cancel' && $this->payment_processor = 'stripe_va') {
1204 $_SESSION['error'][] = $this->language->pay->error_message->canceled_payment;
1205 redirect('pay/' . $this->plan_id);
1206 }
1207
1208 }
1209
1210 private function stripe_alfa_create() {
1211 // echo 'sudah disini';exit;
1212 // // $this->payment_processor = $_GET['payment_processor'];
1213 // // echo $payment_processor ; exit;
1214 // // $this->redirect_pay_thank_you();
1215 $price = $base_amount = $this->plan->{$_POST['payment_frequency'] . '_price'};
1216 $code = '';
1217 $discount_amount = 0;
1218
1219 /* Check for code usage */
1220 if($this->code) {
1221
1222 /* Discount amount */
1223 $discount_amount = number_format(($price * $this->code->discount / 100), 2, '.', '');
1224
1225 /* Calculate the new price */
1226 $price = $price - $discount_amount;
1227
1228 $code = $this->code->code;
1229
1230 }
1231 $payment_id = md5($this->user->user_id . $this->plan_id . $_POST['payment_type'] . $_POST['payment_frequency'] . $this->user->email . Date::$date);
1232
1233 // echo $payment_frequency;exit;
1234 // echo $price;exit;
1235 \Midtrans\Config::$serverKey = 'SB-Mid-server-NzzSoFLl5yluRA2J8tzgtT6Q';
1236 // Set to Development/Sandbox Environment (default). Set to true for Production Environment (accept real transaction).
1237 \Midtrans\Config::$isProduction = false;
1238 // Set sanitization on (default)
1239 \Midtrans\Config::$isSanitized = true;
1240 // Set 3DS transaction for credit card to true
1241 \Midtrans\Config::$is3ds = true;
1242
1243 $transaction_details = array(
1244 'order_id' => $payment_id,
1245 'gross_amount' => $this->plan->{$_POST['payment_frequency'] . '_price'}, // no decimal allowed for creditcard
1246 );
1247 $item_details = array (
1248 array(
1249 'id' => $this->plan_id,
1250 'price' => $this->plan->{$_POST['payment_frequency'] . '_price'},
1251 'quantity' => 1,
1252 'name' => $this->plan->name
1253 ),
1254 );
1255 $customer_details = array(
1256 'first_name' => $this->user->name,
1257 'last_name' => '',
1258 'email' => $this->user->email,
1259 'phone' => $this->user->billing->phone,
1260 'billing_address' => '',
1261 'shipping_address' => ''
1262 );
1263 $params = array(
1264 'transaction_details' => $transaction_details,
1265 'customer_details' => $customer_details,
1266 'item_details' => $item_details,
1267 );
1268 try {
1269 Database::insert(
1270 'payments',
1271 [
1272 'user_id' => $this->user->user_id,
1273 'plan_id' => $this->plan_id,
1274 'processor' => 'Alfa Group',
1275 'type' => $_POST['payment_type'],
1276 'frequency' => $_POST['payment_frequency'],
1277 'code' => $code,
1278 'discount_amount' => $discount_amount,
1279 'base_amount' => $base_amount,
1280 'email' => $this->user->email,
1281 'payment_id' => $payment_id,
1282 'subscription_id' => '',
1283 'payer_id' => $this->user->user_id,
1284 'name' => $this->user->name,
1285 'billing' => $this->settings->payment->taxes_and_billing_is_enabled && $this->user->billing ? json_encode($this->user->billing) : null,
1286 'taxes_ids' => !empty($this->applied_taxes_ids) ? json_encode($this->applied_taxes_ids) : null,
1287 'total_amount' => $price,
1288 'currency' => $this->settings->payment->currency,
1289 'payment_proof' => null,
1290 'status' => 0,
1291 'date' => Date::$date
1292 ],
1293 false
1294 );
1295 Database::insert(
1296 'payment_details',
1297 [
1298 'payment_id' => $payment_id,
1299 ],
1300 false
1301 );
1302 $paymentUrl = Snap::createTransaction($params)->redirect_url;
1303 // echo $paymentUrl;exit;
1304 // $gopay = $paymentUrl.'?'.'language=en&gopayMode=deeplink';
1305
1306 // Redirect to Snap Payment Page
1307 header('Location: ' . $paymentUrl.'#/alfamart/payment-code-charge');
1308 }
1309 catch (Exception $e) {
1310 echo $e->getMessage();
1311 }
1312 // // redirect('pay/' . $this->plan_id);
1313
1314 // // 'success_url' => url('pay/' . $this->plan_id . $this->return_url_parameters('success', $base_amount, $price, $code, $discount_amount)),
1315 // // 'cancel_url' => url('pay/' . $this->plan_id . $this->return_url_parameters('cancel', $base_amount, $price, $code, $discount_amount)),
1316 }
1317
1318 private function stripe_alfa_process() {
1319
1320 /* Return confirmation processing if successfuly */
1321 if($this->return_type && $this->payment_processor && $this->return_type == 'success' && $this->payment_processor = 'stripe_alfa') {
1322
1323 /* Redirect to the thank you page */
1324 $this->redirect_pay_thank_you();
1325 }
1326
1327 /* Return confirmation processing if failed */
1328 if($this->return_type && $this->payment_processor && $this->return_type == 'cancel' && $this->payment_processor = 'stripe_alfa') {
1329 $_SESSION['error'][] = $this->language->pay->error_message->canceled_payment;
1330 redirect('pay/' . $this->plan_id);
1331 }
1332
1333 }
1334
1335
1336
1337 /* Ajax to check if discount codes are available */
1338
1339 /* Generate the generic return url parameters */
1340 private function return_url_parameters($return_type, $base_amount, $total_amount, $code, $discount_amount) {
1341 return
1342 '&return_type=' . $return_type
1343 . '&payment_processor=' . $_POST['payment_processor']
1344 . '&payment_frequency=' . $_POST['payment_frequency']
1345 . '&payment_type=' . $_POST['payment_type']
1346 . '&code=' . $code
1347 . '&discount_amount=' . $discount_amount
1348 . '&base_amount=' . $base_amount
1349 . '&total_amount=' . $total_amount;
1350 }
1351
1352 /* Simple url generator to return the thank you page */
1353 private function redirect_pay_thank_you() {
1354 $thank_you_url_parameters_raw = array_filter($_GET, function($key) {
1355 return $key != 'altum';
1356 }, ARRAY_FILTER_USE_KEY);
1357
1358 $thank_you_url_parameters = '&plan_id=' . $this->plan_id;
1359 $thank_you_url_parameters .= '&user_id=' . $this->user->user_id;
1360
1361 foreach($thank_you_url_parameters_raw as $key => $value) {
1362 $thank_you_url_parameters .= '&' . $key . '=' . $value;
1363 }
1364
1365 $thank_you_url_parameters .= '&unique_transaction_identifier=' . md5(\Altum\Date::get('', 4) . $thank_you_url_parameters);
1366
1367 redirect('pay-thank-you?' . $thank_you_url_parameters);
1368 }
1369}