Skip to content
This repository was archived by the owner on Apr 29, 2019. It is now read-only.

Commit 910e62c

Browse files
Merge remote-tracking branch 'jackalopes/MAGETWO-71765' into BundledPR-Sep7b
2 parents 69080f9 + 1c291fa commit 910e62c

File tree

2 files changed

+102
-10
lines changed

2 files changed

+102
-10
lines changed

app/code/Magento/Paypal/Model/Payflowpro.php

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
use Magento\Framework\DataObject;
99
use Magento\Framework\Exception\LocalizedException;
10+
use Magento\Payment\Helper\Formatter;
1011
use Magento\Payment\Model\InfoInterface;
1112
use Magento\Payment\Model\Method\ConfigInterface;
1213
use Magento\Payment\Model\Method\ConfigInterfaceFactory;
@@ -27,6 +28,8 @@
2728
*/
2829
class Payflowpro extends \Magento\Payment\Model\Method\Cc implements GatewayInterface
2930
{
31+
use Formatter;
32+
3033
/**
3134
* Transaction action codes
3235
*/
@@ -83,8 +86,6 @@ class Payflowpro extends \Magento\Payment\Model\Method\Cc implements GatewayInte
8386

8487
const PNREF = 'pnref';
8588

86-
/**#@-*/
87-
8889
/**#@-*/
8990
protected $_responseParamsMappings = [
9091
'firstname' => 'billtofirstname',
@@ -391,14 +392,14 @@ public function authorize(\Magento\Payment\Model\InfoInterface $payment, $amount
391392
* Get capture amount
392393
*
393394
* @param float $amount
394-
* @return float
395+
* @return float|int
395396
*/
396397
protected function _getCaptureAmount($amount)
397398
{
398399
$infoInstance = $this->getInfoInstance();
399-
$amountToPay = round($amount, 2);
400-
$authorizedAmount = round($infoInstance->getAmountAuthorized(), 2);
401-
return $amountToPay != $authorizedAmount ? $amountToPay : 0;
400+
$amountToPay = $amount;
401+
$authorizedAmount = $infoInstance->getAmountAuthorized();
402+
return abs($amountToPay - $authorizedAmount) < 0.00001 ? 0 : $amountToPay;
402403
}
403404

404405
/**
@@ -414,7 +415,7 @@ public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount)
414415
{
415416
if ($payment->getAdditionalInformation(self::PNREF)) {
416417
$request = $this->buildBasicRequest();
417-
$request->setAmt(round($amount, 2));
418+
$request->setAmt($this->formatPrice($amount));
418419
$request->setTrxtype(self::TRXTYPE_SALE);
419420
$request->setOrigid($payment->getAdditionalInformation(self::PNREF));
420421
$payment->unsAdditionalInformation(self::PNREF);
@@ -423,7 +424,7 @@ public function capture(\Magento\Payment\Model\InfoInterface $payment, $amount)
423424
$request->setOrigid($payment->getParentTransactionId());
424425
$captureAmount = $this->_getCaptureAmount($amount);
425426
if ($captureAmount) {
426-
$request->setAmt($captureAmount);
427+
$request->setAmt($this->formatPrice($captureAmount));
427428
}
428429
$trxType = $this->getInfoInstance()->hasAmountPaid() ? self::TRXTYPE_SALE : self::TRXTYPE_DELAYED_CAPTURE;
429430
$request->setTrxtype($trxType);
@@ -511,7 +512,7 @@ public function refund(\Magento\Payment\Model\InfoInterface $payment, $amount)
511512
$request = $this->buildBasicRequest();
512513
$request->setTrxtype(self::TRXTYPE_CREDIT);
513514
$request->setOrigid($payment->getParentTransactionId());
514-
$request->setAmt(round($amount, 2));
515+
$request->setAmt($this->formatPrice($amount));
515516
$response = $this->postRequest($request, $this->getConfig());
516517
$this->processErrors($response);
517518

@@ -606,7 +607,7 @@ public function postRequest(DataObject $request, ConfigInterface $config)
606607
protected function _buildPlaceRequest(DataObject $payment, $amount)
607608
{
608609
$request = $this->buildBasicRequest();
609-
$request->setAmt(round($amount, 2));
610+
$request->setAmt($this->formatPrice($amount));
610611
$request->setAcct($payment->getCcNumber());
611612
$request->setExpdate(sprintf('%02d', $payment->getCcExpMonth()) . substr($payment->getCcExpYear(), -2, 2));
612613
$request->setCvv2($payment->getCcCid());

app/code/Magento/Paypal/Test/Unit/Model/PayflowproTest.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,97 @@ public function testCaptureWithBuildPlaceRequest()
267267
static::assertFalse((bool)$paymentMock->getIsTransactionPending());
268268
}
269269

270+
/**
271+
* @return array
272+
*/
273+
public function dataProviderCaptureAmountRounding()
274+
{
275+
return [
276+
[
277+
'amount' => 14.13999999999999999999999999999999999999999999999999,
278+
'setAmount' => 49.99,
279+
'expectedResult' => 14.14
280+
],
281+
[
282+
'amount' => 14.13199999999999999999999999999999999999999999999999,
283+
'setAmount' => 49.99,
284+
'expectedResult' => 14.13,
285+
],
286+
[
287+
'amount' => 14.14,
288+
'setAmount' => 49.99,
289+
'expectedResult' => 14.14,
290+
],
291+
[
292+
'amount' => 14.13999999999999999999999999999999999999999999999999,
293+
'setAmount' => 14.14,
294+
'expectedResult' => 0,
295+
]
296+
];
297+
}
298+
299+
/**
300+
* @param float $amount
301+
* @param float $setAmount
302+
* @param float $expectedResult
303+
* @dataProvider dataProviderCaptureAmountRounding
304+
*/
305+
public function testCaptureAmountRounding($amount, $setAmount, $expectedResult)
306+
{
307+
$paymentMock = $this->getPaymentMock();
308+
$orderMock = $this->getMockBuilder(\Magento\Sales\Model\Order::class)
309+
->disableOriginalConstructor()
310+
->getMock();
311+
312+
$infoInstanceMock = $this->getMockForAbstractClass(
313+
InfoInterface::class,
314+
[],
315+
'',
316+
false,
317+
false,
318+
false,
319+
['getAmountAuthorized','hasAmountPaid']
320+
);
321+
322+
$infoInstanceMock->expects($this->once())
323+
->method('getAmountAuthorized')
324+
->willReturn($setAmount);
325+
$infoInstanceMock->expects($this->once())
326+
->method('hasAmountPaid')
327+
->willReturn(true);
328+
$this->payflowpro->setData('info_instance', $infoInstanceMock);
329+
330+
// test case to build basic request
331+
$paymentMock->expects($this->once())
332+
->method('getAdditionalInformation')
333+
->with('pnref')
334+
->willReturn(false);
335+
$paymentMock->expects($this->any())
336+
->method('getParentTransactionId')
337+
->willReturn(true);
338+
339+
$paymentMock->expects($this->once())
340+
->method('getOrder')
341+
->willReturn($orderMock);
342+
343+
$this->initStoreMock();
344+
$response = $this->getGatewayResponseObject();
345+
$this->gatewayMock->expects($this->once())
346+
->method('postRequest')
347+
->with(
348+
$this->callback(function ($request) use ($expectedResult) {
349+
return is_callable([$request, 'getAmt']) && $request->getAmt() == $expectedResult;
350+
}),
351+
$this->isInstanceOf(PayflowConfig::class)
352+
)
353+
->willReturn($response);
354+
355+
$this->payflowpro->capture($paymentMock, $amount);
356+
357+
$this->assertEquals($response['pnref'], $paymentMock->getTransactionId());
358+
$this->assertFalse((bool)$paymentMock->getIsTransactionPending());
359+
}
360+
270361
/**
271362
* @covers \Magento\Paypal\Model\Payflowpro::authorize
272363
*/

0 commit comments

Comments
 (0)