Issues (547)

Security Analysis    not enabled

This project does not seem to handle request data directly as such no vulnerable execution paths were found.

  Cross-Site Scripting
Cross-Site Scripting enables an attacker to inject code into the response of a web-request that is viewed by other users. It can for example be used to bypass access controls, or even to take over other users' accounts.
  File Exposure
File Exposure allows an attacker to gain access to local files that he should not be able to access. These files can for example include database credentials, or other configuration files.
  File Manipulation
File Manipulation enables an attacker to write custom data to files. This potentially leads to injection of arbitrary code on the server.
  Object Injection
Object Injection enables an attacker to inject an object into PHP code, and can lead to arbitrary code execution, file exposure, or file manipulation attacks.
  Code Injection
Code Injection enables an attacker to execute arbitrary code on the server.
  Response Splitting
Response Splitting can be used to send arbitrary responses.
  File Inclusion
File Inclusion enables an attacker to inject custom files into PHP's file loading mechanism, either explicitly passed to include, or for example via PHP's auto-loading mechanism.
  Command Injection
Command Injection enables an attacker to inject a shell command that is execute with the privileges of the web-server. This can be used to expose sensitive data, or gain access of your server.
  SQL Injection
SQL Injection enables an attacker to execute arbitrary SQL code on your database server gaining access to user data, or manipulating user data.
  XPath Injection
XPath Injection enables an attacker to modify the parts of XML document that are read. If that XML document is for example used for authentication, this can lead to further vulnerabilities similar to SQL Injection.
  LDAP Injection
LDAP Injection enables an attacker to inject LDAP statements potentially granting permission to run unauthorized queries, or modify content inside the LDAP tree.
  Header Injection
  Other Vulnerability
This category comprises other attack vectors such as manipulating the PHP runtime, loading custom extensions, freezing the runtime, or similar.
  Regex Injection
Regex Injection enables an attacker to execute arbitrary code in your PHP process.
  XML Injection
XML Injection enables an attacker to read files on your local filesystem including configuration files, or can be abused to freeze your web-server process.
  Variable Injection
Variable Injection enables an attacker to overwrite program variables with custom data, and can lead to further vulnerabilities.
Unfortunately, the security analysis is currently not available for your project. If you are a non-commercial open-source project, please contact support to gain access.

Model/Api/Invoice.php (3 issues)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * PAYONE Magento 2 Connector is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * PAYONE Magento 2 Connector is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with PAYONE Magento 2 Connector. If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 * PHP version 5
18
 *
19
 * @category  Payone
20
 * @package   Payone_Magento2_Plugin
21
 * @author    FATCHIP GmbH <[email protected]>
22
 * @copyright 2003 - 2016 Payone GmbH
23
 * @license   <http://www.gnu.org/licenses/> GNU Lesser General Public License
24
 * @link      http://www.payone.de
25
 */
26
27
namespace Payone\Core\Model\Api;
28
29
use Payone\Core\Model\Api\Request\Base;
30
use Magento\Sales\Model\Order;
31
32
/**
33
 * Collect all invoice parameters
34
 *
35
 * @category  Payone
36
 * @package   Payone_Magento2_Plugin
37
 * @author    FATCHIP GmbH <[email protected]>
38
 * @copyright 2003 - 2016 Payone GmbH
39
 * @license   <http://www.gnu.org/licenses/> GNU Lesser General Public License
40
 * @link      http://www.payone.de
41
 */
