0

I wasn't sure the best way to word the title. My issue involves this function mail($to, $subject, $message, $headers); I have it running in the middle of a PHP file which takes information from a form, creates a token with stripe api and then charges that card with stripe.

Stripe still receives the data and charges the card correctly with the inclusion of the mail function, however the page doesn't show the success message like it used to, pretty much anything but the header shows after the purchase when usually the form would clear and success message would show up. It's like anything after the mail function isn't included on a succesfull form submit.

I spend most of my time in javascript, so this could completely be my lack of familiarity with PHP.

Here is the full code below.

<?php include 'head.php'; ?>
<body>

  <!--header-->
  <?php include 'header.php'; ?>


  <!--header-->

  <script type="text/javascript">
  // $('input.quantity').keyup(function(){
  //     var value = $( this ).val();
  //     var bookQuantity = $( "input.bfh-number" ).text( value );
  //     console.log(bookQuantity);
  // })




  $(document).ready(function() {


    $( ".quantity" )
  .keyup(function() {
    var value = $( this ).val();
    console.log(value);
    subTotal = 150 * value;
    $( '.paymentTotal' ).text( '$' + subTotal );
  }).keyup();


    $('#payment-form').bootstrapValidator({
      message: 'This value is not valid',
      feedbackIcons: {
        valid: 'glyphicon glyphicon-ok',
        invalid: 'glyphicon glyphicon-remove',
        validating: 'glyphicon glyphicon-refresh'
      },
      submitHandler: function(validator, form, submitButton) {
        var chargeAmount = 3000; //amount you want to charge, in cents. 1000 = $10.00, 2000 = $20.00 ...
        // createToken returns immediately - the supplied callback submits the form if there are no errors
        Stripe.createToken({
          number: $('.card-number').val(),
          cvc: $('.card-cvc').val(),
          exp_month: $('.card-expiry-month').val(),
          exp_year: $('.card-expiry-year').val(),
          name: $('.card-holder-name').val(),
          address_line1: $('.address').val(),
          address_city: $('.city').val(),
          address_zip: $('.zip').val(),
          address_state: $('.state').val(),
          quantity: $('.quantity').val(),
          address_country: $('.country').val()
        }, chargeAmount, stripeResponseHandler);
        return false; // submit from callback
      },
      fields: {
        street: {
          validators: {
            notEmpty: {
              message: 'The street is required and cannot be empty'
            },
            stringLength: {
              min: 6,
              max: 96,
              message: 'The street must be more than 6 and less than 96 characters long'
            }
          }
        },
        city: {
          validators: {
            notEmpty: {
              message: 'The city is required and cannot be empty'
            }
          }
        },
        zip: {
          validators: {
            notEmpty: {
              message: 'The zip is required and cannot be empty'
            },
            stringLength: {
              min: 3,
              max: 9,
              message: 'The zip must be more than 3 and less than 9 characters long'
            }
          }
        },
        email: {
          validators: {
            notEmpty: {
              message: 'The email address is required and cannot be empty'
            },
            emailAddress: {
              message: 'The input is not a valid email address'
            },
            stringLength: {
              min: 6,
              max: 65,
              message: 'The email must be more than 6 and less than 65 characters long'
            }
          }
        },
        cardholdername: {
          validators: {
            notEmpty: {
              message: 'The card holder name is required and cannot be empty'
            },
            stringLength: {
              min: 6,
              max: 70,
              message: 'The card holder name must be more than 6 and less than 70 characters long'
            }
          }
        },
        first_name: {
          validators: {
            notEmpty: {
              message: 'The card holder name is required and cannot be empty'
            }
          }
        },
        cardnumber: {
          selector: '#cardnumber',
          validators: {
            notEmpty: {
              message: 'The credit card number is required and cannot be empty'
            },
            creditCard: {
              message: 'The credit card number is invalid'
            },
          }
        },
        expMonth: {
          selector: '[data-stripe="exp-month"]',
          validators: {
            notEmpty: {
              message: 'The expiration month is required'
            },
            digits: {
              message: 'The expiration month can contain digits only'
            },
            callback: {
              message: 'Expired',
              callback: function(value, validator) {
                value = parseInt(value, 10);
                var year         = validator.getFieldElements('expYear').val(),
                currentMonth = new Date().getMonth() + 1,
                currentYear  = new Date().getFullYear();
                if (value < 0 || value > 12) {
                  return false;
                }
                if (year == '') {
                  return true;
                }
                year = parseInt(year, 10);
                if (year > currentYear || (year == currentYear && value > currentMonth)) {
                  validator.updateStatus('expYear', 'VALID');
                  return true;
                } else {
                  return false;
                }
              }
            }
          }
        },
        expYear: {
          selector: '[data-stripe="exp-year"]',
          validators: {
            notEmpty: {
              message: 'The expiration year is required'
            },
            digits: {
              message: 'The expiration year can contain digits only'
            },
            callback: {
              message: 'Expired',
              callback: function(value, validator) {
                value = parseInt(value, 10);
                var month        = validator.getFieldElements('expMonth').val(),
                currentMonth = new Date().getMonth() + 1,
                currentYear  = new Date().getFullYear();
                if (value < currentYear || value > currentYear + 100) {
                  return false;
                }
                if (month == '') {
                  return false;
                }
                month = parseInt(month, 10);
                if (value > currentYear || (value == currentYear && month > currentMonth)) {
                  validator.updateStatus('expMonth', 'VALID');
                  return true;
                } else {
                  return false;
                }
              }
            }
          }
        },
        cvv: {
          selector: '#cvv',
          validators: {
            notEmpty: {
              message: 'The cvv is required and cannot be empty'
            },
            cvv: {
              message: 'The value is not a valid CVV',
              creditCardField: 'cardnumber'
            }
          }
        },
      }
    });
  });
