diff --git a/vendor/magento/module-paypal/Model/Payflow/Service/Gateway.php b/vendor/magento/module-paypal/Model/Payflow/Service/Gateway.php
index 6a2229c3d55..bd9bd21d57d 100644
--- a/vendor/magento/module-paypal/Model/Payflow/Service/Gateway.php
+++ b/vendor/magento/module-paypal/Model/Payflow/Service/Gateway.php
@@ -85,7 +85,8 @@ class Gateway implements GatewayInterface
         );
         $client->setConfig($clientConfig);
         $client->setMethod(\Zend_Http_Client::POST);
-        $client->setParameterPost($request->getData());
+        $requestData = $this->prepareRequestData($request->getData());
+        $client->setParameterPost($requestData);
         $client->setHeaders(
             [
                 'X-VPS-VIT-CLIENT-CERTIFICATION-ID' => '33baf5893fc2123d8b191d2d011b7fdc',
@@ -97,9 +98,7 @@ class Gateway implements GatewayInterface
 
         try {
             $response = $client->request();
-
-            $responseArray = [];
-            parse_str(strstr($response->getBody(), 'RESULT'), $responseArray);
+            $responseArray = $this->parseNVP(strstr($response->getBody(), 'RESULT'));
 
             $result->setData(array_change_key_case($responseArray, CASE_LOWER));
             $result->setData('result_code', $result->getData('result'));
@@ -115,7 +114,7 @@ class Gateway implements GatewayInterface
         } finally {
             $this->logger->debug(
                 [
-                    'request' => $request->getData(),
+                    'request' => $requestData,
                     'result' => $result->getData()
                 ],
                 (array)$config->getValue('getDebugReplacePrivateDataKeys'),
@@ -125,4 +124,62 @@ class Gateway implements GatewayInterface
 
         return $result;
     }
+
+    /**
+     * Add length tag to parameters name which contains special characters: =, &
+     *
+     * The length tag specifies the exact number of characters and spaces (number of bytes) that appear in the value
+     * eg ['COMPANYNAME[14]' => 'Ruff & Johnson')]
+     *
+     * @param array $data
+     * @return array
+     */
+    private function prepareRequestData(array $data): array
+    {
+        $requestData = [];
+        foreach ($data as $k => $v) {
+            if (strpos($v, '&') !== false || strpos($v, '=') !== false) {
+                $requestData[$k . '[' . strlen($v) . ']'] = $v;
+            } else {
+                $requestData[$k] = $v;
+            }
+        }
+        return $requestData;
+    }
+
+    /**
+     * Parse NVP string into array
+     *
+     * Use length tag (if present) to parse the key value.
+     *
+     * The length tag specifies the exact number of characters and spaces (number of bytes) that appear in the value
+     * e.g COMPANYNAME[14]=Ruff & Johnson
+     * e.g COMMENT1[7]=Level=5
+     * @param string $nvp
+     * @return array
+     */
+    private function parseNVP(string $nvp): array
+    {
+        $result = [];
+        while (strlen($nvp) > 0) {
+            $keyPos = strpos($nvp, '=');
+            if ($keyPos !== false) {
+                $key = substr($nvp, 0, $keyPos);
+                if (preg_match('/\[(\d+)]$/', $key, $keyParts)) {
+                    $valueLength = (int)$keyParts[1];
+                    $key = substr($key, 0, strpos($key, '['));
+                    $result[$key] = substr($nvp, $keyPos + 1, $valueLength);
+                    $valuePos = $keyPos + 1 + $valueLength;
+                } else {
+                    $valuePos = strpos($nvp, '&') ? strpos($nvp, '&') : strlen($nvp);
+                    $value = substr($nvp, $keyPos + 1, $valuePos - $keyPos - 1);
+                    $result[$key] = $value;
+                }
+                $nvp = substr($nvp, $valuePos + 1);
+            } else {
+                $nvp = '';
+            }
+        }
+        return $result;
+    }
 }
