Created
January 13, 2016 10:32
-
-
Save gamalan/54c8e2df43bbe89ac8ae to your computer and use it in GitHub Desktop.
Skrill Adapter for BoxBilling
This file contains hidden or 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
<?php | |
/** | |
* BoxBilling | |
* | |
* @copyright BoxBilling, Inc (http://www.boxbilling.com) | |
* @license Apache-2.0 | |
* | |
* Copyright BoxBilling, Inc | |
* This source file is subject to the Apache-2.0 License that is bundled | |
* with this source code in the file LICENSE | |
*/ | |
class Payment_Adapter_Skrill | |
{ | |
private $config = array(); | |
public function __construct($config) | |
{ | |
$this->config = $config; | |
if(!function_exists('curl_exec')) { | |
throw new Exception('PHP Curl extension must be enabled in order to use Skrill gateway'); | |
} | |
if(!$this->config['email']) { | |
throw new Exception('Payment gateway "Skrill" is not configured properly. Please update configuration parameter "Skrill Email address" at "Configuration -> Payments".'); | |
} | |
} | |
public static function getConfig() | |
{ | |
return array( | |
'supports_one_time_payments' => true, | |
'supports_subscriptions' => true, | |
'description' => 'Skrill payment gateway for BoxBilling', | |
'form' => array( | |
'email' => array('text', array( | |
'label' => 'Skrill email address for payment', | |
), | |
) | |
), | |
); | |
} | |
/** | |
* Generate payment text | |
* | |
* @param Api_Admin $api_admin | |
* @param int $invoice_id | |
* @param bool $subscription | |
* | |
* @since BoxBilling v2.9.15 | |
* | |
* @return string - html form with auto submit javascript | |
*/ | |
public function getHtml($api_admin, $invoice_id, $subscription) | |
{ | |
$invoice = $api_admin->invoice_get(array('id'=>$invoice_id)); | |
$param = array( | |
':id'=>sprintf('%05s', $invoice['nr']), | |
':serie'=>$invoice['serie'], | |
':title'=>$invoice['lines'][0]['title'] | |
); | |
$title = __('Payment for invoice :serie:id [:title]', $param); | |
$number = $invoice['nr']; | |
// Payment data. | |
$data = array(); | |
// Merchant Details | |
$data['pay_to_email'] = $this->config['email']; | |
$data['transaction_id'] = $number; | |
$data['return_url'] = $this->config['return_url']; | |
$data['cancel_url'] = $this->config['cancel_url']; | |
$data['status_url'] = $this->config['notify_url']; | |
$data['dynamic_descriptor'] = "Descriptor"; | |
$data['redirect_url'] = $this->config['redirect_url']; | |
$data['continue_shopping_url'] = $this->config['continue_shopping_url']; | |
// Payment Details | |
$data['currency'] = $invoice['currency']; | |
$data['amount'] = $this->moneyFormat($invoice['total'], $invoice['currency']); | |
$data['detail1_description'] = "Invoice Number: "; | |
$data['detail1_text'] = $number; | |
$data['detail2_description'] = "Title: "; | |
$data['detail2_text'] = $title; | |
// Customer Details | |
$data['pay_from_email'] = $invoice['buyer_email']; | |
$data['firstname'] = $invoice['buyer_first_name']; | |
$data['lastname'] = $invoice['buyer_last_name']; | |
$data['address'] = $invoice['buyer_address']; | |
$data['city'] = $invoice['buyer_city']; | |
$data['state'] = $invoice['buyer_state']; | |
$data['country'] = $invoice['buyer_country']; | |
$data['phone_number'] = $invoice['buyer_phone']; | |
$data['postal_code'] = $invoice['buyer_zip']; | |
if($subscription) { | |
$subs = $invoice['subscription']; | |
$data['rec_amount'] = $this->moneyFormat($invoice['total'], $invoice['currency']); | |
$data['rec_period'] = $subs['cycle']; | |
switch( $subs['unit'] ) { | |
case 'D': | |
$rec_cycle = 'day'; | |
break; | |
case 'W': | |
$rec_cycle = 'week'; | |
break; | |
case 'M': | |
$rec_cycle = 'month'; | |
break; | |
case 'Y': | |
$rec_cycle = 'year'; | |
break; | |
} | |
$data['rec_cycle'] = $rec_cycle; | |
$data['rec_status_url'] = $this->config['notify_url']; | |
} | |
return $this->_generateForm($this->serviceUrl(), $data); | |
} | |
/** | |
* Process transaction received from payment gateway | |
* | |
* @since BoxBilling v2.9.15 | |
* | |
* @param Api_Admin $api_admin | |
* @param int $id - transaction id to process | |
* @param array $ipn - post, get, server, http_raw_post_data | |
* @param int $gateway_id - payment gateway id on BoxBilling | |
* | |
* @return mixed | |
*/ | |
public function processTransaction($api_admin, $id, $data, $gateway_id) | |
{ | |
if(APPLICATION_ENV != 'testing' && !$this->_isIpnValid($data)) { | |
throw new Payment_Exception('IPN is not valid'); | |
} | |
$ipn = $data['post']; | |
$tx = $api_admin->invoice_transaction_get(array('id'=>$id)); | |
if(!$tx['invoice_id']) { | |
$api_admin->invoice_transaction_update(array('id'=>$id, 'invoice_id'=>$data['get']['bb_invoice_id'])); | |
} | |
if(!$tx['type']) { | |
$api_admin->invoice_transaction_update(array('id'=>$id, 'type'=>$ipn['payment_type'])); | |
} | |
if(!$tx['txn_id']) { | |
$api_admin->invoice_transaction_update(array('id'=>$id, 'txn_id'=>$ipn['transaction_id'])); | |
} | |
if(!$tx['amount']) { | |
$api_admin->invoice_transaction_update(array('id'=>$id, 'amount'=>$ipn['mb_amount'])); | |
} | |
if(!$tx['currency']) { | |
$api_admin->invoice_transaction_update(array('id'=>$id, 'currency'=>$ipn['mb_currency'])); | |
} | |
$data = array( | |
'id' => $id, | |
'error' => '', | |
'error_code'=> '', | |
'status' => 'processed', | |
'updated_at'=> date('c'), | |
); | |
$api_admin->invoice_transaction_update($data); | |
} | |
private function serviceUrl(){ | |
$url = ''; | |
if($this->config['test_mode']) { | |
$url = 'https://www.skrill.com/app/test_payment.pl'; | |
} else { | |
$url = 'https://www.skrill.com/app/payment.pl'; | |
} | |
return $url; | |
} | |
private function _isIpnValid($data) | |
{ | |
// use http_raw_post_data instead of post due to encoding | |
parse_str($data['http_raw_post_data'], $post); | |
$req = 'cmd=_notify-validate'; | |
foreach ((array) $post as $key => $value) { | |
$value = urlencode(stripslashes($value)); | |
$req .= "&$key=$value"; | |
} | |
$url = $this->serviceUrl(); | |
$ret = $this->download($url, $req); | |
return $ret == 'VERIFIED'; | |
} | |
private function moneyFormat($amount, $currency) | |
{ | |
//HUF currency do not accept decimal values | |
if($currency == 'HUF') { | |
return number_format($amount, 0); | |
} | |
return number_format($amount, 2, '.', ''); | |
} | |
/** | |
* @param string $url | |
*/ | |
private function download($url, $post_vars = false, $phd = array(), $contentType = 'application/x-www-form-urlencoded') | |
{ | |
$post_contents = ''; | |
if ($post_vars) { | |
if (is_array($post_vars)) { | |
foreach($post_vars as $key => $val) { | |
$post_contents .= ($post_contents ? '&' : '').urlencode($key).'='.urlencode($val); | |
} | |
} else { | |
$post_contents = $post_vars; | |
} | |
} | |
$uinf = parse_url($url); | |
$host = $uinf['host']; | |
$path = $uinf['path']; | |
$path .= (isset($uinf['query']) && $uinf['query']) ? ('?'.$uinf['query']) : ''; | |
$headers = Array( | |
($post_contents ? 'POST' : 'GET')." $path HTTP/1.1", | |
"Host: $host", | |
'Connection: Close', | |
'User-Agent: BoxBilling' | |
); | |
if (!empty($phd)) { | |
if (!is_array($phd)) { | |
$headers[count($headers)] = $phd; | |
} else { | |
$next = count($headers); | |
$count = count($phd); | |
for ($i = 0; $i < $count; $i++) { $headers[$next + $i] = $phd[$i]; } | |
} | |
} | |
if ($post_contents) { | |
$headers[] = "Content-Type: $contentType"; | |
$headers[] = 'Content-Length: '.strlen($post_contents); | |
} | |
$ch = curl_init(); | |
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); | |
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); | |
curl_setopt($ch, CURLOPT_URL,$url); | |
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); | |
curl_setopt($ch, CURLOPT_TIMEOUT, 600); | |
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers); | |
// Apply the XML to our curl call | |
if ($post_contents) { | |
curl_setopt($ch, CURLOPT_POST, 1); | |
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_contents); | |
} | |
$data = curl_exec($ch); | |
if (curl_errno($ch)) return false; | |
curl_close($ch); | |
return $data; | |
} | |
private function _generateForm($url, $data, $method = 'post') | |
{ | |
$form = ''; | |
$form .= '<form name="payment_form_skrill" action="'.$url.'" method="'.$method.'">'; | |
//following the procedure at http://skrill.com/app/test-payment.pl all field is hidden | |
foreach($data as $key => $value) { | |
$form .= sprintf('<input type="hidden" name="%s" value="%s" />', $key, $value); | |
} | |
$form .= '<input class="bb-button bb-button-submit" type="submit" value="Pay with Skrill" id="payment_button"/>'; | |
$form .= '</form>'; | |
if(isset($this->config['auto_redirect']) && $this->config['auto_redirect']) { | |
$form .= sprintf('<h2>%s</h2>', __('Redirecting to Skrill.com')); | |
$form .= "<script type='text/javascript'>$(document).ready(function(){ | |
document.getElementById('payment_button').style.display = 'none'; | |
document.forms['payment_form_skrill'].submit();}); | |
</script>"; | |
} | |
return $form; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment