PayflowNvp.php 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Paypal\Model\Api;
  7. use Magento\Payment\Model\Cart;
  8. use Magento\Payment\Model\Method\Logger;
  9. /**
  10. * NVP API wrappers model
  11. * @SuppressWarnings(PHPMD.TooManyFields)
  12. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  13. */
  14. class PayflowNvp extends \Magento\Paypal\Model\Api\Nvp
  15. {
  16. /**#@+
  17. * Transaction types declaration
  18. */
  19. const TRXTYPE_AUTH_ONLY = 'A';
  20. const TRXTYPE_SALE = 'S';
  21. const TRXTYPE_CREDIT = 'C';
  22. const TRXTYPE_DELAYED_CAPTURE = 'D';
  23. const TRXTYPE_DELAYED_VOID = 'V';
  24. /**#@-*/
  25. /**#@+
  26. * Tender definition
  27. */
  28. const TENDER_CC = 'C';
  29. const TENDER_PAYPAL = 'P';
  30. /**#@-*/
  31. /**#@+
  32. * Express Checkout Actions
  33. */
  34. const EXPRESS_SET = 'S';
  35. const EXPRESS_GET = 'G';
  36. const EXPRESS_DO_PAYMENT = 'D';
  37. /**#@-*/
  38. /**#@+
  39. * Response codes definition
  40. */
  41. const RESPONSE_CODE_APPROVED = 0;
  42. const RESPONSE_CODE_FRAUD = 126;
  43. /**#@-*/
  44. /**#@-*/
  45. protected $_captureTypeComplete = 'Y';
  46. /**
  47. * Capture type (make authorization close or remain open)
  48. *
  49. * @var string
  50. */
  51. protected $_captureTypeNotcomplete = 'N';
  52. /**
  53. * Global public interface map
  54. *
  55. * @var array
  56. */
  57. protected $_globalMap = [
  58. // each call
  59. 'PARTNER' => 'partner',
  60. 'VENDOR' => 'vendor',
  61. 'USER' => 'user',
  62. 'PWD' => 'password',
  63. 'BUTTONSOURCE' => 'build_notation_code',
  64. 'TENDER' => 'tender',
  65. // commands
  66. 'RETURNURL' => 'return_url',
  67. 'CANCELURL' => 'cancel_url',
  68. 'INVNUM' => 'inv_num',
  69. 'TOKEN' => 'token',
  70. 'CORRELATIONID' => 'correlation_id',
  71. 'CUSTIP' => 'ip_address',
  72. 'NOTIFYURL' => 'notify_url',
  73. 'NOTE' => 'note',
  74. // style settings
  75. 'PAGESTYLE' => 'page_style',
  76. 'HDRIMG' => 'hdrimg',
  77. 'HDRBORDERCOLOR' => 'hdrbordercolor',
  78. 'HDRBACKCOLOR' => 'hdrbackcolor',
  79. 'PAYFLOWCOLOR' => 'payflowcolor',
  80. 'LOCALECODE' => 'locale_code',
  81. // transaction info
  82. //We need to store paypal trx id for correct IPN working
  83. 'PPREF' => 'paypal_transaction_id',
  84. 'PAYMENTINFO_0_TRANSACTIONID' => 'paypal_transaction_id',
  85. 'TRANSACTIONID' => 'paypal_transaction_id',
  86. 'REFUNDTRANSACTIONID' => 'paypal_transaction_id',
  87. 'PNREF' => 'transaction_id',
  88. 'ORIGID' => 'authorization_id',
  89. 'CAPTURECOMPLETE' => 'complete_type',
  90. 'AMT' => 'amount',
  91. 'AVSADDR' => 'address_verification',
  92. 'AVSZIP' => 'postcode_verification',
  93. // payment/billing info
  94. 'CURRENCY' => 'currency_code',
  95. 'PAYMENTSTATUS' => 'payment_status',
  96. 'PENDINGREASON' => 'pending_reason',
  97. 'PAYERID' => 'payer_id',
  98. 'PAYERSTATUS' => 'payer_status',
  99. 'EMAIL' => 'email',
  100. // backwards compatibility
  101. 'FIRSTNAME' => 'firstname',
  102. 'LASTNAME' => 'lastname',
  103. // paypal direct credit card information
  104. 'ACCT' => 'credit_card_number',
  105. 'EXPDATE' => 'credit_card_expiration_date',
  106. 'CVV2' => 'credit_card_cvv2',
  107. 'CARDSTART' => 'maestro_solo_issue_date',
  108. 'CARDISSUE' => 'maestro_solo_issue_number',
  109. 'CVV2MATCH' => 'cvv2_check_result',
  110. 'USERSELECTEDFUNDINGSOURCE' => 'funding_source',
  111. 'NOSHIPPING' => 'suppress_shipping',
  112. 'REQBILLINGADDRESS' => 'require_billing_address',
  113. ];
  114. /**
  115. * Fields that should be replaced in debug with '***'
  116. *
  117. * @var string[]
  118. */
  119. protected $_debugReplacePrivateDataKeys = ['ACCT', 'EXPDATE', 'CVV2', 'PARTNER', 'USER', 'VENDOR', 'PWD'];
  120. /**
  121. * DoDirectPayment request map
  122. *
  123. * @var string[]
  124. */
  125. protected $_doDirectPaymentRequest = [
  126. 'ACCT',
  127. 'EXPDATE',
  128. 'CVV2',
  129. 'CURRENCY',
  130. 'EMAIL',
  131. 'TENDER',
  132. 'NOTIFYURL',
  133. 'AMT',
  134. 'CUSTIP',
  135. 'INVNUM',
  136. 'CARDISSUE',
  137. 'CARDSTART',
  138. 'AUTHSTATUS3DS',
  139. 'MPIVENDOR3DS',
  140. 'CAVV',
  141. 'ECI',
  142. 'XID',
  143. 'TAXAMT',
  144. 'FREIGHTAMT',
  145. ];
  146. /**
  147. * DoDirectPayment response map
  148. *
  149. * @var string[]
  150. */
  151. protected $_doDirectPaymentResponse = [
  152. 'PNREF',
  153. 'PPREF',
  154. 'CORRELATIONID',
  155. 'CVV2MATCH',
  156. 'AVSADDR',
  157. 'AVSZIP',
  158. 'PENDINGREASON',
  159. ];
  160. /**
  161. * DoCapture request map
  162. *
  163. * @var string[]
  164. */
  165. protected $_doCaptureRequest = ['ORIGID', 'CAPTURECOMPLETE', 'AMT', 'TENDER', 'NOTE', 'INVNUM'];
  166. /**
  167. * DoCapture response map
  168. *
  169. * @var string[]
  170. */
  171. protected $_doCaptureResponse = ['PNREF', 'PPREF'];
  172. /**
  173. * DoVoid request map
  174. *
  175. * @var string[]
  176. */
  177. protected $_doVoidRequest = ['ORIGID', 'NOTE', 'TENDER'];
  178. /**
  179. * Request map for each API call
  180. *
  181. * @var string[]
  182. */
  183. protected $_eachCallRequest = ['PARTNER', 'USER', 'VENDOR', 'PWD', 'BUTTONSOURCE'];
  184. /**
  185. * RefundTransaction request map
  186. *
  187. * @var string[]
  188. */
  189. protected $_refundTransactionRequest = ['ORIGID', 'TENDER'];
  190. /**
  191. * RefundTransaction response map
  192. *
  193. * @var string[]
  194. */
  195. protected $_refundTransactionResponse = ['PNREF', 'PPREF'];
  196. /**
  197. * SetExpressCheckout request map
  198. *
  199. * @var string[]
  200. */
  201. protected $_setExpressCheckoutRequest = [
  202. 'TENDER',
  203. 'AMT',
  204. 'CURRENCY',
  205. 'RETURNURL',
  206. 'CANCELURL',
  207. 'INVNUM',
  208. 'PAGESTYLE',
  209. 'HDRIMG',
  210. 'HDRBORDERCOLOR',
  211. 'HDRBACKCOLOR',
  212. 'PAYFLOWCOLOR',
  213. 'LOCALECODE',
  214. 'USERSELECTEDFUNDINGSOURCE',
  215. 'NOSHIPPING',
  216. 'REQBILLINGADDRESS',
  217. ];
  218. /**
  219. * SetExpressCheckout response map
  220. *
  221. * @var string[]
  222. */
  223. protected $_setExpressCheckoutResponse = ['REPMSG', 'TOKEN'];
  224. /**
  225. * GetExpressCheckoutDetails request/response map
  226. *
  227. * @var string[]
  228. */
  229. protected $_getExpressCheckoutDetailsRequest = ['TENDER', 'TOKEN'];
  230. /**
  231. * DoExpressCheckoutPayment request map
  232. *
  233. * @var string[]
  234. */
  235. protected $_doExpressCheckoutPaymentRequest = [
  236. 'TENDER',
  237. 'TOKEN',
  238. 'PAYERID',
  239. 'AMT',
  240. 'CURRENCY',
  241. 'CUSTIP',
  242. 'BUTTONSOURCE',
  243. 'NOTIFYURL',
  244. ];
  245. /**
  246. * DoExpressCheckoutPayment response map
  247. *
  248. * @var string[]
  249. */
  250. protected $_doExpressCheckoutPaymentResponse = [
  251. 'PNREF',
  252. 'PPREF',
  253. 'REPMSG',
  254. 'AMT',
  255. 'PENDINGREASON',
  256. 'CVV2MATCH',
  257. 'AVSADDR',
  258. 'AVSZIP',
  259. 'CORRELATIONID',
  260. ];
  261. /**
  262. * GetTransactionDetailsRequest
  263. *
  264. * @var string[]
  265. */
  266. protected $_getTransactionDetailsRequest = ['ORIGID', 'TENDER'];
  267. /**
  268. * GetTransactionDetailsResponse
  269. *
  270. * @var string[]
  271. */
  272. protected $_getTransactionDetailsResponse = [
  273. 'PAYERID',
  274. 'FIRSTNAME',
  275. 'LASTNAME',
  276. 'TRANSACTIONID',
  277. 'PARENTTRANSACTIONID',
  278. 'CURRENCYCODE',
  279. 'AMT',
  280. 'PAYMENTSTATUS',
  281. ];
  282. /**
  283. * Map for shipping address import/export (extends billing address mapper)
  284. *
  285. * @var array
  286. */
  287. protected $_shippingAddressMap = [
  288. 'SHIPTOCOUNTRY' => 'country_id',
  289. 'SHIPTOSTATE' => 'region',
  290. 'SHIPTOCITY' => 'city',
  291. 'SHIPTOSTREET' => 'street',
  292. 'SHIPTOSTREET2' => 'street2',
  293. 'SHIPTOZIP' => 'postcode',
  294. 'SHIPTOPHONENUM' => 'telephone',
  295. ];
  296. /**
  297. * Map for billing address import/export
  298. *
  299. * @var array
  300. */
  301. protected $_billingAddressMap = [
  302. 'BUSINESS' => 'company',
  303. 'NOTETEXT' => 'customer_notes',
  304. 'EMAIL' => 'email',
  305. 'FIRSTNAME' => 'firstname',
  306. 'LASTNAME' => 'lastname',
  307. 'MIDDLENAME' => 'middlename',
  308. 'SALUTATION' => 'prefix',
  309. 'SUFFIX' => 'suffix',
  310. 'COUNTRYCODE' => 'country_id',
  311. 'STATE' => 'region',
  312. 'CITY' => 'city',
  313. 'STREET' => 'street',
  314. 'STREET2' => 'street2',
  315. 'ZIP' => 'postcode',
  316. 'PHONENUM' => 'telephone',
  317. ];
  318. /**
  319. * Map for billing address to do request to Payflow
  320. *
  321. * @var array
  322. */
  323. protected $_billingAddressMapRequest = ['country_id' => 'COUNTRY'];
  324. /**
  325. * Line items export mapping settings
  326. *
  327. * @var array
  328. */
  329. protected $_lineItemTotalExportMap = [Cart::AMOUNT_TAX => 'TAXAMT', Cart::AMOUNT_SHIPPING => 'FREIGHTAMT'];
  330. /**
  331. * Line items export request totals format
  332. *
  333. * @var array
  334. */
  335. protected $_lineItemsExportRequestTotalsFormat = [
  336. 'amount' => 'PAYMENTREQUEST_%d_ITEMAMT',
  337. Cart::AMOUNT_TAX => 'TAXAMT',
  338. Cart::AMOUNT_SHIPPING => 'FREIGHTAMT',
  339. ];
  340. /**
  341. * Line items export items format
  342. *
  343. * @var array
  344. */
  345. protected $_lineItemExportItemsFormat = [
  346. 'name' => 'L_NAME%d',
  347. 'qty' => 'L_QTY%d',
  348. 'amount' => 'L_COST%d',
  349. ];
  350. /**
  351. * Payment information response specifically to be collected after some requests
  352. *
  353. * @var string[]
  354. */
  355. protected $_paymentInformationResponse = [
  356. 'PAYERID',
  357. 'CORRELATIONID',
  358. 'ADDRESSID',
  359. 'ADDRESSSTATUS',
  360. 'PAYMENTSTATUS',
  361. 'PENDINGREASON',
  362. 'PROTECTIONELIGIBILITY',
  363. 'EMAIL',
  364. ];
  365. /**
  366. * Required fields in the response
  367. *
  368. * @var array
  369. */
  370. protected $_requiredResponseParams = [
  371. self::DO_DIRECT_PAYMENT => ['RESULT', 'PNREF', 'PPREF'],
  372. ];
  373. /**
  374. * @var \Magento\Framework\Math\Random
  375. */
  376. protected $mathRandom;
  377. /**
  378. * @var NvpFactory
  379. */
  380. protected $nvpFactory;
  381. /**
  382. * @param \Magento\Customer\Helper\Address $customerAddress
  383. * @param \Psr\Log\LoggerInterface $logger
  384. * @param Logger $customLogger
  385. * @param \Magento\Framework\Locale\ResolverInterface $localeResolver
  386. * @param \Magento\Directory\Model\RegionFactory $regionFactory
  387. * @param \Magento\Directory\Model\CountryFactory $countryFactory
  388. * @param ProcessableExceptionFactory $processableExceptionFactory
  389. * @param \Magento\Framework\Exception\LocalizedExceptionFactory $frameworkExceptionFactory
  390. * @param \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory
  391. * @param \Magento\Framework\Math\Random $mathRandom
  392. * @param NvpFactory $nvpFactory
  393. * @param array $data
  394. * @SuppressWarnings(PHPMD.ExcessiveParameterList)
  395. */
  396. public function __construct(
  397. \Magento\Customer\Helper\Address $customerAddress,
  398. \Psr\Log\LoggerInterface $logger,
  399. Logger $customLogger,
  400. \Magento\Framework\Locale\ResolverInterface $localeResolver,
  401. \Magento\Directory\Model\RegionFactory $regionFactory,
  402. \Magento\Directory\Model\CountryFactory $countryFactory,
  403. \Magento\Paypal\Model\Api\ProcessableExceptionFactory $processableExceptionFactory,
  404. \Magento\Framework\Exception\LocalizedExceptionFactory $frameworkExceptionFactory,
  405. \Magento\Framework\HTTP\Adapter\CurlFactory $curlFactory,
  406. \Magento\Framework\Math\Random $mathRandom,
  407. NvpFactory $nvpFactory,
  408. array $data = []
  409. ) {
  410. parent::__construct(
  411. $customerAddress,
  412. $logger,
  413. $customLogger,
  414. $localeResolver,
  415. $regionFactory,
  416. $countryFactory,
  417. $processableExceptionFactory,
  418. $frameworkExceptionFactory,
  419. $curlFactory,
  420. $data
  421. );
  422. $this->mathRandom = $mathRandom;
  423. $this->nvpFactory = $nvpFactory;
  424. }
  425. /**
  426. * API endpoint getter
  427. *
  428. * @return string
  429. */
  430. public function getApiEndpoint()
  431. {
  432. return sprintf(
  433. 'https://%spayflowpro.paypal.com/transaction',
  434. $this->_config->getValue('sandboxFlag') ? 'pilot-' : ''
  435. );
  436. }
  437. /**
  438. * Return Payflow partner based on config data
  439. *
  440. * @return string
  441. */
  442. public function getPartner()
  443. {
  444. return $this->_getDataOrConfig('partner');
  445. }
  446. /**
  447. * Return Payflow user based on config data
  448. *
  449. * @return string
  450. */
  451. public function getUser()
  452. {
  453. return $this->_getDataOrConfig('user');
  454. }
  455. /**
  456. * Return Payflow password based on config data
  457. *
  458. * @return string
  459. */
  460. public function getPassword()
  461. {
  462. return $this->_getDataOrConfig('pwd');
  463. }
  464. /**
  465. * Return Payflow vendor based on config data
  466. *
  467. * @return string
  468. */
  469. public function getVendor()
  470. {
  471. return $this->_getDataOrConfig('vendor');
  472. }
  473. /**
  474. * Return Payflow tender based on config data
  475. *
  476. * @return string
  477. */
  478. public function getTender()
  479. {
  480. if ($this->_config->getMethodCode() == \Magento\Paypal\Model\Config::METHOD_WPP_PE_EXPRESS) {
  481. return self::TENDER_PAYPAL;
  482. }
  483. return self::TENDER_CC;
  484. }
  485. /**
  486. * Override transaction id getting to process payflow accounts not assigned to paypal side
  487. *
  488. * @return string
  489. */
  490. public function getPaypalTransactionId()
  491. {
  492. if ($this->getData('paypal_transaction_id')) {
  493. return $this->getData('paypal_transaction_id');
  494. }
  495. return $this->getTransactionId();
  496. }
  497. /**
  498. * Add method to request array
  499. *
  500. * @param string $methodName
  501. * @param array $request
  502. * @return array
  503. */
  504. protected function _addMethodToRequest($methodName, $request)
  505. {
  506. $request['TRXTYPE'] = $this->_mapPaypalMethodName($methodName);
  507. if ($this->_getPayflowActionName($methodName) !== null) {
  508. $request['ACTION'] = $this->_getPayflowActionName($methodName);
  509. }
  510. return $request;
  511. }
  512. /**
  513. * Return Payflow Edition
  514. *
  515. * @param string $methodName
  516. * @return string|null
  517. */
  518. protected function _getPayflowActionName($methodName)
  519. {
  520. switch ($methodName) {
  521. case \Magento\Paypal\Model\Api\Nvp::SET_EXPRESS_CHECKOUT:
  522. return self::EXPRESS_SET;
  523. case \Magento\Paypal\Model\Api\Nvp::GET_EXPRESS_CHECKOUT_DETAILS:
  524. return self::EXPRESS_GET;
  525. case \Magento\Paypal\Model\Api\Nvp::DO_EXPRESS_CHECKOUT_PAYMENT:
  526. return self::EXPRESS_DO_PAYMENT;
  527. }
  528. return null;
  529. }
  530. /**
  531. * Map paypal method names
  532. *
  533. * @param string| $methodName
  534. * @return string
  535. */
  536. protected function _mapPaypalMethodName($methodName)
  537. {
  538. switch ($methodName) {
  539. case \Magento\Paypal\Model\Api\Nvp::DO_EXPRESS_CHECKOUT_PAYMENT:
  540. case \Magento\Paypal\Model\Api\Nvp::GET_EXPRESS_CHECKOUT_DETAILS:
  541. case \Magento\Paypal\Model\Api\Nvp::SET_EXPRESS_CHECKOUT:
  542. case \Magento\Paypal\Model\Api\Nvp::DO_DIRECT_PAYMENT:
  543. return $this->_config->getValue('payment_action') ==
  544. \Magento\Paypal\Model\Config::PAYMENT_ACTION_AUTH ? self::TRXTYPE_AUTH_ONLY : self::TRXTYPE_SALE;
  545. case \Magento\Paypal\Model\Api\Nvp::DO_CAPTURE:
  546. return self::TRXTYPE_DELAYED_CAPTURE;
  547. case \Magento\Paypal\Model\Api\Nvp::DO_VOID:
  548. return self::TRXTYPE_DELAYED_VOID;
  549. case \Magento\Paypal\Model\Api\Nvp::REFUND_TRANSACTION:
  550. return self::TRXTYPE_CREDIT;
  551. }
  552. }
  553. /**
  554. * Catch success calls and collect warnings
  555. *
  556. * @param array $response
  557. * @return bool success flag
  558. */
  559. protected function _isCallSuccessful($response)
  560. {
  561. $this->_callWarnings = [];
  562. if ($response['RESULT'] == self::RESPONSE_CODE_APPROVED) {
  563. // collect warnings
  564. if (!empty($response['RESPMSG']) && strtoupper($response['RESPMSG']) != 'APPROVED') {
  565. $this->_callWarnings[] = $response['RESPMSG'];
  566. }
  567. return true;
  568. }
  569. return false;
  570. }
  571. /**
  572. * Handle logical errors
  573. *
  574. * @param array $response
  575. * @return void
  576. * @throws \Magento\Framework\Exception\LocalizedException
  577. */
  578. protected function _handleCallErrors($response)
  579. {
  580. if ($response['RESULT'] != self::RESPONSE_CODE_APPROVED) {
  581. $message = $response['RESPMSG'];
  582. $e = new \Exception(sprintf('PayPal gateway errors: %s.', $message));
  583. $this->_logger->critical($e);
  584. throw new \Magento\Framework\Exception\LocalizedException(
  585. __('The PayPal gateway rejected the request. %1', $message)
  586. );
  587. }
  588. }
  589. /**
  590. * Build query string without urlencoding from request
  591. *
  592. * @param array $request
  593. * @return string
  594. */
  595. protected function _buildQuery($request)
  596. {
  597. $result = '';
  598. foreach ($request as $k => $v) {
  599. $result .= '&' . $k . '=' . $v;
  600. }
  601. return trim($result, '&');
  602. }
  603. /**
  604. * Generate Request ID
  605. *
  606. * @return string
  607. */
  608. protected function getRequestId()
  609. {
  610. return $this->mathRandom->getUniqueHash();
  611. }
  612. /**
  613. * GetTransactionDetails method does not exists in Payflow
  614. *
  615. * @return void
  616. */
  617. public function callGetTransactionDetails()
  618. {
  619. }
  620. /**
  621. * Get FMF results from response, if any
  622. *
  623. * @param array $from
  624. * @param array $collectedWarnings
  625. * @return void
  626. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  627. */
  628. protected function _importFraudFiltersResult(array $from, array $collectedWarnings)
  629. {
  630. if ($from['RESULT'] != self::RESPONSE_CODE_FRAUD) {
  631. return;
  632. }
  633. $this->setIsPaymentPending(true);
  634. }
  635. /**
  636. * Return each call request fields
  637. * (PayFlow edition doesn't support Unilateral payments)
  638. *
  639. * @param string $methodName Current method name
  640. * @return string[]
  641. * @SuppressWarnings(PHPMD.UnusedFormalParameter)
  642. */
  643. protected function _prepareEachCallRequest($methodName)
  644. {
  645. return $this->_eachCallRequest;
  646. }
  647. /**
  648. * Overwrite parent logic, simply return input data
  649. * (PayFlow edition doesn't support Unilateral payments)
  650. *
  651. * @param array $requestFields Standard set of values
  652. * @return array
  653. */
  654. protected function _prepareExpressCheckoutCallRequest(&$requestFields)
  655. {
  656. return $requestFields;
  657. }
  658. /**
  659. * Additional response processing.
  660. *
  661. * Hack to cut off length from API type response params.
  662. *
  663. * @param array $response
  664. * @return array
  665. */
  666. protected function _postProcessResponse($response)
  667. {
  668. foreach ($response as $key => $value) {
  669. $pos = strpos($key, '[');
  670. if ($pos === false) {
  671. continue;
  672. }
  673. unset($response[$key]);
  674. if ($pos !== 0) {
  675. $modifiedKey = substr($key, 0, $pos);
  676. $response[$modifiedKey] = $value;
  677. }
  678. }
  679. return $response;
  680. }
  681. /**
  682. * Checking negative line items
  683. *
  684. * @param array $request
  685. * @param int $i
  686. * @return null|true
  687. */
  688. protected function _exportLineItems(array &$request, $i = 0)
  689. {
  690. $requestBefore = $request;
  691. $result = parent::_exportLineItems($request, $i);
  692. if ($this->getIsLineItemsEnabled() && $this->_cart->hasNegativeItemAmount()) {
  693. $this->_lineItemTotalExportMap = [
  694. Cart::AMOUNT_TAX => 'TAXAMT',
  695. Cart::AMOUNT_SHIPPING => 'FREIGHTAMT',
  696. 'amount' => 'PAYMENTREQUEST_0_ITEMAMT',
  697. ];
  698. $request = $requestBefore;
  699. $result = parent::_exportLineItems($request, $i);
  700. /** @var Nvp $paypalNvp */
  701. $paypalNvp = $this->nvpFactory->create();
  702. $this->_doCaptureResponse = $paypalNvp->_doCaptureResponse;
  703. $this->_refundTransactionResponse = $paypalNvp->_refundTransactionResponse;
  704. $this->_getTransactionDetailsResponse = $paypalNvp->_getTransactionDetailsResponse;
  705. $this->_paymentInformationResponse = $paypalNvp->_paymentInformationResponse;
  706. $this->_headers[] = 'PAYPAL-NVP: Y';
  707. $this->_setSpecificForNegativeLineItems();
  708. }
  709. return $result;
  710. }
  711. /**
  712. * Set specific data when negative line item case.
  713. *
  714. * @return void
  715. */
  716. protected function _setSpecificForNegativeLineItems()
  717. {
  718. /** @var Nvp $paypalNvp */
  719. $paypalNvp = $this->nvpFactory->create();
  720. $this->_setExpressCheckoutResponse = $paypalNvp->_setExpressCheckoutResponse;
  721. $index = array_search('PPREF', $this->_doExpressCheckoutPaymentResponse);
  722. if (false !== $index) {
  723. unset($this->_doExpressCheckoutPaymentResponse[$index]);
  724. }
  725. $this->_doExpressCheckoutPaymentResponse[] = 'PAYMENTINFO_0_TRANSACTIONID';
  726. $this->_requiredResponseParams[self::DO_EXPRESS_CHECKOUT_PAYMENT][] = 'PAYMENTINFO_0_TRANSACTIONID';
  727. }
  728. }