Reputation: 13
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:
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.
Thanks in advance
Kaylee
Here is my code so far:
payment page, with form:
<?php $userID = (int) $_GET['id'];
require('../inc/connect/config.php');
?>
<header>
<!-- CSS -->
<link href="admin.css" rel="stylesheet">
<link href="bootstrap.min.css" rel="stylesheet">
<script type="text/javascript" src="https://js.stripe.com/v2/"></script>
<?php
echo '<script type="text/javascript">
Stripe.setPublishableKey("' . STRIPE_PUBLIC_KEY . '");
</script>';
?>
<script type="text/javascript" src="../js/billing.js"></script>
</header>
<body>
<form action="billing.php?id=<?php echo $userID; ?>" method="POST" id="payment-form">
<span id="payment-errors" class=""></span>
<div class="form-row">
<label>
<span>Card Number</span>
<input type="text" size="20" data-stripe="number" class="card-number">
</label>
</div>
<div class="form-row">
<label>
<span>Expiration (MM/YY)</span>
<input type="text" size="2" data-stripe="exp_month" class="card-expiry-month">
</label>
<span> / </span>
<input type="text" size="2" data-stripe="exp_year" class="card-expiry-year">
</div>
<div class="form-row">
<label>
<span>CVC</span>
<input type="text" size="4" data-stripe="cvc" class="card-cvc">
</label>
</div>
<input id="submitBtn" type="submit" class="submit" value="Submit Payment">
</form>
</body>
billing.js:
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("<input type='hidden' name='stripeToken' value='" + token + "' />");
// Submit the form:
f.get(0).submit();
}
} // End of stripeResponseHandler() function.
and billing.php:
<?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" => $token,
"description" => "Example customer")
);
$custID = $customer->id;
try {
$sql = 'INSERT INTO users(cust) VALUES(:cust) WHERE id LIKE :id';
$query = $db->prepare($sql);
$query->execute(array(':cust'=>$custID, ':id'=>$userID));
header('Location: ../admin/signup.php?joined');
} catch (PDOException $e) {
echo 'failed to save customer id to db';
}
?>
Upvotes: 0
Views: 1235
Reputation: 13
here is the updated php:
<?php
$userID = (int) $_GET['id'];
require('../inc/connect/config.php');
require_once('inc/stripe-php/init.php');
session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$errors = array();
if (isset($_POST['stripeToken'])) {
$token = $_POST['stripeToken'];
// Check for a duplicate submission, just in case:
// Uses sessions, you could use a cookie instead.
if (isset($_SESSION['token']) && ($_SESSION['token'] == $token)) {
$errors['token'] = 'You have apparently resubmitted the form. Please do not do that.';
} else { // New submission.
$_SESSION['token'] = $token;
}
} else {
$errors['token'] = 'Your payment details cannot be processed. You have not been charged.
Please confirm that you have JavaScript enabled and try again.';
}
if(empty($errors)) {
\Stripe\Stripe::setApiKey(STRIPE_PRIVATE_KEY);
// Create a Customer
$customer = \Stripe\Customer::create(array(
"source" => $token,
"description" => "Example customer")
);
$custID = $customer->id;
try {
$sql = 'INSERT INTO users(cust) VALUES(:cust) WHERE id LIKE :id';
$query = $db->prepare($sql);
$query->execute(array(':cust'=>$custID, ':id'=>$userID));
header('Location: ../admin/signup.php?joined');
} catch (PDOException $e) {
echo 'failed to save customer id to db';
}
}
} // End of form submission conditional.
?>
Upvotes: 0