@@ -44,6 +44,8 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
44
44
45
45
public const DO_EXPRESS_CHECKOUT_PAYMENT = 'DoExpressCheckoutPayment ' ;
46
46
47
+ public const DO_EXPRESS_CHECKOUT = 'DoExpressCheckout ' ;
48
+
47
49
public const CALLBACK_RESPONSE = 'CallbackResponse ' ;
48
50
49
51
/**
@@ -687,7 +689,11 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
687
689
*
688
690
* @var array
689
691
*/
690
- protected $ _requiredResponseParams = [self ::DO_DIRECT_PAYMENT => ['ACK ' , 'CORRELATIONID ' , 'AMT ' ]];
692
+ protected $ _requiredResponseParams = [
693
+ self ::DO_DIRECT_PAYMENT => ['ACK ' , 'CORRELATIONID ' , 'AMT ' ],
694
+ self ::DO_EXPRESS_CHECKOUT => ['ACK ' ],
695
+ self ::DO_EXPRESS_CHECKOUT_PAYMENT => ['ACK ' ]
696
+ ];
691
697
692
698
/**
693
699
* Warning codes recollected after each API call
@@ -737,6 +743,11 @@ class Nvp extends \Magento\Paypal\Model\Api\AbstractApi
737
743
*/
738
744
protected $ _headers = [];
739
745
746
+ /**
747
+ * @var Curl
748
+ */
749
+ private $ curl ;
750
+
740
751
/**
741
752
* @param \Magento\Customer\Helper\Address $customerAddress
742
753
* @param \Psr\Log\LoggerInterface $logger
@@ -1154,15 +1165,13 @@ protected function _postProcessResponse($response)
1154
1165
}
1155
1166
1156
1167
/**
1157
- * Do the API call
1168
+ * Prepare request for the API call
1158
1169
*
1159
1170
* @param string $methodName
1160
1171
* @param array $request
1161
1172
* @return array
1162
- * @throws ClientException|\Magento\Framework\Exception\LocalizedException|\Exception
1163
- * @SuppressWarnings(PHPMD.CyclomaticComplexity)
1164
1173
*/
1165
- public function call ( $ methodName , array $ request )
1174
+ private function prepareRequest ( string $ methodName , array $ request ): array
1166
1175
{
1167
1176
$ request = $ this ->_addMethodToRequest ($ methodName , $ request );
1168
1177
$ eachCallRequest = $ this ->_prepareEachCallRequest ($ methodName );
@@ -1172,28 +1181,83 @@ public function call($methodName, array $request)
1172
1181
unset($ eachCallRequest [$ key ]);
1173
1182
}
1174
1183
}
1175
- $ request = $ this ->_exportToRequest ($ eachCallRequest , $ request );
1176
- $ debugData = [ ' url ' => $ this -> getApiEndpoint (), $ methodName => $ request ];
1184
+ return $ this ->_exportToRequest ($ eachCallRequest , $ request );
1185
+ }
1177
1186
1178
- try {
1179
- /** @var Curl $http */
1180
- $ http = $ this ->_curlFactory ->create ();
1187
+ /**
1188
+ * Creates a Curl object and sets parameters for the call
1189
+ *
1190
+ * @param array $request
1191
+ * @return Curl
1192
+ */
1193
+ private function getCurl (array $ request = null ): Curl
1194
+ {
1195
+ if (!$ this ->curl ) {
1196
+ $ this ->curl = $ this ->_curlFactory ->create ();
1181
1197
$ config = ['timeout ' => 60 , 'verifypeer ' => $ this ->_config ->getValue ('verifyPeer ' )];
1182
1198
if ($ this ->getUseProxy ()) {
1183
1199
$ config ['proxy ' ] = $ this ->getProxyHost () . ': ' . $ this ->getProxyPort ();
1184
1200
}
1185
1201
if ($ this ->getUseCertAuthentication ()) {
1186
1202
$ config ['ssl_cert ' ] = $ this ->getApiCertificate ();
1187
1203
}
1188
- $ http ->setOptions ($ config );
1189
- $ http ->write (
1190
- Request::METHOD_POST ,
1191
- $ this ->getApiEndpoint (),
1192
- '1.1 ' ,
1193
- $ this ->_headers ,
1194
- $ this ->_buildQuery ($ request )
1204
+ $ this ->curl ->setOptions ($ config );
1205
+ if ($ request ) {
1206
+ $ this ->curl ->write (
1207
+ Request::METHOD_POST ,
1208
+ $ this ->getApiEndpoint (),
1209
+ '1.1 ' ,
1210
+ $ this ->_headers ,
1211
+ $ this ->_buildQuery ($ request )
1212
+ );
1213
+ }
1214
+ }
1215
+ return $ this ->curl ;
1216
+ }
1217
+
1218
+ /**
1219
+ * Checks if transport errors occurred and throws exception if needed
1220
+ *
1221
+ * @return void
1222
+ * @throws ClientException
1223
+ */
1224
+ private function handleConnectionErrors (): void
1225
+ {
1226
+ if ($ this ->getCurl ()->getErrno ()) {
1227
+ $ this ->_logger ->critical (
1228
+ new \Exception (
1229
+ sprintf (
1230
+ 'PayPal NVP CURL connection error #%s: %s ' ,
1231
+ $ this ->getCurl ()->getErrno (),
1232
+ $ this ->getCurl ()->getError ()
1233
+ )
1234
+ )
1235
+ );
1236
+ $ this ->getCurl ()->close ();
1237
+
1238
+ throw new ClientException (
1239
+ __ ('Payment Gateway is unreachable at the moment. Please use another payment option. ' )
1195
1240
);
1196
- $ response = $ http ->read ();
1241
+ }
1242
+ // cUrl resource must be closed after checking it for errors
1243
+ $ this ->getCurl ()->close ();
1244
+ }
1245
+
1246
+ /**
1247
+ * Do the API call
1248
+ *
1249
+ * @param string $methodName
1250
+ * @param array $request
1251
+ * @return array
1252
+ * @throws ClientException|\Magento\Framework\Exception\LocalizedException|\Exception
1253
+ * @SuppressWarnings(PHPMD.CyclomaticComplexity)
1254
+ */
1255
+ public function call ($ methodName , array $ request )
1256
+ {
1257
+ $ request = $ this ->prepareRequest ($ methodName , $ request );
1258
+ $ debugData = ['url ' => $ this ->getApiEndpoint (), $ methodName => $ request ];
1259
+ try {
1260
+ $ response = $ this ->getCurl ($ request )->read ();
1197
1261
} catch (\Exception $ e ) {
1198
1262
$ debugData ['http_error ' ] = ['error ' => $ e ->getMessage (), 'code ' => $ e ->getCode ()];
1199
1263
$ this ->_debug ($ debugData );
@@ -1203,29 +1267,11 @@ public function call($methodName, array $request)
1203
1267
$ response = preg_split ('/^\r?$/m ' , $ response , 2 );
1204
1268
$ response = trim ($ response [1 ] ?? '' );
1205
1269
$ response = $ this ->_deformatNVP ($ response );
1206
-
1207
1270
$ debugData ['response ' ] = $ response ;
1208
1271
$ this ->_debug ($ debugData );
1209
-
1210
1272
$ response = $ this ->_postProcessResponse ($ response );
1211
1273
1212
- // handle transport error
1213
- if ($ http ->getErrno ()) {
1214
- $ this ->_logger ->critical (
1215
- new \Exception (
1216
- sprintf ('PayPal NVP CURL connection error #%s: %s ' , $ http ->getErrno (), $ http ->getError ())
1217
- )
1218
- );
1219
- $ http ->close ();
1220
-
1221
- throw new ClientException (
1222
- __ ('Payment Gateway is unreachable at the moment. Please use another payment option. ' )
1223
- );
1224
- }
1225
-
1226
- // cUrl resource must be closed after checking it for errors
1227
- $ http ->close ();
1228
-
1274
+ $ this ->handleConnectionErrors ();
1229
1275
if (!$ this ->_validateResponse ($ methodName , $ response )) {
1230
1276
$ this ->_logger ->critical (new \Exception (__ ('PayPal response hasn \'t required fields. ' )));
1231
1277
throw new \Magento \Framework \Exception \LocalizedException (
0 commit comments