VM暫存
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

1059 řádky
36KB

  1. <?php
  2. /*
  3. file: Allpay_invoice_model.php 電子發票 (歐付寶)
  4. */
  5. require_once(ALLPAY_INVOICE_FILE) ;
  6. class Allpay_invoice_model extends CI_Model
  7. {
  8. function __construct()
  9. {
  10. parent::__construct();
  11. $this->load->database();
  12. // ----- 測試環境設定 -----
  13. define('ALLPAY_INVOICE_TEST_MerchantID', "2000132");
  14. define('ALLPAY_INVOICE_TEST_HashKey', "ejCk326UnaZWKisg");
  15. define('ALLPAY_INVOICE_TEST_HashIV', "q9jcZX8Ib9LM8wYk");
  16. define('ALLPAY_INVOICE_TEST_SERVICE_PATH', "https://einvoice-stage.allpay.com.tw");
  17. // ----- 測試環境設定(end) -----
  18. // ----- 正式環境設定 (總公司) -----
  19. define('ALLPAY_INVOICE_80682490_MerchantID', "1148391"); // 80682490
  20. define('ALLPAY_INVOICE_80682490_HashKey', "Pjkm8Tun7neLqTtj");
  21. define('ALLPAY_INVOICE_80682490_HashIV', "eLKm6GgvetijrRcc");
  22. define('ALLPAY_INVOICE_80682490_SERVICE_PATH', "https://einvoice.allpay.com.tw/");
  23. // ----- 正式環境設定(end) -----
  24. // ----- 正式環境設定 (場站) -----
  25. define('ALLPAY_INVOICE_MerchantID', "1148391"); // 80682490 (待切換為對應場站)
  26. define('ALLPAY_INVOICE_HashKey', "Pjkm8Tun7neLqTtj");
  27. define('ALLPAY_INVOICE_HashIV', "eLKm6GgvetijrRcc");
  28. define('ALLPAY_INVOICE_SERVICE_PATH', "https://einvoice.allpay.com.tw/");
  29. // ----- 正式環境設定(end) -----
  30. // 切換 FLAG
  31. define('ALLPAY_INVOICE_TEST_FLAG', "test");
  32. define('ALLPAY_INVOICE_MAIN_FLAG', "80682490");
  33. define('ALLPAY_INVOICE_STATION_FLAG', "station");
  34. // 5.一般開立發票 API
  35. define('ALLPAY_INVOICE_Invoice_Issue_Method', "INVOICE");
  36. define('ALLPAY_INVOICE_Invoice_Issue_Url', "/Invoice/Issue");
  37. // 7.開立折讓 API
  38. define('ALLPAY_INVOICE_Allowance_Method', "ALLOWANCE");
  39. define('ALLPAY_INVOICE_Allowance_Url', "/Invoice/Allowance");
  40. // 8.發票作廢 API
  41. define('ALLPAY_INVOICE_Invoice_Void_Method', "INVOICE_VOID");
  42. define('ALLPAY_INVOICE_Invoice_Void_Url', "/Invoice/IssueInvalid");
  43. // 10.折讓作廢 API
  44. define('ALLPAY_INVOICE_Allowance_Void_Method', "ALLOWANCE_VOID");
  45. define('ALLPAY_INVOICE_Allowance_Void_Url', "/Invoice/AllowanceInvalid");
  46. // 14.通知 API
  47. define('ALLPAY_INVOICE_Invoice_Notify_Method', "INVOICE_NOTIFY");
  48. define('ALLPAY_INVOICE_Invoice_Notify_Url', "/Notify/InvoiceNotify");
  49. // ----- 回傳訊息 -----
  50. define('ALLPAY_INVOICE_RESULT_CODE_OK', "OK");
  51. define('ALLPAY_INVOICE_RESULT_MSG_OK', "成功");
  52. define('ALLPAY_INVOICE_RESULT_CODE_NOT_FOUND', "-1");
  53. define('ALLPAY_INVOICE_RESULT_MSG_NOT_FOUND', "找不到資料");
  54. define('ALLPAY_INVOICE_RESULT_CODE_INVOICE_ERROR', "-2");
  55. define('ALLPAY_INVOICE_RESULT_MSG_INVOICE_ERROR', "錯誤回傳");
  56. define('ALLPAY_INVOICE_RESULT_CODE_COMPANY_NO_ERROR', "-10");
  57. define('ALLPAY_INVOICE_RESULT_MSG_COMPANY_NO_ERROR', "統編有誤");
  58. define('ALLPAY_INVOICE_RESULT_CODE_GG', "-99");
  59. define('ALLPAY_INVOICE_RESULT_MSG_GG', "異常");
  60. // ----- 回傳訊息 (END) -----
  61. }
  62. // 載入歐付寶電子發票
  63. function load_allpay_invoice_by_flag($flag)
  64. {
  65. // 1.載入 SDK 程式
  66. $allpay_invoice = new AllInvoice ;
  67. $allpay_invoice->MerchantID = $this->get_allpay_merchant_id($flag) ;
  68. // 2.寫入基本介接參數
  69. switch($flag)
  70. {
  71. case ALLPAY_INVOICE_TEST_FLAG: // 測試環境
  72. $allpay_invoice->HashKey = ALLPAY_INVOICE_TEST_HashKey ;
  73. $allpay_invoice->HashIV = ALLPAY_INVOICE_TEST_HashIV ;
  74. break;
  75. case ALLPAY_INVOICE_MAIN_FLAG: // 總公司
  76. $allpay_invoice->HashKey = ALLPAY_INVOICE_80682490_HashKey ;
  77. $allpay_invoice->HashIV = ALLPAY_INVOICE_80682490_HashIV ;
  78. break;
  79. default: // 場站
  80. $allpay_invoice->HashKey = ALLPAY_INVOICE_HashKey ;
  81. $allpay_invoice->HashIV = ALLPAY_INVOICE_HashIV ;
  82. break;
  83. }
  84. return $allpay_invoice;
  85. }
  86. // 載入歐付寶電子發票 (由歐付寶廠商編號)
  87. function load_allpay_invoice_by_merchant_id($merchant_id)
  88. {
  89. // 1.載入 SDK 程式
  90. $allpay_invoice = new AllInvoice ;
  91. $allpay_invoice->MerchantID = $merchant_id;
  92. // 2.寫入基本介接參數
  93. switch($merchant_id)
  94. {
  95. case ALLPAY_INVOICE_TEST_MerchantID: // 測試環境
  96. $allpay_invoice->HashKey = ALLPAY_INVOICE_TEST_HashKey ;
  97. $allpay_invoice->HashIV = ALLPAY_INVOICE_TEST_HashIV ;
  98. break;
  99. case ALLPAY_INVOICE_80682490_MerchantID: // 總公司
  100. $allpay_invoice->HashKey = ALLPAY_INVOICE_80682490_HashKey ;
  101. $allpay_invoice->HashIV = ALLPAY_INVOICE_80682490_HashIV ;
  102. break;
  103. default: // 場站
  104. $allpay_invoice->HashKey = ALLPAY_INVOICE_HashKey ;
  105. $allpay_invoice->HashIV = ALLPAY_INVOICE_HashIV ;
  106. break;
  107. }
  108. return $allpay_invoice;
  109. }
  110. // 取得歐付寶店家編號
  111. function get_allpay_merchant_id($flag)
  112. {
  113. $id = 0;
  114. switch($flag)
  115. {
  116. case ALLPAY_INVOICE_TEST_FLAG: // 測試環境
  117. $id = ALLPAY_INVOICE_TEST_MerchantID ;
  118. break;
  119. case ALLPAY_INVOICE_MAIN_FLAG: // 總公司
  120. $id = ALLPAY_INVOICE_80682490_MerchantID ;
  121. break;
  122. default: // 場站
  123. $id = ALLPAY_INVOICE_MerchantID ;
  124. break;
  125. }
  126. return $id;
  127. }
  128. // Z.1 產生交易編號
  129. function gen_tx_bill_ats_order_no($tx_bill_no)
  130. {
  131. return time().str_pad($tx_bill_no, 10, '0', STR_PAD_LEFT);
  132. }
  133. // Z.2 由交易編號取得會員交易編號
  134. function get_tx_bill_no_from_order_no($order_no)
  135. {
  136. return intval(substr($order_no, -10));
  137. }
  138. // M.1 開立月租系統發票 (情境: 1. 新增會員開立, 2. 繳租開立, 3. 退租戶補開立, 4. 拆分的金額接續開立)
  139. public function create_member_tx_bill_invoice($station_no, $tx_bill_no, $amt, $member_company_no, $company_no, $email, $mobile, $lpr='')
  140. {
  141. // 暫不開放
  142. $result = array();
  143. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_GG;
  144. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_GG;
  145. return $result;
  146. // 統編不能一樣
  147. if($member_company_no == $company_no)
  148. {
  149. $result = array();
  150. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_COMPANY_NO_ERROR;
  151. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_COMPANY_NO_ERROR;
  152. return $result;
  153. }
  154. $order_no = $this->gen_tx_bill_ats_order_no($tx_bill_no); // 交易編號
  155. $invoice_flag = ($company_no == '80682490') ? ALLPAY_INVOICE_MAIN_FLAG : ALLPAY_INVOICE_STATION_FLAG; // 賣方統編切換 (總公司或場站)
  156. $company_no = $member_company_no; // 買方統編
  157. $this->db->trans_start();
  158. // 1. 建立交易記錄
  159. $this->create_bill_handler('tx_bill_ats', $station_no, $order_no, $amt,
  160. $company_no, $email, $mobile, $lpr, 'TODO', '停車費用帳單', 100);
  161. // 2. 列印歐付寶電子發票
  162. $result = $this->invoice_issue_handler('tx_bill_ats', $order_no, $amt, $invoice_flag);
  163. $this->db->trans_complete();
  164. if ($this->db->trans_status() === FALSE)
  165. {
  166. trigger_error(__FUNCTION__ . '..trans_error..data:' . "{$station_no}, {$tx_bill_no}". '| last_query: ' . $this->db->last_query());
  167. $result = array();
  168. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_GG;
  169. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_GG;
  170. }
  171. return $result;
  172. }
  173. // M.2 作廢月租系統發票 (tx_bill_ats)
  174. public function void_member_tx_bill_invoice($station_no, $order_no, $invoice_no)
  175. {
  176. // 檢查
  177. $bill = $this->db
  178. ->select('invoice_no, status')
  179. ->from('tx_bill_ats')
  180. ->where(array('invoice_no' => $invoice_no, 'order_no' => $order_no, 'station_no' => $station_no))
  181. ->limit(1)
  182. ->get()
  183. ->row_array();
  184. if (empty($bill))
  185. {
  186. $result = array();
  187. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_NOT_FOUND;
  188. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_NOT_FOUND;
  189. return $result;
  190. }
  191. else if($bill['status'] != TX_BILL_ATS_STATUS_PAID)
  192. {
  193. $result = array();
  194. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_INVOICE_ERROR;
  195. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_INVOICE_ERROR;
  196. return $result;
  197. }
  198. $result = $this->invoice_void($invoice_no, '月租發票作廢');
  199. if($result["result_code"] == ALLPAY_INVOICE_RESULT_CODE_OK)
  200. {
  201. $this->db->trans_start();
  202. // 於 tx_bill_ats 註記
  203. $this->db->update('tx_bill_ats', array('status' => TX_BILL_ATS_STATUS_INVOICE_VOID), array('station_no' => $station_no, 'invoice_no' => $invoice_no));
  204. $this->db->trans_complete();
  205. if ($this->db->trans_status() === FALSE)
  206. {
  207. trigger_error(__FUNCTION__ . '..trans_error..data:' . "{$station_no}, {$order_no}, {$invoice_no}". '| last_query: ' . $this->db->last_query());
  208. $result = array();
  209. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_GG;
  210. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_GG;
  211. }
  212. else
  213. {
  214. $result['tx_bill_no'] = $this->get_tx_bill_no_from_order_no($order_no); // 帶上 tx_bill_no
  215. }
  216. }
  217. return $result;
  218. }
  219. // M.3 折讓月租系統發票 (tx_bill_ats)
  220. public function allowance_member_tx_bill_invoice($station_no, $invoice_no, $allowance_amt)
  221. {
  222. // 檢查
  223. $bill = $this->db
  224. ->select('invoice_no, status')
  225. ->from('tx_bill_ats')
  226. ->where(array('invoice_no' => $invoice_no, 'station_no' => $station_no))
  227. ->limit(1)
  228. ->get()
  229. ->row_array();
  230. if (empty($bill))
  231. {
  232. $result = array();
  233. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_NOT_FOUND;
  234. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_NOT_FOUND;
  235. return $result;
  236. }
  237. else if($bill['status'] != TX_BILL_ATS_STATUS_PAID)
  238. {
  239. $result = array();
  240. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_INVOICE_ERROR;
  241. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_INVOICE_ERROR;
  242. return $result;
  243. }
  244. $result = $this->invoice_allowance($invoice_no, $allowance_amt, "折讓月租發票");
  245. if($result["result_code"] == ALLPAY_INVOICE_RESULT_CODE_OK)
  246. {
  247. $this->db->trans_start();
  248. // 於 tx_bill_ats 註記
  249. $this->db->update('tx_bill_ats', array('status' => TX_BILL_ATS_STATUS_INVOICE_ALLOWANCE), array('station_no' => $station_no, 'invoice_no' => $invoice_no));
  250. $this->db->trans_complete();
  251. if ($this->db->trans_status() === FALSE)
  252. {
  253. trigger_error(__FUNCTION__ . '..trans_error..data:' . "{$station_no}, {$invoice_no}, {$allowance_amt}". '| last_query: ' . $this->db->last_query());
  254. $result = array();
  255. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_GG;
  256. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_GG;
  257. }
  258. }
  259. return $result;
  260. }
  261. /*
  262. 建立消費記錄
  263. */
  264. function create_bill_handler($target_table_name, $station_no, $order_no, $amt,
  265. $company_no, $email, $mobile, $lpr, $invoice_receiver, $invoice_remark, $tx_type)
  266. {
  267. $txTime = time(); // 產生交易時間
  268. $data = array();
  269. $data['invoice_remark'] = $invoice_remark;
  270. $data['order_no'] = $order_no;
  271. $data['station_no'] = $station_no; // 場站編號
  272. $data['amt'] = $amt; // 金額
  273. $data['lpr'] = $lpr; // 車牌號碼
  274. if(strlen($invoice_receiver) >= 7){ // 手機載具編號
  275. $data['invoice_receiver'] = '/'.$invoice_receiver;
  276. }
  277. if(strlen($company_no) >= 8){ // 公司統編
  278. $data['company_no'] = $company_no;
  279. $data['company_receiver'] = "公司名稱";
  280. $data['company_address'] = "公司地址";
  281. }
  282. if(strlen($email) >= 5){ // a@b.c
  283. $data['email'] = $email;
  284. }
  285. if(strlen($mobile) >= 10){ // 手機
  286. $data['mobile'] = $mobile;
  287. }
  288. $data['status'] = TX_BILL_ATS_STATUS_PAID; //狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
  289. $data['tx_time'] = date('Y/m/d H:i:s', $txTime);
  290. $data['tx_type'] = $tx_type; // 交易種類: 0:未定義, 1:現金, 40:博辰人工模組, 41:博辰自動繳費機, 50:歐付寶轉址刷卡, 51:歐付寶APP, 52:歐付寶轉址WebATM, 60:中國信託刷卡轉址, 100:月租系統開立歐付寶發票
  291. $this->db->insert($target_table_name, $data);
  292. return $data;
  293. }
  294. // A.1 開立歐Pa卡發票 (product_bill)
  295. public function invoice_issue_for_product_bill($order_no, $amt)
  296. {
  297. return $this->invoice_issue_handler('product_bill', $order_no, $amt);
  298. }
  299. // A.2 開立臨停發票 (tx_bill)
  300. public function invoice_issue_for_tx_bill($order_no, $amt)
  301. {
  302. return $this->invoice_issue_handler('tx_bill', $order_no, $amt);
  303. }
  304. // A.3 開立繳款機發票 (tx_bill_ats)
  305. public function invoice_issue_for_tx_bill_ats($order_no, $amt)
  306. {
  307. return $this->invoice_issue_handler('tx_bill_ats', $order_no, $amt);
  308. }
  309. /*
  310. 開立發票處理入口
  311. $bill 總之要包含這些欄位
  312. order_no 交易編號
  313. status 交易狀態
  314. amt 金額
  315. company_no 公司統編
  316. company_receiver 公司收件人
  317. company_address 公司地址
  318. mobile 手機號碼
  319. email 信箱
  320. mobile_receiver 手機載具編號
  321. natural_receiver 自然人憑證條碼
  322. love_code 愛心碼
  323. invoice_remark 備註
  324. invoice_no 發票號碼
  325. */
  326. protected function invoice_issue_handler($target_table_name, $order_no, $amt, $invoice_flag=ALLPAY_INVOICE_STATION_FLAG)
  327. {
  328. try{
  329. $bill = $this->db
  330. ->select('
  331. order_no, status, amt,
  332. company_no, company_receiver, company_address,
  333. mobile, email, mobile_receiver, natural_receiver, love_code,
  334. invoice_remark, invoice_no
  335. ')
  336. ->from($target_table_name)
  337. ->where(array('order_no' => $order_no, 'amt' => $amt))
  338. ->limit(1)
  339. ->get()
  340. ->row_array();
  341. if (! empty($bill))
  342. {
  343. $invoice_issue_result = '';
  344. switch($bill['status'])
  345. {
  346. case 1: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
  347. // 印發票流程
  348. if(empty($bill['invoice_no']))
  349. {
  350. $invoice_issue_result = $this->invoice_issue($bill, $bill["invoice_remark"], $invoice_flag);
  351. }
  352. else
  353. {
  354. $sMsg = ' invoice_no is not NULL?? : '.$bill['invoice_no'];
  355. trigger_error(__FUNCTION__ .', order_no=>' . $order_no.'<br>'.$sMsg);
  356. }
  357. break;
  358. default:
  359. // 對方多傳一次時??
  360. $sMsg = ' status != 1';
  361. trigger_error(__FUNCTION__ .', order_no=>' . $order_no.'<br>'.$sMsg);
  362. }
  363. if(strlen($invoice_issue_result) == 10)
  364. {
  365. $data = array();
  366. $data['invoice_no'] = $invoice_issue_result;
  367. $this->db->update($target_table_name, $data, array('order_no' => $order_no));
  368. $result = array();
  369. $result["invoice_no"] = $invoice_issue_result;
  370. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_OK;
  371. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_OK;
  372. return $result;
  373. }
  374. else
  375. {
  376. $result = array();
  377. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_INVOICE_ERROR;
  378. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_INVOICE_ERROR;
  379. return $result;
  380. }
  381. }
  382. else
  383. {
  384. $result = array();
  385. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_NOT_FOUND;
  386. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_NOT_FOUND;
  387. return $result;
  388. }
  389. }
  390. catch (Exception $e)
  391. {
  392. // 例外錯誤處理。
  393. $sMsg = $e->getMessage();
  394. trigger_error(__FUNCTION__ .', order_no=>' . $order_no .'<br>'.$sMsg);
  395. $result = array();
  396. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_GG;
  397. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_GG;
  398. return $result;
  399. }
  400. }
  401. // 5.一般開立發票 API
  402. protected function invoice_issue($data, $invoice_remark, $invoice_flag)
  403. {
  404. $order_no = $data['order_no'];
  405. $amt = $data['amt'];
  406. // 1.載入 SDK 程式
  407. $allpay_invoice = $this->load_allpay_invoice_by_flag($invoice_flag);
  408. // 2.寫入基本介接參數
  409. $allpay_invoice->Invoice_Method = ALLPAY_INVOICE_Invoice_Issue_Method ;
  410. $allpay_invoice->Invoice_Url = ALLPAY_INVOICE_SERVICE_PATH.ALLPAY_INVOICE_Invoice_Issue_Url ;
  411. // 3.寫入發票傳送資訊
  412. $aItems = array();
  413. array_push(
  414. $allpay_invoice->Send['Items'],
  415. array(
  416. 'ItemName' => $invoice_remark,
  417. 'ItemCount' => 1,
  418. 'ItemWord' => '筆',
  419. 'ItemPrice' => $amt,
  420. 'ItemTaxType' => 1,
  421. 'ItemAmount' => $amt
  422. )
  423. );
  424. $company_no = '';
  425. $mobile = '';
  426. $email = '';
  427. $company_receiver = '';
  428. $company_address = '';
  429. $mobile_receiver = '';
  430. $natural_receiver = '';
  431. $love_code = '';
  432. if(strlen($data['company_no']) == 8){
  433. $company_no = $data['company_no'];
  434. }
  435. if(strlen($data['mobile']) > 0){
  436. $mobile = $data['mobile'];
  437. }
  438. if(strlen($data['email']) > 0){
  439. $email = $data['email'];
  440. }
  441. if(strlen($data['company_receiver']) > 0){
  442. $company_receiver = $data['company_receiver'];
  443. }
  444. if(strlen($data['company_address']) > 0){
  445. $company_address = $data['company_address'];
  446. }
  447. if(strlen($data['mobile_receiver']) > 0){
  448. $mobile_receiver = $data['mobile_receiver'];
  449. }
  450. if(strlen($data['natural_receiver']) > 0){
  451. $natural_receiver = $data['natural_receiver'];
  452. }
  453. if(strlen($data['love_code']) > 0){
  454. $love_code = $data['love_code'];
  455. }
  456. $donation = '2' ; // 捐贈註記 1.捐贈 2.不捐贈
  457. $print = '0'; // 列印註記 0.不列印 1.列印
  458. $carruer_type = ''; // 載具類別
  459. $carruer_num = '';
  460. if(strlen($company_no) > 0){
  461. // 打統編
  462. $print = '1';
  463. }else if(strlen($love_code) > 0){
  464. // 捐贈
  465. $donation = '1';
  466. }else if(strlen($natural_receiver) > 0){
  467. // 載具類別: 自然人憑證
  468. $carruer_type = '2';
  469. $carruer_num = $natural_receiver;
  470. }else if(strlen($mobile_receiver) > 0){
  471. // 載具類別: 手機條碼
  472. $carruer_type = '3';
  473. $carruer_num = $mobile_receiver;
  474. //$carruer_num = str_replace ('+', ' ', $mobile_receiver); // 如果有+可能會出錯
  475. }
  476. $allpay_invoice->Send['RelateNumber'] = $order_no ; // 廠商自訂編號
  477. $allpay_invoice->Send['CustomerID'] = '' ; // 客戶代號
  478. $allpay_invoice->Send['CustomerIdentifier'] = $company_no ; // 統一編號
  479. $allpay_invoice->Send['CustomerName'] = $company_receiver ; // 客戶名稱
  480. $allpay_invoice->Send['CustomerAddr'] = $company_address ; // 客戶地址
  481. $allpay_invoice->Send['CustomerPhone'] = $mobile ; // 客戶手機號碼
  482. $allpay_invoice->Send['CustomerEmail'] = $email ; // 客戶電子信箱
  483. $allpay_invoice->Send['ClearanceMark'] = '' ; // 通關方式
  484. $allpay_invoice->Send['Print'] = $print; // 列印註記 0.不列印 1.列印
  485. $allpay_invoice->Send['Donation'] = $donation ; // 捐贈註記 1.捐贈 2.不捐贈
  486. $allpay_invoice->Send['LoveCode'] = $love_code ;// 愛心碼
  487. $allpay_invoice->Send['CarruerType'] = $carruer_type ; // 載具類別
  488. $allpay_invoice->Send['CarruerNum'] = $carruer_num; // 載具編號
  489. $allpay_invoice->Send['TaxType'] = 1 ; // 課稅類別 1.應稅 2.零稅率 3.免稅
  490. $allpay_invoice->Send['SalesAmount'] = $amt ; // 發票金額
  491. $allpay_invoice->Send['InvoiceRemark'] = $invoice_remark ; // 備註
  492. $allpay_invoice->Send['InvType'] = '07' ; // 字軌類別 07.一般稅額 08.特種稅額
  493. $allpay_invoice->Send['InvCreateDate'] = '' ; // 發票開立時間
  494. $allpay_invoice->Send['vat'] = '' ; // 商品單價是否含稅
  495. trigger_error(__FUNCTION__. ' $allpay_invoice->Send : ' . print_r($allpay_invoice->Send, true));
  496. $aReturn_Info = $allpay_invoice->Check_Out();
  497. $sMsg = '';
  498. foreach ($aReturn_Info as $key => $value){
  499. $sMsg .= $key . ' => ' . $value . '<br>' ;
  500. switch ($key){
  501. case "RelateNumber": $eRelateNumber = $value; break;
  502. case "InvoiceDate": $eInvoiceDate = $value; break;
  503. case "InvoiceNumber": $eInvoiceNumber = $value; break;
  504. case "RandomNumber": $eRandomNumber = $value; break;
  505. case "RtnCode": $eRtnCode = $value; break;
  506. case "RtnMsg": $eRtnMsg = $value; break;
  507. case "CheckMacValue": $eCheckMacValue = $value; break;
  508. default: break;
  509. }
  510. }
  511. trigger_error(__FUNCTION__ .', return: '.$sMsg);
  512. $invoice_data = array(
  513. 'order_no' => $order_no,
  514. //'relate_number' => $eRelateNumber, // ?? 沒拿到
  515. 'invoice_date' => $eInvoiceDate,
  516. 'invoice_number' => $eInvoiceNumber,
  517. 'random_number' => $eRandomNumber,
  518. 'rtn_code' => $eRtnCode,
  519. 'rtn_msg' => $eRtnMsg,
  520. 'check_mac_value' => $eCheckMacValue,
  521. 'merchant_id' => $this->get_allpay_merchant_id($invoice_flag)
  522. );
  523. // 建立log
  524. $this->db->insert('allpay_invoice_log', $invoice_data);
  525. // eInvoiceNumber記到tx_bill
  526. if($eRtnCode == '1'){
  527. // 發送通知
  528. /* (歐付寶後台有提供對應設定, 無需自行手動送出?? But, 測試環境設定後無效 ??)
  529. if(strlen($email) > 0 && strlen($mobile) > 0){
  530. $this->invoice_notify($eInvoiceNumber, 'A', 'I', 'C', $email, $mobile);
  531. }else if(strlen($mobile) > 0){
  532. $this->invoice_notify($eInvoiceNumber, 'S', 'I', 'C', $email, $mobile);
  533. }else if(strlen($email) > 0){
  534. $this->invoice_notify($eInvoiceNumber, 'E', 'I', 'C', $email, $mobile);
  535. }else{
  536. $sMsg = 'empty tx_bill.mobile && tx_bill.email can not send notify';
  537. trigger_error(APP_NAME.'[allpay_invoice_issue] order_no=>' . $order_no.'<br>'.$sMsg);
  538. }*/
  539. // 回傳發票號碼
  540. return $eInvoiceNumber;
  541. }else{
  542. trigger_error(__FUNCTION__ .', order_no=>' . $order_no.'<br>'.$sMsg);
  543. }
  544. return ''; // 不是發票號碼就是空字串
  545. }
  546. // 7.開立折讓 API
  547. public function invoice_allowance($invoice_no, $allowance_amt, $item_name="停車費用帳單")
  548. {
  549. // 取得開立記錄
  550. $invoice_log = $this->db
  551. ->select('merchant_id')
  552. ->from('allpay_invoice_log')
  553. ->where(array('invoice_number' => $invoice_no))
  554. ->limit(1)
  555. ->get()
  556. ->row_array();
  557. if (empty($invoice_log))
  558. {
  559. $result = array();
  560. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_NOT_FOUND;
  561. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_NOT_FOUND;
  562. return $result;
  563. }
  564. else if(empty($invoice_log['merchant_id']))
  565. {
  566. $result = array();
  567. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_INVOICE_ERROR;
  568. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_INVOICE_ERROR;
  569. return $result;
  570. }
  571. else
  572. {
  573. trigger_error(__FUNCTION__ .', invoice_no: ' . $invoice_no.', merchant_id: ' . $invoice_log['merchant_id'] . '..start..');
  574. }
  575. try {
  576. $sMsg = '' ;
  577. $merchant_id = $invoice_log['merchant_id'];
  578. // 1.載入 SDK 程式
  579. $allpay_invoice = $this->load_allpay_invoice_by_merchant_id($merchant_id);
  580. // 2.寫入基本介接參數
  581. $allpay_invoice->Invoice_Method = ALLPAY_INVOICE_Allowance_Method ;
  582. $allpay_invoice->Invoice_Url = ALLPAY_INVOICE_SERVICE_PATH.ALLPAY_INVOICE_Allowance_Url ;
  583. // 3.寫入發票傳送資訊
  584. array_push($allpay_invoice->Send['Items'], // 商品資訊
  585. array(
  586. 'ItemName' => $item_name, 'ItemTaxType' => 1, 'ItemCount' => 1, 'ItemWord' => '筆',
  587. 'ItemPrice' => $allowance_amt, 'ItemAmount' => $allowance_amt)
  588. );
  589. $allpay_invoice->Send['CustomerName'] = '' ; // 買受人姓名
  590. $allpay_invoice->Send['InvoiceNo'] = $invoice_no; // 發票號碼
  591. $allpay_invoice->Send['AllowanceNotify'] = 'N'; // 通知類別 S.簡訊 E.電子郵件 A.皆通知 N.皆不通知
  592. //$allpay_invoice->Send['NotifyMail'] = $notify_mail; // 通知電子信箱
  593. //$allpay_invoice->Send['NotifyPhone'] = $notify_phone; // 通知手機號碼
  594. $allpay_invoice->Send['AllowanceAmount'] = $allowance_amt; // 含稅總金額
  595. // 4.送出
  596. $aReturn_Info = $allpay_invoice->Check_Out();
  597. // 5.返回
  598. foreach($aReturn_Info as $key => $value){
  599. $sMsg .= $key . ' => ' . $value . '<br>' ;
  600. switch ($key){
  601. case "RtnCode": $rtn_code = $value; break;
  602. case "RtnMsg": $rtn_msg = $value; break;
  603. case "CheckMacValue": $check_mac_value = $value; break; // 驗證碼
  604. case "IA_Allow_No": $allowance_no = $value; break; // 折讓單號
  605. case "IA_Invoice_No": $allowance_invoice_no = $value; break; // 折讓發票號碼
  606. case "IA_Date": $allowance_date = $value; break; // 折讓時間
  607. case "IA_Remain_Allowance_Amt": $allowance_remain_amt = $value; break; // 折讓剩餘金額
  608. default: break;
  609. }
  610. }
  611. trigger_error(__FUNCTION__ .', invoice_no: ' . $invoice_no.', allowance_amt: ' . $allowance_amt.
  612. ', item_name: ' . $item_name.'| return: '.$sMsg);
  613. if($rtn_code == '1')
  614. {
  615. $allowance_data = array(
  616. 'allowance_no' => $allowance_no,
  617. 'invoice_no' => $allowance_invoice_no,
  618. 'allowance_date' => $allowance_date,
  619. 'allowance_remain_amt' => $allowance_remain_amt,
  620. 'check_mac_value' => $check_mac_value,
  621. 'merchant_id' => $merchant_id
  622. );
  623. // 建立log
  624. $this->db->insert('allpay_allowance_log', $allowance_data);
  625. $result = array();
  626. $result['result_code'] = ALLPAY_INVOICE_RESULT_CODE_OK;
  627. $result['result_msg'] = $rtn_msg;
  628. $result['check_mac_value'] = $check_mac_value;
  629. $result['allowance_no'] = $allowance_no;
  630. $result['allowance_invoice_no'] = $allowance_invoice_no;
  631. $result['allowance_date'] = $allowance_date;
  632. $result['allowance_remain_amt'] = $allowance_remain_amt;
  633. return $result;
  634. }
  635. else
  636. {
  637. $result = array();
  638. $result['result_code'] = ALLPAY_INVOICE_RESULT_CODE_GG;
  639. $result['result_msg'] = $rtn_msg;
  640. return $result;
  641. }
  642. }catch (Exception $e){
  643. // 例外錯誤處理。
  644. $sMsg = $e->getMessage();
  645. trigger_error(__FUNCTION__ .', invoice_no: ' . $invoice_no.', allowance_amt: ' . $allowance_amt.
  646. ', item_name: ' . $item_name.'| return: '.$sMsg);
  647. }
  648. $result = array();
  649. $result['result_code'] = ALLPAY_INVOICE_RESULT_CODE_GG;
  650. $result['result_msg'] = ALLPAY_INVOICE_RESULT_MSG_GG;
  651. return $result;
  652. }
  653. // 8.發票作廢 API
  654. protected function invoice_void($invoice_no, $reason_str)
  655. {
  656. // 取得開立記錄
  657. $invoice_log = $this->db
  658. ->select('merchant_id')
  659. ->from('allpay_invoice_log')
  660. ->where(array('invoice_number' => $invoice_no))
  661. ->limit(1)
  662. ->get()
  663. ->row_array();
  664. if (empty($invoice_log))
  665. {
  666. $result = array();
  667. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_NOT_FOUND;
  668. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_NOT_FOUND;
  669. return $result;
  670. }
  671. else if(empty($invoice_log['merchant_id']))
  672. {
  673. $result = array();
  674. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_INVOICE_ERROR;
  675. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_INVOICE_ERROR;
  676. return $result;
  677. }
  678. else
  679. {
  680. trigger_error(__FUNCTION__ .', invoice_no: ' . $invoice_no.', merchant_id: ' . $invoice_log['merchant_id'] . '..start..');
  681. }
  682. try {
  683. $sMsg = '' ;
  684. $merchant_id = $invoice_log['merchant_id'];
  685. // 1.載入 SDK 程式
  686. $allpay_invoice = $this->load_allpay_invoice_by_merchant_id($merchant_id);
  687. // 2.寫入基本介接參數
  688. $allpay_invoice->Invoice_Method = ALLPAY_INVOICE_Invoice_Void_Method ;
  689. $allpay_invoice->Invoice_Url = ALLPAY_INVOICE_SERVICE_PATH.ALLPAY_INVOICE_Invoice_Void_Url ;
  690. // 3.寫入發票傳送資訊
  691. $allpay_invoice->Send['InvoiceNumber'] = $invoice_no; // 發票號碼
  692. $allpay_invoice->Send['Reason'] = $reason_str; // 原因
  693. // 4.送出
  694. $aReturn_Info = $allpay_invoice->Check_Out();
  695. // 5.返回
  696. foreach($aReturn_Info as $key => $value){
  697. $sMsg .= $key . ' => ' . $value . '<br>' ;
  698. switch ($key){
  699. case "RtnCode": $rtn_code = $value; break;
  700. case "RtnMsg": $rtn_msg = $value; break;
  701. case "CheckMacValue": $check_mac_value = $value; break; // 驗證碼
  702. case "InvoiceNumber": $invoice_number = $value; break; // 發票號碼
  703. default: break;
  704. }
  705. }
  706. trigger_error(__FUNCTION__.', invoice_no: ' . $invoice_no.', reason_str: ' . $reason_str.'| return: '.$sMsg);
  707. if($rtn_code == '1')
  708. {
  709. $result = array();
  710. $result['result_code'] = ALLPAY_INVOICE_RESULT_CODE_OK;
  711. $result['result_msg'] = $rtn_msg;
  712. $result['check_mac_value'] = $check_mac_value;
  713. $result['invoice_number'] = $invoice_number;
  714. return $result;
  715. }
  716. else
  717. {
  718. $result = array();
  719. $result['result_code'] = ALLPAY_INVOICE_RESULT_CODE_GG;
  720. $result['result_msg'] = $rtn_msg;
  721. return $result;
  722. }
  723. }catch (Exception $e){
  724. // 例外錯誤處理。
  725. $sMsg = $e->getMessage();
  726. trigger_error(__FUNCTION__ .', invoice_no: ' . $invoice_no.', reason_str: ' . $reason_str.'| error: '.$sMsg);
  727. }
  728. $result = array();
  729. $result['result_code'] = ALLPAY_INVOICE_RESULT_CODE_GG;
  730. $result['result_msg'] = ALLPAY_INVOICE_RESULT_MSG_GG;
  731. return $result;
  732. }
  733. // 10.折讓作廢 API
  734. public function allowance_void($invoice_no, $allowance_no, $reason_str)
  735. {
  736. // 取得折讓記錄
  737. $invoice_log = $this->db
  738. ->select('merchant_id')
  739. ->from('allpay_allowance_log')
  740. ->where(array('invoice_no' => $invoice_no, 'allowance_no' => $allowance_no))
  741. ->limit(1)
  742. ->get()
  743. ->row_array();
  744. if (empty($invoice_log))
  745. {
  746. $result = array();
  747. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_NOT_FOUND;
  748. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_NOT_FOUND;
  749. return $result;
  750. }
  751. else if(empty($invoice_log['merchant_id']))
  752. {
  753. $result = array();
  754. $result["result_code"] = ALLPAY_INVOICE_RESULT_CODE_INVOICE_ERROR;
  755. $result["result_msg"] = ALLPAY_INVOICE_RESULT_MSG_INVOICE_ERROR;
  756. return $result;
  757. }
  758. else
  759. {
  760. trigger_error(__FUNCTION__ .', invoice_no: ' . $invoice_no.', merchant_id: ' . $invoice_log['merchant_id'] . '..start..');
  761. }
  762. try {
  763. $sMsg = '' ;
  764. $merchant_id = $invoice_log['merchant_id'];
  765. // 1.載入 SDK 程式
  766. $allpay_invoice = $this->load_allpay_invoice_by_merchant_id($merchant_id);
  767. // 2.寫入基本介接參數
  768. $allpay_invoice->Invoice_Method = ALLPAY_INVOICE_Allowance_Void_Method ;
  769. $allpay_invoice->Invoice_Url = ALLPAY_INVOICE_SERVICE_PATH.ALLPAY_INVOICE_Allowance_Void_Url ;
  770. /*
  771. // 1.載入 SDK 程式
  772. $allpay_invoice = new AllInvoice ;
  773. // 2.寫入基本介接參數
  774. $allpay_invoice->Invoice_Method = ALLPAY_INVOICE_Allowance_Void_Method ;
  775. $allpay_invoice->Invoice_Url = ALLPAY_INVOICE_SERVICE_PATH.ALLPAY_INVOICE_Allowance_Void_Url ;
  776. $allpay_invoice->MerchantID = ALLPAY_INVOICE_MerchantID ;
  777. $allpay_invoice->HashKey = ALLPAY_INVOICE_HashKey ;
  778. $allpay_invoice->HashIV = ALLPAY_INVOICE_HashIV ;
  779. */
  780. // 3.寫入發票傳送資訊
  781. $allpay_invoice->Send['InvoiceNo'] = $invoice_no; // 發票號碼
  782. $allpay_invoice->Send['AllowanceNo'] = $allowance_no; // 折讓編號
  783. $allpay_invoice->Send['Reason'] = $reason_str; // 作廢原因
  784. // 4.送出
  785. $aReturn_Info = $allpay_invoice->Check_Out();
  786. // 5.返回
  787. foreach($aReturn_Info as $key => $value){
  788. $sMsg .= $key . ' => ' . $value . '<br>' ;
  789. switch ($key){
  790. case "RtnCode": $rtn_code = $value; break;
  791. case "RtnMsg": $rtn_msg = $value; break;
  792. case "CheckMacValue": $check_mac_value = $value; break; // 驗證碼
  793. case "IA_Invoice_No": $invoice_number = $value; break; // 發票號碼
  794. default: break;
  795. }
  796. }
  797. trigger_error(__FUNCTION__ .', invoice_no: ' . $invoice_no.', allowance_no: ' . $allowance_no.
  798. ', reason_str: ' . $reason_str.'| return: '.$sMsg);
  799. if($rtn_code == '1')
  800. {
  801. $result = array();
  802. $result['result_code'] = ALLPAY_INVOICE_RESULT_CODE_OK;
  803. $result['result_msg'] = $rtn_msg;
  804. $result['check_mac_value'] = $check_mac_value;
  805. $result['invoice_number'] = $invoice_number;
  806. return $result;
  807. }
  808. else
  809. {
  810. $result = array();
  811. $result['result_code'] = ALLPAY_INVOICE_RESULT_CODE_GG;
  812. $result['result_msg'] = $rtn_msg;
  813. return $result;
  814. }
  815. }catch (Exception $e){
  816. // 例外錯誤處理。
  817. $sMsg = $e->getMessage();
  818. trigger_error(__FUNCTION__ .', invoice_no: ' . $invoice_no.', allowance_no: ' . $allowance_no.
  819. ', reason_str: ' . $reason_str.'| return: '.$sMsg);
  820. }
  821. $result = array();
  822. $result['result_code'] = ALLPAY_INVOICE_RESULT_CODE_GG;
  823. $result['result_msg'] = ALLPAY_INVOICE_RESULT_MSG_GG;
  824. return $result;
  825. }
  826. /*
  827. // 通知
  828. protected function invoice_notify($eInvoiceNo, $eNotify, $eInvoiceTag, $eNotified, $eNotifyMail, $ePhone)
  829. {
  830. //$eInvoiceNo = $this->uri->segment(3); // 發票號碼
  831. //$eNotify = $this->uri->segment(4); // 發送方式 S.簡訊 E.電子郵件 A.皆通知
  832. //$eInvoiceTag = $this->uri->segment(5); // 發送類型 I.開立 II.作廢 A.折讓 AI.折讓作廢 AW.發票中獎
  833. //$eNotified = $this->uri->segment(6); // 發送對象 C.客戶 M.廠商 A.皆通知
  834. //$eNotifyMail = $this->uri->segment(7); // 發送電子信箱
  835. //$ePhone = $this->uri->segment(8); // 發送手機號碼
  836. try {
  837. $sMsg = '' ;
  838. // 1.載入 SDK 程式
  839. $allpay_invoice = new AllInvoice ;
  840. // 2.寫入基本介接參數
  841. $allpay_invoice->Invoice_Method = ALLPAY_INVOICE_Invoice_Notify_Method ;
  842. $allpay_invoice->Invoice_Url = ALLPAY_INVOICE_SERVICE_PATH.ALLPAY_INVOICE_Invoice_Notify_Url ;
  843. $allpay_invoice->MerchantID = ALLPAY_INVOICE_MerchantID ;
  844. $allpay_invoice->HashKey = ALLPAY_INVOICE_HashKey ;
  845. $allpay_invoice->HashIV = ALLPAY_INVOICE_HashIV ;
  846. // 3.寫入發票傳送資訊
  847. $allpay_invoice->Send['InvoiceNo'] = $eInvoiceNo; // 發票號碼
  848. $allpay_invoice->Send ['Notify'] = $eNotify; // 發送方式 S.簡訊 E.電子郵件 A.皆通知
  849. $allpay_invoice->Send['InvoiceTag'] = $eInvoiceTag; // 發送類型 I.開立 II.作廢 A.折讓 AI.折讓作廢 AW.發票中獎
  850. $allpay_invoice->Send ['Notified'] = $eNotified; // 發送對象 C.客戶 M.廠商 A.皆通知
  851. $allpay_invoice->Send['NotifyMail'] = $eNotifyMail; // 發送電子信箱
  852. $allpay_invoice->Send['Phone'] = $ePhone; // 發送手機號碼
  853. // 4.送出
  854. $aReturn_Info = $allpay_invoice->Check_Out();
  855. // 5.返回
  856. foreach($aReturn_Info as $key => $value){
  857. $sMsg .= $key . ' => ' . $value . '<br>' ;
  858. switch ($key){
  859. case "RtnCode": $eRtnCode = $value; break;
  860. case "RtnMsg": $eRtnMsg = $value; break;
  861. case "MerchantID": $eMerchantID = $value; break;
  862. default: break;
  863. }
  864. }
  865. // error log
  866. if($eRtnCode == '1'){
  867. // do nothing
  868. }else{
  869. trigger_error(__FUNCTION__.', eInvoiceNo=>' . $eInvoiceNo.'<br>'.$sMsg);
  870. }
  871. }catch (Exception $e){
  872. // 例外錯誤處理。
  873. $sMsg = $e->getMessage();
  874. trigger_error(__FUNCTION__.', eInvoiceNo=>' . $eInvoiceNo.'<br>'.$sMsg.'<br> email: '.$eNotifyMail.', mobile: '.$ePhone);
  875. }
  876. }
  877. */
  878. // 測試遠端呼叫
  879. public function test_curl($station_no, $tx_bill_no, $amt, $company_no, $email, $mobile)
  880. {
  881. try{
  882. $param = array(
  883. 'station_no' => $station_no,
  884. 'tx_bill_no' => $tx_bill_no,
  885. 'amt' => $amt,
  886. 'company_no' => $company_no,
  887. 'email' => $email,
  888. 'mobile' => $mobile
  889. );
  890. $ch = curl_init();
  891. curl_setopt($ch, CURLOPT_URL, 'http://localhost/allpay_invoice.html/create_member_tx_bill_invoice');
  892. curl_setopt($ch, CURLOPT_HEADER, FALSE);
  893. curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
  894. curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
  895. curl_setopt($ch, CURLOPT_POST, TRUE);
  896. //curl_setopt($ch, CURLOPT_CONNECTTIMEOUT ,10);
  897. //curl_setopt($ch, CURLOPT_TIMEOUT, 10); //timeout in seconds
  898. curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($param));
  899. $data = curl_exec($ch);
  900. curl_close($ch);
  901. if(!empty($data))
  902. {
  903. $data_decode = json_decode($data, true);
  904. if($data_decode['result_code'] == 'OK')
  905. {
  906. $result = array();
  907. $result['einvoice_track'] = substr($data_decode['invoice_no'], 0, 2); // 發票字軌
  908. $result['einvoice_no'] = substr($data_decode['invoice_no'], 2, 8); // 發票號碼
  909. return $result;
  910. }
  911. //trigger_error(__FUNCTION__ . ', test 2: '. print_r($data_decode, true));
  912. }
  913. }catch (Exception $e){
  914. trigger_error(__FUNCTION__ . 'error:'.$e->getMessage());
  915. }
  916. $result = array();
  917. $result['einvoice_track'] = ''; // 發票字軌
  918. $result['einvoice_no'] = ''; // 發票號碼
  919. return $result;
  920. }
  921. }