Skip to content

Commit

Permalink
歐付寶WHMCS 購物車金流模組
Browse files Browse the repository at this point in the history
  • Loading branch information
AllennChang committed Aug 30, 2017
0 parents commit e33cd8e
Show file tree
Hide file tree
Showing 18 changed files with 1,211 additions and 0 deletions.
23 changes: 23 additions & 0 deletions README.md
@@ -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 added allpay 使用手冊.pdf
Binary file not shown.
Binary file added allpay 程式規格書.pdf
Binary file not shown.
116 changes: 116 additions & 0 deletions modules/gateways/allpay/allpay.php
@@ -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;
}
}
125 changes: 125 additions & 0 deletions modules/gateways/allpay_atm.php
@@ -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']);
}
114 changes: 114 additions & 0 deletions modules/gateways/allpay_credit.php
@@ -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,
);
}

0 comments on commit e33cd8e

Please sign in to comment.