</script>
<script type="text/javascript">
  // this identifies your website in the createToken call below
  //Stripe.setPublishableKey('pk_live_random');
  Stripe.setPublishableKey('pk_test_random');



  function stripeResponseHandler(status, response) {
    if (response.error) {
      // re-enable the submit button
      $('.submit-button').removeAttr("disabled");
      // show hidden div
      document.getElementById('a_x200').style.display = 'block';
      // show the errors on the form
      $(".payment-errors").html(response.error.message);
    } else {
      var form$ = $("#payment-form");
      // token contains id, last4, and card type
      var token = response['id'];
      // insert the token into the form so it gets submitted to the server
      form$.append("<input type='hidden' name='stripeToken' value='" + token + "' />");
      // and submit
      form$.get(0).submit();
    }
  }

</script>

<!--content-->

<div class="global indent">
  <div class="container partner-wrap">
    <form action="" method="POST" id="payment-form" class="form-horizontal">
      <div class="row"> <div class="col-lg-6"><img id="buyImage" src="img/book.jpg" /></div>
        <div class="col-lg-6"><h2>The Economic Definition of Ore</h2><p>Price:$150</p>
          <label class="control-label" for="textinput">Quantity</label>
          <div class="form-group col-sm-4">
            <div class="col-lg-12">
            <h4>Quantity</h4>
            </div>
            <div class="col-lg-12">
            <input type="text" name="quantity" value="1" data-buttons="false" class="quantity form-control bfh-number">
            </div>
          </div>

          <div class="col-sm-8">
          <h4 class="subTotalRight borderBottom">Total:</h4>
          <h5 class="paymentTotal subTotalRight"></h5>
          </div>
        </div>

  </div>




    <div class="row row-centered">
      <div class="col-md-12">
        <div class="page-header">
          <h2 class="gdfg">Secure Payment Form</h2>
        </div>
        <noscript>
          <div class="bs-callout bs-callout-danger">
            <h4>JavaScript is not enabled!</h4>
            <p>This payment form requires your browser to have JavaScript enabled. Please activate JavaScript and reload this page. Check <a href="http://enable-javascript.com" target="_blank">enable-javascript.com</a> for more informations.</p>
          </div>
        </noscript>
        <?php

        $error = '';
        $success = '';

        require 'Stripe.php';

        if ($_POST) {

          $token = $_POST['stripeToken'];
          $email = $_POST["email"];
          $quantity = $_POST["quantity"];
          $firstName = $_POST["firstName"];
          $lastName = $_POST["lastName"];


          // Get the values from the $_POST array:
         $price = 15000;




        $total = $price * $quantity;
        $customertotal = $price * $quantity / 100;



          //Stripe::setApiKey("sk_random");
          Stripe::setApiKey("sk_random");

          $error = '';
          $success = '';





          try {

            $customer = Stripe_Customer::create(array(
            'email' => $email,
            'card'  => $token,
            "description" => $quantity . " copies of The Economic Definition of Ore -Cut-off Grades in Theory and Practice"
            ));

            $charge = Stripe_Charge::create(array(
            "amount" => $total, // amount in cents, again
            "currency" => "cad",
            'customer' => $customer->id,
            "metadata" => array("First Name:" => $firstName, "Last Name:" => $lastName)

            )
            );

            $success = '<div class="alert alert-success">
              <strong>Success!</strong> Your payment was successful. For $' . $customertotal . ', and you have ordered ' . $quantity . ' copies </div>';



              $to  = $email; // note the comma

              // subject
              $subject = 'Economic Definition of Ore Purchase';

              // message
              $message = '
              <html>
              <head>
                <title>Sumary of Purchase</title>
              </head>
              <body>
                <table>
                  <tr>
                    <td> Hi ' . $firstName . '</td>
                  </tr>
                  <tr>
                    <td>
                      <p>Here is a summary of your recent purchase.</p>
                    </td>
                  </tr>
                  <tr>
                    <td>
                      <p>Your total purchase is $'.$customertotal . ' </p>
                      <p>The number of books you have ordered is <b>'  . $quantity . '</b> </p>
                    </td>
                  </tr>

                </table>
              </body>
              </html>
              ';

              // To send HTML mail, the Content-type header must be set
              $headers  = 'MIME-Version: 1.0' . "\r\n";
              $headers .= 'Content-type: text/html; charset=iso-8859-1' . "\r\n";

              // Additional headers
              $headers .= 'To: '. $firstName .' <' . $email . ' >  ' . "\r\n";
              $headers .= 'From: Comet <info@cometstrategy.com>' . "\r\n";
              // $headers .= 'Bcc: birthdaycheck@example.com' . "\r\n";

              // Mail it
              mail($to, $subject, $message, $headers);



          }
          catch (Exception $e) {
            $error = '<div class="alert alert-danger">
              <strong></strong> '.$e->getMessage().'
            </div>';
          }
        }
        ?>
        <span class="payment-success">
          <?= $success ?>
          <?= $error ?>

        </span>

        <div class="alert alert-danger" id="a_x200" style="display: none;"> <strong></strong> Please fill out all required fields. </div>




          <!-- Street -->

          <div class="row">
            <div class="col-md-6">

              <!-- Form Name -->
              <legend>Billing Details</legend>


              <fieldset>


          <!-- Street -->
          <div class="form-group">
            <label class="col-sm-4 control-label" for="textinput">First Name</label>
            <div class="col-sm-12">
              <input type="text" name="firstName" placeholder="First Name" class="firstName form-control">
            </div>
          </div>

          <!-- Street -->
          <div class="form-group">
            <label class="col-sm-4 control-label" for="textinput">Last Name</label>
            <div class="col-sm-12">
              <input type="text" name="lastName" placeholder="Last Name" class="firstName form-control">
            </div>
          </div>



          <!-- Street -->
          <div class="form-group">
            <label class="col-sm-4 control-label" for="textinput">Street</label>
            <div class="col-sm-12">
              <input type="text" name="street" placeholder="Billing Address" class="address form-control">
            </div>
          </div>

          <!-- City -->
          <div class="form-group">
            <label class="col-sm-4 control-label" for="textinput">City</label>
            <div class="col-sm-12">
              <input type="text" name="city" placeholder="City" class="city form-control">
            </div>
          </div>

          <!-- State -->
          <div class="form-group">
            <label class="col-sm-4 control-label" for="textinput">State</label>
            <div class="col-sm-12">
              <input type="text" name="state" maxlength="65" placeholder="State" class="state form-control">
            </div>
          </div>

          <!-- Postcal Code -->
          <div class="form-group">
            <label class="col-sm-4 control-label" for="textinput">Postal Code</label>
            <div class="col-sm-12">
              <input type="text" name="zip" maxlength="9" placeholder="Postal Code" class="zip form-control">
            </div>
          </div>

          <!-- Country -->
          <div class="form-group">
            <label class="col-sm-4 control-label" for="textinput">Country</label>
            <div class="col-sm-12">
              <!--input type="text" name="country" placeholder="Country" class="country form-control"-->
              <!-- <div class="country bfh-selectbox bfh-countries" name="country" placeholder="Select Country" data-flags="true" data-filter="true"> </div> -->
              <select class="form-control bfh-countries" data-country="AU"></select>
              <!-- <div class="bfh-selectbox bfh-countries" data-country="AU" data-flags="true"> -->
              <!-- </div> -->
            </div>
          </div>

          <!-- Email -->
          <div class="form-group">
            <label class="col-sm-4 control-label" for="textinput">Email</label>
            <div class="col-sm-12">
              <input type="text" name="email" maxlength="65" placeholder="Email" class="email form-control">
            </div>
          </div>


        </div>

        <div class="col-md-6">


          <fieldset>
            <legend>Card Details</legend>

            <!-- Card Holder Name -->
            <div class="form-group">
              <label class="col-sm-4 control-label"  for="textinput">Card Holder's Name</label>
              <div class="col-sm-12">
                <input type="text" name="cardholdername" maxlength="70" placeholder="Card Holder Name" class="card-holder-name form-control">
              </div>
            </div>

            <!-- Card Number -->
            <div class="form-group">
              <label class="col-sm-4 control-label" for="textinput">Card Number</label>
              <div class="col-sm-12">
                <input type="text" id="cardnumber" maxlength="19" placeholder="Card Number" class="card-number form-control">
              </div>
            </div>

            <!-- Expiry-->
            <div class="form-group">
              <label class="col-xs-12 col-sm-12 control-label" for="textinput">Card Expiry Date</label>
              <div class="col-sm-12">
                <div class="form-inline">
                  <select name="select2" data-stripe="exp-month" class="card-expiry-month stripe-sensitive required form-control">
                    <option value="01" selected="selected">01</option>
                    <option value="02">02</option>
                    <option value="03">03</option>
                    <option value="04">04</option>
                    <option value="05">05</option>
                    <option value="06">06</option>
                    <option value="07">07</option>
                    <option value="08">08</option>
                    <option value="09">09</option>
                    <option value="10">10</option>
                    <option value="11">11</option>
                    <option value="12">12</option>
                  </select>
                  <span> / </span>
                  <select name="select2" data-stripe="exp-year" class="card-expiry-year stripe-sensitive required form-control">
                  </select>
                  <script type="text/javascript">
                    var select = $(".card-expiry-year"),
                    year = new Date().getFullYear();

                    for (var i = 0; i < 12; i++) {
                      select.append($("<option value='"+(i + year)+"' "+(i === 0 ? "selected" : "")+">"+(i + year)+"</option>"))
                    }
                  </script>
                </div>
              </div>
            </div>

            <!-- CVV -->
            <div class="form-group">
              <label class="col-sm-4 control-label" for="textinput">CVV/CVV2</label>
              <div class="col-sm-4">
                <input type="text" id="cvv" placeholder="CVV" maxlength="4" class="card-cvc form-control">
              </div>

            </div>
            <hr>
            <div class="row">
            <div class="col-sm-12">
              <h3>Total ($USD)</h3>
            </div>
            <div class="col-sm-12">
            <h4 class="paymentTotal"></h4>
            </div>

            <div class="col-sm-12">
              <button class="btn btn-success" type="submit">Pay Now</button>
            </div>

          </div>
            <!-- Important notice -->
            <!-- <div class="form-group"> -->
              <!-- <div class="panel panel-success"> -->
              <!-- <div class="panel-heading">
              <h3 class="panel-title">Important notice</h3>
            </div>
            <div class="panel-body">
            <p>Your card will be charged 30€ after submit.</p>
            <p>Your account statement will show the following booking text:
            XXXXXXX </p>
          </div>
        </div> -->


      </fieldset>
    </div>
  </div>
    </form>

  </div>
