title: How to catch a Stripe Fatal Error in PHP?
body: <p>I am spinning up an application using the Stripe.js elements. Using the test card numbers provided by Stripe, I have no issues.  All works as expected.</p>
  
  <p>I'm now focusing on error handling.  When using the test card 4000 0000 0000 0002 to handle a card that is intentionally declined, I get this error:</p>
  
  <blockquote>
    <p><strong>Fatal error</strong>: Uncaught Stripe\Error\Card: Your card was declined. in
    C:\Apache24\htdocs...\vendor\stripe\stripe-php\lib\ApiRequestor.php:128 from API request {token}....</p>
  </blockquote>
  
  <p>Now I'm assuming this is not a PHP Fatal Error (which can not be handled in a try/catch block), so I searched and found <a href="https://stackoverflow.com/a/32030740/2626197">this example</a> and implemented it into my code like this:</p>
  
  <pre><code>\Stripe\Stripe::setApiKey(self::APIKEY);
  
      $charge_arr = array(
          "key" =&gt; value, etc ... )
  
          try {               
              $charge = \Stripe\Charge::create($charge_arr);
              if($charge-&gt;paid == true) { 
                  echo '&lt;br&gt;the card was successfully charged!';
              }
  
          } catch (\Stripe\Error\Base $e) {
              echo '&lt;br&gt;base';
              echo ($e-&gt;getMessage());
  
          } catch (\Stripe\Error\Card $e) {
              $body = $e-&gt;getJsonBody();
              $err  = $body['error'];
  
              print('Status is:' . $e-&gt;getHttpStatus() . "\n");
              print('Type is:' . $err['type'] . "\n");
              print('Code is:' . $err['code'] . "\n");                
  
              echo ($e-&gt;getMessage()); 
  
          } catch (\Stripe\Error\Authentication $e) {
              echo '&lt;br&gt;Auth';                
              // a good one to catch
          } catch (\Stripe\Error\InvalidRequest $e) {
              echo '&lt;br&gt;Invalid Request';             
              // and catch this one just in case
          } catch (Exception $e) {
              //catch any non-stripe exceptions
          }
  </code></pre>
  
  <p>This does not, however, catch the error.  The message continues to be displayed as it was before I had the catch block.</p>
  
  <p>Any clues why I'm getting the Fatal Error?  I, of course, expected the card to be declined, but I expected the result of the decline to be something I could handle in the try/catch block.</p>
  
  <p><strong>EDITS</strong></p>
  
  <p>I should add that I'm using composer to include the Stripe php libraries.</p>
  
  <p>Further note: It may not be relevant, but the Fatal Error message appears for all test cards that are supposed to be declined.  The reason for the decline is stated clearly in the error message for each card like (not verbatim) zip code failed validation, CVC not correct, card expired, etc.  </p>
  
  <p>As @Ywain rightfully notes, this actually isn't a try/catch block problem.  The Fatal Error is generated by the charge transaction in the first place.  In other words the call to \Stripe\Charge should return a JSON array with appropriate flags or field values, not a Fatal Error.  </p>