The Error I am getting when I try to checkout after putting card details:
Invalid source object: must be a dictionary or a non-empty string. See API docs at https://stripe.com/docs'
Here I taking all the card information:
<form method="post" action="{{route('checkout')}}" enctype="multipart/form-data" id="checkout-form">
#csrf
<div class="col-sm-3">
<div class="form-group">
<label>Card Number*</label>
<input type="text" class="form-control" name="card-number" id="card-number" placeholder="4111 1111 1111 1111"> </div>
</div>
<div class="col-sm-3">
<div class="form-group">
<label>Card CVC*</label>
<input type="text" class="form-control" name="card-cvc" id="card-cvc" placeholder="111"> </div>
</div>
<div class="col-sm-3">
<div class="form-group">
<label>Card Expiry Month*</label>
<input type="text" class="form-control" name="card-month" id="card-month" placeholder="12"> </div>
</div>
<div class="col-sm-3">
<div class="form-group">
<label>Card Expiry Year*</label>
<input type="text" class="form-control" name="card-expiry-year" id="card-expiry-year" placeholder="2020"> </div>
</div>
<div class="col-sm-6">
<div class="form-group">
<label>Card Name*</label>
<input type="text" class="form-control" name="card-name" id="card-name" placeholder="John"> </div>
</div>
</form>
I am sending the Token through script:
<script>
var stripe = Stripe('test_key');
var $form = $('#checkout-form');
$form.submit(function (event) {
$('charge-error').addClass('hidden');
$form.find('button').prop('disabled' , true);
Stripe.card.createToken({
number: $('.card-number').val(),
cvc: $('.card-cvc').val(),
exp_month: $('.card-expiry-month').val(),
exp_year: $('.card-expiry-year').val(),
name: $('.card-name').val(),
}, stripeResponseHandler);
return false;
});
function stripeResponseHandler(status, response) {
var $form = $('#checkout-form');
if (response.error){
$('.charge-error').removeClass('hidden');
$('.charge-error').text(response.error.message);
$form.find('button').prop('disabled', false);
} else {
var token = response.id;
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
//Submit the form:
$form.get(0).submit();
}
}
and this is the controller Function:
$stripe = new \Stripe\StripeClient('secret_test_key');
try {
$charge = $stripe->charges->create([
"amount" => 6800,
"currency" => "usd",
"source" => $request->input('stripeToken'),
"description" => "Charge for test#expamle.com"
]
);
} catch (\Exception $e) {
return redirect()->route('checkout')->with('error', $e->getMessage());
}
If the replace the "source" => $request->input('stripeToken'), with "source" => "visa", then the code works fine.
Why am I getting this error? Please help.
If you're using Stripe.js v2 you need to set the publishable key like this:
Stripe.setPublishableKey('pk_test_xxx');
not what you're currently doing:
var stripe = Stripe('test_key');
(see https://stripe.com/docs/stripe-js/v2#setting-publishable-key)
At the line where you have "source" => $request->input('stripeToken') try to print that input out before carrying out the charge to see if the value is actually there or is in a valid format. If the value is not there ensure the variable you have called token assigned to the hidden field actually has the correct value.
Related
I'm working with DOM and web API to POST some information about the company like name, worker's name.
But when I write something in the input DOM can't reach the value and return empty so I post an empty object.
That looks like :
adress: ""
companyName: ""
contactName: ""
contactTitle: ""
My form block:
<form>
<div class="form-group">
<label for="">Company Name</label>
<input
type="text"
class="form-control"
id="companyName"
placeholder="Company Name!"
/>
</div>
<div class="form-group">
<label for="">Contact Name</label>
<input
type="text"
class="form-control"
id="contactName"
placeholder="Contact Name!"
value=""
/>
</div>
<div class="form-group">
<label for="">Contact Title</label>
<input
type="text"
class="form-control"
id="contactTitle"
placeholder="Contact Title!"
/>
</div>
<div class="form-group">
<label for="">Country</label>
<input
type="text"
class="form-control"
id="inputCountry"
placeholder="Country!"
/>
</div>
</form>
And my JS code:
'use strict';
let inputCompanyName = document.getElementById('companyName');
let inputContactName = document.getElementById('contactName');
let inputContactTitle = document.getElementById('contactTitle');
let country = document.getElementById('inputCountry');
const btnSubmit = document.getElementById('submit');
let newCompany = {
companyName: inputCompanyName.value,
contactName: inputContactName.value,
contactTitle: inputContactTitle.value,
adress: country.value,
};
btnSubmit.addEventListener('click', e => {
e.preventDefault();
axios
.post('https://northwind.vercel.app/api/suppliers', newCompany)
.then(res => {
console.log('Response', res.data);
alert('Success!');
});
});
I tried innerHTML and innerText and form method but I cant solve this problem.
You're reading the values immediately upon loading the page, long before the user has had a chance to enter any values.
Instead, read the values in the click event:
btnSubmit.addEventListener('click', e => {
let newCompany = {
companyName: inputCompanyName.value,
contactName: inputContactName.value,
contactTitle: inputContactTitle.value,
adress: country.value,
};
// the rest of the click handler logic...
});
I can't get the values of these three fields; it only returns an empty value (a space).
The ids are correctly set in the form.
<script>
const data = {
id: document.getElementById('idbook').value,
name: document.getElementById('namebook').value,
price: document.getElementById('pricebook').value
};
function myFunction(){
const http = new easyHTTP;
http.put('https://otg0gf6qw5.execute-api.us-east-2.amazonaws.com/books',
data, function(err, post){
if(err) {
console.log(err);
} else {
console.log(post);
}
});
</script>
<!DOCTYPE html>
<html>
<body>
<div class="container">
<form method="post" id="save" action="javascript:myFunction()">
<h1>Insert Book</h1>
<div class="field">
<label for="id">ID Book:</label>
<input type="text" id="idbook" name="id"/>
<small></small>
</div>
<div class="field">
<label for="id">Name Book:</label>
<input type="text" id="namebook" name="nameBook"/>
<small></small>
</div>
<div class="field">
<label for="id">Price Book:</label>
<input type="text" id="pricebook" name="priceBook"/>
<small></small>
</div>
<div class="field">
<button type="submit" class="full">SAVE BOOK</button>
</div>
</form>
</div>
When I enter the values, and click on SAVE I get an empty json, i.e .:
{"id":"","name":"","price":""}
with error:
"One or more parameter values are not valid. The AttributeValue for a key attribute cannot contain an empty string value. Key: id"
The problem is that you are getting the values from the input fields as soon as the script runs, so you will get empty strings because the inputs at that point are empty.
To get the input values after the form is submitted, put the data variable inside the myFunction() method, it's important to read the values right before sending the data.
Example
<script>
function myFunction() {
const data = {
id: document.getElementById('idbook').value,
name: document.getElementById('namebook').value,
price: document.getElementById('pricebook').value
};
const http = new easyHTTP;
http.put('https://otg0gf6qw5.execute-api.us-east-2.amazonaws.com/books', data, function(err, post) {
if(err) {
console.log(err);
} else {
console.log(post);
}
});
};
</script>
I don't know if this is what you mean, but I did let the data save in the console log when you press submit
<div class="container">
<form method="post" id="save" action="javascript:myFunction()">
<h1>Insert Book</h1>
<div class="field">
<label for="id">ID Book:</label>
<input type="text" id="idbook" name="id"/>
<small></small>
</div>
<div class="field">
<label for="id">Name Book:</label>
<input type="text" id="namebook" name="nameBook"/>
<small></small>
</div>
<div class="field">
<label for="id">Price Book:</label>
<input type="text" id="pricebook" name="priceBook"/>
<small></small>
</div>
<div class="field">
<button type="submit" class="full">SAVE BOOK</button>
</div>
</form>
<script>
function myFunction(){
const data = {
id: document.getElementById('idbook').value,
name: document.getElementById('namebook').value,
price: document.getElementById('pricebook').value
};
console.log(data);
}
</script>
</div></body></html>
I'm using validate.js for form validation . I also tried jQuery and form validation it throws the validation message "this field is required" so , i have tried for the first time the validate.js. My requirement is the input box should be red and the error messages should not be displayed .
here is my script for reference ,
<script src="<?php echo base_url(); ?>js/validate.js"></script>
<script>
(function() {
// These are the constraints used to validate the form
var constraints = {
email: {
// Email is required
presence: true,
// and must be an email (duh)
email: true
},
password: {
// Password is also required
presence: true,
// And must be at least 5 characters long
length: {
minimum: 5
}
},
"confirm-password": {
// You need to confirm your password
presence: true,
// and it needs to be equal to the other password
equality: "password"
},
username: {
// You need to pick a username too
presence: true,
// And it must be between 3 and 20 characters long
length: {
minimum: 3,
maximum: 20
},
format: {
// We don't allow anything that a-z and 0-9
pattern: "[a-z0-9]+",
// but we don't care if the username is uppercase or lowercase
flags: "i",
message: "can only contain a-z and 0-9"
}
},
country: {
// You also need to input where you live
presence: true,
// And we restrict the countries supported to Sweden
inclusion: {
within: ["SE"],
// The ^ prevents the field name from being prepended to the error
message: "^Sorry, this service is for Sweden only"
}
},
zip: {
// Zip is optional but if specified it must be a 5 digit long number
format: {
pattern: "\\d{5}"
}
},
"number-of-children": {
// You don't have to input the number of children but it you do
// you need to input an integer > 0
numericality: {
onlyInteger: true,
greaterThanOrEqualTo: 0
}
}
};
// Hook up the form so we can prevent it from being posted
document.querySelector("form#main")
.addEventListener("submit", function(ev) {
ev.preventDefault();
handleFormSubmit(this);
});
function handleFormSubmit(form) {
// First we gather the values from the form
var values = validate.collectFormValues(form);
// then we validate them against the constraints
var errors = validate(values, constraints);
// then we update the form to reflect the results
showErrors(form, errors || {});
// And if all constraints pass we let the user know
if (!errors) {
showSuccess();
}
}
// Updates the inputs with the validation errors
function showErrors(form, errors) {
// We loop through all the inputs and show the errors for that input
_.each(form.querySelectorAll("input[name], select[name]"), function(input) {
// Since the errors can be null if no errors were found we need to handle
// that
showErrorsForInput(input, errors && errors[input.name]);
});
}
// Shows the errors for a specific input
function showErrorsForInput(input, errors) {
// This is the root of the input
var formGroup = closestParent(input.parentNode, "form-group")
// Find where the error messages will be insert into
, messages = formGroup.querySelector(".messages");
// First we remove any old messages and resets the classes
resetFormGroup(formGroup);
// If we have errors
if (errors) {
// we first mark the group has having errors
formGroup.classList.add("has-error");
// then we append all the errors
_.each(errors, function(error) {
addError(messages, error);
});
} else {
// otherwise we simply mark it as success
formGroup.classList.add("has-success");
}
}
// Recusively finds the closest parent that has the specified class
function closestParent(child, className) {
if (!child || child == document) {
return null;
}
if (child.classList.contains(className)) {
return child;
} else {
return closestParent(child.parentNode, className);
}
}
function resetFormGroup(formGroup) {
// Remove the success and error classes
formGroup.classList.remove("has-error");
formGroup.classList.remove("has-success");
// and remove any old messages
_.each(formGroup.querySelectorAll(".help-block.error"), function(el) {
el.parentNode.removeChild(el);
});
}
// Adds the specified error with the following markup
// <p class="help-block error">[message]</p>
function addError(messages, error) {
var block = document.createElement("p");
block.classList.add("help-block");
block.classList.add("error");
block.innerHTML = error;
messages.appendChild(block);
}
function showSuccess() {
// We made it \:D/
alert("Success!");
}
})();
</script>
My form
<form id="main" class="form-horizontal" action="/example" method="post" novalidate>
<div class="form-group">
<label class="col-sm-2 control-label" for="email">Email</label>
<div class="col-sm-5">
<input id="email" class="form-control" type="email" placeholder="Email" name="email">
</div>
<div class="col-sm-5 messages"></div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="password">Password</label>
<div class="col-sm-5">
<input id="password" class="form-control" type="password" placeholder="Password" name="password">
</div>
<div class="col-sm-5 messages"></div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="confirm-password">Confirm password</label>
<div class="col-sm-5">
<input id="confirm-password" class="form-control" type="password" placeholder="Confirm password" name="confirm-password">
</div>
<div class="col-sm-5 messages"></div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="username">Username</label>
<div class="col-sm-5">
<input id="username" class="form-control" type="text" placeholder="Username" name="username">
</div>
<div class="col-sm-5 messages">
</div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="birthdate">Birthdate</label>
<div class="col-sm-5">
<input id="birthdate" class="form-control" type="date" placeholder="YYYY-MM-DD" name="birthdate">
</div>
<div class="col-sm-5 messages"></div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="country">Country</label>
<div class="col-sm-5">
<select id="country" class="form-control" name="country">
<option value=""></option>
<option value="CA">Canada</option>
<option value="SE">Sweden</option>
<option value="US">United States</option>
</select>
</div>
<div class="col-sm-5 messages"></div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="zip">ZIP Code</label>
<div class="col-sm-5">
<input id="zip" class="form-control" type="text" placeholder="12345" name="zip">
</div>
<div class="col-sm-5 messages"></div>
</div>
<div class="form-group">
<label class="col-sm-2 control-label" for="number-of-children">Number of children</label>
<div class="col-sm-5">
<input id="number-of-children" class="form-control" type="number" placeholder="Number of children" name="number-of-children">
</div>
<div class="col-sm-5 messages"></div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" class="btn btn-default">Submit</button>
</div>
</div>
</form>
</div>
I'm getting this error in console
while submitting the form error is triggered. I dont know where the problem is !
I have a form where I am using dropzone.js for file upload. Now I am validating all the input fields. But i'm not able to validate the file before submission. If the file is uploaded, then the submission should work. Otherwise it should throw an error like - "please upload the file". How can i achieve this?
HTML code:
<form action="/action">
<div class="form-row">
<div class="form-group col-md-6">
<input type="text" class="form-control" id="first_name" name="first_name" placeholder="First Name" required>
</div>
<div class="form-group col-md-6">
<input type="text" class="form-control" id="last_name" name="last_name" placeholder="Last Name" required>
</div>
</div>
<div class="form-row">
<div class="form-group col-md-12">
<textarea class="form-control" id="message" name="message" placeholder="Message"></textarea>
</div>
</div>
<div class="form-row">
<div id="resume" class="dropzone form-control"></div>
</div>
<input type="submit" class="btn btn-primary mt-10" id="item-submit" value="submit">
</form>
Javascript :
<script type="text/javascript">
$(document).ready(function () {
$("div#resume").dropzone({ url: "/change-this-later" });
var dropzone3;
Dropzone.autoDiscover = false;
dropzone3 = new Dropzone('#resume', {
maxFiles: 1,
});
$('#item-submit').click(function(e) {
e.preventDefault();
e.stopPropagation();
if ($('form#resume').valid()) {};
});
});
</script>
You can add a callback event which is called if the upload is successful
//indicates file upload is complete and is successful
var uploaded = false;
$("div#resume").dropzone({
url: "/change-this-later",
success: function (file, response) {
uploaded = true;
}
});
//Check the value of 'uploaded' when validating rest of fields
So I come around this. Since I submit all my images and fields in the same button, I just acceded to the files array in side the dropzone and validate that it's lenght wasn't 0. $animalImage is my dropzone.
var validateImages = function (animal) {
if ($animalImage.files.length == 0) {
swal({
title: 'Advertencia',
type: 'info',
html: "Debe de guardar al menos una imágen",
showCloseButton: true,
focusConfirm: false
});
return false;
}
return animal;
};
Hope it helps, side note a submit trough ajax so I just used dropzone for the user experience.
I am implementing Google's Invisible Recaptcha and I am trying to have everything run from my mail.js file (and I would really prefer to keep it there). For some reason Recaptcha is not finding "onSuccess" in mail.js but if I move it to the HTML inside <script></script> it works.
I am getting this error in JavaScript console: ReCAPTCHA couldn't find user-provided function: onSuccess when it is in mail.js
$(".input-field").each(function () {
var $this = $(this);
if ($this.val().length) {
$this.parent().addClass("input--filled")
}
$this.on("focus", function () {
$this.parent().addClass("input--filled");
});
$this.on("blur", function () {
if (!$this.val().length) {
$this.parent().removeClass("input--filled")
}
})
});
$(function () {
// Get the form.
var form = $('#ajax-contact'),
// Get the messages div.
formMessages = $('#form-messages');
// Set up an event listener for the contact form.
$(form).submit(function (e) {
// Stop the browser from submitting the form.
grecaptcha.execute();
e.preventDefault();
});
});
var onSuccess = function(response) {
$("#btn-submit").addClass("btn-loading");
// Serialize the form data.
var formData = $(form).serialize();
// Submit the form using AJAX.
$.ajax({
type: 'POST',
url: $(form).attr('action'),
data: formData
})
.done(function (response) {
// Make sure that the formMessages div has the 'success' class.
$(formMessages).removeClass('error').addClass('success').fadeIn().delay(5000).fadeOut();
// Set the message text.
$(formMessages).text(response);
// Clear the form.
$(form).trigger("reset");
grecaptcha.reset();
$("#btn-submit").removeClass("btn-loading");
})
.fail(function (data) {
// Make sure that the formMessages div has the 'error' class.
$(formMessages).removeClass('success').addClass('error').fadeIn().delay(5000).fadeOut();
// Set the message text.
if (data.responseText !== '') {
$(formMessages).text(data.responseText);
} else {
$(formMessages).text('Oops! An error occured and your message could not be sent.');
}
$("#btn-submit").removeClass("btn-loading");
});
};
here is the HTML:
<form id="ajax-contact" class="" method="post" action="mailer.php">
<fieldset>
<div class="row">
<div class="input col-xs-12 col-sm-12 padding-bottom-xs-50 padding-bottom-40">
<label class="input-label" for="name">
<span class="input-label-content font-second" data-content="name">name *</span>
</label>
<input class="input-field" type="text" name="name" id="name" required />
</div>
<div class="input col-xs-12 col-sm-6 padding-bottom-xs-50 padding-bottom-50">
<label class="input-label" for="email">
<span class="input-label-content font-second" data-content="email">email *</span>
</label>
<input class="input-field" type="email" name="email" id="email" required />
</div>
<div class="input col-xs-12 col-sm-6 padding-bottom-xs-60 padding-bottom-50">
<label class="input-label" for="company">
<span class="input-label-content font-second" data-content="company">company</span>
</label>
<input class="input-field" type="text" name="company" id="company" />
</div>
<div class="message col-xs-12 col-sm-12 padding-bottom-xs-40 padding-bottom-30">
<label class="textarea-label font-second" for="message">message *</label>
<textarea class="input-field textarea" name="message" id="message" required></textarea>
</div>
</div>
<div class="g-recaptcha" data-sitekey="6Lf-6XQUAAAAAGhsZxXTlA3MtMGr_xDhOXPG-Ds0" data-badge="inline" data-size="invisible" data-callback="onSuccess"></div>
<div id="form-messages" class="form-message"></div>
<div class="col-xs-12 margin-top-30 text-center">
<button id="btn-submit" type="submit" class="btn btn-animated btn-contact ripple-alone" data-text="send it"><span class="btn-icon"><span class="loader-parent"><span class="loader3"></span></span>
</span>
</button>
</div>
</fieldset>