app_version = "1"; // 1= old app; 2=new app; date related $this->setDefaultTimeStamp(); } public function beforeFilter() { parent::beforeFilter(); // TODO: Change the autogenerated stub } public function beforeRender() { // parent::beforeRender(); // $this->layout = 'visitor'; } // product List API public function list() { list($data, $status, $status_desc, $error) = $this->processValidation('GET'); $input = array(); if (empty($status)) { $activeStatus = 1; $conditions = array('status' => $activeStatus); $this->loadModel('Product'); $products = $this->Product->list($conditions); if(!empty($products)){ $input["products"] = $products; $status = "+000"; $status_desc = "SUCCESS."; } else { $status = "-995"; $status_desc = "Product Not Found."; } } $this->processResponse($input, $data, $status, $status_desc); } // myproducts API public function myproducts() { list($data, $status, $status_desc, $error) = $this->processValidation('GET'); if (empty($status)) { list($status, $status_desc, $userObj) = $this->validateUser($data['user_id']); } $input = array(); if (empty($status)) { $this->loadModel('Product'); $this->loadModel('Order'); $activeStatus = 1; $productIds = array(); $orderArr = array(); $expenseTypeArr = [1,2,3]; $orderConditions = array( 'user_id' => $data['user_id'], 'SUBSTR(order_unique_id,1,1)' => $data['expense_type'], 'expire_date > ' => $this->getSystemCurrentTimeStamp(), ); $orders = $this->Order->list($orderConditions); if(!empty($orders)){ foreach($orders as $k => $order){ if(!in_array($order['Order']['product_id'], $productIds)){ $productIds[] = $order['Order']['product_id']; $orderArr[] = $order['Order']; } } $prodConditions = array( 'status' => $activeStatus, 'id' => $productIds ); if(in_array($data['expense_type'], $expenseTypeArr)){ $prodConditions['expense_type'] = $data['expense_type']; } $products = $this->Product->list($prodConditions); $input["products"] = $products; $input["orders"] = $orderArr; $status = "+000"; $status_desc = "SUCCESS."; } else { $status = "-994"; $status_desc = "Order Not Found."; } } $this->processResponse($input, $data, $status, $status_desc); } // product buy API public function buy() { list($data, $status, $status_desc, $error) = $this->processValidation(); if (empty($status)) { list($status, $status_desc) = $this->validateBuyProduct($data); } if (empty($status)) { list($status, $status_desc, $userObj) = $this->validateUser($data['user_id']); } $input = array(); if (empty($status)) { $this->loadModel('Product'); $this->loadModel('Order'); $this->loadModel('OrderBilling'); $this->loadModel('Transaction'); $this->loadModel('Recurring'); $this->loadModel('Wallet'); $activeStatus = 1; $conditions = array( 'id' => $data['product_id'], 'sku' => $data['product_sku'], 'status' => $activeStatus ); $productData = $this->Product->list($conditions); if (!empty($productData)) { $product = $productData[0]; // user wallet data $wConditions = array( 'user_id' => $data['user_id'], 'status' => $activeStatus ); $userWallet = $this->Wallet->list($wConditions); $userWalletData = (isset($userWallet[0]['Wallet'])) ? $userWallet[0]['Wallet'] : array(); // Insert into orders $orderInput = $this->preparingOrderInput($data, $product, $userObj['id']); $orderObj = $this->Order->add($orderInput); $input["order"] = $orderObj[1]; unset($input["order"]['id']); if (isset($orderObj[1]['id']) && ($orderObj[1]['id'] > 0)) { // Order_billings $billingData = (isset($data['billing_info'])) ? $data['billing_info'] : array(); $orderBillingInput = $this->preparingOrderBillingInput($userObj, $orderObj[1]['id'], $billingData); $orderBillingObj = $this->OrderBilling->add($orderBillingInput); // transactions $transactionInput = $this->preparingTransactionInput($data, $product, $orderObj[1], $userWalletData); $transactionObj = $this->Transaction->add($transactionInput); } // incase Recurrings if ($product['type'] == 1) // 0 = One Time, 1 = Recurring { $recurringInput = $this->preparingRecurringInput($data, $product); $recurringObj = $this->Recurring->add($recurringInput); } // Update user table expiry date $this->updateUserTableExpiryDate($data['user_id'], $product); $status = "+000"; $status_desc = "SUCCESS."; } else { $status = "-995"; $status_desc = "Product Not Found."; } } $this->processResponse($input, $data, $status, $status_desc); } private function preparingOrderBillingInput($user, $order_id, $billingData) { $returnData = array(); $returnData['order_id'] = $order_id; $returnData['first_name'] = (isset($billingData['first_name'])) ? $billingData['first_name'] : $user['first_name']; $returnData['last_name'] = (isset($billingData['last_name'])) ? $billingData['last_name'] : $user['last_name']; $returnData['address1'] = (isset($billingData['address1'])) ? $billingData['address1'] : ''; $returnData['address2'] = (isset($billingData['address2'])) ? $billingData['address2'] : ''; $returnData['city'] = (isset($billingData['city'])) ? $billingData['city'] : ''; $returnData['state'] = (isset($billingData['state'])) ? $billingData['state'] : ''; $returnData['zip'] = (isset($billingData['zip'])) ? $billingData['zip'] : ''; $returnData['country'] = (isset($billingData['country'])) ? $billingData['country'] : ''; $returnData['phone'] = (isset($billingData['phone'])) ? $billingData['phone'] : ''; $returnData['email'] = (isset($billingData['email'])) ? $billingData['email'] : $user['profile_id']; $returnData["created_date"] = $this->getSystemCurrentTimeStamp(); $returnData["updated_date"] = $this->getSystemCurrentTimeStamp(); return $returnData; } private function preparingTransactionInput($data, $product, $order, $userWalletData) { $returnData = array(); $returnData['payment_id'] = $order['payment_id']; $returnData['user_id'] = $data['user_id']; $returnData['type'] = 1; // 1 = Purchase, 2 = Deposit $returnData['entity_id'] = $order['id']; //order_id / deposit_id $returnData['description'] = ''; $returnData['product_price'] = $product['price']; $returnData['fee'] = 0; $returnData['gross'] = $product['price']; $returnData['cost'] = 0; $returnData['net'] = $product['price']; $returnData['currency_id'] = 1; // 1 = USD $returnData['money_flow'] = '-'; $returnData['current_balance'] = (isset($userWalletData['balance']))? $userWalletData['balance'] : 0; $returnData['status'] = 1; //0 = Pending, 1= Paid, 2 = Refund, 3 = Payment Fail $returnData["created_date"] = $this->getSystemCurrentTimeStamp(); $returnData["updated_date"] = $this->getSystemCurrentTimeStamp(); return $returnData; } private function preparingRecurringInput($data, $product) { /* * id * user_id * product_id * expense_type 1=Group, 2= Mess, 3 = Family * next_action_date * amount * total_amount * payment_number Total number of installments * payment_interval after how many payment cycle * payment_cycle D, W, M, Y * created_date * updated_date * */ $returnData = array(); $returnData['user_id'] = $data['user_id']; $returnData['product_id'] = $data['product_id']; $returnData['expense_type'] = $product['expense_type']; $returnData['product_price'] = $product['price']; $returnData["start_date"] = $this->getSystemCurrentTimeStamp(); $returnData['next_action_date'] = $this->getNextActionDate($product, $returnData["start_date"]); $returnData["amount"] = $data['amount']; // for recurring product $returnData['total_amount'] = $data['amount'] * $product['payment_number']; $returnData['payment_number'] = $product['payment_number']; //Total number of installments $returnData["payment_interval"] = $product['payment_interval']; // after how many payment cycle $returnData['payment_cycle'] = $product['payment_cycle']; // D, W, M, Y $returnData["created_date"] = $this->getSystemCurrentTimeStamp(); $returnData["updated_date"] = $this->getSystemCurrentTimeStamp(); return $returnData; } private function getNextActionDate($product, $start_date) { if ($product['type']) { // if recurring $intervalType = 0; // day if ($product['payment_interval'] > 0) { switch ($product['payment_cycle']) { case "D": $unit = $product['payment_interval']; break; case "W": $unit = $product['payment_interval'] * 7; break; case "M": $intervalType = 1; $unit = $product['payment_interval']; break; case "Y": $intervalType = 2; $unit = $product['payment_interval']; break; default: $unit = 0; } } if ($intervalType == 1) { // month return date('Y-m-d H:i:s', strtotime('+' . $unit . ' months', strtotime($start_date))); } elseif ($intervalType == 2) { // year return date('Y-m-d H:i:s', strtotime('+' . $unit . ' years', strtotime($start_date))); } else { return date('Y-m-d H:i:s', strtotime('+' . $unit . ' days', strtotime($start_date))); } } return false; } private function preparingOrderInput($data, $product, $user_id) { $returnData = array(); $returnData['payment_id'] = $this->systemGeneratedUniqueId($user_id, $product['expense_type']); $order_unique_id = $this->orderUniqueId($data, $product['expense_type']); $returnData['order_unique_id'] = $order_unique_id; $returnData['purchase_token'] = hash('sha256',$order_unique_id); $returnData['user_id'] = $data['user_id']; $returnData['product_id'] = $data['product_id']; $returnData['expire_date'] = $this->getProductExpireDate($product); $returnData['product_price'] = $product['price']; $returnData['fee'] = 0; $returnData['gross'] = $product['price']; $returnData['cost'] = 0; $returnData['net'] = $product['price']; $returnData['currency_id'] = $product['currency_id']; $returnData['platform_id'] = $data['platform_id']; // 1=iOS,2=Android,3=Windows $returnData["device_id"] = session_id(); $returnData['status'] = 1; //0 = Pending, 1= Paid, 2 = Refund, 3 = Payment Fail $returnData['type'] = $product['type']; //0 = One Time, 1 = Recurring $returnData["user_ip"] = $this->getClientIp(); $returnData['payment_type_id'] = $data['payment_type_id']; $returnData["created_date"] = $this->getSystemCurrentTimeStamp(); $returnData["updated_date"] = $this->getSystemCurrentTimeStamp(); return $returnData; } private function orderUniqueId($data, $expense_type) { return $expense_type . '-' . $data['user_id'] . '-' . time(); } private function updateUserTableExpiryDate($user_id, $product) { $status = false; if ($user_id > 0) { switch ($product['expense_type']) { case "1": $fields['group_expiry_date'] = '"' . $this->getProductExpireDate($product) . '"'; if ($this->User->updateFieldsById($user_id, $fields)) { $status = true; } break; case "2": $fields['mess_expiry_date'] = '"' . $this->getProductExpireDate($product) . '"'; if ($this->User->updateFieldsById($user_id, $fields)) { $status = true; } break; case "3": $fields['family_expiry_date'] = '"' . $this->getProductExpireDate($product) . '"'; if ($this->User->updateFieldsById($user_id, $fields)) { $status = true; } break; default: // do nothing break; } } return $status; } private function getProductExpireDate($product) { $unit = 0; $intervalType = 0; // day if ($product['payment_interval'] > 0) { switch ($product['payment_cycle']) { case "D": $unit = $product['payment_interval']; break; case "W": $unit = $product['payment_interval'] * 7; break; case "M": $intervalType = 1; $unit = $product['payment_interval']; break; case "Y": $intervalType = 2; $unit = $product['payment_interval']; break; default: $unit = 0; } } if ($intervalType == 1) { // month return date('Y-m-d H:i:s', strtotime('+' . $unit . ' months')); } elseif ($intervalType == 2) { // year return date('Y-m-d H:i:s', strtotime('+' . $unit . ' years')); } else { return date('Y-m-d H:i:s', strtotime('+' . $unit . ' days')); } } private function validateBuyProduct($data) { //check validity $error = ""; $error_desc = ""; if (empty($error)) { if (!array_key_exists('product_id', $data) || !array_key_exists('product_sku', $data) || !array_key_exists('user_id', $data) ) { $error = "6"; $error_desc = "product_id, product_sku and user_id are required"; } } if (empty($error)) { if (array_key_exists('billing_info', $data)) { if (array_key_exists('phone', $data['billing_info']) && ($data['billing_info']['phone'] != '')) { if (!is_numeric($data['billing_info']['phone'])) { $error = "7"; $error_desc = "phone number must be numeric"; } } } } if (empty($error)) { if (array_key_exists('billing_info', $data)) { if (array_key_exists('zip', $data['billing_info']) && ($data['billing_info']['zip'] != '')) { if (!is_numeric($data['billing_info']['zip'])) { $error = "8"; $error_desc = "zip code must be numeric"; } } } } if (empty($error)) { if (array_key_exists('billing_info', $data)) { if (array_key_exists('email', $data['billing_info'])) { $regex = '/^[_a-z0-9-]+(\.[_a-z0-9-]+)*@[a-z0-9-]+(\.[a-z0-9-]+)*(\.[a-z]{2,3})$/'; if (!preg_match($regex, $data['billing_info']['email'])) { $error = "9"; $error_desc = "email address is invalid"; } } } } return array($error, $error_desc); } }