Last updated on 2021 年 6 月 29 日
公司的網站因為要串接電子發票,串接的過程,遇到一些問題,所以紀錄一下。
我們電子發票的部分使用了 ezPay ,相關文件可以看這: https://inv.ezpay.com.tw/dw_files/info_api/EZP_INVI_1_2_0.pdf
前面訂單的部分我就不多贅述,先看一下開立發票的流程。(圖片擷取自官方文件)
在開立發票前,無論是測試環境或是正式環境,都要先去後台建立字軌,才可以成功開立。
接著,我們就可以開始來寫 code。在傳送發票資料中,除了 MerchantID 之外,其餘欄位都需要採用 Aes 加密後放 到 PostData ,再用 CURL 模組透過背景方式送至電子發票開立閘道。
我們先寫一個 function ,為的是補足字串長度
function addpadding($string, $blocksize = 32) { $len = strlen($string); $pad = $blocksize - ($len % $blocksize); $string .= str_repeat(chr($pad), $pad); return $string; }
接著寫下第二個 function ,這是為了可以用 CURL 模組透過背景方式送至電子發票開立閘道
function curl_work($url = '', $parameter = '') { $curl_options = array( CURLOPT_URL => $url, CURLOPT_HEADER => false, CURLOPT_RETURNTRANSFER => true, CURLOPT_USERAGENT => 'ezPay', CURLOPT_FOLLOWLOCATION => true, CURLOPT_SSL_VERIFYPEER => false, CURLOPT_SSL_VERIFYHOST => false, CURLOPT_POST => '1', CURLOPT_POSTFIELDS => $parameter ); $ch = curl_init(); curl_setopt_array($ch, $curl_options); $result = curl_exec($ch); $retcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $curl_error = curl_errno($ch); curl_close($ch); $return_info = array( 'url' => $url, 'sent_parameter' => $parameter, 'http_status' => $retcode, 'curl_error_no' => $curl_error, 'web_info' => $result ); return $return_info; }
最後我們要來組成 $post_data_array ,將該放的參數放進去。順帶一提,如果有設定 CarrierType 的話,CarrierNum 有一定的格式。舉例來說,自然人憑證的 regexp 就是 /^[A-Z]{2}[0-9]{14}$/ ,手機載具的 regexp 就是 /^\/{1}[0-9A-Z]{7}$/ ,
PrintFlag 也要記得設定成 N 喔,這部分,文件好像沒有提到,可能要注意一下
$post_data_array = array( //post_data 欄位資料 'RespondType' => 'JSON', 'Version' => '1.4', 'TimeStamp' => '1444963784', //請以 time() 格式 'TransNum' => '', 'MerchantOrderNo' => '201409170000001', 'BuyerName' => '王大品', 'BuyerUBN' => '54352706', 'BuyerAddress' => '台北市南港區南港路二段 97 號 8 樓', 'BuyerEmail' => '[email protected]', 'Category' => 'B2B', 'TaxType' => '1', 'TaxRate' => '5', 'Amt' => '490', 'TaxAmt' => '10', 'TotalAmt' => '500', 'CarrierType' => '', 'CarrierNum' => rawurlencode(''), 'LoveCode' => '', 'PrintFlag' => 'Y', 'ItemName' => '商品一|商品二', //多項商品時,以「|」分開 'ItemCount' => '1|2', //多項商品時,以「|」分開 'ItemUnit' => '個|個', //多項商品時,以「|」分開 'ItemPrice' => '300|100', //多項商品時,以「|」分開 'ItemAmt' => '300|200', //多項商品時,以「|」分開 'Comment' => '備註', 'CreateStatusTime' => '', 'Status' => '1' //1=立即開立,0=待開立,3=延遲開立 ); $post_data_str = http_build_query($post_data_array); //轉成字串排列 $key = 'abcdefghijklmnopqrstuvwxyzabcdef'; //商店專屬串接金鑰 HashKey 值 $iv = '1234567891234567'; //商店專屬串接金鑰 HashIV 值 if (phpversion() > 7) { $post_data = trim(bin2hex(openssl_encrypt(addpadding($post_data_str), 'AES-256-CBC', $key, OPENSSL_RAW_DATA | OPENSSL_ZERO_PADDING, $iv))); //php 7 以上版本加密 } else { $post_data = trim(bin2hex(mcrypt_encrypt(MCRYPT_RIJNDAEL_128, $key, addpadding($post_data_str), MCRYPT_MODE_CBC, $iv))); //php 7 之前版本加密 }
然後, $url 的部分,如果是要測試環境就是 https://cinv.ezpay.com.tw/Api/invoice_issue ,正式環境的話就是 https://inv.ezpay.com.tw/Api/invoice_issue ,填入你的商店代號。最後,我們就可以透過剛剛寫好的 function: curl_work 來把電子發票開立出去
$url = 'https://inv.ezpay.com.tw/Api/invoice_issue'; $MerchantID = '3622183'; //商店代號 $transaction_data_array = array(//送出欄位 'MerchantID_' => $MerchantID, 'PostData_' => $post_data ); $transaction_data_str = http_build_query($transaction_data_array); $result = curl_work($url, $transaction_data_str);
這樣就可以成功開立發票囉
感謝大大無私的分享