title: Payment succeeds with wrong expiration, card verification code, name, and address
body: <p>I have a PayPal business account. I generated an API username, password, and signature, and copied some PHP code from a previously-made website that would process payment fields on a form.</p>
  
  <p>In the previously-made website, everything runs fine, to this day. However, in this new website, <strong>as long as the credit card number is valid, I can make up a name, input the wrong expiration date, input a bogus card security code, and make up an address, and the payment still goes through!</strong> I see my PayPal balance increase, and I also see the charge on my credit card! I'm <em>not</em> using the sandboxed environment at the moment.</p>
  
  <p>How can that be possible? Also, perhaps worth noting, the charge comes up on my credit card's pending transactions as some irrelevant business, "Sally Beauty Supply." Nowhere in my code have I written these words! I tried both an American Express and a Visa Card.</p>
  
  <hr>
  
  <p>Here's my code. <em>Everything</em> is copied from the previously-made website, except where noted by <code>&lt;REPLACED&gt;</code>. Code has been simplified a little bit.</p>
  
  <pre><code>$paypal = array(
      'version'   =&gt; '85.0',
      'endpoint'  =&gt; 'https://api-3t.paypal.com/nvp',
      'username'  =&gt; '&lt;REPLACED&gt;',
      'password'  =&gt; '&lt;REPLACED&gt;',
      'signature' =&gt; '&lt;REPLACED&gt;',
  );
  
  $request_params = array
                    (
                        'METHOD' =&gt; 'DoDirectPayment',
                        'USER' =&gt; $paypal['username'],
                        'PWD' =&gt; $paypal['password'],
                        'SIGNATURE' =&gt; $paypal['signature'],
                        'VERSION' =&gt; $paypal['version'],
                        'PAYMENTACTION' =&gt; 'Sale',
                        'IPADDRESS' =&gt; $_SERVER['REMOTE_ADDR'],
                        'ACCT' =&gt; $_POST['form_PaymentCardNumber'],
                        'EXPDATE' =&gt; $_POST['form_PaymentCardExpiryMonth'].$_POST['form_PaymentCardExpiryYear'],
                        'CVV2' =&gt; $_POST['form_PaymentCardCVV2'],
                        'FIRSTNAME' =&gt; $_POST['form_PaymentFirstName'],
                        'LASTNAME' =&gt; $_POST['form_PaymentLastName'],
                        'STREET' =&gt; $_POST['form_PaymentAddressLine1'],
                        'STREET2' =&gt; $_POST['form_PaymentAddressLine2'],
                        'CITY' =&gt; $_POST['form_PaymentCity'],
                        'STATE' =&gt; $_POST['form_PaymentStateProvince'],
                        'COUNTRYCODE' =&gt; $_POST['form_PaymentCountry'],
                        'ZIP' =&gt; $_POST['form_PaymentZipPostalCode'],
                        'AMT' =&gt; $_POST['form_PaymentAmount'],
                        'CURRENCYCODE' =&gt; 'USD',
                        'DESC' =&gt; "&lt;REPLACED&gt;"
                    );
  
  $nvp_string = '';
  foreach($request_params as $var=&gt;$val)
  {
     $nvp_string .= '&amp;'.$var.'='.urlencode($val);
  }
  
  $curl = curl_init();
  curl_setopt($curl, CURLOPT_VERBOSE, 1);
  curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
  curl_setopt($curl, CURLOPT_TIMEOUT, 30);
  curl_setopt($curl, CURLOPT_URL, $paypal['endpoint']);
  curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
  curl_setopt($curl, CURLOPT_POSTFIELDS, $nvp_string);
  $result = curl_exec($curl);
  curl_close($curl);
  
  function NVPToArray($str)
  {
     $proArray = array();
     while(strlen($str))
     {
        // name
        $keypos= strpos($str,'=');
        $keyval = substr($str,0,$keypos);
        // value
        $valuepos = strpos($str,'&amp;') ? strpos($str,'&amp;'): strlen($str);
        $valval = substr($str,$keypos+1,$valuepos-$keypos-1);
        // decoding the respose
        $proArray[$keyval] = urldecode($valval);
        $str = substr($str,$valuepos+1,strlen($str));
     }
     return $proArray;
  }
  
  $result = NVPToArray($result);
  
  $paid = false;
  
  if (strtoupper($result['ACK']) === 'SUCCESS' ||
      strtoupper($result['ACK']) === 'SUCCESSWITHWARNING')
  {
      $paid = true;
  }
  </code></pre>
  
  <p>Should I not have copied <code>'version' =&gt; '85.0'</code> and/or <code>'endpoint' =&gt; 'https://api-3t.paypal.com/nvp'</code>? Or, what is it?</p>