42
class Invoice
43
{
44
    /**
45
     * Index of added invoice items
46
     *
47
     * @var integer
48
     */
49
    protected $iIndex = 1;
50
51
    /**
52
     * Invoice amount
53
     *
54
     * @var integer
55
     */
56
    protected $dAmount = 0;
57
58
    /**
59
     * Vat rate for following entities which may not have the vat attached to it
60
     *
61
     * @var double
62
     */
63
    protected $dTax = false;
64
65
    /**
66
     * PAYONE toolkit helper
67
     *
68
     * @var \Payone\Core\Helper\Toolkit
69
     */
70
    protected $toolkitHelper;
71
72
    /**
73
     * Request object
74
     *
75
     * @var Base
76
     */
77
    protected $oRequest;
78
79
    /**
80
     * Constructor
81
     *
82
     * @param \Payone\Core\Helper\Toolkit $toolkitHelper Toolkit helper
83
     */
84
    public function __construct(\Payone\Core\Helper\Toolkit $toolkitHelper)
85
    {
86
        $this->toolkitHelper = $toolkitHelper;
87
    }
88
89
    /**
90
     * Add parameters for a invoice position
91
     *
92
     * @param  string $sId       item identification
93
     * @param  double $dPrice    item price
94
     * @param  string $sItemType item type
95
     * @param  int    $iAmount   item amount
96
     * @param  string $sDesc     item description
97
     * @param  double $dVat      item tax rate
98
     * @return void
99
     */
100
    protected function addInvoicePosition($sId, $dPrice, $sItemType, $iAmount, $sDesc, $dVat)
101
    {
102
        $this->oRequest->addParameter('id['.$this->iIndex.']', $sId); // add invoice item id
103
        $this->oRequest->addParameter('pr['.$this->iIndex.']', $this->toolkitHelper->formatNumber($dPrice) * 100); // expected in smallest unit of currency
104
        $this->oRequest->addParameter('it['.$this->iIndex.']', $sItemType); // add invoice item type
105
        $this->oRequest->addParameter('no['.$this->iIndex.']', $iAmount); // add invoice item amount
106
        $this->oRequest->addParameter('de['.$this->iIndex.']', $sDesc); // add invoice item description
107
        $this->oRequest->addParameter('va['.$this->iIndex.']', $this->toolkitHelper->formatNumber($dVat * 100, 0)); // expected * 100 to also handle vats with decimals
108
        $this->dAmount += $dPrice * $iAmount; // needed for return of the main method
109
        $this->iIndex++; // increase index for next item
110
    }
111
112
    /**
113
     * Add invoicing data to the request and return the summed invoicing amount
114
     *
115
     * @param  Base  $oRequest   Request object
116
     * @param  Order $oOrder     Order object
117
     * @param  array $aPositions Is given with non-complete captures or debits
118
     * @param  bool  $blDebit    Is the call coming from a debit request
119
     * @return integer
120
     */
121
    public function addProductInfo(Base $oRequest, Order $oOrder, $aPositions = false, $blDebit = false)
122
    {
123
        $this->oRequest = $oRequest; // write request to property for manipulation of the object
124
        $sInvoiceAppendix = $this->toolkitHelper->getInvoiceAppendix($oOrder); // get invoice appendix
125
        if (!empty($sInvoiceAppendix)) {// invoice appendix existing?
126
            $this->oRequest->addParameter('invoiceappendix', $sInvoiceAppendix); // add appendix to request
127
        }
128
129
        $iQtyInvoiced = 0;
130
        foreach ($oOrder->getAllItems() as $oItem) { // add invoice items for all order items
131
            if ($oItem->isDummy() === false) { // prevent variant-products of adding 2 items
132
                $this->addProductItem($oItem, $aPositions); // add product invoice params to request
0 ignored issues
show
It seems like $aPositions defined by parameter $aPositions on line 121 can also be of type false; however, Payone\Core\Model\Api\Invoice::addProductItem() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
133
            }
134
            $iQtyInvoiced += $oItem->getOrigData('qty_invoiced'); // get data pre-capture
135
        }
136
137
        $blFirstCapture = true; // Is first capture?
138
        if ($iQtyInvoiced > 0) {
139
            $blFirstCapture = false;
140
        }
141
142
        if ($aPositions === false || $blFirstCapture === true || $blDebit === true) {
143
            $this->addShippingItem($oOrder, $aPositions, $blDebit); // add shipping invoice params to request
0 ignored issues
show
It seems like $aPositions defined by parameter $aPositions on line 121 can also be of type false; however, Payone\Core\Model\Api\Invoice::addShippingItem() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
144
            $this->addDiscountItem($oOrder, $aPositions, $blDebit); // add discount invoice params to request
0 ignored issues
show
It seems like $aPositions defined by parameter $aPositions on line 121 can also be of type false; however, Payone\Core\Model\Api\Invoice::addDiscountItem() does only seem to accept array, maybe add an additional type check?

This check looks at variables that have been passed in as parameters and are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
145
        }
146
        return $this->dAmount;
147
    }
148
149
    /**
150
     * Add invoicing item for a product
151
     *
152
     * @param  \Magento\Sales\Model\Order\Item $oItem
153
     * @param  array $aPositions
154
     * @return void
155
     */
156
    protected function addProductItem($oItem, $aPositions)
157
    {
158
        if ($aPositions === false || array_key_exists($oItem->getProductId(), $aPositions) !== false) { // full or single-invoice?
159
            $dItemAmount = $oItem->getQtyOrdered(); // get ordered item amount
160
            if ($aPositions !== false && array_key_exists($oItem->getProductId(), $aPositions) !== false) { // product existing in single-invoice?
161
                $dItemAmount = $aPositions[$oItem->getProductId()]; // use amount from single-invoice
162
            }
163
            $iAmount = $this->convertItemAmount($dItemAmount);
164
            $this->addInvoicePosition($oItem->getSku(), $oItem->getPriceInclTax(), 'goods', $iAmount, $oItem->getName(), $oItem->getTaxPercent()); // add invoice params to request
165
            if ($this->dTax === false) { // is dTax not set yet?
166
                $this->dTax = $oItem->getTaxPercent(); // set the tax for following entities which dont have the vat attached to it
167
            }
168
        }
169
    }
170
171
    /**
172
     * Add invoicing item for shipping
173
     *
174
     * @param  Order $oOrder
175
     * @param  array $aPositions
176
     * @param  bool  $blDebit
177
     * @return void
178
     */
179
    protected function addShippingItem(Order $oOrder, $aPositions, $blDebit)
180
    {
181
        // shipping costs existing or given for partial captures/debits?
182
        if ($oOrder->getBaseShippingInclTax() != 0 && ($aPositions === false || ($blDebit === false || array_key_exists('delcost', $aPositions) !== false))) {
183
            $dPrice = $oOrder->getBaseShippingInclTax();
184
            if ($aPositions !== false && array_key_exists('delcost', $aPositions) !== false) { // product existing in single-invoice?
185
                $dPrice = $aPositions['delcost'];
186
            }
187
            $sDelDesc = __('Surcharge').' '.__('Shipping Costs'); // default description
188
            if ($dPrice < 0) { // negative shipping cost
189
                $sDelDesc = __('Deduction').' '.__('Shipping Costs'); // change item description to deduction
190
            }
191
            $sShippingSku = $this->toolkitHelper->getConfigParam('sku', 'costs', 'payone_misc'); // get configured shipping SKU
192
            $this->addInvoicePosition($sShippingSku, $dPrice, 'shipment', 1, $sDelDesc, $this->dTax); // add invoice params to request
193
        }
194
    }
195
196
    /**
197
     * Add invoicing item for discounts
198
     *
199
     * @param  Order $oOrder
200
     * @param  array $aPositions
201
     * @param  bool  $blDebit
202
     * @return void
203
     */
204
    protected function addDiscountItem(Order $oOrder, $aPositions, $blDebit)
205
    {
206
        // discount costs existing or given for partial captures/debis?
207
        if ($oOrder->getBaseDiscountAmount() != 0 && $oOrder->getCouponCode() && ($aPositions === false || ($blDebit === false || array_key_exists('oxvoucherdiscount', $aPositions) !== false))) {
208
            $dDiscount = $this->toolkitHelper->formatNumber($oOrder->getBaseDiscountAmount()); // format discount
209
            if ($aPositions === false) {// full invoice?
210
                // The calculations broken down to single items of Magento2 are unprecise and the Payone API will send an error if
211
                // the calculated positions don't match, so we compensate for rounding-problems here
212
                $dDiff = ($this->dAmount + $oOrder->getBaseDiscountAmount()) - $oOrder->getGrandTotal(); // calc rounding discrepancy
213
                $dDiscount -= $dDiff; // subtract difference from discount
214
            }
215
            $sDiscountSku = $this->toolkitHelper->getConfigParam('sku', 'discount', 'payone_misc'); // get configured discount SKU
216
            $sDesc = (string)__('Discount'); // default description
217
            if ($oOrder->getCouponCode()) {// was a coupon code used?
218
                $sDiscountSku = $this->toolkitHelper->getConfigParam('sku', 'voucher', 'payone_misc'); // get configured voucher SKU
219
                $sDesc = (string)__('Coupon').' - '.$oOrder->getCouponCode(); // add counpon code to description
220
            }
221
            $this->addInvoicePosition($sDiscountSku, $dDiscount, 'voucher', 1, $sDesc, $this->dTax); // add invoice params to request
222
        }
223
    }
224
225
    /**
226
     * Check if item amount has decimal places
227
     * Throw exception if given amount is no integer
228
     *
229
     * @param  double $dItemAmount
230
     * @throws \InvalidArgumentException
231
     * @return int
232
     */
233
    protected function convertItemAmount($dItemAmount)
234
    {
235
        if (fmod(floatval($dItemAmount), 1.0) > 0) { // input does not represent an integer
236
            $sErrorMessage = "Unable to use floating point values for item amounts! Parameter was: ";
237
            throw new \InvalidArgumentException($sErrorMessage . strval($dItemAmount), 1);
238
        } else { // return the integer value
239
            return intval($dItemAmount);
240
        }
241
    }
242
}
243