Skip to content

ezPay 電子發票串接筆記

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);

這樣就可以成功開立發票囉

Published in筆記

One Comment

Leave a Reply

Your email address will not be published. Required fields are marked *