VM暫存
Du kan inte välja fler än 25 ämnen Ämnen måste starta med en bokstav eller siffra, kan innehålla bindestreck ('-') och vara max 35 tecken långa.

1607 lines
56KB

  1. <?php
  2. /*
  3. file: Allpa_service_model.php (歐Pa卡)
  4. */
  5. require_once(ALTOB_TWGC_FILE);
  6. class Allpa_service_model extends CI_Model
  7. {
  8. function __construct()
  9. {
  10. parent::__construct();
  11. $this->load->database();
  12. define('PRODUCT_CODE', "allpa"); // 產品代碼: 歐Pa卡
  13. define('ADMIN_PRODUCT_CODE', "allpa_admin"); // 產品代碼: 歐Pa卡 (管理者)
  14. /*
  15. // ----- TWGC 測試環境 -----
  16. define('TWGC_issuerIdentity', "52856206"); // 發行商認證碼8碼 (測試環境填52856206)
  17. define('TWGC_IssuerID', "20016"); // 發行商代碼,依禮物卡公司與各發行商的約定設定其值 (測試環境填20016)
  18. define('TWGC_StoreID', "001"); // 店號,依禮物卡公司與各發行商的約定設定其值 (測試環境填001)
  19. define('TWGC_POSID', "1"); // 機號,依禮物卡公司與各發行商的約定設定其值 (測試環境填1)
  20. define('TWGC_ServiceURL', "https://issuer-test.twgiftcard.com/TWNGC/WebServices/DataProcessor.asmx");
  21. // ----- TWGC 測試環境 (END) -----
  22. */
  23. // ----- TWGC 正式環境 -----
  24. define('TWGC_issuerIdentity', "70876800"); // 發行商認證碼8碼 (測試環境填52856206)
  25. define('TWGC_IssuerID', "20016"); // 發行商代碼,依禮物卡公司與各發行商的約定設定其值 (測試環境填20016)
  26. define('TWGC_StoreID', "A046"); // 店號,依禮物卡公司與各發行商的約定設定其值 (測試環境填001)
  27. define('TWGC_POSID', "1"); // 機號,依禮物卡公司與各發行商的約定設定其值 (測試環境填1)
  28. define('TWGC_ServiceURL', "https://ws.twgiftcard.com/TWNGC/Webservices/DataProcessor.asmx");
  29. // ----- TWGC 正式環境 (END) -----
  30. // ----- 回傳訊息 -----
  31. define('ALLPA_RESULT_CODE_OK', "OK");
  32. define('ALLPA_RESULT_MSG_OK', "成功");
  33. define('ALLPA_RESULT_CODE_NOT_FOUND', "-1");
  34. define('ALLPA_RESULT_MSG_NOT_FOUND', "找不到資料");
  35. define('ALLPA_RESULT_CODE_NOT_DEFINED', "-2");
  36. define('ALLPA_RESULT_MSG_NOT_DEFINED', "產品資料未定義");
  37. define('ALLPA_RESULT_CODE_LPR_NOT_FOUND', "-3");
  38. define('ALLPA_RESULT_MSG_LPR_NOT_FOUND', "找不到車牌");
  39. define('ALLPA_RESULT_CODE_UNKNOWN_ERROR', "-99");
  40. define('ALLPA_RESULT_MSG_UNKNOWN_ERROR', "發生未預期錯誤");
  41. define('ALLPA_RESULT_CODE_ERROR_virtual_card_activation', "-100");
  42. define('ALLPA_RESULT_CODE_ERROR_get_otpin', "-101");
  43. define('ALLPA_RESULT_CODE_ERROR_balance_inquiry', "-102");
  44. define('ALLPA_RESULT_CODE_ERROR_pin_reload', "-103");
  45. define('ALLPA_RESULT_CODE_ERROR_allpa_register', "-104");
  46. define('ALLPA_RESULT_CODE_INVALID_CARD', "-200");
  47. define('ALLPA_RESULT_MSG_INVALID_CARD', "卡片未開通");
  48. define('ALLPA_RESULT_CODE_INVALID_LPR', "-201");
  49. define('ALLPA_RESULT_MSG_INVALID_LPR', "車牌已註冊, 是否轉移點數?");
  50. // -- 內部代碼 --
  51. define('ALLPA_GO_RESULT_CODE_OK', 0);
  52. define('ALLPA_GO_RESULT_MSG_OK', "成功");
  53. define('ALLPA_GO_RESULT_CODE_CK_ERROR', 10);
  54. define('ALLPA_GO_RESULT_MSG_CK_ERROR', "CK ERROR");
  55. define('ALLPA_GO_RESULT_CODE_USER_NOT_FOUND', 11);
  56. define('ALLPA_GO_RESULT_MSG_USER_NOT_FOUND', "查無歐Pa卡用戶");
  57. define('ALLPA_GO_RESULT_CODE_NO_MONEY', 12);
  58. define('ALLPA_GO_RESULT_MSG_NO_MONEY', "餘額不足");
  59. define('ALLPA_GO_RESULT_CODE_CONSUME_ERROR', 13);
  60. define('ALLPA_GO_RESULT_MSG_CONSUME_ERROR', "扣款失敗");
  61. define('ALLPA_GO_RESULT_CODE_DEBT', 14);
  62. define('ALLPA_GO_RESULT_MSG_DEBT', "有欠款");
  63. define('ALLPA_GO_RESULT_CODE_BILL_NOT_FOUND', 15);
  64. define('ALLPA_GO_RESULT_MSG_BILL_NOT_FOUND', "查無歐Pa卡帳單");
  65. // ----- 回傳訊息 (END) -----
  66. }
  67. // 產生交易序號
  68. private function gen_trx_no()
  69. {
  70. return time().rand(10000,99999);
  71. }
  72. // TWGC 回傳字串轉換為值
  73. private function parse_twgc_number($value)
  74. {
  75. return str_replace( ',', '', (string) $value);
  76. }
  77. // 判斷錢是否夠扣
  78. private function is_money_enough($balance, $bonus, $price)
  79. {
  80. return ($balance >= $price || $bonus >= $price || ($balance + $bonus) >= $price); // 點數一律一比一
  81. }
  82. // 異常卡片處理
  83. private function twgc_notfound_handler($result_code, $lpr, $barcode)
  84. {
  85. if($result_code == "-11"){
  86. // 找不到禮物卡資料
  87. $data = array();
  88. $data['status'] = 44; // '狀態: 0:剛建立, 1:啟用中, 2:啟用記名失敗, 4:手動關閉, 44:異常停用, 99:已停用'
  89. $this->db->update('allpa_user', $data, array('lpr' => $lpr, 'barcode' => $barcode));
  90. }
  91. }
  92. // TWGC: 消費
  93. public function allpa_consume($lpr, $barcode, $amount, $order_no)
  94. {
  95. $result = array();
  96. // 產生交易序號
  97. $custTrxNo = $this->gen_trx_no();
  98. $result["cust_trx_no"] = $custTrxNo;
  99. // 使用TWGCAgent
  100. $oTWGCAgent = new TWGCAgent();
  101. $oTWGCAgent->issuerIdentity = TWGC_issuerIdentity;
  102. $oTWGCAgent->IssuerID = TWGC_IssuerID;
  103. $oTWGCAgent->StoreID = TWGC_StoreID;
  104. $oTWGCAgent->POSID = TWGC_POSID;
  105. $oTWGCAgent->ServiceURL = TWGC_ServiceURL;
  106. try{
  107. $data = array(
  108. 'CustTrxNo' => $custTrxNo,
  109. 'BarCode' => $barcode,
  110. 'MemberID' => $lpr,
  111. 'Amount' => $amount
  112. );
  113. $resultXml = $oTWGCAgent->BalanceMaintenance3($data, TRUE); // 使用紅利點數
  114. if($resultXml->RespCode == "00"){
  115. $result["result_code"] = ALLPA_RESULT_CODE_OK;
  116. $result["result_msg"] = ALLPA_RESULT_MSG_OK;
  117. $result["barcode"] = (string) $resultXml->Barcode;
  118. $result["prev_balance"] = $this->parse_twgc_number($resultXml->PrevBalance);//str_replace( ',', '', (string) $resultXml->PrevBalance);
  119. $result["balance"] = $this->parse_twgc_number($resultXml->Balance);//str_replace( ',', '', (string) $resultXml->Balance);
  120. $result["auth_code"] = (string) $resultXml->AuthCode;
  121. $result["amount_due"] = (string) $resultXml->AmountDue;
  122. $result["bonus"] = $this->parse_twgc_number($resultXml->Bonus);//str_replace( ',', '', (string) $resultXml->Bonus);
  123. }else{
  124. $result["result_code"] = (string) $resultXml->RespCode;
  125. $result["result_msg"] = (string) $resultXml->ErrorMessage;
  126. $result["auth_code"] = (string) $resultXml->AuthCodeForInsufficientFund;
  127. }
  128. }catch (Exception $e){
  129. trigger_error(__FUNCTION__.', CustTrxNo=>' . $custTrxNo.'<br>'.$e->getMessage());
  130. $result["result_code"] = ALLPA_RESULT_CODE_UNKNOWN_ERROR;
  131. $result["result_msg"] = ALLPA_RESULT_MSG_UNKNOWN_ERROR;
  132. $result["auth_code"] = "";
  133. }
  134. // API LOG
  135. $data = array();
  136. $data['cust_trx_no'] = $custTrxNo;
  137. $data['api_no'] = TWGC_API_NO::BalanceMaintenance3;
  138. $data['result_code'] = $result["result_code"];
  139. $data['result_msg'] = $result["result_msg"];
  140. $data['auth_code'] = $result["auth_code"];
  141. $data['barcode'] = $barcode;
  142. $data['order_no'] = $order_no;
  143. $this->db->insert('twgc_api_log', $data);
  144. return $result;
  145. }
  146. // TWGC: 卡片綁定
  147. public function allpa_register($lpr, $barcode)
  148. {
  149. $result = array();
  150. // 產生交易序號
  151. $custTrxNo = $this->gen_trx_no();
  152. $result["cust_trx_no"] = $custTrxNo;
  153. // 使用TWGCAgent
  154. $oTWGCAgent = new TWGCAgent();
  155. $oTWGCAgent->issuerIdentity = TWGC_issuerIdentity;
  156. $oTWGCAgent->IssuerID = TWGC_IssuerID;
  157. $oTWGCAgent->StoreID = TWGC_StoreID;
  158. $oTWGCAgent->POSID = TWGC_POSID;
  159. $oTWGCAgent->ServiceURL = TWGC_ServiceURL;
  160. try{
  161. $data = array(
  162. 'CustTrxNo' => $custTrxNo,
  163. 'BarCode' => $barcode,
  164. 'UserID' => $lpr
  165. );
  166. $resultXml = $oTWGCAgent->Register($data);
  167. if($resultXml->RespCode == "00"){
  168. $result["result_code"] = ALLPA_RESULT_CODE_OK;
  169. $result["result_msg"] = "卡片綁定完成";
  170. $result["register_barcode"] = $barcode;
  171. $result["register_lpr"] = $lpr;
  172. $result["register_no"] = $custTrxNo;
  173. }else{
  174. $result["result_code"] = (string) $resultXml->RespCode;
  175. $result["result_msg"] = (string) $resultXml->ErrorMessage;
  176. }
  177. }catch (Exception $e){
  178. trigger_error(__FUNCTION__.', CustTrxNo=>' . $custTrxNo.'<br>'.$e->getMessage());
  179. $result["result_code"] = ALLPA_RESULT_CODE_UNKNOWN_ERROR;
  180. $result["result_msg"] = ALLPA_RESULT_MSG_UNKNOWN_ERROR;
  181. }
  182. // API LOG
  183. $data = array();
  184. $data['cust_trx_no'] = $custTrxNo;
  185. $data['api_no'] = TWGC_API_NO::Register;
  186. $data['result_code'] = $result["result_code"];
  187. $data['result_msg'] = $result["result_msg"];
  188. $data['barcode'] = $barcode;
  189. $this->db->insert('twgc_api_log', $data);
  190. return $result;
  191. }
  192. // TWGC: 虛擬卡開卡
  193. public function virtual_card_activation($cardEAN, $amount, $order_no)
  194. {
  195. $result = array();
  196. // 產生交易序號
  197. $custTrxNo = $this->gen_trx_no();
  198. $result["cust_trx_no"] = $custTrxNo;
  199. // 使用TWGCAgent
  200. $oTWGCAgent = new TWGCAgent();
  201. $oTWGCAgent->issuerIdentity = TWGC_issuerIdentity;
  202. $oTWGCAgent->IssuerID = TWGC_IssuerID;
  203. $oTWGCAgent->StoreID = TWGC_StoreID;
  204. $oTWGCAgent->POSID = TWGC_POSID;
  205. $oTWGCAgent->ServiceURL = TWGC_ServiceURL;
  206. try{
  207. $data = array(
  208. 'CustTrxNo' => $custTrxNo,
  209. 'EAN' => $cardEAN,
  210. 'Amount' => $amount
  211. );
  212. $resultXml = $oTWGCAgent->VirtualCardActivation($data);
  213. if($resultXml->Detail->Card->RespCode == "00"){ // 白目的結構
  214. $result["result_code"] = ALLPA_RESULT_CODE_OK;
  215. $result["result_msg"] = "開卡完成";
  216. $result["barcode"] = (string) $resultXml->Detail->Card->Barcode;
  217. $result["amount"] = $this->parse_twgc_number($resultXml->Detail->Card->Amount);//str_replace( ',', '', (string) $resultXml->Detail->Card->Amount);
  218. }else{
  219. $result["result_code"] = (string) $resultXml->RespCode;
  220. $result["result_msg"] = (string) $resultXml->ErrorMessage;
  221. }
  222. }catch (Exception $e){
  223. trigger_error(__FUNCTION__.', CustTrxNo=>' . $custTrxNo.'<br>'.$e->getMessage());
  224. $result["result_code"] = ALLPA_RESULT_CODE_UNKNOWN_ERROR;
  225. $result["result_msg"] = ALLPA_RESULT_MSG_UNKNOWN_ERROR;
  226. }
  227. // API LOG
  228. $data = array();
  229. $data['cust_trx_no'] = $custTrxNo;
  230. $data['api_no'] = TWGC_API_NO::VirtualCardActivation;
  231. $data['result_code'] = $result["result_code"];
  232. $data['result_msg'] = $result["result_msg"];
  233. $data['order_no'] = $order_no;
  234. $this->db->insert('twgc_api_log', $data);
  235. return $result;
  236. }
  237. // TWGC: 取得儲值的PIN碼
  238. public function get_otpin($barcode, $order_no)
  239. {
  240. $result = array();
  241. // 產生交易序號
  242. $custTrxNo = $this->gen_trx_no();
  243. $result["cust_trx_no"] = $custTrxNo;
  244. // 使用TWGCAgent
  245. $oTWGCAgent = new TWGCAgent();
  246. $oTWGCAgent->issuerIdentity = TWGC_issuerIdentity;
  247. $oTWGCAgent->IssuerID = TWGC_IssuerID;
  248. $oTWGCAgent->StoreID = TWGC_StoreID;
  249. $oTWGCAgent->POSID = TWGC_POSID;
  250. $oTWGCAgent->ServiceURL = TWGC_ServiceURL;
  251. try{
  252. $data = array(
  253. 'BarCode' => $barcode,
  254. 'Size' => 'S' // *Size:回傳圖檔大小 (L/M/S)
  255. );
  256. $resultXml = $oTWGCAgent->GetOTPin2($data);
  257. if($resultXml->RespCode == "00"){
  258. $result["result_code"] = ALLPA_RESULT_CODE_OK;
  259. $result["result_msg"] = ALLPA_RESULT_MSG_OK;
  260. $result["password_type"] = (string) $resultXml->PasswordType; // PasswordType:不處理
  261. $result["encoded_pic"] = (string) $resultXml->EncodedPIC; // EncodedPIC:密碼圖檔,以base64編碼 (文件少一個 d)
  262. $result["valid_time"] = (string) $resultXml->ValidTime; // ValidTime:密碼有效時間 (分)
  263. $result["valid_before"] = date('Y-m-d H:i:s', strtotime((string) $resultXml->ValidBefore)); // ValidBefore:相對於上傳的本機時間, 密碼到期時間
  264. }else{
  265. $result["result_code"] = (string) $resultXml->RespCode;
  266. $result["result_msg"] = (string) $resultXml->ErrorMessage;
  267. }
  268. }catch (Exception $e){
  269. trigger_error(__FUNCTION__.', barcode=>' . $barcode.'<br>'.$e->getMessage());
  270. $result["result_code"] = ALLPA_RESULT_CODE_UNKNOWN_ERROR;
  271. $result["result_msg"] = ALLPA_RESULT_MSG_UNKNOWN_ERROR;
  272. }
  273. // API LOG
  274. $data = array();
  275. $data['cust_trx_no'] = $custTrxNo;
  276. $data['api_no'] = TWGC_API_NO::GetOTPin2;
  277. $data['result_code'] = $result["result_code"];
  278. $data['result_msg'] = $result["result_msg"];
  279. $data['order_no'] = $order_no;
  280. $data['barcode'] = $barcode;
  281. $this->db->insert('twgc_api_log', $data);
  282. return $result;
  283. }
  284. // TWGC: PIN 儲值
  285. public function pin_reload($pin, $amount, $order_no, $barcode)
  286. {
  287. $result = array();
  288. // 產生交易序號
  289. $custTrxNo = $this->gen_trx_no();
  290. $result["cust_trx_no"] = $custTrxNo;
  291. // 使用TWGCAgent
  292. $oTWGCAgent = new TWGCAgent();
  293. $oTWGCAgent->issuerIdentity = TWGC_issuerIdentity;
  294. $oTWGCAgent->IssuerID = TWGC_IssuerID;
  295. $oTWGCAgent->StoreID = TWGC_StoreID;
  296. $oTWGCAgent->POSID = TWGC_POSID;
  297. $oTWGCAgent->ServiceURL = TWGC_ServiceURL;
  298. try{
  299. $data = array(
  300. 'CustTrxNo' => $custTrxNo,
  301. 'Amount' => $amount,
  302. 'PIN' => $pin
  303. );
  304. $resultXml = $oTWGCAgent->Reload2($data);
  305. if($resultXml->RespCode == "00"){
  306. $result["result_code"] = ALLPA_RESULT_CODE_OK;
  307. $result["result_msg"] = ALLPA_RESULT_MSG_OK;
  308. $result["auth_code"] = (string) $resultXml->AuthCode; // 授權碼
  309. $result["prev_balance"] = $this->parse_twgc_number($resultXml->PrevBalance);//str_replace( ',', '', (string) $resultXml->PrevBalance); // 卡片儲值前餘額
  310. $result["balance"] = $this->parse_twgc_number($resultXml->Balance);//str_replace( ',', '', (string) $resultXml->Balance); // 卡片儲值後新餘額
  311. }else{
  312. $result["result_code"] = (string) $resultXml->ErrorCode;
  313. $result["result_msg"] = (string) $resultXml->ErrorMessage;
  314. $result["auth_code"] = "";
  315. }
  316. }catch (Exception $e){
  317. trigger_error(__FUNCTION__.', custTrxNo=>' . $custTrxNo.'<br>'.$e->getMessage());
  318. $result["result_code"] = ALLPA_RESULT_CODE_UNKNOWN_ERROR;
  319. $result["result_msg"] = ALLPA_RESULT_MSG_UNKNOWN_ERROR;
  320. $result["auth_code"] = "";
  321. }
  322. // API LOG
  323. $data = array();
  324. $data['cust_trx_no'] = $custTrxNo;
  325. $data['api_no'] = TWGC_API_NO::Reload2;
  326. $data['result_code'] = $result["result_code"];
  327. $data['result_msg'] = $result["result_msg"];
  328. $data['auth_code'] = $result["auth_code"];
  329. $data['order_no'] = $order_no;
  330. $data['barcode'] = $barcode;
  331. $this->db->insert('twgc_api_log', $data);
  332. return $result;
  333. }
  334. // TWGC: 查詢 barcode
  335. public function balance_inquiry($barcode, $order_no=NULL)
  336. {
  337. $result = array();
  338. // 產生交易序號
  339. $custTrxNo = $this->gen_trx_no();
  340. $result["cust_trx_no"] = $custTrxNo;
  341. // 使用TWGCAgent
  342. $oTWGCAgent = new TWGCAgent();
  343. $oTWGCAgent->issuerIdentity = TWGC_issuerIdentity;
  344. $oTWGCAgent->IssuerID = TWGC_IssuerID;
  345. $oTWGCAgent->StoreID = TWGC_StoreID;
  346. $oTWGCAgent->POSID = TWGC_POSID;
  347. $oTWGCAgent->ServiceURL = TWGC_ServiceURL;
  348. try{
  349. $data = array(
  350. 'CustTrxNo' => $custTrxNo,
  351. 'BarCode' => $barcode
  352. );
  353. $resultXml = $oTWGCAgent->BalanceInquiry($data);
  354. if($resultXml->RespCode == "00"){
  355. $result["result_code"] = ALLPA_RESULT_CODE_OK;
  356. $result["result_msg"] = ALLPA_RESULT_MSG_OK;
  357. $result["van19"] = (string) $resultXml->Detail->Card->VAN19;
  358. $result["balance"] = $this->parse_twgc_number($resultXml->Detail->Card->Balance);//str_replace( ',', '', (string) $resultXml->Detail->Card->Balance);
  359. $result["status_code"] = (string) $resultXml->Detail->Card->StatusCode;
  360. $result["card_status"] = (string) $resultXml->Detail->Card->CardStatus;
  361. $result["bonus"] = $this->parse_twgc_number($resultXml->Detail->Card->Bonus);//str_replace( ',', '', (string) $resultXml->Detail->Card->Bonus);
  362. $result["cash_per_point"] = (string) $resultXml->Detail->Card->CashPerPoint;
  363. }else{
  364. $result["result_code"] = (string) $resultXml->RespCode;
  365. $result["result_msg"] = (string) $resultXml->ErrorMessage;
  366. }
  367. }catch (Exception $e){
  368. trigger_error(__FUNCTION__.', custTrxNo=>' . $custTrxNo.'<br>'.$e->getMessage());
  369. $result["result_code"] = ALLPA_RESULT_CODE_UNKNOWN_ERROR;
  370. $result["result_msg"] = ALLPA_RESULT_MSG_UNKNOWN_ERROR;
  371. }
  372. // API LOG
  373. $data = array();
  374. $data['cust_trx_no'] = $custTrxNo;
  375. $data['api_no'] = TWGC_API_NO::BalanceInquiry;
  376. $data['result_code'] = $result["result_code"];
  377. $data['result_msg'] = $result["result_msg"];
  378. $data['order_no'] = $order_no;
  379. $data['barcode'] = $barcode;
  380. $this->db->insert('twgc_api_log', $data);
  381. return $result;
  382. }
  383. // 新增卡片使用記錄 (開卡)
  384. public function create_allpa_init_log($cust_trx_no, $lpr, $barcode, $order_no)
  385. {
  386. $this->create_allpa_log($cust_trx_no, $lpr, $barcode, "01", 0, 0, $order_no, 0); // 訂單種類: 0:開卡, 1:儲值, 2:扣款, 10:實體卡記名, 44:未知
  387. }
  388. // 新增卡片使用記錄 (儲值)
  389. public function create_allpa_reload_log($cust_trx_no, $lpr, $barcode, $pre_status_code, $pre_balance, $pre_bonus, $order_no)
  390. {
  391. $this->create_allpa_log($cust_trx_no, $lpr, $barcode, $pre_status_code, $pre_balance, $pre_bonus, $order_no, 1); // 訂單種類: 0:開卡, 1:儲值, 2:扣款, 10:實體卡記名, 44:未知
  392. }
  393. // 新增卡片使用記錄 (扣款)
  394. public function create_allpa_consume_log($cust_trx_no, $lpr, $barcode, $pre_status_code, $pre_balance, $pre_bonus, $order_no)
  395. {
  396. $this->create_allpa_log($cust_trx_no, $lpr, $barcode, $pre_status_code, $pre_balance, $pre_bonus, $order_no, 2); // 訂單種類: 0:開卡, 1:儲值, 2:扣款, 10:實體卡記名, 44:未知
  397. }
  398. // 新增卡片使用記錄 (實體卡記名)
  399. public function create_allpa_card_register_log($cust_trx_no, $lpr, $barcode)
  400. {
  401. $this->create_allpa_log($cust_trx_no, $lpr, $barcode, "01", 0, 0, 0, 10); // 訂單種類: 0:開卡, 1:儲值, 2:扣款, 10:實體卡記名, 44:未知
  402. }
  403. // 新增卡片使用記錄 (未知)
  404. public function create_allpa_unknown_log($cust_trx_no, $lpr, $barcode, $pre_status_code, $pre_balance, $pre_bonus, $order_no)
  405. {
  406. $this->create_allpa_log($cust_trx_no, $lpr, $barcode, $pre_status_code, $pre_balance, $pre_bonus, $order_no, 44); // 訂單種類: 0:開卡, 1:儲值, 2:扣款, 10:實體卡記名, 44:未知
  407. }
  408. // 新增卡片使用記錄
  409. private function create_allpa_log($cust_trx_no, $lpr, $barcode, $pre_status_code, $pre_balance, $pre_bonus, $order_no, $order_type)
  410. {
  411. $data = array();
  412. // 重新查詢一次
  413. $balance_inquiry_result = $this->balance_inquiry($barcode);
  414. if($balance_inquiry_result["result_code"] == ALLPA_RESULT_CODE_OK){
  415. $data['status_code'] = $balance_inquiry_result["status_code"];
  416. $data['balance'] = $balance_inquiry_result["balance"];
  417. $data['bonus'] = $balance_inquiry_result["bonus"];
  418. }else{
  419. $data['status_code'] = $pre_status_code;
  420. $data['balance'] = $pre_balance;
  421. $data['bonus'] = $pre_bonus;
  422. }
  423. // 更新用戶資訊
  424. $this->db->update('allpa_user', $data, array('lpr' => $lpr, 'barcode' => $barcode));
  425. // 更新使用記錄
  426. $data["cust_trx_no"] = $cust_trx_no;
  427. $data['lpr'] = $lpr;
  428. $data['barcode'] = $barcode;
  429. $data['pre_status_code'] = $pre_status_code;
  430. $data['pre_balance'] = $pre_balance;
  431. $data['pre_bonus'] = $pre_bonus;
  432. $data['order_no'] = $order_no;
  433. $data['order_type'] = $order_type;
  434. $this->db->insert('allpa_balance_log', $data);
  435. }
  436. // 儲值
  437. public function allpa_reload($order_no, $pin, $pin_check_id)
  438. {
  439. $check_result = $this->db->select('allpa_pin_check.lpr as lpr, allpa_pin_check.barcode as barcode, product_bill.product_plan as product_plan')
  440. ->from('allpa_pin_check')
  441. ->join('product_bill', 'allpa_pin_check.order_no = product_bill.order_no', 'left')
  442. ->where(array(
  443. 'allpa_pin_check.allpa_pin_check_id' => $pin_check_id,
  444. 'allpa_pin_check.order_no' => $order_no,
  445. 'product_bill.status' => 1)) // '狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 111:產品已領取'
  446. ->limit(1)
  447. ->get()
  448. ->row_array();
  449. // 查無結帳記錄
  450. if(empty($check_result)){
  451. $result = array();
  452. $result["result_code"] = ALLPA_RESULT_CODE_NOT_FOUND;
  453. $result["result_msg"] = ALLPA_RESULT_MSG_NOT_FOUND;
  454. return $result; // NOT FOUND
  455. }
  456. // 產品內容未定義
  457. if (empty($check_result['product_plan']))
  458. {
  459. $result = array();
  460. $result["result_code"] = ALLPA_RESULT_CODE_NOT_DEFINED;
  461. $result["result_msg"] = ALLPA_RESULT_MSG_NOT_DEFINED;
  462. return $result; // NOT DEFINED
  463. }
  464. $lpr = $check_result['lpr'];
  465. $barcode = $check_result['barcode'];
  466. $product_plan = json_decode($check_result['product_plan'], true);
  467. $cardEAN = $product_plan["EAN"];
  468. $cardAmount = $product_plan["Amount"];
  469. // 查遠端餘額
  470. $pre_status_code = "";
  471. $pre_balance = 0;
  472. $pre_bonus = 0;
  473. $balance_inquiry_result = $this->balance_inquiry($barcode);
  474. if($balance_inquiry_result["result_code"] == ALLPA_RESULT_CODE_OK){
  475. $pre_status_code = $balance_inquiry_result["status_code"];
  476. $pre_balance = $balance_inquiry_result["balance"];
  477. $pre_bonus = $balance_inquiry_result["bonus"];
  478. }else{
  479. // 未知卡片處理
  480. $this->twgc_notfound_handler($balance_inquiry_result["result_code"], $lpr, $barcode);
  481. // 查詢barcode失敗
  482. $result = array();
  483. $result["result_code"] = ALLPA_RESULT_CODE_ERROR_balance_inquiry;
  484. $result["result_msg"] = $balance_inquiry_result["result_msg"];
  485. return $result;
  486. }
  487. // 查本地餘額
  488. $recent_balance_log = $this->db->select('status_code, balance, bonus')
  489. ->from('allpa_balance_log')
  490. ->where(array('lpr' => $lpr, 'barcode' => $barcode))
  491. ->order_by("create_time", "desc")
  492. ->limit(1)
  493. ->get()
  494. ->row_array();
  495. // 檢記錄是否出現未知斷層
  496. if( $pre_status_code != $recent_balance_log["status_code"] ||
  497. $pre_balance != $recent_balance_log["balance"] ||
  498. $pre_bonus != $recent_balance_log["bonus"]) {
  499. $unknown_trx_no = $this->gen_trx_no();
  500. // 產生一筆未知的balance_log
  501. $this->create_allpa_unknown_log(
  502. $unknown_trx_no, $lpr, $barcode,
  503. $recent_balance_log["status_code"], $recent_balance_log["balance"], $recent_balance_log["bonus"],
  504. $order_no);
  505. }
  506. // 開始儲值
  507. $pin_reload_result = $this->pin_reload($pin, $cardAmount, $order_no, $barcode);
  508. if($pin_reload_result["result_code"] == ALLPA_RESULT_CODE_OK){
  509. // 已領取
  510. $this->transfer_money_done_and_finished($order_no);
  511. // 新增卡片使用記錄
  512. $this->create_allpa_reload_log(
  513. $pin_reload_result["cust_trx_no"], $lpr, $barcode,
  514. $pre_status_code, $pre_balance, $pre_bonus,
  515. $order_no);
  516. // 跳到顯示個資的流程??
  517. return $this->get_allpa_info($lpr);
  518. }else{
  519. // 儲值barcode失敗
  520. $result = array();
  521. $result["result_code"] = ALLPA_RESULT_CODE_ERROR_pin_reload;
  522. $result["result_msg"] = $pin_reload_result["result_msg"];
  523. return $result;
  524. }
  525. }
  526. // 卡片記名
  527. public function card_register($lpr, $barcode)
  528. {
  529. $user = $this->get_valid_user($lpr);
  530. if(empty($user)){
  531. // 新開立
  532. $allpa_register_result = $this->allpa_register($lpr, $barcode);
  533. if($allpa_register_result["result_code"] == ALLPA_RESULT_CODE_OK){
  534. $data = array();
  535. $data['lpr'] = $lpr;
  536. $data['barcode'] = $barcode;
  537. $data['status'] = 1; // '狀態: 0:剛建立, 1:啟用中, 2:啟用記名失敗, 99:已停用'
  538. $this->db->insert('allpa_user', $data);
  539. // 新增卡片記名記錄
  540. $this->create_allpa_card_register_log($allpa_register_result["cust_trx_no"], $lpr, $barcode);
  541. // 跳到顯示個資的流程??
  542. return $this->get_allpa_info($lpr);
  543. }else{
  544. // 記名失敗
  545. $result = array();
  546. $result["result_code"] = ALLPA_RESULT_CODE_ERROR_allpa_register;
  547. $result["result_msg"] = $allpa_register_result["result_msg"];
  548. return $result;
  549. }
  550. }else{
  551. // 車牌已註冊, 詢問點數移轉
  552. $result = array();
  553. $result["result_code"] = ALLPA_RESULT_CODE_INVALID_LPR;
  554. $result["result_msg"] = ALLPA_RESULT_MSG_INVALID_LPR;
  555. return $result;
  556. }
  557. }
  558. // 領貨 (新帳號, 開卡, 記名)
  559. public function activate_bill_for_new_register($order_no)
  560. {
  561. $bill = $this->db->select('order_no, lpr, product_bill.product_plan as product_plan, tx_time, product_name, product_desc, remarks')
  562. ->from('product_bill')
  563. ->join('products', 'products.product_id = product_bill.product_id', 'left')
  564. ->where(array('order_no' => $order_no, 'status' => 1)) // '狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 111:產品已領取'
  565. ->limit(1)
  566. ->get()
  567. ->row_array();
  568. if(empty($bill))
  569. {
  570. $result = array();
  571. $result["result_code"] = ALLPA_RESULT_CODE_NOT_FOUND;
  572. $result["result_msg"] = ALLPA_RESULT_MSG_NOT_FOUND;
  573. return $result; // NOT FOUND
  574. }
  575. if (empty($bill['product_plan']))
  576. {
  577. $result = array();
  578. $result["result_code"] = ALLPA_RESULT_CODE_NOT_DEFINED;
  579. $result["result_msg"] = ALLPA_RESULT_MSG_NOT_DEFINED;
  580. return $result; // NOT DEFINED
  581. }
  582. if (empty($bill['lpr']))
  583. {
  584. $result = array();
  585. $result["result_code"] = ALLPA_RESULT_CODE_LPR_NOT_FOUND;
  586. $result["result_msg"] = ALLPA_RESULT_MSG_LPR_NOT_FOUND;
  587. return $result; // 車牌 NOT FOUND
  588. }
  589. $lpr = $bill['lpr'];
  590. $product_name = $bill['product_name'];
  591. $product_desc = $bill['product_desc'];
  592. $remarks = $bill['remarks'];
  593. $product_plan = json_decode($bill['product_plan'], true);
  594. $cardEAN = $product_plan["EAN"];
  595. $cardAmount = $product_plan["Amount"];
  596. $userAmount = 0;
  597. // 取得有效用戶
  598. $user = $this->get_valid_user($lpr);
  599. if(empty($user)){
  600. // A. 新帳號, 開卡
  601. $virtual_card_activation_result = $this->virtual_card_activation($cardEAN, $cardAmount, $order_no);
  602. if($virtual_card_activation_result["result_code"] == ALLPA_RESULT_CODE_OK){
  603. // 開卡完成
  604. $barcode = $virtual_card_activation_result["barcode"];
  605. $amount = $virtual_card_activation_result["amount"];
  606. $custTrxNo = $virtual_card_activation_result["cust_trx_no"];
  607. // 卡片記名
  608. $allpa_register_result = $this->allpa_register($lpr, $barcode);
  609. if($allpa_register_result["result_code"] == ALLPA_RESULT_CODE_OK){
  610. $data = array();
  611. $data['lpr'] = $lpr;
  612. $data['barcode'] = $barcode;
  613. $data['status'] = 1; // '狀態: 0:剛建立, 1:啟用中, 2:啟用記名失敗, 99:已停用'
  614. $this->db->insert('allpa_user', $data);
  615. }else{
  616. $data = array();
  617. $data['lpr'] = $lpr;
  618. $data['barcode'] = $barcode;
  619. $data['status'] = 2; // '狀態: 0:剛建立, 1:啟用中, 2:啟用記名失敗, 99:已停用'
  620. $this->db->insert('allpa_user', $data);
  621. }
  622. // 訂單編號, 已領取
  623. $this->transfer_money_done_and_finished($order_no);
  624. // 新增卡片使用記錄
  625. $this->create_allpa_init_log($custTrxNo, $lpr, $barcode, $order_no);
  626. // 成功
  627. $result = array();
  628. $result["result_code"] = ALLPA_RESULT_CODE_OK;
  629. $result["result_msg"] = ALLPA_RESULT_MSG_OK;
  630. return $result;
  631. }else{
  632. // 開卡失敗
  633. $result = array();
  634. $result["result_code"] = ALLPA_RESULT_CODE_ERROR_virtual_card_activation;
  635. $result["result_msg"] = $virtual_card_activation_result["result_msg"];
  636. return $result;
  637. }
  638. }else{
  639. // 車牌已註冊, 詢問點數移轉
  640. $result = array();
  641. $result["result_code"] = ALLPA_RESULT_CODE_INVALID_LPR;
  642. $result["result_msg"] = ALLPA_RESULT_MSG_INVALID_LPR;
  643. return $result;
  644. }
  645. }
  646. // 領貨 (通用)
  647. public function activate_bill($order_no)
  648. {
  649. $bill = $this->db->select('order_no, lpr, product_bill.product_plan as product_plan, tx_time, product_name, product_desc, remarks')
  650. ->from('product_bill')
  651. ->join('products', 'products.product_id = product_bill.product_id', 'left')
  652. ->where(array('order_no' => $order_no, 'status' => 1)) // '狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 111:產品已領取'
  653. ->limit(1)
  654. ->get()
  655. ->row_array();
  656. if(empty($bill)){
  657. $result = array();
  658. $result["result_code"] = ALLPA_RESULT_CODE_NOT_FOUND;
  659. $result["result_msg"] = ALLPA_RESULT_MSG_NOT_FOUND;
  660. return $result; // NOT FOUND
  661. }
  662. if (empty($bill['product_plan']))
  663. {
  664. $result = array();
  665. $result["result_code"] = ALLPA_RESULT_CODE_NOT_DEFINED;
  666. $result["result_msg"] = ALLPA_RESULT_MSG_NOT_DEFINED;
  667. return $result; // NOT DEFINED
  668. }
  669. if (empty($bill['lpr']))
  670. {
  671. $result = array();
  672. $result["result_code"] = ALLPA_RESULT_CODE_LPR_NOT_FOUND;
  673. $result["result_msg"] = ALLPA_RESULT_MSG_LPR_NOT_FOUND;
  674. return $result; // 車牌 NOT FOUND
  675. }
  676. $lpr = $bill['lpr'];
  677. $product_name = $bill['product_name'];
  678. $product_desc = $bill['product_desc'];
  679. $remarks = $bill['remarks'];
  680. $product_plan = json_decode($bill['product_plan'], true);
  681. $cardEAN = $product_plan["EAN"];
  682. $cardAmount = $product_plan["Amount"];
  683. $userAmount = 0;
  684. // 取得有效用戶
  685. $user = $this->get_valid_user($lpr);
  686. if(empty($user)){
  687. // A. 新帳號, 開卡
  688. $virtual_card_activation_result = $this->virtual_card_activation($cardEAN, $cardAmount, $order_no);
  689. if($virtual_card_activation_result["result_code"] == ALLPA_RESULT_CODE_OK){
  690. // 開卡完成
  691. $barcode = $virtual_card_activation_result["barcode"];
  692. $amount = $virtual_card_activation_result["amount"];
  693. $custTrxNo = $virtual_card_activation_result["cust_trx_no"];
  694. // 卡片記名
  695. $allpa_register_result = $this->allpa_register($lpr, $barcode);
  696. if($allpa_register_result["result_code"] == ALLPA_RESULT_CODE_OK){
  697. $data = array();
  698. $data['lpr'] = $lpr;
  699. $data['barcode'] = $barcode;
  700. $data['status'] = 1; // '狀態: 0:剛建立, 1:啟用中, 2:啟用記名失敗, 99:已停用'
  701. $this->db->insert('allpa_user', $data);
  702. }else{
  703. $data = array();
  704. $data['lpr'] = $lpr;
  705. $data['barcode'] = $barcode;
  706. $data['status'] = 2; // '狀態: 0:剛建立, 1:啟用中, 2:啟用記名失敗, 99:已停用'
  707. $this->db->insert('allpa_user', $data);
  708. }
  709. // 訂單編號, 已領取
  710. $this->transfer_money_done_and_finished($order_no);
  711. // 新增卡片使用記錄
  712. $this->create_allpa_init_log($custTrxNo, $lpr, $barcode, $order_no);
  713. // 跳到顯示個資的流程??
  714. return $this->get_allpa_info($lpr);
  715. }else{
  716. // 開卡失敗
  717. $result = array();
  718. $result["result_code"] = ALLPA_RESULT_CODE_ERROR_virtual_card_activation;
  719. $result["result_msg"] = $virtual_card_activation_result["result_msg"];
  720. return $result;
  721. }
  722. }else{
  723. $barcode = $user["barcode"];
  724. // B.1 查詢barcode
  725. $balance_inquiry_result = $this->balance_inquiry($barcode, $order_no);
  726. if($balance_inquiry_result["result_code"] == ALLPA_RESULT_CODE_OK){
  727. if($balance_inquiry_result["status_code"] == "01"){
  728. $userAmount = $balance_inquiry_result["balance"]; // 目前卡片餘額
  729. }else{
  730. // 卡片未開通
  731. $result = array();
  732. $result["result_code"] = ALLPA_RESULT_CODE_INVALID_CARD;
  733. $result["result_msg"] = ALLPA_RESULT_MSG_INVALID_CARD." : ".$result["card_status"];
  734. return $result;
  735. }
  736. }else{
  737. // 未知卡片處理
  738. $this->twgc_notfound_handler($balance_inquiry_result["result_code"], $lpr, $barcode);
  739. // 查詢barcode失敗
  740. $result = array();
  741. $result["result_code"] = ALLPA_RESULT_CODE_ERROR_balance_inquiry;
  742. $result["result_msg"] = $balance_inquiry_result["result_msg"];
  743. return $result;
  744. }
  745. // B.2 取得儲值的PIN碼
  746. $get_otpin_result = $this->get_otpin($barcode, $order_no);
  747. if($get_otpin_result["result_code"] == ALLPA_RESULT_CODE_OK){
  748. $password_type = $get_otpin_result["password_type"]; // PasswordType:不處理
  749. $encoded_pic = $get_otpin_result["encoded_pic"]; // EncodedPIC:密碼圖檔,以base64編碼 (文件少一個 d);
  750. $valid_time = $get_otpin_result["valid_time"]; // ValidTime:密碼有效時間 (分)
  751. $valid_before = $get_otpin_result["valid_before"]; // ValidBefore:相對於上傳的本機時間, 密碼到期時間
  752. // 建立PIN CHECK
  753. $data = array();
  754. $data['lpr'] = $lpr;
  755. $data['barcode'] = $barcode;
  756. $data['order_no'] = $order_no;
  757. $data['password_type'] = $password_type;
  758. $data['valid_time'] = $valid_time;
  759. $data['valid_before'] = $valid_before;
  760. $this->db->insert('allpa_pin_check', $data);
  761. $pin_check_id = $this->db->insert_id();
  762. // 回傳
  763. $result = array();
  764. $result['pin_check_id'] = $pin_check_id;
  765. $result['lpr'] = $lpr;
  766. $result['barcode'] = $barcode;
  767. $result['order_no'] = $order_no;
  768. $result['product_name'] = $product_name;
  769. $result['product_desc'] = $product_desc;
  770. $result['remarks'] = $remarks;
  771. $result["amount_before"] = $userAmount;
  772. $result['amt'] = $cardAmount;
  773. $result["encoded_pic"] = $encoded_pic;
  774. $result["valid_before"] = $valid_before;
  775. $result["result_code"] = ALLPA_RESULT_CODE_OK;
  776. $result["result_msg"] = ALLPA_RESULT_MSG_OK;
  777. return $result;
  778. }else{
  779. // 取得儲值的PIN碼失敗
  780. $result = array();
  781. $result["result_code"] = ALLPA_RESULT_CODE_ERROR_get_otpin;
  782. $result["result_msg"] = $get_otpin_result["result_msg"];
  783. return $result;
  784. }
  785. }
  786. }
  787. // 查詢, 卡片資訊
  788. public function get_barcode_info($barcode)
  789. {
  790. $data = array();
  791. // A. 取得卡片資訊
  792. $results = $this->db->select('lpr, barcode, status')
  793. ->from('allpa_user')
  794. ->where('barcode', $barcode)
  795. ->get()
  796. ->result_array();
  797. foreach($results as $idx => $rows)
  798. {
  799. switch($rows['status']){
  800. case 1: // 啟用中
  801. // 跳到顯示個資的流程??
  802. return $this->get_allpa_info($rows['lpr']);
  803. break;
  804. default: // 其它
  805. $data['result']['allpa_other'][$idx] = array
  806. (
  807. 'lpr' => $rows['lpr'],
  808. 'status' => $rows['status']
  809. );
  810. }
  811. }
  812. // B.1 查詢barcode
  813. $balance_inquiry_result = $this->balance_inquiry($barcode);
  814. if($balance_inquiry_result["result_code"] == ALLPA_RESULT_CODE_OK){
  815. $data["balance"] = $balance_inquiry_result["balance"];
  816. $data["card_status"] = $balance_inquiry_result["card_status"];
  817. $data["bonus"] = $balance_inquiry_result["bonus"];
  818. }else{
  819. // 查詢barcode失敗
  820. $result = array();
  821. $result["result_code"] = ALLPA_RESULT_CODE_ERROR_balance_inquiry;
  822. $result["result_msg"] = $balance_inquiry_result["result_msg"];
  823. return $result;
  824. }
  825. $data["barcode"] = $barcode;
  826. $data["result_code"] = ALLPA_RESULT_CODE_OK;
  827. $data["result_msg"] = ALLPA_RESULT_MSG_OK;
  828. return $data;
  829. }
  830. // 查詢, 歐Pa卡資訊
  831. public function get_allpa_info($user_lpr)
  832. {
  833. $data = array();
  834. // A. 取得卡片資訊
  835. $results = $this->db->select('lpr, barcode, status')
  836. ->from('allpa_user')
  837. ->where('lpr', $user_lpr)
  838. ->get()
  839. ->result_array();
  840. foreach($results as $idx => $rows)
  841. {
  842. switch($rows['status']){
  843. case 1: // 啟用中
  844. // B.1 查詢barcode
  845. $barcode = $rows['barcode'];
  846. $balance_inquiry_result = $this->balance_inquiry($barcode);
  847. $balance = 0;
  848. $bonus = 0;
  849. if($balance_inquiry_result["result_code"] == ALLPA_RESULT_CODE_OK){
  850. $balance = $balance_inquiry_result["balance"]; // 卡片餘額
  851. $bonus = $balance_inquiry_result["bonus"]; // 卡片紅利點數
  852. if($balance_inquiry_result["status_code"] == "01"){
  853. // 唯一, 有效
  854. $data['result']['allpa_current'] = array
  855. (
  856. 'lpr' => $user_lpr,
  857. 'barcode' => $barcode,
  858. 'balance' => $balance,
  859. 'bonus' => $bonus,
  860. 'card_status' => $balance_inquiry_result["card_status"]
  861. );
  862. }else{
  863. // 卡片未開通
  864. $data['result']['allpa_invalid'] = array
  865. (
  866. 'lpr' => $user_lpr,
  867. 'barcode' => $barcode,
  868. 'balance' => $balance,
  869. 'bonus' => $bonus,
  870. 'card_status' => $balance_inquiry_result["card_status"]
  871. );
  872. }
  873. }else{
  874. // 未知卡片處理
  875. $this->twgc_notfound_handler($balance_inquiry_result["result_code"], $user_lpr, $barcode);
  876. // 查詢barcode失敗
  877. $data['result']['allpa_error'][$idx] = array
  878. (
  879. 'lpr' => $user_lpr,
  880. 'barcode' => $barcode,
  881. 'result_code' => $balance_inquiry_result["result_code"],
  882. 'result_msg' => $balance_inquiry_result["result_msg"]
  883. );
  884. }
  885. break;
  886. default: // 其它
  887. $data['result']['allpa_other'][$idx] = array
  888. (
  889. 'lpr' => $user_lpr,
  890. 'barcode' => $rows['barcode'],
  891. 'status' => $rows['status']
  892. );
  893. }
  894. }
  895. // B. 取得帳單資訊
  896. $results = $this->db->select('order_no, product_bill.amt as amt, product_bill.product_plan as product_plan, tx_time, status, product_name, product_desc')
  897. ->from('product_bill')
  898. ->join('products', 'products.product_id = product_bill.product_id', 'left')
  899. ->where('product_bill.lpr', $user_lpr)
  900. //->where('product_bill.product_code', PRODUCT_CODE)
  901. ->where_in('product_bill.status', array(1, 111))
  902. ->order_by("status ASC, update_time DESC")
  903. ->limit(3)
  904. ->get()
  905. ->result_array();
  906. foreach($results as $idx => $rows)
  907. {
  908. switch($rows['status']){ // '狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 111:產品已領取'
  909. case 1: // 結帳完成
  910. $data['result']['bill_ready'][$idx] = array
  911. (
  912. 'order_no' => $rows['order_no'],
  913. 'amt' => $rows['amt'],
  914. 'product_plan' => $rows['product_plan'] ,
  915. 'product_name' => $rows['product_name'] ,
  916. 'product_desc' => $rows['product_desc'] ,
  917. 'tx_time' => $rows['tx_time'] ,
  918. 'status' => $rows['status']
  919. );
  920. break;
  921. case 111: // 產品已領取
  922. $data['result']['bill_finished'][$idx] = array
  923. (
  924. 'order_no' => $rows['order_no'],
  925. 'amt' => $rows['amt'],
  926. 'product_plan' => $rows['product_plan'] ,
  927. 'product_name' => $rows['product_name'] ,
  928. 'product_desc' => $rows['product_desc'] ,
  929. 'tx_time' => $rows['tx_time'] ,
  930. 'status' => $rows['status']
  931. );
  932. break;
  933. }
  934. }
  935. // C. 取得歐Pa卡用戶帳單資訊
  936. $results = $this->db->select('order_no, barcode, station_no, in_time, balance_time, amt, status')
  937. ->from('allpa_user_bill')
  938. ->where(array('lpr' => $user_lpr))
  939. ->order_by("balance_time DESC")
  940. ->limit(3)
  941. ->get()
  942. ->result_array();
  943. foreach($results as $idx => $rows)
  944. {
  945. switch($rows['status']){ // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:交易失敗
  946. case 1: // 結帳完成
  947. $data['result']['allpa_user_bill_finished'][$idx] = array
  948. (
  949. 'order_no' => $rows['order_no'],
  950. 'barcode' => $rows['barcode'],
  951. 'station_no' => $rows['station_no'],
  952. 'in_time' => $rows['in_time'],
  953. 'balance_time' => $rows['balance_time'],
  954. 'amt' => $rows['amt'],
  955. 'status' => $rows['status']
  956. );
  957. break;
  958. case 2: // 錢沒對上
  959. $data['result']['allpa_user_bill_gg'][$idx] = array
  960. (
  961. 'order_no' => $rows['order_no'],
  962. 'barcode' => $rows['barcode'],
  963. 'station_no' => $rows['station_no'],
  964. 'in_time' => $rows['in_time'],
  965. 'balance_time' => $rows['balance_time'],
  966. 'amt' => $rows['amt'],
  967. 'status' => $rows['status']
  968. );
  969. break;
  970. default: // 未付款
  971. $data['result']['allpa_user_bill_debt'][$idx] = array
  972. (
  973. 'order_no' => $rows['order_no'],
  974. 'barcode' => $rows['barcode'],
  975. 'station_no' => $rows['station_no'],
  976. 'in_time' => $rows['in_time'],
  977. 'balance_time' => $rows['balance_time'],
  978. 'amt' => $rows['amt'],
  979. 'status' => $rows['status']
  980. );
  981. break;
  982. }
  983. }
  984. // 判斷是否有資料
  985. if(empty($data)){
  986. $result = array();
  987. $result["result_code"] = ALLPA_RESULT_CODE_NOT_FOUND;
  988. $result["result_msg"] = ALLPA_RESULT_MSG_NOT_FOUND;
  989. return $result; // NOT FOUND
  990. }
  991. $data["result_code"] = ALLPA_RESULT_CODE_OK;
  992. $data["result_msg"] = ALLPA_RESULT_MSG_OK;
  993. return $data;
  994. }
  995. // 取得歐Pa卡產品清單 (管理者專用)
  996. public function get_allpa_admin_products()
  997. {
  998. return $this->get_allpa_products(ADMIN_PRODUCT_CODE);
  999. }
  1000. // 取得歐Pa卡產品清單
  1001. public function get_allpa_products($product_code=PRODUCT_CODE)
  1002. {
  1003. $data = array();
  1004. $now = date('Y/m/d H:i:s');
  1005. $result = $this->db->select('product_id, product_name, product_desc, amt, remarks')
  1006. ->from('products')
  1007. ->where(array(
  1008. 'start_time <= ' => $now,
  1009. 'valid_time > ' => $now,
  1010. 'product_code' => $product_code
  1011. ))
  1012. ->get()
  1013. ->result_array();
  1014. return $result;
  1015. }
  1016. // 建立歐Pa卡帳單 (管理者專用)
  1017. public function create_admin_bill($product_id)
  1018. {
  1019. return $this->create_bill($product_id, ADMIN_PRODUCT_CODE);
  1020. }
  1021. // 建立歐Pa卡帳單
  1022. public function create_bill($product_id, $product_code=PRODUCT_CODE)
  1023. {
  1024. $now = date('Y/m/d H:i:s');
  1025. $product = $this->db->select('product_id, product_name, product_desc, amt, remarks, product_code, product_plan')
  1026. ->from('products')
  1027. ->where(array(
  1028. 'product_id' => $product_id,
  1029. 'start_time <= ' => $now,
  1030. 'valid_time > ' => $now,
  1031. 'product_code' => $product_code
  1032. ))
  1033. ->limit(1)
  1034. ->get()
  1035. ->row_array();
  1036. if(empty($product)){
  1037. $result = array();
  1038. $result["result_code"] = ALLPA_RESULT_CODE_NOT_FOUND;
  1039. $result["result_msg"] = ALLPA_RESULT_MSG_NOT_FOUND;
  1040. return $result; // NOT FOUND
  1041. }
  1042. // create product_bill
  1043. $data = array();
  1044. $data['order_no'] = $this->gen_trx_no();
  1045. $data['product_id'] = $product["product_id"];
  1046. $data['product_code'] = $product["product_code"];
  1047. $data['product_plan'] = $product["product_plan"];
  1048. $data['invoice_remark'] = $product["product_name"];
  1049. $data['amt'] = $product["amt"];
  1050. $data['valid_time'] = date('Y-m-d H:i:s', strtotime($now) + 60 * 15); // 15 min
  1051. $this->db->insert('product_bill', $data);
  1052. $data['product_name'] = $product["product_name"];
  1053. $data['product_desc'] = $product["product_desc"];
  1054. $data['remarks'] = $product["remarks"];
  1055. $data["result_code"] = ALLPA_RESULT_CODE_OK;
  1056. $data["result_msg"] = ALLPA_RESULT_MSG_OK;
  1057. return $data;
  1058. }
  1059. // 建立產品帳單 (限定 CTBC)
  1060. public function pay_bill($lpr, $order_no, $invoice_receiver, $company_no, $email, $mobile)
  1061. {
  1062. $data = $this->db
  1063. ->from('product_bill')
  1064. ->where(array('order_no' => $order_no))
  1065. ->limit(1)
  1066. ->get()
  1067. ->row_array();
  1068. if (!empty($data['valid_time']))
  1069. {
  1070. $data['lpr'] = $lpr; // 車牌號碼
  1071. if(strlen($invoice_receiver) >= 7){ // 手機載具編號
  1072. $data['invoice_receiver'] = '/'.$invoice_receiver;
  1073. }
  1074. if(strlen($company_no) >= 8){ // 公司統編
  1075. $data['company_no'] = $company_no;
  1076. $data['company_receiver'] = "公司名稱";
  1077. $data['company_address'] = "公司地址";
  1078. }
  1079. if(strlen($email) >= 5){ // a@b.c
  1080. $data['email'] = $email;
  1081. }
  1082. if(strlen($mobile) >= 10){ // 手機
  1083. $data['mobile'] = $mobile;
  1084. }
  1085. $txTime = time(); // 產生交易時間
  1086. if(strtotime($data['valid_time']) - $txTime > 0){
  1087. $data['status'] = 100; //狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
  1088. $data['tx_time'] = date('Y/m/d H:i:s', $txTime);
  1089. $data['tx_type'] = 60; // 交易種類: 0:未定義, 1:現金, 40:博辰人工模組, 41:博辰自動繳費機, 50:歐付寶轉址刷卡, 51:歐付寶APP, 52:歐付寶轉址WebATM, 60:中國信託刷卡轉址
  1090. $this->db->update('product_bill', $data, array('order_no' => $order_no));
  1091. return $data;
  1092. }
  1093. $data['status'] = 99; //狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
  1094. $this->db->update('product_bill', $data, array('order_no' => $order_no));
  1095. return null;
  1096. }
  1097. trigger_error(__FUNCTION__."|{$order_no}|無資料");
  1098. }
  1099. // 取得產品帳單
  1100. public function get_product_bill($order_no)
  1101. {
  1102. $result = $this->db->from('product_bill')
  1103. ->where(array('order_no' => $order_no))
  1104. ->limit(1)
  1105. ->get()
  1106. ->row_array();
  1107. return $result;
  1108. }
  1109. // 取得使用中的歐Pa用戶
  1110. public function get_valid_user($lpr)
  1111. {
  1112. $user = $this->db->select('lpr, status_code, balance, barcode, bonus')
  1113. ->from('allpa_user')
  1114. ->where(array('lpr' => $lpr, 'status' => 1)) // '狀態: 0:剛建立, 1:啟用中, 2:啟用記名失敗, 99:已停用'
  1115. ->limit(1)
  1116. ->get()
  1117. ->row_array();
  1118. return $user;
  1119. }
  1120. // 狀態: 產品已領取
  1121. public function transfer_money_done_and_finished($order_no)
  1122. {
  1123. $data = array();
  1124. $data['status'] = 111; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
  1125. $this->db->update('product_bill', $data, array('order_no' => $order_no));
  1126. return true;
  1127. }
  1128. // 狀態: 結帳完成
  1129. public function transfer_money_done($order_no)
  1130. {
  1131. $data = array();
  1132. $data['status'] = 1; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
  1133. $this->db->update('product_bill', $data, array('order_no' => $order_no));
  1134. return true;
  1135. }
  1136. // 狀態: 錢沒對上
  1137. public function transfer_money_done_with_amt_error($order_no)
  1138. {
  1139. $data = array();
  1140. $data['status'] = 2; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
  1141. $this->db->update('product_bill', $data, array('order_no' => $order_no));
  1142. return true;
  1143. }
  1144. // 狀態: 交易失敗
  1145. public function transfer_money_done_with_tx_error($order_no)
  1146. {
  1147. $data = array();
  1148. $data['status'] = 101; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
  1149. $this->db->update('product_bill', $data, array('order_no' => $order_no));
  1150. return true;
  1151. }
  1152. // 狀態: 發票沒建立
  1153. public function transfer_money_set_invoice_error($order_no)
  1154. {
  1155. $data = array();
  1156. $data['status'] = 3; // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中, 101: 交易失敗, 111:產品已領取
  1157. $this->db->update('product_bill', $data, array('order_no' => $order_no));
  1158. return true;
  1159. }
  1160. // [公司內部呼叫] 歐Pa卡 - 開門
  1161. public function allpa_go($in_time, $lpr, $station_no, $check_mac)
  1162. {
  1163. if(empty($check_mac) || md5($in_time.$lpr.$station_no) != $check_mac){
  1164. // check mac fail
  1165. $result = array();
  1166. $result["result_code"] = ALLPA_GO_RESULT_CODE_CK_ERROR;
  1167. $result["result_msg"] = ALLPA_GO_RESULT_MSG_CK_ERROR;
  1168. return $result; // CK ERROR
  1169. }
  1170. require_once(ALTOB_BILL_FILE); // 臨停費率
  1171. $oPayment = new AltobPayment();
  1172. $oPayment->ServiceURL = "http://localhost/txdata.html";
  1173. $in_time = date('Y-m-d H:i:s', $in_time);
  1174. $balance_time = date('Y-m-d H:i:s');
  1175. $bill = $oPayment->getBill($in_time, $balance_time, $station_no);
  1176. $price = $bill[BillResultKey::price];
  1177. // 查有效用戶
  1178. $user = $this->get_valid_user($lpr);
  1179. $barcode = $user["barcode"];
  1180. if(empty($user)){
  1181. $result = array();
  1182. $result["result_code"] = ALLPA_GO_RESULT_CODE_USER_NOT_FOUND;
  1183. $result["result_msg"] = ALLPA_GO_RESULT_MSG_USER_NOT_FOUND;
  1184. return $result; // USER NOT FOUND
  1185. }
  1186. // 查欠款
  1187. $allpa_user_bill = $this->db->select('station_no, amt')
  1188. ->from('allpa_user_bill')
  1189. ->where(array('lpr' => $lpr))
  1190. ->where_not_in('status', 1) // '狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:交易失敗'
  1191. ->limit(1)
  1192. ->get()
  1193. ->row_array();
  1194. if(! empty($allpa_user_bill)){
  1195. $result = array();
  1196. $result["result_code"] = ALLPA_GO_RESULT_CODE_DEBT;
  1197. $result["result_msg"] = ALLPA_GO_RESULT_MSG_DEBT;
  1198. return $result; // DEBT
  1199. }
  1200. // 檢查扣款條件
  1201. if(! $this->is_money_enough($user["balance"], $user["bonus"], $price)){
  1202. $result = array();
  1203. $result["result_code"] = ALLPA_GO_RESULT_CODE_NO_MONEY;
  1204. $result["result_msg"] = ALLPA_GO_RESULT_MSG_NO_MONEY;
  1205. $result["amt"] = $price;
  1206. return $result; // NO MONEY
  1207. }
  1208. /* 2016/03/28 不查log了
  1209. $recent_balance_log = $this->db->select('balance, bonus')
  1210. ->from('allpa_balance_log')
  1211. ->where(array('lpr' => $lpr, 'barcode' => $barcode))
  1212. ->order_by("create_time", "desc")
  1213. ->limit(1)
  1214. ->get()
  1215. ->row_array();
  1216. // 檢查扣款條件
  1217. if(! $this->is_money_enough($recent_balance_log["balance"], $recent_balance_log["bonus"], $price)){
  1218. $result = array();
  1219. $result["result_code"] = ALLPA_GO_RESULT_CODE_NO_MONEY;
  1220. $result["result_msg"] = ALLPA_GO_RESULT_MSG_NO_MONEY;
  1221. $result["amt"] = $price;
  1222. return $result; // NO MONEY
  1223. }
  1224. */
  1225. // 產生交易序號
  1226. $order_no = $this->gen_trx_no();
  1227. // 產生用戶帳單
  1228. $data = array();
  1229. $data['order_no'] = $order_no;
  1230. $data['barcode'] = $barcode;
  1231. $data['lpr'] = $lpr;
  1232. $data['station_no'] = $station_no;
  1233. $data['in_time'] = $in_time;
  1234. $data['balance_time'] = $balance_time;
  1235. $data['amt'] = $price;
  1236. $this->db->insert('allpa_user_bill', $data);
  1237. // 可以開門了
  1238. $result = array();
  1239. $result["result_code"] = ALLPA_GO_RESULT_CODE_OK;
  1240. $result["result_msg"] = ALLPA_GO_RESULT_MSG_OK;
  1241. $result["order_no"] = $order_no;
  1242. $result["amt"] = $price;
  1243. return $result;
  1244. }
  1245. // 歐Pa卡帳單 - 扣款
  1246. public function allpa_pay_bill($order_no)
  1247. {
  1248. // 取得歐Pa卡帳單
  1249. $allpa_user_bill = $this->db->select('lpr, barcode, amt')
  1250. ->from('allpa_user_bill')
  1251. ->where(array('order_no' => $order_no))
  1252. ->where_not_in('status', 1) // '狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:交易失敗'
  1253. ->limit(1)
  1254. ->get()
  1255. ->row_array();
  1256. if(empty($allpa_user_bill)){
  1257. $result = array();
  1258. $result["result_code"] = ALLPA_GO_RESULT_CODE_BILL_NOT_FOUND;
  1259. $result["result_msg"] = ALLPA_GO_RESULT_MSG_BILL_NOT_FOUND;
  1260. return $result; // BILL NOT FOUND
  1261. }
  1262. $lpr = $allpa_user_bill["lpr"];
  1263. $order_barcode = $allpa_user_bill["barcode"]; // 當時產生帳單時的barcode (規則是要唯一, 但意外可能發生)
  1264. $price = $allpa_user_bill["amt"];
  1265. // 查有效用戶
  1266. $user = $this->get_valid_user($lpr);
  1267. $barcode = $user["barcode"];
  1268. if(empty($user)){
  1269. $result = array();
  1270. $result["result_code"] = ALLPA_GO_RESULT_CODE_USER_NOT_FOUND;
  1271. $result["result_msg"] = ALLPA_GO_RESULT_MSG_USER_NOT_FOUND;
  1272. return $result; // USER NOT FOUND
  1273. }
  1274. // 查遠端餘額
  1275. $pre_status_code = "";
  1276. $pre_balance = 0;
  1277. $pre_bonus = 0;
  1278. $balance_inquiry_result = $this->balance_inquiry($barcode);
  1279. if($balance_inquiry_result["result_code"] == ALLPA_RESULT_CODE_OK){
  1280. $pre_status_code = $balance_inquiry_result["status_code"];
  1281. $pre_balance = $balance_inquiry_result["balance"];
  1282. $pre_bonus = $balance_inquiry_result["bonus"];
  1283. }else{
  1284. // 未知卡片處理
  1285. $this->twgc_notfound_handler($balance_inquiry_result["result_code"], $lpr, $barcode);
  1286. // 查詢barcode失敗
  1287. $result = array();
  1288. $result["result_code"] = ALLPA_RESULT_CODE_ERROR_balance_inquiry;
  1289. $result["result_msg"] = $balance_inquiry_result["result_msg"];
  1290. return $result;
  1291. }
  1292. // 記錄是否出現未知斷層
  1293. if( $pre_status_code != $user["status_code"] ||
  1294. $pre_balance != $user["balance"] ||
  1295. $pre_bonus != $user["bonus"]) {
  1296. $unknown_trx_no = $this->gen_trx_no();
  1297. // 產生一筆未知的balance_log
  1298. $this->create_allpa_unknown_log(
  1299. $unknown_trx_no, $lpr, $barcode,
  1300. $user["status_code"], $user["balance"], $user["bonus"],
  1301. $order_no);
  1302. }
  1303. /* 2016/03/28 不查log了
  1304. $recent_balance_log = $this->db->select('status_code, balance, bonus')
  1305. ->from('allpa_balance_log')
  1306. ->where(array('lpr' => $lpr, 'barcode' => $barcode))
  1307. ->order_by("create_time", "desc")
  1308. ->limit(1)
  1309. ->get()
  1310. ->row_array();
  1311. // 記錄是否出現未知斷層
  1312. if( $pre_status_code != $recent_balance_log["status_code"] ||
  1313. $pre_balance != $recent_balance_log["balance"] ||
  1314. $pre_bonus != $recent_balance_log["bonus"]) {
  1315. $unknown_trx_no = $this->gen_trx_no();
  1316. // 產生一筆未知的balance_log
  1317. $this->create_allpa_unknown_log(
  1318. $unknown_trx_no, $lpr, $barcode,
  1319. $recent_balance_log["status_code"], $recent_balance_log["balance"], $recent_balance_log["bonus"],
  1320. $order_no);
  1321. }*/
  1322. // 檢查扣款條件
  1323. if(! $this->is_money_enough($pre_balance, $pre_bonus, $price)){
  1324. $result = array();
  1325. $result["result_code"] = ALLPA_GO_RESULT_CODE_NO_MONEY;
  1326. $result["result_msg"] = ALLPA_GO_RESULT_MSG_NO_MONEY;
  1327. return $result; // NO MONEY
  1328. }
  1329. // 扣款
  1330. $allpa_consume_result = $this->allpa_consume($lpr, $barcode, $price, $order_no);
  1331. if($allpa_consume_result["result_code"] == ALLPA_RESULT_CODE_OK){
  1332. // 新增卡片使用記錄
  1333. $this->create_allpa_consume_log(
  1334. $allpa_consume_result["cust_trx_no"], $lpr, $barcode,
  1335. $pre_status_code, $pre_balance, $pre_bonus,
  1336. $order_no);
  1337. // 更新帳單資訊
  1338. if($pre_balance + $pre_bonus == $allpa_consume_result["balance"] + $allpa_consume_result["bonus"] + $price){
  1339. $data = array();
  1340. $data['status'] = 1; // '狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:交易失敗'
  1341. $this->db->update('allpa_user_bill', $data, array('order_no' => $order_no));
  1342. }else{
  1343. $data = array();
  1344. $data['status'] = 2; // '狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:交易失敗'
  1345. $this->db->update('allpa_user_bill', $data, array('order_no' => $order_no));
  1346. }
  1347. $result = array();
  1348. $result["result_code"] = ALLPA_GO_RESULT_CODE_OK;
  1349. $result["result_msg"] = ALLPA_GO_RESULT_MSG_OK;
  1350. $result["lpr"] = $lpr;
  1351. return $result;
  1352. }else{
  1353. // 更新帳單資訊
  1354. $data = array();
  1355. $data['status'] = 3; // '狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:交易失敗'
  1356. $this->db->update('allpa_user_bill', $data, array('order_no' => $order_no));
  1357. $result = array();
  1358. $result["result_code"] = ALLPA_GO_RESULT_CODE_CONSUME_ERROR;
  1359. $result["result_msg"] = $allpa_consume_result["result_msg"];
  1360. return $result; // CONSUME ERROR
  1361. }
  1362. }
  1363. // 歐Pa卡 - 判斷有效用戶
  1364. public function get_allpa_valid_user($lpr, $check_mac)
  1365. {
  1366. if(empty($check_mac) || md5($lpr) != $check_mac){
  1367. // check mac fail
  1368. $result = array();
  1369. $result["result_code"] = ALLPA_GO_RESULT_CODE_CK_ERROR;
  1370. $result["result_msg"] = ALLPA_GO_RESULT_MSG_CK_ERROR;
  1371. return $result; // CK ERROR
  1372. }
  1373. // 查有效用戶
  1374. $user = $this->get_valid_user($lpr);
  1375. if(empty($user)){
  1376. $result = array();
  1377. $result["result_code"] = ALLPA_GO_RESULT_CODE_USER_NOT_FOUND;
  1378. $result["result_msg"] = ALLPA_GO_RESULT_MSG_USER_NOT_FOUND;
  1379. return $result; // USER NOT FOUND
  1380. }
  1381. $result = array();
  1382. $result["result_code"] = ALLPA_GO_RESULT_CODE_OK;
  1383. $result["result_msg"] = ALLPA_GO_RESULT_MSG_OK;
  1384. $result["lpr"] = $user["lpr"];
  1385. $result["barcode"] = $user["barcode"];
  1386. $result["balance"] = $user["balance"];
  1387. $result["bonus"] = $user["bonus"];
  1388. return $result;
  1389. }
  1390. }