<?php

	class Payment {
		protected $db;
		private $method;
		private $type;
		
		public function __construct($connection, $type = "request") {
			$this->db = $connection;
			$this->type = $type;
			$this->method = $this->db->query("SELECT * FROM `payment_methods` WHERE method_id = ".PAYMENT_METHOD."")->fetch(PDO::FETCH_ASSOC);
		}
		
		public function PayTR($user = null, $amount = null, $phone = null) {
		    
		    global $db;
		    
			$data = json_decode($this->method["method_details"], true);
			
			if($this->type == "request") {

				if($user && $amount) {
					$merchant_id 	= $data["mid"];
					$merchant_key 	= $data["key"];
					$merchant_salt	= $data["salt"];
					$email = $user["user_email"];
					$payment_amount	= $amount * 100;
					$merchant_oid = uniqid().$user["user_id"];
					$user_name = $user["user_first_name"]." ".$user["user_last_name"];
					$user_address = "Belirtilmemiş";
					$user_phone = $phone;
					$merchant_ok_url = site($siteLinks['add-funds']['url']);
					$merchant_fail_url = site($siteLinks['add-funds']['url']);
					$user_basket = base64_encode(json_encode(array(
						array("Add Funds", $amount, 1)
					)));
					if(isset($_SERVER["HTTP_CLIENT_IP"])) {
						$ip = $_SERVER["HTTP_CLIENT_IP"];
					} elseif(isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {
						$ip = $_SERVER["HTTP_X_FORWARDED_FOR"];
					} else {
						$ip = $_SERVER["REMOTE_ADDR"];
					}
					$user_ip = $ip;
					$debug_on = 0;
					$no_installment	= 1;
					$max_installment = 0;
					$currency = "TL";
					$test_mode = 0;
					$timeout_limit = 30;
					$hash_str = $merchant_id .$user_ip .$merchant_oid .$email .$payment_amount .$user_basket.$no_installment.$max_installment.$currency.$test_mode;
					$paytr_token=base64_encode(hash_hmac('sha256',$hash_str.$merchant_salt,$merchant_key,true));
					$post_vals=array(
						'merchant_id'=>$merchant_id,
						'user_ip'=>$user_ip,
						'merchant_oid'=>$merchant_oid,
						'email'=>$email,
						'payment_amount'=>$payment_amount,
						'paytr_token'=>$paytr_token,
						'user_basket'=>$user_basket,
						'debug_on'=>$debug_on,
						'no_installment'=>$no_installment,
						'max_installment'=>$max_installment,
						'user_name'=>$user_name,
						'user_address'=>$user_address,
						'user_phone'=>$user_phone,
						'merchant_ok_url'=>$merchant_ok_url,
						'merchant_fail_url'=>$merchant_fail_url,
						'timeout_limit'=>$timeout_limit,
						'currency'=>$currency,
						'test_mode'=>$test_mode
					);
					
						
					
					$ch = curl_init();
					curl_setopt($ch, CURLOPT_URL, "https://www.paytr.com/odeme/api/get-token");//"https://www.paytr.com/odeme/api/get-token"
					curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
					curl_setopt($ch, CURLOPT_POST, 1) ;
					curl_setopt($ch, CURLOPT_POSTFIELDS, $post_vals);
					curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
					curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
					curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
					curl_setopt($ch, CURLOPT_TIMEOUT, 20);
					$result = @curl_exec($ch);

                    

					if(curl_errno($ch))
						return [
							"status" => false,
							"message" => "{TECHNICAL_FAILURE}"
						];
					curl_close($ch);
					
					$jsonDecode=json_decode($result, false);
					
					if($jsonDecode->status == 'success') {
					    
						$query = $this->db->prepare("INSERT INTO `deposits` SET user_id = ?, order_id = ?, deposit_date = ?, deposit_method = ?, deposit_amount = ?, deposit_status = ?");
						$insert_order = $query->execute([$user["user_id"], $merchant_oid, time(), PAYMENT_METHOD, $amount, 2]);
						if($insert_order) {
							return [
								"status" => true,
								"location" => "https://www.paytr.com/odeme/guvenli/".$jsonDecode->token
							];
						} else {
							return [
								"status" => false,
								"message" => "{TECHNICAL_FAILURE}"
							];
						}
					} else {
						return [
							"status" => false,
							"message" => $jsonDecode->reason
						];
					}
				} else {
					return [
						"status" => false,
						"message" => "{TECHNICAL_FAILURE}"
					];
				}
			} elseif($this->type == "notify") {
				$merchant_key 	= $data["key"];
				$merchant_salt	= $data["salt"];
				$posts = [
					"merchant_oid" => true,
					"status" => true,
					"total_amount" => true,
					"hash" => true
				];
				$error = false;
				foreach($posts as $post => $required) {
					if($required) {
						if(isset($_POST[$post]) && filter($_POST[$post]) != null) {
							$$post = filter($_POST[$post]);
						} else {
							$error = true;
							break;
						}
					} else {
						if(isset($_POST[$post])) {
							$$post = filter($_POST[$post]);
						} else {
							$error = true;
							break;
						}
					}
				}
			    
				if(!$error) {
					$created_hash = base64_encode( hash_hmac('sha256', $merchant_oid.$merchant_salt.$status.$total_amount, $merchant_key, true) );
					if($created_hash != $hash) {
						die('PAYTR notification failed: bad hash');
					} else {
						$query = $this->db->prepare("SELECT * FROM `deposits` WHERE deposit_method = ? AND order_id = ?");
						$query->execute([PAYMENT_METHOD, $merchant_oid]);
						if($query->rowCount()) {
							$deposit = $query->fetch(PDO::FETCH_ASSOC);
							if($deposit["deposit_status"] == 2) {
								if($status == "success") {
									$query = $this->db->prepare("SELECT * FROM `users` WHERE user_id = ?");
									$query->execute([$deposit["user_id"]]);
									if($query->rowCount()) {
										$user = $query->fetch(PDO::FETCH_ASSOC);
										$amount = $total_amount / 100;
										$balance = $user["user_balance"] + $amount;
										$this->db->beginTransaction();
										$query = $this->db->prepare("UPDATE `users` SET user_balance = ? WHERE user_id = ?");
										$update_user = $query->execute([$balance, $user["user_id"]]);
										$query = $this->db->prepare("UPDATE `deposits` SET deposit_status = 1 WHERE deposit_method = ? AND order_id = ?");
										$update_deposit = $query->execute([PAYMENT_METHOD, $merchant_oid]);
										if($update_user && $update_deposit) {
											reference($db, $user["user_id"], $amount);
											$this->db->commit();
											die("OK");
										} else {
											$this->db->rollBack();
											die("OK");
										}
									} else {
										die("OK");
									}
								} else {
									$query = $this->db->prepare("UPDATE `deposits` SET deposit_status = 0 WHERE deposit_method = ? AND order_id = ?");
									$update_deposit = $query->execute([PAYMENT_METHOD, $merchant_oid]);
								}
							} else {
								die("OK");
							}
						} else {
							die("OK");
						}
					}
				}
			}
		}
		
		public function Buypayer($user = null, $amount = null) {
			$data = json_decode($this->method["method_details"], true);
			if($this->type == "request") {
				if($user && $amount) {
					$merchant_oid = uniqid().$user["user_id"];
					$query = $this->db->prepare("INSERT INTO `deposits` SET user_id = ?, order_id = ?, deposit_date = ?, deposit_method = ?, deposit_amount = ?, deposit_status = ?");
					$insert_order = $query->execute([$user["user_id"], $merchant_oid, time(), PAYMENT_METHOD, $amount, 2]);
					if($insert_order) {
						$order_id = $merchant_oid;
						$postUrl='https://www.buypayer.com/receiveper.asp';
						$mid = $data["mid"];
						$mcode = $data["mcode"];
						$email	= $data["email"];
						$xmlString='xml=<send>
							<mgzid>'.$mid.'</mgzid>
							<itt>'.$amount.'</itt>
							<sipid>'.$order_id.'</sipid>
							<urunadi>Add Funds</urunadi>
							<gvk>'.$mcode.'</gvk>
							<uyemail>'.$email.'</uyemail>
							</send>';
						$Veriler = $xmlString;
						$ch = curl_init();
						curl_setopt($ch, CURLOPT_URL, $postUrl);
						curl_setopt($ch, CURLOPT_POST, 1);
						curl_setopt($ch, CURLOPT_POSTFIELDS, $Veriler);
						curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
						curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,0);
						curl_setopt($ch, CURLOPT_TIMEOUT, 30);
						$responsee = curl_exec($ch);
						curl_close($ch);
						return [
							"status" => true,
							"location" => $responsee
						];
					} else {
						return [
							"status" => false,
							"message" => "{TECHNICAL_FAILURE}"
						];
					}
				} else {
					return [
						"status" => false,
						"message" => "{TECHNICAL_FAILURE}"
					];
				}
			} elseif($this->type == "notify") {
				$guvenlik = $data["mcode"];
				$posts = [
					"sipid" => true,
					"sifre" => true,
					"itt" => true,
					"opr" => true
				];
				$error = false;
				foreach($posts as $post => $required) {
					if($required) {
						if(isset($_POST[$post]) && filter($_POST[$post]) != null) {
							$$post = filter($_POST[$post]);
						} else {
							$error = true;
							break;
						}
					} else {
						if(isset($_POST[$post])) {
							$$post = filter($_POST[$post]);
						} else {
							$error = true;
							break;
						}
					}
				}
				if(!$error) {
					if($guvenlik == $sifre) {
						if($opr == "success") {
							$query = $this->db->prepare("SELECT * FROM `deposits` WHERE deposit_method = ? AND order_id = ?");
							$query->execute([PAYMENT_METHOD, $sipid]);
							if($query->rowCount()) {
								$deposit = $query->fetch(PDO::FETCH_ASSOC);
								if($deposit["deposit_status"] == 2) {
									$query = $this->db->prepare("SELECT * FROM `users` WHERE user_id = ?");
									$query->execute([$deposit["user_id"]]);
									if($query->rowCount()) {
										$user = $query->fetch(PDO::FETCH_ASSOC);
										$balance = $user["user_balance"] + $deposit["deposit_amount"];
										$this->db->beginTransaction();
										$query = $this->db->prepare("UPDATE `users` SET user_balance = ? WHERE user_id = ?");
										$update_user = $query->execute([$balance, $user["user_id"]]);
										$query = $this->db->prepare("UPDATE `deposits` SET deposit_status = 1 WHERE deposit_method = ? AND order_id = ?");
										$update_deposit = $query->execute([PAYMENT_METHOD, $sipid]);
										if($update_user && $update_deposit) {
											reference($db, $user["user_id"], $deposit["deposit_amount"]);
											$this->db->commit();
											die("OK");
										} else {
											$this->db->rollBack();
											die("OK");
										}
									}
								}
							}
							die("OK");
						}
					}
				}
			}
		}

		public function shopier($user = null, $amount = null) {

			global $db;

			$data = json_decode($this->method["method_details"], true);
			
			if($this->type == "request") {

				if($user && $amount) {

					$shopier = new Shopier($data["key"], $data["secret"]);

					$shopier->setBuyer([
						'id' => $user["user_id"],
						'first_name' => $user["user_first_name"], 
						'last_name' => $user["user_last_name"], 
						'email' => $user["user_email"], 
						'phone' => $user["user_skype"]
					]);

					$shopier->setOrderBilling([
						'billing_address' => 'NA',
						'billing_city' => 'NA',
						'billing_country' => 'Turkey',
						'billing_postcode' => '35000',
					]);

					$shopier->setOrderShipping([
						'shipping_address' => 'NA',
						'shipping_city' => 'NA',
						'shipping_country' => 'Turkey',
						'shipping_postcode' => '35000',
					]);

					$orderid = uniqid().$user["user_id"];

					$insert_order = $db->insert('deposits')
					->set(array(
						'user_id' => $user["user_id"],
						'order_id' => $orderid,
						'deposit_date' => time(),
						'deposit_method' => PAYMENT_METHOD,
						'deposit_amount' => $amount,
					));

					if($insert_order){

						$getPay = $shopier->run($orderid, $amount, site.'notify/shopier');

						if($getPay){

							return [
								"method" => 'shopier',
								"status" => true,
								"order" => $getPay
							];

						}else{

							return [
								"status" => false,
								"message" => "{TECHNICAL_FAILURE}"
							];

						}

					}else{

						return [
							"status" => false,
							"message" => "{TECHNICAL_FAILURE}"
						];

					}

				} else {

					return [
						"status" => false,
						"message" => "{TECHNICAL_FAILURE}"
					];

				}

			} elseif($this->type == "notify") {

				$posts = [
					'platform_order_id' =>  $_POST['platform_order_id'],
					'API_key' =>  $_POST['API_key'],
					'status' =>  $_POST['status'],
					'installment' =>  $_POST['installment'],
					'payment_id' =>  $_POST['payment_id'],
					'random_nr' =>  $_POST['random_nr'],
					'signature' =>  $_POST['signature']
				];

				$shopier = new Shopier($data["key"], $data["secret"]);

				$verifyPayment = verifyShopierSignature($posts);

				if($verifyPayment){

					$query = $db->from('deposits')
					->where('order_id', $posts['platform_order_id'])
					->where('deposit_method', PAYMENT_METHOD)
					->all();

					if($query){

						if($query['deposit_status'] == 2){

							if($posts['status'] == "success"){

								$userQuery = $db->from('users')->where('user_id', $query['user_id'])->first();

								if($userQuery){

									$newBalance = $userQuery['user_balance']+$query['deposit_amount'];
									$updateBalance = $db->update('users')
									->where('user_id', $query['user_id'])
									->set(array(
										'user_balance' => $newBalance
									));

									$updateDeposit = $db->update('deposits')
									->where('order_id', $posts['platform_order_id'])
									->where('deposit_method', PAYMENT_METHOD)
									->set(array(
										'deposit_status' => 1
									));

									if($updateBalance && $updateDeposit){

										reference($db, $userQuery["user_id"], $amount);
										die("OK");

									}else{

										die("ERROR");

									}


								}else{

									die("ERROR");

								}

							}else{

								die("ERROR");

							}

						}else{

							die("ERROR");

						}

					}else{

						die("ERROR");

					}


				}else{

					die("ERROR");

				}
				
			}

		}
		
		public function Paywant($user = null, $amount = null) {
			$data = json_decode($this->method["method_details"], true);
			if($this->type == "request") {
				if($user && $amount) {
					$apiKey		= $data["key"];
					$apiSecret 	= $data["secret"];
					$userID		= $user["user_id"];
					$userEmail	= $user["user_email"];
					$returnData	= $user["user_email"];
					$userIPAdresi = $_SERVER['REMOTE_ADDR'];
					$hashOlustur = base64_encode(hash_hmac('sha256',"$returnData|$userEmail|$userID".$apiKey,$apiSecret,true));
					$productData = array(
						"name" =>  "Bakiye Yükleme",
						"amount" => $amount * 100,
						"extraData" => $amount,
						"paymentChannel" => "2,3",
						"commissionType" => 2
					);
					$postData = array(
						'apiKey' => $apiKey,
						'hash' => $hashOlustur,
						'returnData'=> $returnData,
						'userEmail' => $userEmail,
						'userIPAddress' => $userIPAdresi,
						'userID' => $userID,
						'proApi' => true,
						'productData' => $productData
					);
					$curl = curl_init();
					curl_setopt_array($curl, array(
						CURLOPT_URL => "http://api.paywant.com/gateway.php",
						CURLOPT_RETURNTRANSFER => true,
						CURLOPT_ENCODING => "",
						CURLOPT_MAXREDIRS => 10,
						CURLOPT_TIMEOUT => 30,
						CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
						CURLOPT_CUSTOMREQUEST => "POST",
						CURLOPT_POSTFIELDS =>  http_build_query($postData),
					));
					$return = curl_exec($curl);
					$err = curl_error($curl);
					curl_close($curl);
					if($err) {
						return [
							"status" => false,
							"message" => $err
						];
					} else {
						$jsonDecode = json_decode($return, false);
						if($jsonDecode->Status == 100) {
							if(!strpos($jsonDecode->Message,"https")) {
								$jsonDecode->Message = str_replace("http","https",$jsonDecode->Message);
							}
							return [
								"status" => true,
								"location" => $jsonDecode->Message
							];
						} else {
							return [
								"status" => false,
								"message" => "{TECHNICAL_FAILURE}"
							];
						}
					}
				} else {
					return [
						"status" => false,
						"message" => "{TECHNICAL_FAILURE}"
					];
				}
			} elseif($this->type == "notify") {
				$apiKey = $data["key"];
				$apiSecret = $data["secret"];
				$posts = [
					"SiparisID" => true,
					"ExtraData" => true,
					"UserID" => true,
					"ReturnData" => true,
					"Status" => true,
					"OdemeKanali" => true,
					"OdemeTutari" => true,
					"NetKazanc" => true,
					"Hash" => true
				];
				$error = false;
				foreach($posts as $post => $required) {
					if($required) {
						if(isset($_POST[$post]) && filter($_POST[$post]) != null) {
							$$post = filter($_POST[$post]);
						} else {
							$error = true;
							break;
						}
					} else {
						if(isset($_POST[$post])) {
							$$post = filter($_POST[$post]);
						} else {
							$error = true;
							break;
						}
					}
				}
				if(!$error) {
					$hashKontrol = base64_encode(hash_hmac('sha256',"$SiparisID|$ExtraData|$UserID|$ReturnData|$Status|$OdemeKanali|$OdemeTutari|$NetKazanc".$apiKey,$apiSecret,true));
					if($Hash == $hashKontrol) {
						$query = $this->db->prepare("SELECT * FROM `users` WHERE user_id = ?");
						$query->execute([$UserID]);
						if($query->rowCount()) {
							$user = $query->fetch(PDO::FETCH_ASSOC);
							$query = $this->db->prepare("SELECT * FROM `deposits` WHERE deposit_method = ? AND order_id = ?");
							$query->execute([PAYMENT_METHOD, $SiparisID]);
							if(!$query->rowCount()) {
								$query = $this->db->prepare("INSERT INTO `deposits` SET user_id = ?, order_id = ?, deposit_date = ?, deposit_method = ?, deposit_amount = ?, deposit_status = ?");
								$insert_order = $query->execute([$UserID, $SiparisID, time(), PAYMENT_METHOD, $ExtraData, ($Status == "100" ? 1 : 0)]);
								if($insert_order && $Status == "100") {
									$query = $this->db->prepare("UPDATE `users` SET user_balance = ? WHERE user_id = ?");
									$update_user = $query->execute([$user["user_balance"] + $ExtraData, $user["user_id"]]);
									if($update_user) {
										reference($db, $user["user_id"], $ExtraData);
										exit("OK");
									}
								}
							} else {
								exit("OK");
							}
						}
					}
				}
			}
		}
		
	}