Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
0 parents
commit e33cd8e
Showing
18 changed files
with
1,211 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
# WHMCS_OPay V1.0.0 | ||
--- | ||
|
||
## 1. 介紹 | ||
|
||
- 提供WHMCS 串接歐付寶金流模組使用, | ||
|
||
|
||
## 2. 安裝環境 | ||
- 需有安裝一個完整的WHMCS 系統 (不相容6.0以前的版本) | ||
|
||
|
||
## 3. 使用教學 | ||
- 使用者文件放置於資料夾內,可供參閱 | ||
|
||
|
||
## 4. 聯絡我們 | ||
- 歐付寶技術客服信箱: techsupport@Opay.tw | ||
|
||
|
||
|
||
|
||
[//]: # (These are reference links used in the body of this note and get stripped out when the markdown processor does its job. There is no need to format nicely because it shouldn't be seen. Thanks SO - http://stackoverflow.com/questions/4823468/store-comments-in-markdown-syntax) |
Binary file not shown.
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,116 @@ | ||
<?php | ||
|
||
if (!function_exists('isMobile')) { | ||
function isMobile() { | ||
$useragent = $_SERVER['HTTP_USER_AGENT']; | ||
return (preg_match('/(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows (ce|phone)|xda|xiino/i',$useragent)||preg_match('/1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i',substr($useragent,0,4))); | ||
} | ||
} | ||
|
||
if (!function_exists('CheckMacValue')) { | ||
function CheckMacValue($data, $HashKey='5294y06JbISpM5x9', $HashIV='v77hoKGq4kWxNNIS') { | ||
if (isset($data['CheckMacValue'])) unset($data['CheckMacValue']); | ||
ksort($data); | ||
$value = strtolower( | ||
'HashKey='.$HashKey.'&'.http_build_query($data).'&HashIV='.$HashIV | ||
); | ||
$value = str_replace('=', '%3d', $value); | ||
$value = str_replace('&', '%26', $value); | ||
return strtoupper(hash("sha256", $value)); | ||
} | ||
} | ||
|
||
class AllPay_Pay | ||
{ | ||
private $data = array( | ||
'PaymentType' => 'aio', | ||
'EncryptType' => 1 | ||
); | ||
private $posturl = 'https://payment.allPay.com.tw/Cashier/AioCheckOut/V4'; | ||
public $HashIV; | ||
public $HashKey; | ||
|
||
function __construct($payment) | ||
{ | ||
$this->data['ChoosePayment'] = $payment; | ||
$this->data['MerchantTradeDate'] = date('Y/m/d H:i:s'); | ||
} | ||
|
||
function setTestMode() | ||
{ | ||
$this->posturl = 'https://payment-stage.allPay.com.tw/Cashier/AioCheckOut/V4'; | ||
$this->MerchantID = '2000132'; | ||
$this->HashKey = '5294y06JbISpM5x9'; | ||
$this->HashIV = 'v77hoKGq4kWxNNIS'; | ||
} | ||
|
||
function __get($key) | ||
{ | ||
return $this->data[$key]; | ||
} | ||
|
||
function __set($key, $val) | ||
{ | ||
$this->data[$key] = $val; | ||
} | ||
|
||
function GetHTML($btnText='Pay Now') { | ||
$this->data['CheckMacValue'] = CheckMacValue($this->data, $this->HashKey, $this->HashIV); | ||
$form = '<form action="'.$this->posturl.'" method="post">'; | ||
foreach ($this->data as $key => &$val) { | ||
$form .= '<input type="hidden" name="'.$key.'" value="'.$val.'">'; | ||
} | ||
$form .= '<input type="submit" class="btn btn-success btn-sm" value="'.$btnText.'"></form>'; | ||
return $form; | ||
} | ||
} | ||
|
||
class AllPay_Credit | ||
{ | ||
private $data = array(); | ||
private $HashIV; | ||
private $HashKey; | ||
|
||
function __get($key) | ||
{ | ||
return $this->data[$key]; | ||
} | ||
|
||
function __set($key, $val) | ||
{ | ||
$this->data[$key] = $val; | ||
} | ||
|
||
function Close() { | ||
$this->Action = 'C'; | ||
return $this->Sent(); | ||
} | ||
|
||
function Refund() { | ||
$this->Action = 'R'; | ||
return $this->Sent(); | ||
} | ||
|
||
function Cancel() { | ||
$this->Action = 'E'; | ||
return $this->Sent(); | ||
} | ||
|
||
function GiveUp() { | ||
$this->Action = 'N'; | ||
return $this->Sent(); | ||
} | ||
|
||
private function Sent() | ||
{ | ||
$this->CheckMacValue = CheckMacValue($this->data, $this->HashKey, $this->HashIV); | ||
$ch = curl_init(); | ||
curl_setopt($ch, CURLOPT_URL, 'https://payment.allpay.com.tw/CreditDetail/DoAction'); | ||
curl_setopt($ch, CURLOPT_POST, true); | ||
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($this->data)); | ||
$res = curl_exec($ch); | ||
curl_close($ch); | ||
parse_str($res, $result); | ||
return $result; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
<?php | ||
|
||
if (!defined('WHMCS')) { | ||
die('This file cannot be accessed directly'); | ||
} | ||
|
||
use WHMCS\Database\Capsule; | ||
require_once __DIR__ . '/allpay/allpay.php'; | ||
|
||
function allpay_atm_MetaData() { | ||
return array( | ||
'DisplayName' => '歐付寶 - ATM', | ||
'APIVersion' => '1.1', // Use API Version 1.1 | ||
'DisableLocalCredtCardInput' => false, | ||
'TokenisedStorage' => false, | ||
); | ||
} | ||
|
||
function allpay_atm_config() { | ||
return array( | ||
'FriendlyName' => array( | ||
'Type' => 'System', | ||
'Value' => 'ATM', | ||
), | ||
'MerchantID' => array( | ||
'FriendlyName' => '會員編號', | ||
'Type' => 'text', | ||
'Size' => '7', | ||
'Default' => '', | ||
'Description' => '歐付寶會員編號。', | ||
), | ||
'HashKey' => array( | ||
'FriendlyName' => 'HashKey', | ||
'Type' => 'password', | ||
'Size' => '16', | ||
'Default' => '', | ||
'Description' => '於廠商管理後台->系統開發管理->系統介接設定中取得', | ||
), | ||
'HashIV' => array( | ||
'FriendlyName' => 'HashIV', | ||
'Type' => 'password', | ||
'Size' => '16', | ||
'Default' => '', | ||
'Description' => '於廠商管理後台->系統開發管理->系統介接設定中取得', | ||
), | ||
'ExpireDate' => array( | ||
'FriendlyName' => '繳費有效天數', | ||
'Type' => 'text', | ||
'Size' => '3', | ||
'Default' => '7', | ||
'Description' => '', | ||
), | ||
'InvoicePrefix' => array( | ||
'FriendlyName' => '帳單前綴', | ||
'Type' => 'text', | ||
'Default' => '', | ||
'Description' => '選填(只能為數字、英文,且與帳單 ID 合併總字數不能超過 20)', | ||
'Size' => '5', | ||
), | ||
'testMode' => array( | ||
'FriendlyName' => '測試模式', | ||
'Type' => 'yesno', | ||
'Description' => '測試模式', | ||
), | ||
); | ||
} | ||
|
||
function allpay_atm_link($params) { | ||
|
||
# check if in log | ||
$log = Capsule::table('tblactivitylog') | ||
->where('description', 'like', 'allpay_atm:{"'.$params['invoiceid'].'":%') | ||
->orderBy('id', 'desc') | ||
->first(); | ||
if ($log) { | ||
$log = json_decode(substr($log->description, 11), true); | ||
$log = $log[$params['invoiceid']]; | ||
$BankCode = $log['BankCode']; | ||
$vAccount = $log['vAccount']; | ||
$ExpireDateStr = $log['ExpireDate']; | ||
$ExpireDate = strtotime($ExpireDateStr); | ||
if ($ExpireDate >= date()) { | ||
return '<div class="text-left alert alert-info"><p><b>銀行代碼:</b><code>'.$BankCode.'</code></p>'. | ||
'<p><b>帳號:</b><code>'.chunk_split($vAccount, 4, ' ').'</code></p>'. | ||
'<p><b>帳號繳費期限:</b><code>'.$ExpireDateStr.'</code></p></div>'; | ||
} | ||
} | ||
|
||
# Invoice Variables | ||
$TimeStamp = time(); | ||
$TradeNo = $params['InvoicePrefix'].$TimeStamp.$params['invoiceid']; | ||
$amount = $params['amount']; # Format: ##.## | ||
$TotalAmount = round($amount); # Format: ## | ||
|
||
# System Variables | ||
$systemurl = $params['systemurl']; | ||
|
||
# 交易設定 | ||
$ExpireDate = $params['ExpireDate']; | ||
if (!$params['ExpireDate']) { | ||
$ExpireDate = 7; //預設7天 | ||
} | ||
|
||
$transaction = new AllPay_Pay('ATM'); | ||
|
||
# 是否為測試模式 | ||
if ($params['testMode'] == 'on') { | ||
$transaction->setTestMode(); | ||
} else { | ||
$transaction->MerchantID = $params['MerchantID']; | ||
$transaction->HashKey = $params['HashKey']; | ||
$transaction->HashIV = $params['HashIV']; | ||
} | ||
|
||
$transaction->MerchantTradeNo = $TradeNo; | ||
$transaction->TotalAmount = $TotalAmount; | ||
$transaction->TradeDesc = $params['description']; | ||
$transaction->ItemName = $params['description']; | ||
$transaction->ReturnURL = $systemurl.'/modules/gateways/callback/allpay_atm.php'; | ||
$transaction->PaymentInfoURL = $systemurl.'/modules/gateways/callback/allpay_atm_info.php'; | ||
$transaction->ClientBackURL = $params['returnurl']; | ||
$transaction->ExpireDate = $ExpireDate; | ||
|
||
return $transaction->GetHTML($params['langpaynow']); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
<?php | ||
|
||
if (!defined('WHMCS')) { | ||
die('This file cannot be accessed directly'); | ||
} | ||
|
||
require_once __DIR__ . '/allpay/allpay.php'; | ||
|
||
function allpay_credit_MetaData() { | ||
return array( | ||
'DisplayName' => '歐付寶 - 信用卡', | ||
'APIVersion' => '1.1', // Use API Version 1.1 | ||
'DisableLocalCredtCardInput' => false, | ||
'TokenisedStorage' => false, | ||
); | ||
} | ||
|
||
function allpay_credit_config() { | ||
return array( | ||
'FriendlyName' => array( | ||
'Type' => 'System', | ||
'Value' => '信用卡', | ||
), | ||
'MerchantID' => array( | ||
'FriendlyName' => '會員編號', | ||
'Type' => 'text', | ||
'Size' => '7', | ||
'Default' => '', | ||
'Description' => '歐付寶會員編號。', | ||
), | ||
'HashKey' => array( | ||
'FriendlyName' => 'HashKey', | ||
'Type' => 'password', | ||
'Size' => '16', | ||
'Default' => '', | ||
'Description' => '於廠商管理後台->系統開發管理->系統介接設定中取得', | ||
), | ||
'HashIV' => array( | ||
'FriendlyName' => 'HashIV', | ||
'Type' => 'password', | ||
'Size' => '16', | ||
'Default' => '', | ||
'Description' => '於廠商管理後台->系統開發管理->系統介接設定中取得', | ||
), | ||
'InvoicePrefix' => array( | ||
'FriendlyName' => '帳單前綴', | ||
'Type' => 'text', | ||
'Default' => '', | ||
'Description' => '選填(只能為數字、英文,且與帳單 ID 合併總字數不能超過 20)', | ||
'Size' => '5', | ||
), | ||
'testMode' => array( | ||
'FriendlyName' => '測試模式', | ||
'Type' => 'yesno', | ||
'Description' => '測試模式', | ||
), | ||
); | ||
} | ||
|
||
function allpay_credit_link($params) { | ||
|
||
# Invoice Variables | ||
$TimeStamp = time(); | ||
$TradeNo = $params['InvoicePrefix'].$TimeStamp.$params['invoiceid']; | ||
$amount = $params['amount']; # Format: ##.## | ||
$TotalAmount = round($amount); # Format: ## | ||
|
||
# System Variables | ||
$systemurl = $params['systemurl']; | ||
|
||
$transaction = new AllPay_Pay('Credit'); | ||
|
||
# 是否為測試模式 | ||
if ($params['testMode'] == 'on') { | ||
$transaction->setTestMode(); | ||
} else { | ||
$transaction->MerchantID = $params['MerchantID']; | ||
$transaction->HashKey = $params['HashKey']; | ||
$transaction->HashIV = $params['HashIV']; | ||
} | ||
|
||
$transaction->MerchantTradeNo = $TradeNo; | ||
$transaction->TotalAmount = $TotalAmount; | ||
$transaction->TradeDesc = $params['description']; | ||
$transaction->ItemName = $params['description']; | ||
$transaction->ReturnURL = $systemurl.'/modules/gateways/callback/allpay_credit.php'; | ||
$transaction->ClientBackURL = $params['returnurl']; | ||
|
||
return $transaction->GetHTML($params['langpaynow']); | ||
} | ||
|
||
function allpay_credit_refund($params) { | ||
if ($params['testMode'] == 'on') { | ||
return array( | ||
'status' => 'error', | ||
'rawdata' => 'Cannot refund in test mode.', | ||
); | ||
} | ||
list($MerchantTradeNo, $TradeNo) = explode('-', $params['transid']); | ||
$credit = new AllPay_Credit(); | ||
$credit->MerchantTradeNo = $MerchantTradeNo; | ||
$credit->TradeNo = $TradeNo; | ||
$credit->TotalAmount = $params['amount']; | ||
$credit->HashKey = $params['HashKey']; | ||
$credit->HashIV = $params['HashIV']; | ||
$CloseResult = $credit->Close(); | ||
$RefundResult = $credit->Refund(); | ||
return array( | ||
'status' => ($RefundResult['RtnCode']==='1')?'success':'declined', | ||
'rawdata' => $RefundResult, | ||
'transid' => $RefundResult['TradeNo'], | ||
'fees' => 0, | ||
); | ||
} |
Oops, something went wrong.