</div>


  </div>
</div>

    <!--footer-->
    <?php include 'footer.php'; ?>

    <script src="js/bootstrap.min.js"></script>
    <script src="js/tm-scripts.js"></script>
  </body>
  </html>
Anders Kitson
  • 1,413
  • 6
  • 38
  • 98
  • Is there anything in your error log? Is the email actually sending successfully? It sounds like the mail function (or something near it) is fataling. – Peter Apr 09 '15 at 17:15
  • The email is sending fine, where is my error log for php, i have setup the server with digital ocean to display php errors. – Anders Kitson Apr 09 '15 at 17:18

1 Answers1

0

Is anything after the PHP block being sent to the client (if you view source, is there any HTML after <noscript> block?), or is the payment-success span just empty?

If it's the former (nothing after the PHP block), then execution is stopping after the call to mail(). If mail() is reporting some kind of error, it will not be caught by the try/catch since it is an internal function that does not throw exceptions--it relies on the older PHP error reporting mechanism. For debugging purposes, try setting error_reporting(E_ALL) and manually testing to see if mail() is returning true:

<?php // Top of the file error_reporting(E_ALL); include 'head.php'; ?> .... ... // In the PHP block where you call mail() if (!mail($to, $subject, $message, $headers)) { echo "There was a problem with mail()<br />\n"; }

