Hexasoft_FraudLabsPro - Version 1.0.0

Version Notes

First public release.

Download this release

Release Info

Developer Hexasoft
Extension Hexasoft_FraudLabsPro
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

app/code/local/Hexasoft/FraudLabsPro/Block/Sales/Order/FraudLabsProResult.php ADDED
@@ -0,0 +1,196 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Hexasoft_FraudLabsPro_Block_Sales_Order_FraudLabsProResult extends Mage_Adminhtml_Block_Template{
3
+ protected function _toHtml(){
4
+ if(!Mage::getStoreConfig('fraudlabspro/basic_settings/active')){
5
+ return false;
6
+ }
7
+
8
+ $order = Mage::registry('current_order');
9
+
10
+ $data = unserialize($order->getfraudlabspro_response());
11
+
12
+ if(isset($_GET['approve']) || isset($_GET['fraud'])){
13
+ $data['fraudlabspro_status'] = (isset($_GET['approve'])) ? 'APPROVE' : 'REJECT';
14
+ $apiKey = (isset($_GET['apiKey'])) ? $_GET['apiKey'] : '';
15
+ $flpId = (isset($_GET['flpId'])) ? $_GET['flpId'] : '';
16
+
17
+
18
+ for($i=0; $i<3; $i++){
19
+ $response = $this->_get('https://api.fraudlabspro.com/v1/order/feedback?key=' . rawurlencode($apiKey) . '&action=' . $data['fraudlabspro_status'] . '&id=' . rawurlencode($flpId) . '&format=json');
20
+
21
+ if(is_null($result = json_decode($response, true)) === FALSE) break;
22
+ }
23
+
24
+ $order->setfraudlabspro_response(serialize($data))->save();
25
+
26
+ die(header('Location: ' . substr(Mage::helper('core/url')->getCurrentUrl(), 0, strpos(Mage::helper('core/url')->getCurrentUrl(), '?'))));
27
+ }
28
+
29
+ if(!$data) return '
30
+ <div class="entry-edit">
31
+ <div class="entry-edit-head" style="background:#cc0000;">
32
+ <h4 class="icon-head head-shipping-method"><a href="http://www.fraudlabspro.com" target="_blank"><img src="http://www.fraudlabspro.com/images/logo-small.png" width="163" height="20" border="0" align="absMiddle" /></a></h4>
33
+ </div>
34
+
35
+ <fieldset>
36
+ This order is not procssed by FraudLabs Pro.
37
+ </fieldset>
38
+ </div>';
39
+
40
+ if($data['fraudlabspro_score'] > 80){
41
+ $score = '<div style="color:#FF0000;font-size:4em;margin-top:20px;"><strong>'.$data['fraudlabspro_score'].'</strong></div>';
42
+ }
43
+ elseif($data['fraudlabspro_score'] > 60){
44
+ $score = '<div style="color:#FFCC00;font-size:4em;margin-top:20px;"><strong>'.$data['fraudlabspro_score'].'</strong></div>';
45
+ }
46
+ elseif($data['fraudlabspro_score'] > 40){
47
+ $score = '<div style="color:#ffc166;font-size:4em;margin-top:20px;"><strong>'.$data['fraudlabspro_score'].'</strong></div>';
48
+ }
49
+ elseif($data['fraudlabspro_score'] > 20){
50
+ $score = '<div style="color:#66CC66;font-size:4em;margin-top:20px;"><strong>'.$data['fraudlabspro_score'].'</strong></div>';
51
+ }
52
+ else{
53
+ $score = '<div style="color:#33CC00;font-size:3em;margin-top:20px;"><strong>'.$data['fraudlabspro_score'].'</strong></div>';
54
+ }
55
+
56
+ $countryName = Mage::getModel('directory/country')->load($data['ip_country'])->getName();
57
+ $location = array($this->_case($data['ip_continent']), $countryName, $this->_case($data['ip_region']), $this->_case($data['ip_city']));
58
+ $location = array_unique($location);
59
+
60
+ switch($data['fraudlabspro_status']){
61
+ case 'REVIEW':
62
+ $status = '<div style="color:#FFCC00;font-size:2em;margin-top:10px;"><strong>'.$data['fraudlabspro_status'].'</strong></div>';
63
+ break;
64
+
65
+ case 'REJECT':
66
+ $status = '<div style="color:#cc0000;font-size:2em;margin-top:10px;"><strong>'.$data['fraudlabspro_status'].'</strong></div>';
67
+ break;
68
+
69
+ case 'APPROVE':
70
+ $status = '<div style="color:#336600;font-size:2em;margin-top:10px;"><strong>'.$data['fraudlabspro_status'].'</strong></div>';
71
+ break;
72
+
73
+ default:
74
+ $status = '-';
75
+ }
76
+
77
+ $out = '
78
+ <div class="entry-edit">
79
+ <div class="entry-edit-head" style="background:#cc0000; padding:5px;">
80
+ <h4 class="icon-head head-shipping-method"><a href="http://www.fraudlabspro.com" target="_blank"><img src="http://www.fraudlabspro.com/images/logo-small.png" width="163" height="20" border="0" align="absMiddle" /></a></h4>
81
+ </div>
82
+
83
+ <fieldset>
84
+ <table width="100%" border="1" bordercolor="#c0c0c0" style="border-collapse:collapse;">
85
+ <tr>
86
+ <td rowspan="3" style="width:90px; text-align:center; vertical-align:top; padding:5px;"><strong>Score</strong> <a href="javascript:;" title="Overall score between 0 and 100. 100 is the highest risk. 0 is the lowest risk.">[?]</a><br/>' . $score . '</td>
87
+ <td style="width:120px; padding:5px;"><span><strong>IP Address</strong></span></td>
88
+ <td style="width:150px; padding:5px;"><span>' . $data['ip_address'] . '</span></td>
89
+ <td style="width:140px; padding:5px;"><span><strong>IP Net Speed</strong> <a href="javascript:;" title="Connection speed.">[?]</a></span></td>
90
+ <td style="width:120px; padding:5px;"><span>' . $data['ip_netspeed'] . '</span></td>
91
+ <td style="width:120px; padding:5px;"><span><strong>IP ISP Name</strong> <a href="javascript:;" title="Estimated ISP of the IP address.">[?]</a></span></td>
92
+ <td style="padding:5px;"><span>' . $this->_case($data['ip_isp_name']) . '</span></td>
93
+ </tr>
94
+ <tr>
95
+ <td style="padding:5px;"><span><strong>IP Usage Type</strong> <a href="javascript:;" title="Estimated usage type of the IP address. For example: ISP, Commercial, Residential.">[?]</a></span></td>
96
+ <td style="padding:5px;"><span>' . $data['ip_usage_type'] . '</span></td>
97
+ <td style="padding:5px;"><span><strong>IP Domain</strong> <a href="javascript:;" title="Estimated domain name of the IP address.">[?]</a></span></td>
98
+ <td style="padding:5px;"><span>' . $data['ip_domain'] . '</span></td>
99
+ <td style="padding:5px;"><span><strong>IP Time Zone</strong> <a href="javascript:;" title="Estimated time zone of the IP address.">[?]</a></span></td>
100
+ <td style="padding:5px;"><span>' . $data['ip_timezone'] . '</span></td>
101
+ </tr>
102
+ <tr>
103
+ <td style="padding:5px;"><span><strong>IP Location</strong> <a href="javascript:;" title="Estimated location of the IP address.">[?]</a></span></td>
104
+ <td colspan="3" style="padding:5px;"><span>' . implode(', ', $location) . ' <a href="http://www.geolocation.com/' . $data['ip_address'] . '" target="_blank">[Map]</a></span></td>
105
+ <td style="padding:5px;"><span><strong>IP Distance</strong> <a href="javascript:;" title="Distance from IP address to Billing Location.">[?]</a></span></td>
106
+ <td style="padding:5px;"><span>' . $data['distance_in_mile'] . ' Miles</span></td>
107
+ </tr>
108
+ <tr>
109
+ <td rowspan="4" style="padding:5px; vertical-align:top; text-align:center;"><span><strong>FraudLabs Pro Status</strong> <a href="javascript:;" title="FraudLabs Pro status.">[?]</a><br>' . $status . '</span></td>
110
+ <td style="padding:5px;"><span><strong>IP Latitude</strong> <a href="javascript:;" title="Estimated latitude of the IP address.">[?]</a></span></td>
111
+ <td style="padding:5px;"><span>' . $data['ip_latitude'] . '</span></td>
112
+ <td style="padding:5px;"><span><strong>IP Longitude</strong> <a href="javascript:;" title="Estimated longitude of the IP address.">[?]</a></span></td>
113
+ <td colspan="3" style="padding:5px;"><span>' . $data['ip_longitude'] . '</span></td>
114
+ </tr>
115
+ <tr>
116
+ <td style="padding:5px;"><span><strong>Risk Country</strong> <a href="javascript:;" title="Whether IP address or billing address country is in the latest high risk list.">[?]</a></span></td>
117
+ <td style="padding:5px;"><span>' . (($data['is_high_risk_country'] == 'Y') ? 'Yes' : (($data['is_high_risk_country'] == 'N') ? 'No' : '-')) . '</span></td>
118
+ <td style="padding:5px;"><span><strong>Free Email</strong> <a href="javascript:;" title="Whether e-mail is from free e-mail provider.">[?]</a></span></td>
119
+ <td style="padding:5px;"><span>' . (($data['is_free_email'] == 'Y') ? 'Yes' : (($data['is_free_email'] == 'N') ? 'No' : '-')) . '</span></td>
120
+ <td style="padding:5px;"><span><strong>Ship Forward</strong> <a href="javascript:;" title="Whether shipping address is in database of known mail drops.">[?]</a></span></td>
121
+ <td style="padding:5px;"><span>' . (($data['is_address_ship_forward'] == 'Y') ? 'Yes' : (($data['is_address_ship_forward'] == 'N') ? 'No' : '-')) . '</span></td>
122
+ </tr>
123
+ <tr>
124
+ <td style="padding:5px;"><span><strong>Using Proxy</strong> <a href="javascript:;" title="Whether IP address is from Anonymous Proxy Server.">[?]</a></span></td>
125
+ <td style="padding:5px;"><span>' . (($data['is_proxy_ip_address'] == 'Y') ? 'Yes' : 'No') . '</span></td>
126
+ <td style="padding:5px;"><span><strong>BIN Found</strong> <a href="javascript:;" title="Whether the BIN information matches our BIN list.">[?]</a></span></td>
127
+ <td style="padding:5px;"><span>' . (($data['is_bin_found'] == 'Y') ? 'Yes' : (($data['is_bin_found'] == 'N') ? 'No' : '-')) . '</span></td>
128
+ <td colspan="3" style="padding:5px;"></td>
129
+ </tr>
130
+ <tr>
131
+ <td style="padding:5px;"><span><strong>Email Blacklist</strong> <a href="javascript:;" title="Whether the email address is in our blacklist database.">[?]</a></span></td>
132
+ <td style="padding:5px;"><span>' . (($data['is_email_blacklist'] == 'Y') ? 'Yes' : (($data['is_email_blacklist'] == 'N') ? 'No' : '-')) . '</span></td>
133
+ <td style="padding:5px;"><span><strong>Credit Card Blacklist</strong> <a href="javascript:;" title="Whether the credit card is in our blacklist database.">[?]</a></span></td>
134
+ <td style="padding:5px;"><span>' . (($data['is_credit_card_blacklist'] == 'Y') ? 'Yes' : (($data['is_credit_card_blacklist'] == 'N') ? 'No' : '-')) . '</span></td>
135
+ <td colspan="3" style="padding:5px;"><span>&nbsp;</span></td>
136
+ </tr>
137
+ <tr>
138
+ <td style="padding:5px;"><span><strong>Message</strong> <a href="javascript:;" title="FraudLabs Pro service message response.">[?]</a></span></td>
139
+ <td colspan="6" style="padding:5px;"><span>' . (($data['fraudlabspro_error_code']) ? $data['fraudlabspro_error_code'] . ': ' : '') . $data['fraudlabspro_message'] . '</span></td>
140
+ </tr>
141
+ <tr>
142
+ <td style="padding:5px;"><span><strong>Link</strong></span></td>
143
+ <td colspan="6" style="padding:5px;"><span><a href="http://www.fraudlabspro.com/merchant/transaction-details/' . $data['fraudlabspro_id'] . '" target="_blank">http://www.fraudlabspro.com/merchant/transaction-details/' . $data['fraudlabspro_id'] . '</a></span></td>
144
+ </tr>';
145
+
146
+ if($data['fraudlabspro_status'] == 'REVIEW'){
147
+ $out .= '
148
+ <tr>
149
+ <td colspan="7">
150
+ <form>
151
+ <input type="hidden" name="apiKey" value="' . $data['api_key'] . '" />
152
+ <input type="hidden" name="flpId" value="' . $data['fraudlabspro_id'] . '" />
153
+
154
+ <div style="text-align:center;padding:10px">
155
+ <input type="submit" name="approve" value="Approve Order" />
156
+ <input type="submit" name="fraud" value="Reject Order" />
157
+ </div>
158
+ </form>
159
+ </td>
160
+ </tr>';
161
+ }
162
+
163
+ $out .= '
164
+ </table>
165
+ </fieldset>
166
+ </div>';
167
+
168
+ return $out;
169
+ }
170
+
171
+ private function _get($url){
172
+ $ch = curl_init();
173
+
174
+ curl_setopt($ch, CURLOPT_FAILONERROR, 1);
175
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
176
+ curl_setopt($ch, CURLOPT_ENCODING , 'gzip, deflate');
177
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
178
+ curl_setopt($ch, CURLOPT_URL, $url);
179
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
180
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
181
+
182
+ $result = curl_exec($ch);
183
+
184
+ if(!curl_errno($ch)) return $result;
185
+
186
+ curl_close($ch);
187
+
188
+ return false;
189
+ }
190
+
191
+ private function _case($s){
192
+ $s = ucwords(strtolower($s));
193
+ $s = preg_replace_callback("/( [ a-zA-Z]{1}')([a-zA-Z0-9]{1})/s",create_function('$matches','return $matches[1].strtoupper($matches[2]);'),$s);
194
+ return $s;
195
+ }
196
+ }
app/code/local/Hexasoft/FraudLabsPro/Block/Sales/Order/Grid.php ADDED
@@ -0,0 +1,180 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Hexasoft_FraudLabsPro_Block_Sales_Order_Grid extends Mage_Adminhtml_Block_Widget_Grid{
3
+ public function __construct(){
4
+ parent::__construct();
5
+ $this->setId('sales_order_grid');
6
+ $this->setUseAjax(true);
7
+ $this->setDefaultSort('created_at');
8
+ $this->setDefaultDir('DESC');
9
+ $this->setSaveParametersInSession(true);
10
+ }
11
+
12
+ protected function _getCollectionClass(){
13
+ return 'sales/order_grid_collection';
14
+ }
15
+
16
+ protected function _prepareCollection(){
17
+ $collection = Mage::getResourceModel($this->_getCollectionClass());
18
+
19
+ $this->setCollection($collection);
20
+ return parent::_prepareCollection();
21
+ }
22
+
23
+ protected function _prepareColumns(){
24
+ $this->addColumn('real_order_id', array(
25
+ 'header'=> Mage::helper('sales')->__('Order #'),
26
+ 'width' => '80px',
27
+ 'type' => 'text',
28
+ 'index' => 'increment_id',
29
+ ));
30
+
31
+ if (!Mage::app()->isSingleStoreMode()) {
32
+ $this->addColumn('store_id', array(
33
+ 'header' => Mage::helper('sales')->__('Purchased From (Store)'),
34
+ 'index' => 'store_id',
35
+ 'type' => 'store',
36
+ 'store_view'=> true,
37
+ 'display_deleted' => true,
38
+ ));
39
+ }
40
+
41
+ $this->addColumn('created_at', array(
42
+ 'header' => Mage::helper('sales')->__('Purchased On'),
43
+ 'index' => 'created_at',
44
+ 'type' => 'datetime',
45
+ 'width' => '100px',
46
+ ));
47
+
48
+ $this->addColumn('billing_name', array(
49
+ 'header' => Mage::helper('sales')->__('Bill to Name'),
50
+ 'index' => 'billing_name',
51
+ ));
52
+
53
+ $this->addColumn('shipping_name', array(
54
+ 'header' => Mage::helper('sales')->__('Ship to Name'),
55
+ 'index' => 'shipping_name',
56
+ ));
57
+
58
+ $this->addColumn('base_grand_total', array(
59
+ 'header' => Mage::helper('sales')->__('G.T. (Base)'),
60
+ 'index' => 'base_grand_total',
61
+ 'type' => 'currency',
62
+ 'currency' => 'base_currency_code',
63
+ ));
64
+
65
+ $this->addColumn('grand_total', array(
66
+ 'header' => Mage::helper('sales')->__('G.T. (Purchased)'),
67
+ 'index' => 'grand_total',
68
+ 'type' => 'currency',
69
+ 'currency' => 'order_currency_code',
70
+ ));
71
+
72
+ $this->addColumn('status', array(
73
+ 'header' => Mage::helper('sales')->__('Status'),
74
+ 'index' => 'status',
75
+ 'type' => 'options',
76
+ 'width' => '70px',
77
+ 'options' => Mage::getSingleton('sales/order_config')->getStatuses(),
78
+ ));
79
+
80
+ $this->addColumn('risk', array(
81
+ 'header' => Mage::helper('sales')->__('Risk Assessment'),
82
+ 'width' => '50px',
83
+ 'sortable' => false,
84
+ 'filter' => false,
85
+ 'renderer' => 'fraudlabspro/sales_order_grid_renderer_risk',
86
+ ));
87
+
88
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
89
+ $this->addColumn('action',
90
+ array(
91
+ 'header' => Mage::helper('sales')->__('Action'),
92
+ 'width' => '50px',
93
+ 'type' => 'action',
94
+ 'getter' => 'getId',
95
+ 'actions' => array(
96
+ array(
97
+ 'caption' => Mage::helper('sales')->__('View'),
98
+ 'url' => array('base'=>'*/sales_order/view'),
99
+ 'field' => 'order_id'
100
+ )
101
+ ),
102
+ 'filter' => false,
103
+ 'sortable' => false,
104
+ 'index' => 'stores',
105
+ 'is_system' => true,
106
+ ));
107
+ }
108
+ $this->addRssList('rss/order/new', Mage::helper('sales')->__('New Order RSS'));
109
+ $this->addExportType('*/*/exportCsv', Mage::helper('sales')->__('CSV'));
110
+ $this->addExportType('*/*/exportExcel', Mage::helper('sales')->__('Excel XML'));
111
+
112
+ return parent::_prepareColumns();
113
+ }
114
+
115
+ protected function _prepareMassaction(){
116
+ $this->setMassactionIdField('entity_id');
117
+ $this->getMassactionBlock()->setFormFieldName('order_ids');
118
+ $this->getMassactionBlock()->setUseSelectAll(false);
119
+
120
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/cancel')) {
121
+ $this->getMassactionBlock()->addItem('cancel_order', array(
122
+ 'label'=> Mage::helper('sales')->__('Cancel'),
123
+ 'url' => $this->getUrl('*/sales_order/massCancel'),
124
+ ));
125
+ }
126
+
127
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/hold')) {
128
+ $this->getMassactionBlock()->addItem('hold_order', array(
129
+ 'label'=> Mage::helper('sales')->__('Hold'),
130
+ 'url' => $this->getUrl('*/sales_order/massHold'),
131
+ ));
132
+ }
133
+
134
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/unhold')) {
135
+ $this->getMassactionBlock()->addItem('unhold_order', array(
136
+ 'label'=> Mage::helper('sales')->__('Unhold'),
137
+ 'url' => $this->getUrl('*/sales_order/massUnhold'),
138
+ ));
139
+ }
140
+
141
+ $this->getMassactionBlock()->addItem('pdfinvoices_order', array(
142
+ 'label'=> Mage::helper('sales')->__('Print Invoices'),
143
+ 'url' => $this->getUrl('*/sales_order/pdfinvoices'),
144
+ ));
145
+
146
+ $this->getMassactionBlock()->addItem('pdfshipments_order', array(
147
+ 'label'=> Mage::helper('sales')->__('Print Packingslips'),
148
+ 'url' => $this->getUrl('*/sales_order/pdfshipments'),
149
+ ));
150
+
151
+ $this->getMassactionBlock()->addItem('pdfcreditmemos_order', array(
152
+ 'label'=> Mage::helper('sales')->__('Print Credit Memos'),
153
+ 'url' => $this->getUrl('*/sales_order/pdfcreditmemos'),
154
+ ));
155
+
156
+ $this->getMassactionBlock()->addItem('pdfdocs_order', array(
157
+ 'label'=> Mage::helper('sales')->__('Print All'),
158
+ 'url' => $this->getUrl('*/sales_order/pdfdocs'),
159
+ ));
160
+
161
+ $this->getMassactionBlock()->addItem('print_shipping_label', array(
162
+ 'label'=> Mage::helper('sales')->__('Print Shipping Labels'),
163
+ 'url' => $this->getUrl('*/sales_order_shipment/massPrintShippingLabel'),
164
+ ));
165
+
166
+ return $this;
167
+ }
168
+
169
+ public function getRowUrl($row){
170
+ if (Mage::getSingleton('admin/session')->isAllowed('sales/order/actions/view')) {
171
+ return $this->getUrl('*/sales_order/view', array('order_id' => $row->getId()));
172
+ }
173
+ return false;
174
+ }
175
+
176
+ public function getGridUrl(){
177
+ return $this->getUrl('*/*/grid', array('_current'=>true));
178
+ }
179
+ }
180
+ ?>
app/code/local/Hexasoft/FraudLabsPro/Block/Sales/Order/Grid/Renderer/Risk.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Hexasoft_FraudLabsPro_Block_Sales_Order_Grid_Renderer_Risk extends Mage_Adminhtml_Block_Widget_Grid_Column_Renderer_Abstract{
3
+ public function render(Varien_Object $row){
4
+ $out = '';
5
+
6
+ $order = Mage::getModel('sales/order')->load($row->getId());
7
+ $result = $order->getfraudlabspro_response();
8
+
9
+ if(!$result){
10
+ $out = Mage::helper('fraudlabspro')->__('-');
11
+ }else{
12
+ $data = unserialize($result);
13
+ $out .= $data['fraudlabspro_status'];
14
+ }
15
+ return $out;
16
+ }
17
+ }
app/code/local/Hexasoft/FraudLabsPro/Controller/Observer.php ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Hexasoft_FraudLabsPro_Controller_Observer{
3
+
4
+ public function sendRequestToFraudLabsProNonObserver($order_id){
5
+ if(!Mage::getStoreConfig('fraudlabspro/basic_settings/active')){
6
+ return true;
7
+ }
8
+
9
+ $order = Mage::getModel('sales/order')->load($order_id);
10
+
11
+ if($order->getfraudlabspro_response()){
12
+ Mage::getSingleton('adminhtml/session')->addError(Mage::helper('fraudlabspro')->__('Request already submitted to FraudLabs Pro.'));
13
+ return true;
14
+ }
15
+
16
+ return $this->processSendRequestToFraudLabsPro($order);
17
+ }
18
+
19
+ public function sendRequestToFraudLabsPro($observer){
20
+
21
+ if(!Mage::getStoreConfig('fraudlabspro/basic_settings/active')){
22
+ return true;
23
+ }
24
+
25
+ $event = $observer->getEvent();
26
+ $order = $event->getOrder();
27
+
28
+ if($order->getfraudlabspro_response()){
29
+ return true;
30
+ }
31
+
32
+ return $this->processSendRequestToFraudLabsPro($order);
33
+ }
34
+
35
+ public function processSendRequestToFraudLabsPro($order){
36
+ if(isset($_SERVER['DEV_MODE'])) $_SERVER['REMOTE_ADDR'] = '175.143.8.154';
37
+
38
+ $apiKey = Mage::getStoreConfig('fraudlabspro/basic_settings/api_key');
39
+
40
+ $billingAddress = $order->getBillingAddress();
41
+
42
+ $queries = array(
43
+ 'format'=>'json',
44
+ 'key'=>$apiKey,
45
+ 'ip'=>$_SERVER['REMOTE_ADDR'],
46
+ 'bill_city'=>$billingAddress->getCity(),
47
+ 'bill_state'=>$billingAddress->getRegion(),
48
+ 'bill_country'=>$billingAddress->getCountryId(),
49
+ 'bill_zip_code'=>$billingAddress->getPostcode(),
50
+ 'email_domain'=>substr($order->getCustomerEmail(), strpos($order->getCustomerEmail(), '@')+1),
51
+ 'email_hash'=>$this->_hash($order->getCustomerEmail()),
52
+ 'phone'=>$billingAddress->getTelephone(),
53
+ 'amount'=>$order->getBaseGrandTotal(),
54
+ 'quantity'=>count($order->getAllItems()),
55
+ 'currency'=>Mage::app()->getStore()->getCurrentCurrencyCode(),
56
+ 'user_order_id'=>$order->getIncrementId(),
57
+ 'magento_order_id'=>$order->getEntityId(),
58
+ );
59
+
60
+ $shippingAddress = $order->getShippingAddress();
61
+
62
+ if($shippingAddress){
63
+ $queries['ship_addr'] = trim($shippingAddress->getStreet(1) . ' ' . $shippingAddress->getStreet(2));
64
+ $queries['ship_city'] = $shippingAddress->getCity();
65
+ $queries['ship_state'] = $shippingAddress->getRegion();
66
+ $queries['ship_zip_code'] = $shippingAddress->getPostcode();
67
+ $queries['ship_country'] = $shippingAddress->getCountryId();
68
+ }
69
+
70
+ $query = '';
71
+ foreach($queries as $key=>$value){
72
+ $query .= $key . '=' . rawurlencode($value) . '&';
73
+ }
74
+
75
+ for($i=0; $i<3; $i++){
76
+ $response = $this->_get('https://api.fraudlabspro.com/v1/order/screen?' . $query);
77
+
78
+ if(is_null($result = json_decode($response, true)) === FALSE) break;
79
+ }
80
+
81
+ if(!$result) return false;
82
+
83
+ $result['ip_address'] = $queries['ip'];
84
+ $result['api_key'] = $apiKey;
85
+
86
+ $order->setfraudlabspro_response(serialize($result))->save();
87
+
88
+ Mage::getSingleton('adminhtml/session')->addSuccess(Mage::helper('fraudlabspro')->__('FraudLabs Pro Request sent.'));
89
+ return true;
90
+ }
91
+
92
+ private function _get($url){
93
+ $ch = curl_init();
94
+
95
+ curl_setopt($ch, CURLOPT_FAILONERROR, 1);
96
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
97
+ curl_setopt($ch, CURLOPT_ENCODING , 'gzip, deflate');
98
+ curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
99
+ curl_setopt($ch, CURLOPT_URL, $url);
100
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
101
+ curl_setopt($ch, CURLOPT_TIMEOUT, 30);
102
+
103
+ $result = curl_exec($ch);
104
+
105
+ if(!curl_errno($ch)) return $result;
106
+
107
+ curl_close($ch);
108
+
109
+ return false;
110
+ }
111
+
112
+ private function _hash($s, $prefix='fraudlabspro_'){
113
+ $hash = $prefix . $s;
114
+ for($i=0; $i<65536; $i++) $hash = sha1($prefix . $hash);
115
+
116
+ return $hash;
117
+ }
118
+ }
app/code/local/Hexasoft/FraudLabsPro/Helper/Data.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php
2
+ class Hexasoft_FraudLabsPro_Helper_Data extends Mage_Core_Helper_Abstract{}
3
+ ?>
app/code/local/Hexasoft/FraudLabsPro/controllers/IndexController.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ class Hexasoft_FraudLabsPro_IndexController extends Mage_Core_Controller_Front_Action{
3
+ public function indexAction(){
4
+ $this->loadLayout(array('default'));
5
+ $this->renderLayout();
6
+ }
7
+ }
app/code/local/Hexasoft/FraudLabsPro/etc/adminhtml.xml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <acl>
4
+ <resources>
5
+ <admin>
6
+ <children>
7
+ <system>
8
+ <children>
9
+ <config>
10
+ <children>
11
+ <fraudlabspro translate="title" module="fraudlabspro">
12
+ <title>FraudLabs Pro</title>
13
+ <sort_order>10</sort_order>
14
+ </fraudlabspro>
15
+ </children>
16
+ </config>
17
+ </children>
18
+ </system>
19
+ </children>
20
+ </admin>
21
+ </resources>
22
+ </acl>
23
+ </config>
app/code/local/Hexasoft/FraudLabsPro/etc/config.xml ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Hexasoft_FraudLabsPro>
5
+ <version>1.0.0</version>
6
+ </Hexasoft_FraudLabsPro>
7
+ </modules>
8
+
9
+ <global>
10
+ <blocks>
11
+ <fraudlabspro>
12
+ <class>Hexasoft_FraudLabsPro_Block</class>
13
+ </fraudlabspro>
14
+ <adminhtml>
15
+ <rewrite>
16
+ <sales_order_grid>Hexasoft_FraudLabsPro_Block_Sales_Order_Grid</sales_order_grid>
17
+ </rewrite>
18
+ </adminhtml>
19
+ </blocks>
20
+ <models>
21
+ <fraudlabspro>
22
+ <class>Hexasoft_FraudLabsPro_Model</class>
23
+ </fraudlabspro>
24
+ </models>
25
+ <helpers>
26
+ <fraudlabspro>
27
+ <class>Hexasoft_FraudLabsPro_Helper</class>
28
+ </fraudlabspro>
29
+ </helpers>
30
+
31
+ <resources>
32
+ <fraudlabspro_setup>
33
+ <setup>
34
+ <module>Hexasoft_FraudLabsPro</module>
35
+ </setup>
36
+ <connection>
37
+ <use>core_setup</use>
38
+ </connection>
39
+ </fraudlabspro_setup>
40
+
41
+ <fraudlabspro_write>
42
+ <connection>
43
+ <use>core_write</use>
44
+ </connection>
45
+ </fraudlabspro_write>
46
+ <fraudlabspro_read>
47
+ <connection>
48
+ <use>core_read</use>
49
+ </connection>
50
+ </fraudlabspro_read>
51
+ </resources>
52
+
53
+ <events>
54
+ <sales_order_save_after>
55
+ <observers>
56
+ <send_request_to_fraudlabspro>
57
+ <type>singleton</type>
58
+ <class>Hexasoft_FraudLabsPro_Controller_Observer</class>
59
+ <method>sendRequestToFraudLabsPro</method>
60
+ </send_request_to_fraudlabspro>
61
+ </observers>
62
+ </sales_order_save_after>
63
+ </events>
64
+ </global>
65
+
66
+ <adminhtml>
67
+ <layout>
68
+ <updates>
69
+ <fraudlabspro>
70
+ <file>fraudlabspro.xml</file>
71
+ </fraudlabspro>
72
+ </updates>
73
+ </layout>
74
+ </adminhtml>
75
+
76
+ <frontend>
77
+ <routers>
78
+ <fraudlabspro>
79
+ <use>standard</use>
80
+ <args>
81
+ <module>Hexasoft_FraudLabsPro</module>
82
+ <frontName>fraudlabspro</frontName>
83
+ </args>
84
+ </fraudlabspro>
85
+ </routers>
86
+ </frontend>
87
+
88
+ <default>
89
+ <fraudlabspro>
90
+ <basic_settings>
91
+ <active>0</active>
92
+ <api_key></api_key>
93
+ </basic_settings>
94
+ </fraudlabspro>
95
+ </default>
96
+ </config>
app/code/local/Hexasoft/FraudLabsPro/etc/system.xml ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <tabs>
4
+ <fraudlabspro translate="label" module="fraudlabspro">
5
+ <label>FraudLabs Pro</label>
6
+ <sort_order>200</sort_order>
7
+ </fraudlabspro>
8
+ </tabs>
9
+ <sections>
10
+ <fraudlabspro translate="label" module="fraudlabspro">
11
+ <class>separator-top</class>
12
+ <label>Settings</label>
13
+ <tab>fraudlabspro</tab>
14
+ <sort_order>130</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <show_in_website>1</show_in_website>
17
+ <show_in_store>1</show_in_store>
18
+ <groups>
19
+ <basic_settings translate="label">
20
+ <label>FraudLabs Pro</label>
21
+ <frontend_type>text</frontend_type>
22
+ <sort_order>10</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>0</show_in_website>
25
+ <show_in_store>0</show_in_store>
26
+ <fields>
27
+ <active translate="label">
28
+ <label>Enabled</label>
29
+ <frontend_type>select</frontend_type>
30
+ <source_model>adminhtml/system_config_source_yesno</source_model>
31
+ <sort_order>1</sort_order>
32
+ <show_in_default>1</show_in_default>
33
+ <show_in_website>1</show_in_website>
34
+ <show_in_store>1</show_in_store>
35
+ </active>
36
+ <api_key translate="label">
37
+ <label>API Key</label>
38
+ <frontend_type>text</frontend_type>
39
+ <sort_order>20</sort_order>
40
+ <show_in_default>1</show_in_default>
41
+ <show_in_website>1</show_in_website>
42
+ <show_in_store>1</show_in_store>
43
+ <comment><![CDATA[You can register for a free license key at <a href="http://www.fraudlabspro.com/sign-up?r=magento" target="_blank">http://www.fraudlabspro.com/sign-up</a> if you do not have one.]]></comment>
44
+ </api_key>
45
+ </fields>
46
+ </basic_settings>
47
+ </groups>
48
+ </fraudlabspro>
49
+ </sections>
50
+ </config>
app/code/local/Hexasoft/FraudLabsPro/sql/fraudlabspro_setup/mysql4-install-1.0.0.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+ $installer = $this;
3
+ $installer->startSetup();
4
+ $conn = $installer->getConnection();
5
+ $conn->addColumn($installer->getTable('sales_flat_order'), 'fraudlabspro_response', 'text');
6
+ $installer->endSetup();
7
+ ?>
app/design/adminhtml/default/default/layout/fraudlabspro.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout>
3
+ <adminhtml_sales_order_view>
4
+ <reference name="order_tab_info">
5
+ <action method="setTemplate" ifconfig="fraudlabspro/basic_settings/active"><template>fraudlabspro/sales/order/view/tab/info.phtml</template></action>
6
+ <block type="fraudlabspro/sales_order_fraudlabsproresult" name="fraudlabspro_sales_order_fraudlabsproresult"></block>
7
+ </reference>
8
+ </adminhtml_sales_order_view>
9
+ </layout>
app/design/adminhtml/default/default/template/fraudlabspro/sales/order/view/tab/info.phtml ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $_order = $this->getOrder()
3
+ ?>
4
+ <div>
5
+ <div id="order-messages">
6
+ <?php echo $this->getChildHtml('order_messages') ?>
7
+ </div>
8
+ <?php echo $this->getChildHtml('order_info') ?>
9
+ <input type="hidden" name="order_id" value="<?php echo $_order->getId() ?>"/>
10
+ <?php if ($_order->getIsVirtual()): ?>
11
+ <div class="box-right">
12
+ <?php else: ?>
13
+ <div class="box-left">
14
+ <?php endif; ?>
15
+ <!--Payment Method-->
16
+ <div class="entry-edit">
17
+ <div class="entry-edit-head">
18
+ <h4 class="icon-head head-payment-method"><?php echo Mage::helper('sales')->__('Payment Information') ?></h4>
19
+ </div>
20
+ <fieldset>
21
+ <?php echo $this->getPaymentHtml() ?>
22
+ <div><?php echo Mage::helper('sales')->__('Order was placed using %s', $_order->getOrderCurrencyCode()) ?></div>
23
+ </fieldset>
24
+ </div>
25
+ </div>
26
+ <?php if (!$_order->getIsVirtual()): ?>
27
+ <div class="box-right">
28
+ <!--Shipping Method-->
29
+ <div class="entry-edit">
30
+ <div class="entry-edit-head">
31
+ <h4 class="icon-head head-shipping-method"><?php echo Mage::helper('sales')->__('Shipping &amp; Handling Information') ?></h4>
32
+ </div>
33
+ <fieldset>
34
+ <?php if ($_order->getTracksCollection()->count()) : ?>
35
+ <a href="#" id="linkId" onclick="popWin('<?php echo $this->helper('shipping')->getTrackingPopupUrlBySalesModel($_order) ?>','trackorder','width=800,height=600,resizable=yes,scrollbars=yes')" title="<?php echo $this->__('Track Order') ?>"><?php echo $this->__('Track Order') ?></a>
36
+ <br/>
37
+ <?php endif; ?>
38
+ <?php if ($_order->getShippingDescription()): ?>
39
+ <strong><?php echo $_order->getShippingDescription() ?></strong>
40
+
41
+ <?php if ($this->helper('tax')->displayShippingPriceIncludingTax()): ?>
42
+ <?php $_excl = $this->displayShippingPriceInclTax($_order); ?>
43
+ <?php else: ?>
44
+ <?php $_excl = $this->displayPriceAttribute('shipping_amount', false, ' '); ?>
45
+ <?php endif; ?>
46
+ <?php $_incl = $this->displayShippingPriceInclTax($_order); ?>
47
+
48
+ <?php echo $_excl; ?>
49
+ <?php if ($this->helper('tax')->displayShippingBothPrices() && $_incl != $_excl): ?>
50
+ (<?php echo $this->__('Incl. Tax'); ?> <?php echo $_incl; ?>)
51
+ <?php endif; ?>
52
+ <?php else: ?>
53
+ <?php echo $this->helper('sales')->__('No shipping information available'); ?>
54
+ <?php endif; ?>
55
+ </fieldset>
56
+ </div>
57
+ </div>
58
+ <?php endif; ?>
59
+ <div class="clear"></div>
60
+ <?php echo $this->getGiftOptionsHtml() ?>
61
+ <div class="clear"></div>
62
+ <div class="entry-edit">
63
+ <div class="entry-edit-head">
64
+ <h4 class="icon-head head-products"><?php echo Mage::helper('sales')->__('Items Ordered') ?></h4>
65
+ </div>
66
+ </div>
67
+ <?php echo $this->getItemsHtml() ?>
68
+ <div class="clear"></div>
69
+
70
+ <?php echo $this->getChildHtml('fraudlabspro_sales_order_fraudlabsproresult') ?>
71
+ <div class="clear"></div>
72
+
73
+ <div class="box-left">
74
+ <div class="entry-edit">
75
+ <div class="entry-edit-head">
76
+ <h4><?php echo Mage::helper('sales')->__('Comments History') ?></h4>
77
+ </div>
78
+ <fieldset><?php echo $this->getChildHtml('order_history') ?></fieldset>
79
+ </div>
80
+ </div>
81
+ <div class="box-right entry-edit">
82
+ <div class="entry-edit-head"><h4><?php echo Mage::helper('sales')->__('Order Totals') ?></h4></div>
83
+ <div class="order-totals"><?php echo $this->getChildHtml('order_totals') ?></div>
84
+ </div>
85
+ <div class="clear"></div>
86
+ </div>
87
+
88
+ <?php echo $this->getChildHtml('popup_window');?>
89
+ <script type="text/javascript">
90
+ //<![CDATA[
91
+ /**
92
+ * Retrieve gift options tooltip content
93
+ */
94
+ function getGiftOptionsTooltipContent(itemId) {
95
+ var contentLines = [];
96
+ var headerLine = null;
97
+ var contentLine = null;
98
+
99
+ $$('#gift_options_data_' + itemId + ' .gift-options-tooltip-content').each(function (element) {
100
+ if (element.down(0)) {
101
+ headerLine = element.down(0).innerHTML;
102
+ contentLine = element.down(0).next().innerHTML;
103
+ if (contentLine.length > 30) {
104
+ contentLine = contentLine.slice(0,30) + '...';
105
+ }
106
+ contentLines.push(headerLine + ' ' + contentLine);
107
+ }
108
+ });
109
+ return contentLines.join('<br/>');
110
+ }
111
+ giftOptionsTooltip.setTooltipContentLoaderFunction(getGiftOptionsTooltipContent);
112
+ //]]>
113
+ </script>
app/etc/modules/Hexasoft_FraudLabsPro.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Hexasoft_FraudLabsPro>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ </Hexasoft_FraudLabsPro>
8
+ </modules>
9
+ </config>
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Hexasoft_FraudLabsPro</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license>Open Software License (OSL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>This extension screens online transactions for frauds.</summary>
10
+ <description>FraudLabs Pro service screens online transactions for frauds. It increases e-commerce merchant profits by reduces chargeback, improves operation efficiency and provides business intelligence.</description>
11
+ <notes>First public release.</notes>
12
+ <authors><author><name>Hexasoft</name><user>hexasoft</user><email>tech@hexasoft.com.my</email></author></authors>
13
+ <date>2013-07-12</date>
14
+ <time>01:41:35</time>
15
+ <contents><target name="magelocal"><dir name="Hexasoft"><dir name="FraudLabsPro"><dir name="Block"><dir name="Sales"><dir name="Order"><file name="FraudLabsProResult.php" hash="f16c67db7020388de0fb3900c938e507"/><dir name="Grid"><dir name="Renderer"><file name="Risk.php" hash="19c8ca6a7656fee2e66b904dc97079a0"/></dir></dir><file name="Grid.php" hash="154790c49632c35af5e301c33a1e3188"/></dir></dir></dir><dir name="Controller"><file name="Observer.php" hash="190bc519c9d3e12b78e44ca5ec89f454"/></dir><dir name="Helper"><file name="Data.php" hash="948a251b0d5415653b1efce1af279b28"/></dir><dir name="controllers"><file name="IndexController.php" hash="92a43627feee95218815cf1aad91f439"/></dir><dir name="etc"><file name="adminhtml.xml" hash="38ccfabe77e18a8f8d9050359d44d13e"/><file name="config.xml" hash="3db2bad6f5b6a9f7fee4497cd3846f25"/><file name="system.xml" hash="5e30289646a3fb03640b7b4bbeb4ab26"/></dir><dir name="sql"><dir name="fraudlabspro_setup"><file name="mysql4-install-1.0.0.php" hash="be13e48218b5120641393e68df201d8b"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="fraudlabspro.xml" hash="43ae7917d3084744031b90d33f515f87"/></dir><dir name="template"><dir name="fraudlabspro"><dir name="sales"><dir name="order"><dir name="view"><dir name="tab"><file name="info.phtml" hash="25a46ae56e812c120f2125ad32f4bb1c"/></dir></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Hexasoft_FraudLabsPro.xml" hash="cb24470085e8e4038abdfab1426c2ca1"/></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
18
+ </package>