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.

414 lines
16KB

  1. <?php
  2. /*
  3. file: Allpay_payment.php 付費系統 (歐付寶)
  4. */
  5. if (!defined('BASEPATH')) exit('No direct script access allowed');
  6. require_once(ALLPAY_FILE);
  7. class Allpay_payment extends CI_Controller
  8. {
  9. var $vars = array(); // 共用變數
  10. function __construct()
  11. {
  12. parent::__construct();
  13. // ----- 程式開發階段log設定 -----
  14. if (@ENVIRONMENT == 'development')
  15. {
  16. ini_set('display_errors', '1');
  17. //error_reporting(E_ALL ^ E_NOTICE);
  18. error_reporting(E_ALL);
  19. }
  20. set_error_handler(array($this, 'error_handler'), E_ALL); // 資料庫異動需做log
  21. // ----- 定義常數(路徑, cache秒數) -----
  22. define('APP_VERSION', '100'); // 版本號
  23. define('MAX_AGE', 604800); // cache秒數, 此定義1個月
  24. define('APP_NAME', 'allpay_payment'); // 應用系統名稱
  25. define('PAGE_PATH', APP_BASE.'ci_application/views/'.APP_NAME.'/'); // path of views
  26. define('SERVER_URL', 'http://'.(isset($_SERVER['SERVER_NAME']) ? $_SERVER['SERVER_NAME'] : 'localhost').'/'); // URL
  27. define('APP_URL', SERVER_URL.APP_NAME.'.html/'); // controller路徑
  28. define('WEB_URL', SERVER_URL.APP_NAME.'/'); // 網頁路徑
  29. define('WEB_LIB', SERVER_URL.'libs/'); // 網頁lib
  30. define('BOOTSTRAPS', WEB_LIB.'bootstrap_sb/'); // bootstrap lib
  31. define('LOG_PATH', FILE_BASE.APP_NAME.'/logs/'); // log path
  32. $this->load->model('allpay_payment_model');
  33. $this->load->model('payment_model'); // 一般臨停帳單 (tx_bill)
  34. $this->load->model('payment_ats_model'); // 月租繳費機帳單 (tx_bill_ats)
  35. /*
  36. // ----- 正式環境 -----
  37. define('ALLPAY_ServiceURL', "https://payment.ecpay.com.tw/Cashier/AioCheckOut"); // 您要呼叫的服務位址 (綠界)
  38. //define('ALLPAY_ServiceURL', "https://payment.allpay.com.tw/Cashier/AioCheckOut"); // 您要呼叫的服務位址
  39. define('ALLPAY_HashKey', "tLBnwUiKlbB0e6sS"); // AllPay提供給您的Hash Key
  40. define('ALLPAY_HashIV', "bMhtNluToYSYoJBw"); // AllPay提供給您的Hash IV
  41. define('ALLPAY_MerchantID', "1148391"); // AllPay提供給您的特店編號
  42. // ----- 正式環境(end) -----
  43. */
  44. // ----- 測試環境 -----
  45. define('ALLPAY_ServiceURL', "http://payment-stage.allpay.com.tw/Cashier/AioCheckOut"); // 您要呼叫的服務位址
  46. define('ALLPAY_HashKey', "5294y06JbISpM5x9"); // AllPay提供給您的Hash Key
  47. define('ALLPAY_HashIV', "v77hoKGq4kWxNNIS"); // AllPay提供給您的Hash IV
  48. define('ALLPAY_MerchantID', "2000132"); // AllPay提供給您的特店編號
  49. // ----- 測試環境(end) -----
  50. }
  51. // 發生錯誤時集中在此處理
  52. public function error_handler($errno, $errstr, $errfile, $errline, $errcontext)
  53. {
  54. $str = date('H:i:s')."|{$errstr}|{$errfile}|{$errline}|{$errno}\n";
  55. //error_log($str, 3, $log_file . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名
  56. error_log($str, 3, LOG_PATH.APP_NAME . '.' . date('Ymd').'.log.txt'); // 3代表參考後面的檔名
  57. }
  58. // 付款 (tx_bill)
  59. public function transfer_money_tx_bill()
  60. {
  61. $order_no = $this->uri->segment(3); // 序號
  62. try{
  63. // 0. check tx_bill
  64. $data = $this->payment_model->get_tx_bill($order_no);
  65. if (! empty($data))
  66. {
  67. $status = $data['status'];
  68. switch($status){
  69. case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
  70. $oPayment = new AllInOne();
  71. $oPayment->ServiceURL = ALLPAY_ServiceURL;
  72. $oPayment->HashKey = ALLPAY_HashKey;
  73. $oPayment->HashIV = ALLPAY_HashIV;
  74. $oPayment->MerchantID = ALLPAY_MerchantID;
  75. /* 基本參數 */
  76. $oPayment->Send['ReturnURL'] = STATION_URL.APP_NAME.'.html/tx_bill_finished/'; // 您要收到付款完成通知的伺服器端網址(server)
  77. $oPayment->Send['ClientBackURL'] = $data['client_back_url']; // 您要歐付寶返回按鈕導向的瀏覽器端網址";
  78. $oPayment->Send['OrderResultURL'] = $data['order_result_url']; // 您要收到付款完成通知的瀏覽器端網址(browser) ps. WebATM大部份銀行都回不來;
  79. $oPayment->Send['MerchantTradeNo'] = $data['order_no']; // 您此筆訂單交易編號
  80. $oPayment->Send['MerchantTradeDate'] = date('Y/m/d H:i:s', strtotime($data['tx_time'])); // 交易時間
  81. $oPayment->Send['TotalAmount'] = (int) $data['amt']; // 您此筆訂單的交易總金額
  82. $oPayment->Send['TradeDesc'] = $data['invoice_remark']; // 您該筆訂單的描述
  83. $oPayment->Send['ChoosePayment'] = PaymentMethod::ALL; // PaymentMethod::WebATM;
  84. $oPayment->Send['Remark'] = "";
  85. $oPayment->Send['ChooseSubPayment'] = PaymentMethodItem::None;
  86. $oPayment->Send['NeedExtraPaidInfo'] = ExtraPaymentInfo::No;
  87. $oPayment->Send['DeviceSource'] = DeviceType::Mobile; //DeviceType::PC;
  88. //$oPayment->Send['IgnorePayment'] = "Alipay#Tenpay"; //"<<您不要顯示的付款方式>>"; // 例(排除支付寶與財富通): Alipay#Tenpay
  89. // 加入選購商品資料。
  90. array_push($oPayment->Send['Items'],
  91. array(
  92. 'Name' => "結算",
  93. 'Price' => (int)$data['amt'],
  94. 'Currency' => "元",
  95. 'Quantity' => (int) "1",
  96. 'URL' => "http://www.altob.com.tw" // 網址是做什麼用的 ?
  97. )
  98. );
  99. /* 產生訂單 */
  100. $oPayment->CheckOut();
  101. /* 產生訂單 Html Code 的方法 */
  102. $szHtml = $oPayment->CheckOutString();
  103. default:
  104. $sMsg = 'status != 100';
  105. trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.$sMsg);
  106. echo $sMsg;
  107. }
  108. }
  109. }catch (Exception $e){
  110. // 例外錯誤處理。
  111. $sMsg = $e->getMessage();
  112. trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.$sMsg);
  113. echo $sMsg;
  114. }
  115. }
  116. // 付款 (tx_bill_ats)
  117. public function transfer_money_tx_bill_ats()
  118. {
  119. $order_no = $this->uri->segment(3); // 序號
  120. try{
  121. // 0. check tx_bill
  122. $data = $this->payment_ats_model->get_tx_bill($order_no);
  123. if (! empty($data))
  124. {
  125. $status = $data['status'];
  126. switch($status){
  127. case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
  128. $oPayment = new AllInOne();
  129. $oPayment->ServiceURL = ALLPAY_ServiceURL;
  130. $oPayment->HashKey = ALLPAY_HashKey;
  131. $oPayment->HashIV = ALLPAY_HashIV;
  132. $oPayment->MerchantID = ALLPAY_MerchantID;
  133. /* 基本參數 */
  134. $oPayment->Send['ReturnURL'] = STATION_URL.APP_NAME.'.html/tx_bill_ats_finished/'; // 您要收到付款完成通知的伺服器端網址(server)
  135. $oPayment->Send['ClientBackURL'] = $data['client_back_url']; // 您要歐付寶返回按鈕導向的瀏覽器端網址";
  136. $oPayment->Send['OrderResultURL'] = $data['order_result_url']; // 您要收到付款完成通知的瀏覽器端網址(browser) ps. WebATM大部份銀行都回不來;
  137. $oPayment->Send['MerchantTradeNo'] = $data['order_no']; // 您此筆訂單交易編號
  138. $oPayment->Send['MerchantTradeDate'] = date('Y/m/d H:i:s', strtotime($data['tx_time'])); // 交易時間
  139. $oPayment->Send['TotalAmount'] = (int) $data['amt']; // 您此筆訂單的交易總金額
  140. $oPayment->Send['TradeDesc'] = $data['invoice_remark']; // 您該筆訂單的描述
  141. $oPayment->Send['ChoosePayment'] = PaymentMethod::WebATM; //PaymentMethod::ALL;;
  142. $oPayment->Send['Remark'] = "";
  143. $oPayment->Send['ChooseSubPayment'] = PaymentMethodItem::None;
  144. $oPayment->Send['NeedExtraPaidInfo'] = ExtraPaymentInfo::No;
  145. $oPayment->Send['DeviceSource'] = DeviceType::PC; //DeviceType::Mobile;
  146. //$oPayment->Send['IgnorePayment'] = "Alipay#Tenpay"; //"<<您不要顯示的付款方式>>"; // 例(排除支付寶與財富通): Alipay#Tenpay
  147. // 加入選購商品資料。
  148. array_push($oPayment->Send['Items'],
  149. array(
  150. 'Name' => "結算",
  151. 'Price' => (int)$data['amt'],
  152. 'Currency' => "元",
  153. 'Quantity' => (int) "1",
  154. 'URL' => "http://www.altob.com.tw" // 網址是做什麼用的 ?
  155. )
  156. );
  157. /* 產生訂單 */
  158. $oPayment->CheckOut();
  159. /* 產生訂單 Html Code 的方法 */
  160. $szHtml = $oPayment->CheckOutString();
  161. default:
  162. $sMsg = 'status != 100';
  163. trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.$sMsg);
  164. echo $sMsg;
  165. }
  166. }
  167. }catch (Exception $e){
  168. // 例外錯誤處理。
  169. $sMsg = $e->getMessage();
  170. trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.$sMsg);
  171. echo $sMsg;
  172. }
  173. }
  174. // 付款完成 (tx_bill)
  175. public function tx_bill_finished()
  176. {
  177. ob_end_clean();
  178. ignore_user_abort();
  179. ob_start();
  180. try{
  181. $oPayment = new AllInOne();
  182. /* 服務參數 */
  183. $oPayment->HashKey = ALLPAY_HashKey;
  184. $oPayment->HashIV = ALLPAY_HashIV;
  185. $oPayment->MerchantID = ALLPAY_MerchantID;
  186. /* 取得回傳參數 */
  187. $arFeedback = $oPayment->CheckOutFeedback();
  188. /* 檢核與變更訂單狀態 */
  189. if (sizeof($arFeedback) > 0){
  190. foreach ($arFeedback as $key => $value){
  191. switch ($key){
  192. /* 支付後的回傳的基本參數 */
  193. case "MerchantID": $szMerchantID = $value; break;
  194. case "MerchantTradeNo": $szMerchantTradeNo = $value; break;
  195. case "PaymentDate": $szPaymentDate = $value; break;
  196. case "PaymentType": $szPaymentType = $value; break;
  197. case "PaymentTypeChargeFee": $szPaymentTypeChargeFee = $value; break;
  198. case "RtnCode": $szRtnCode = $value; break;
  199. case "RtnMsg": $szRtnMsg = $value; break;
  200. case "SimulatePaid": $szSimulatePaid = $value; break;
  201. case "TradeAmt": $szTradeAmt = $value; break;
  202. case "TradeDate": $szTradeDate = $value; break;
  203. case "TradeNo": $szTradeNo = $value; break;
  204. default: break;
  205. }
  206. }
  207. // 一律記錄log。
  208. $data = array(
  209. 'merchant_id' => $szMerchantID,
  210. 'merchant_trade_no' => $szMerchantTradeNo,
  211. 'payment_date' => $szPaymentDate,
  212. 'payment_type' => $szPaymentType,
  213. 'payment_type_charge_fee' => $szPaymentTypeChargeFee,
  214. 'rtn_code' => $szRtnCode,
  215. 'rtn_msg' => $szRtnMsg,
  216. 'simulate_paid' => $szSimulatePaid,
  217. 'trade_amt' => $szTradeAmt,
  218. 'trade_date' => $szTradeDate,
  219. 'trade_no' => $szTradeNo
  220. );
  221. $this->allpay_payment_model->create_allpay_feedback_log($data);
  222. print '1|OK'; //先回傳ok
  223. header('Connection: close');
  224. header('Content-Length: ' . ob_get_length());
  225. ob_end_flush();
  226. flush();
  227. // 此筆交易為成功
  228. if($szRtnCode == '1')
  229. {
  230. $data = $this->payment_model->get_tx_bill($szMerchantTradeNo);
  231. if (! empty($data))
  232. {
  233. $order_no = $data['order_no'];
  234. $amt = $data['amt'];
  235. $status = $data['status'];
  236. switch($status){
  237. case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
  238. // 印發票流程
  239. if($szTradeAmt == $amt){
  240. // 先記錄
  241. $this->payment_model->transfer_money_done($order_no);
  242. if(! empty($data["service_url"])){
  243. file_get_contents($data["service_url"]."/{$order_no}"); // 執行指定的結帳呼叫
  244. }else{
  245. // 找不到付款成功服務位址
  246. trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.'service_url not found..');
  247. }
  248. }else{
  249. // 錢沒對上
  250. $this->payment_model->transfer_money_done_with_amt_error($szMerchantTradeNo);
  251. }
  252. break;
  253. default:
  254. // 對方多傳一次時??
  255. trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.'tx_bill.status != 100');
  256. }
  257. }else{
  258. // 我們自己找不到記錄時??
  259. trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.'tx_bill NOT FOUND !!');
  260. }
  261. }
  262. }else{
  263. print '0|Fail';
  264. }
  265. }catch (Exception $e){
  266. // 例外錯誤處理。
  267. print '0|' . $e->getMessage();
  268. }
  269. exit();
  270. }
  271. // 付款完成 (tx_bill_ats)
  272. public function tx_bill_ats_finished()
  273. {
  274. ob_end_clean();
  275. ignore_user_abort();
  276. ob_start();
  277. try{
  278. $oPayment = new AllInOne();
  279. /* 服務參數 */
  280. $oPayment->HashKey = ALLPAY_HashKey;
  281. $oPayment->HashIV = ALLPAY_HashIV;
  282. $oPayment->MerchantID = ALLPAY_MerchantID;
  283. /* 取得回傳參數 */
  284. $arFeedback = $oPayment->CheckOutFeedback();
  285. /* 檢核與變更訂單狀態 */
  286. if (sizeof($arFeedback) > 0){
  287. foreach ($arFeedback as $key => $value){
  288. switch ($key){
  289. /* 支付後的回傳的基本參數 */
  290. case "MerchantID": $szMerchantID = $value; break;
  291. case "MerchantTradeNo": $szMerchantTradeNo = $value; break;
  292. case "PaymentDate": $szPaymentDate = $value; break;
  293. case "PaymentType": $szPaymentType = $value; break;
  294. case "PaymentTypeChargeFee": $szPaymentTypeChargeFee = $value; break;
  295. case "RtnCode": $szRtnCode = $value; break;
  296. case "RtnMsg": $szRtnMsg = $value; break;
  297. case "SimulatePaid": $szSimulatePaid = $value; break;
  298. case "TradeAmt": $szTradeAmt = $value; break;
  299. case "TradeDate": $szTradeDate = $value; break;
  300. case "TradeNo": $szTradeNo = $value; break;
  301. default: break;
  302. }
  303. }
  304. // 一律記錄log。
  305. $data = array(
  306. 'merchant_id' => $szMerchantID,
  307. 'merchant_trade_no' => $szMerchantTradeNo,
  308. 'payment_date' => $szPaymentDate,
  309. 'payment_type' => $szPaymentType,
  310. 'payment_type_charge_fee' => $szPaymentTypeChargeFee,
  311. 'rtn_code' => $szRtnCode,
  312. 'rtn_msg' => $szRtnMsg,
  313. 'simulate_paid' => $szSimulatePaid,
  314. 'trade_amt' => $szTradeAmt,
  315. 'trade_date' => $szTradeDate,
  316. 'trade_no' => $szTradeNo
  317. );
  318. $this->allpay_payment_model->create_allpay_feedback_log($data);
  319. print '1|OK'; //先回傳ok
  320. header('Connection: close');
  321. header('Content-Length: ' . ob_get_length());
  322. ob_end_flush();
  323. flush();
  324. // 此筆交易為成功
  325. if($szRtnCode == '1')
  326. {
  327. $data = $this->payment_ats_model->get_tx_bill($szMerchantTradeNo);
  328. if (! empty($data))
  329. {
  330. $order_no = $data['order_no'];
  331. $amt = $data['amt'];
  332. $status = $data['status'];
  333. switch($status){
  334. case 100: // 狀態: 0:剛建立, 1:結帳完成, 2:錢沒對上, 3:發票沒建立, 4:手動調整, 99:訂單逾期作廢, 100:交易進行中
  335. // 印發票流程
  336. if($szTradeAmt == $amt){
  337. // 先記錄
  338. $this->payment_ats_model->transfer_money_done($order_no);
  339. if(! empty($data["service_url"])){
  340. file_get_contents($data["service_url"]."/{$order_no}"); // 執行指定的結帳呼叫
  341. }else{
  342. // 找不到付款成功服務位址
  343. trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.' service_url not found..');
  344. }
  345. }else{
  346. // 錢沒對上
  347. $this->payment_ats_model->transfer_money_done_with_amt_error($szMerchantTradeNo);
  348. }
  349. break;
  350. default:
  351. // 對方多傳一次時??
  352. trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.' status != 100');
  353. }
  354. }else{
  355. // 我們自己找不到記錄時??
  356. trigger_error(APP_NAME.', '._FUNCTION_.', order_no=>' . $order_no.'<br>'.' NOT FOUND !!');
  357. }
  358. }
  359. }else{
  360. print '0|Fail';
  361. }
  362. }catch (Exception $e){
  363. // 例外錯誤處理。
  364. print '0|' . $e->getMessage();
  365. }
  366. exit();
  367. }
  368. }