Then, submit the form and see if there is a PHP error message somewhere in the output and/or the message "There was a problem with mail()'. Depending on what you find, we can go from there.

Chris Brendel
  • 700
  • 3
  • 10
  • I don't seem to be getting any results from doing that, the code you suggested is uploaded to this site http://mini-dev.cf/purchase.php you can use 4242424242424242 as a test card for stripe. It takes a very long time to submit the form as well. – Anders Kitson Apr 09 '15 at 17:46
  • Honestly, it seems like the PHP script is just timing out because something is taking too long. You could use `set_time_limit ()` to increase the timeout to a higher amount (the default is 30 seconds), but it would be better to figure out what's holding up execution. It may be the call to the Stripe API. Try commenting out the API calls and if that doesn't make it work, comment out the `mail()` call, and we'll see what's causing it. – Chris Brendel Apr 09 '15 at 18:06
  • Its definitely the mail() call that is slowing things down, I originally wanted to just do this mailer with a smtp server, but our client is admit about their server handling the mail send, because thats how it has worked in the past. Not really sure how to debug at this point. – Anders Kitson Apr 09 '15 at 21:49
  • Dang. Well, if troubleshooting SMTP on the system isn't an option, take a look at this thread which talks about offloading the call so that your script can still execute in a timely manner: http://stackoverflow.com/questions/6618293/email-on-separate-thread-in-php Not ideal, but may be what you're looking for in this scenario. I don't know enough about SMTP programs to troubleshoot the actual cause of the slowness, and if it's a shared server, you may not have much ability to fix the issue, anyway. – Chris Brendel Apr 09 '15 at 22:46
  • I looked at that question, Im not sure how to apply the parameters part, passing the data to the separate php file. Ill look into storing in the database, but If i could do it with just passing some parameters that would be ideal, since I have no mysql and php database interaction. – Anders Kitson Apr 11 '15 at 18:44