title: Stripe token error
body: <p>I'm trying to setup a section on my site that collects card details (using stripe), save as a customer, and charge at a later date. Looked through several tutorials and still getting an error, in particular:</p>
  
  <p>Undefined variable: token in /Applications/XAMPP/xamppfiles/htdocs/love-deals/admin/billing.php on line 21 failed to save customer id to db. I want to be able to save the customer id to a users table in my database (user already created) to be used at a later date for payments, but for the life of me I cant seem to get past this error! any help will be greatly appreciated.</p>
  
  <p>Thanks in advance</p>
  
  <p>Kaylee</p>
  
  <p>Here is my code so far:</p>
  
  <p>payment page, with form:</p>
  
  <pre><code>&lt;?php $userID = (int) $_GET['id'];
  require('../inc/connect/config.php');
  ?&gt;
  &lt;header&gt;
  &lt;!-- CSS --&gt;
  &lt;link href="admin.css" rel="stylesheet"&gt;
  &lt;link href="bootstrap.min.css" rel="stylesheet"&gt;
  
  &lt;script type="text/javascript" src="https://js.stripe.com/v2/"&gt;&lt;/script&gt;
  &lt;?php
  echo '&lt;script type="text/javascript"&gt;
  Stripe.setPublishableKey("' . STRIPE_PUBLIC_KEY . '");
  &lt;/script&gt;';
  ?&gt;
  &lt;script type="text/javascript" src="../js/billing.js"&gt;&lt;/script&gt;
  &lt;/header&gt;
  &lt;body&gt;
  &lt;form action="billing.php?id=&lt;?php echo $userID; ?&gt;" method="POST" id="payment-form"&gt;
  &lt;span id="payment-errors" class=""&gt;&lt;/span&gt;
  
  &lt;div class="form-row"&gt;
    &lt;label&gt;
      &lt;span&gt;Card Number&lt;/span&gt;
      &lt;input type="text" size="20" data-stripe="number" class="card-number"&gt;
    &lt;/label&gt;
  &lt;/div&gt;
  
  &lt;div class="form-row"&gt;
    &lt;label&gt;
      &lt;span&gt;Expiration (MM/YY)&lt;/span&gt;
      &lt;input type="text" size="2" data-stripe="exp_month" class="card-expiry-month"&gt;
    &lt;/label&gt;
    &lt;span&gt; / &lt;/span&gt;
    &lt;input type="text" size="2" data-stripe="exp_year" class="card-expiry-year"&gt;
  &lt;/div&gt;
  
  &lt;div class="form-row"&gt;
    &lt;label&gt;
      &lt;span&gt;CVC&lt;/span&gt;
      &lt;input type="text" size="4" data-stripe="cvc" class="card-cvc"&gt;
    &lt;/label&gt;
  &lt;/div&gt;
  
  &lt;input id="submitBtn" type="submit" class="submit" value="Submit Payment"&gt;
  &lt;/form&gt;
  &lt;/body&gt;
  </code></pre>
  
  <p>billing.js:</p>
  
  <pre><code>function reportError(msg) {
  // Show the error in the form:
  $('#payment-errors').text(msg).addClass('alert alert-danger');
  // re-enable the submit button:
  $('#submitBtn').prop('disabled', false);
  return false;
  }
  
  // Assumes jQuery is loaded!
  // Watch for the document to be ready:
  $(document).ready(function() {
  
  // Watch for a form submission:
  $("#payment-form").submit(function(event) {
  
      // Flag variable:
      var error = false;
  
      // disable the submit button to prevent repeated clicks:
      $('#submitBtn').attr("disabled", "disabled");
  
      // Get the values:
      var ccNum = $('.card-number').val(), cvcNum = $('.card-cvc').val(), expMonth = $('.card-expiry-month').val(), expYear = $('.card-expiry-year').val();
  
      // Validate the number:
      if (!Stripe.card.validateCardNumber(ccNum)) {
          error = true;
          reportError('The credit card number appears to be invalid.');
      }
  
      // Validate the CVC:
      if (!Stripe.card.validateCVC(cvcNum)) {
          error = true;
          reportError('The CVC number appears to be invalid.');
      }
  
      // Validate the expiration:
      if (!Stripe.card.validateExpiry(expMonth, expYear)) {
          error = true;
          reportError('The expiration date appears to be invalid.');
      }
  
      // Validate other form elements, if needed!
  
      // Check for errors:
      if (!error) {
  
          // Get the Stripe token:
          Stripe.card.createToken({
              number: ccNum,
              cvc: cvcNum,
              exp_month: expMonth,
              exp_year: expYear
          }, stripeResponseHandler);
  
      }
  
      // Prevent the form from submitting:
      return false;
  
  }); // Form submission
  
  }); // Document ready.
  
  // Function handles the Stripe response:
  function stripeResponseHandler(status, response) {
  
  // Check for an error:
  if (response.error) {
  
      reportError(response.error.message);
  
  } else { // No errors, submit the form:
  
    var f = $("#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
    f.append("&lt;input type='hidden' name='stripeToken' value='" + token + "' /&gt;");
  
    // Submit the form:
    f.get(0).submit();
  
  }
  
  } // End of stripeResponseHandler() function.
  </code></pre>
  
  <p>and billing.php:</p>
  
  <pre><code>&lt;?php
  $userID = (int) $_GET['id'];
  require('../inc/connect/config.php');
  require_once('inc/stripe-php/init.php');
  
  session_start();
  \Stripe\Stripe::setApiKey(STRIPE_PRIVATE_KEY);
  
  if ($_SERVER['REQUEST_METHOD'] == 'POST') {
  $errors = array();
  if (isset($_POST['stripeToken'])) {
      $token = $_POST['stripeToken'];
  } else {
      $errors['token'] = 'Your payment details cannot be processed. You have not been charged. 
                          Please confirm that you have JavaScript enabled and try again.';
  }
  } // End of form submission conditional.
  
  // Create a Customer
  $customer = \Stripe\Customer::create(array(
  "source" =&gt; $token,
  "description" =&gt; "Example customer")
  );
  $custID = $customer-&gt;id;
  
  try {
  $sql = 'INSERT INTO users(cust) VALUES(:cust) WHERE id LIKE :id';
  $query = $db-&gt;prepare($sql);
  $query-&gt;execute(array(':cust'=&gt;$custID, ':id'=&gt;$userID));
  header('Location: ../admin/signup.php?joined');
  } catch (PDOException $e) {
  echo 'failed to save customer id to db';
  }
  
  ?&gt;
  </code></pre>