My aim to to verify a users card information and store that info in a customer object.
I run a pay-upon delivery service and am building a hack to protect against fake orders (we can charge people via the strip dashboard if they place false orders or don't show up).
A full stripe integration is the long term goal, but I need something ASAP. I've read (re-read) the the docs but am having trouble.
The simple stripe checkout works great, but I am clueless about how to create a customer from there.
Script:
<form action="/charge" method="POST">
<script
src="https://checkout.stripe.com/checkout.js" class="stripe-button"
data-key="TEST KEY"
data-image="/square-image.png"
data-name="Food Bazooka"
data-description="Customer Verification. No charges :)"
data-panel-label="Confirm and Verify"
data-label="Confirm">
</script>
</form>
Any feedback or ideas are greatly appreciated.
Thanks!
You're using the embedded form, where as you need to use custom forms and some server side code.
You would need first create a single use token which represents a customer card from your form
(Assuming your form contains credit card number, expiry date etc...)
Taken from the docs:
Form markup:
<form action="/customer" method="POST" id="payment-form">
<span class="payment-errors"></span>
<div class="form-row">
<label>
<span>Card Number</span>
<input type="text" size="20" data-stripe="number"/>
</label>
</div>
<div class="form-row">
<label>
<span>CVC</span>
<input type="text" size="4" data-stripe="cvc"/>
</label>
</div>
<div class="form-row">
<label>
<span>Expiration (MM/YYYY)</span>
<input type="text" size="2" data-stripe="exp-month"/>
</label>
<span> / </span>
<input type="text" size="4" data-stripe="exp-year"/>
</div>
<button type="submit">Submit Payment</button>
</form>
Javascript:
jQuery(function($) {
$('#payment-form').submit(function(event) {
var $form = $(this);
// Disable the submit button to prevent repeated clicks
$form.find('button').prop('disabled', true);
Stripe.card.createToken($form, stripeResponseHandler);
// Prevent the form from submitting with the default action
return false;
});
});
function stripeResponseHandler(status, response) {
var $form = $('#payment-form');
if (response.error) {
// Show the errors on the form
$form.find('.payment-errors').text(response.error.message);
$form.find('button').prop('disabled', false);
} else {
// response contains id and card, which contains additional card details
var token = response.id;
// Insert the token into the form so it gets submitted to the server
$form.append($('<input type="hidden" name="stripeToken" />').val(token));
// and submit
$form.get(0).submit();
}
};
This essentially takes your form, and adds a hidden field called stripeToken before submitting
Notice the form action is /customer
I see you're using Ruby On Rails from your tag - so you would need to handle the customer POST with a controller
This is what you'll need to do:
https://stripe.com/docs/tutorials/charges#saving-credit-card-details-for-later
# Set your secret key: remember to change this to your live secret key in production
# See your keys here https://dashboard.stripe.com/account
Stripe.api_key = "sk_test_X9S2nHIxFy399uoNvakwJYSn"
# Get the credit card details submitted by the form
# notice stripeToken - this is the hidden field
token = params[:stripeToken]
# Create a Customer
customer = Stripe::Customer.create(
:card => token,
:description => "payinguser#example.com"
)
# Charge the Customer instead of the card
# ** I have commented this block out, as you say you do not want to charge the customer
# Stripe::Charge.create(
# :amount => 1000, # incents
# :currency => "gbp",
# :customer => customer.id
# )
# Save the customer ID in your database so you can use it later
save_stripe_customer_id(user, customer.id)
Related
I have a form with id theForm which has the following div with a submit button inside:
<div id="placeOrder"
style="text-align: right; width: 100%; background-color: white;">
<button type="submit"
class='input_submit'
style="margin-right: 15px;"
onClick="placeOrder()">Place Order
</button>
</div>
When clicked, the function placeOrder() is called. The function changes the innerHTML of the above div to be "processing ..." (so the submit button is now gone).
The above code works, but now the problem is that I can't get the form to submit! I've tried putting this in the placeOrder() function:
document.theForm.submit();
But that doesn't work.
How can I get the form to submit?
Set the name attribute of your form to "theForm" and your code will work.
You can use...
document.getElementById('theForm').submit();
...but don't replace the innerHTML. You could hide the form and then insert a processing... span which will appear in its place.
var form = document.getElementById('theForm');
form.style.display = 'none';
var processing = document.createElement('span');
processing.appendChild(document.createTextNode('processing ...'));
form.parentNode.insertBefore(processing, form);
It works perfectly in my case.
document.getElementById("form1").submit();
Also, you can use it in a function as below:
function formSubmit()
{
document.getElementById("form1").submit();
}
document.forms["name of your form"].submit();
or
document.getElementById("form id").submit();
You can try any of this...this will definitely work...
I will leave the way I do to submit the form without using the name tag inside the form:
HTML
<button type="submit" onClick="placeOrder(this.form)">Place Order</button>
JavaScript
function placeOrder(form){
form.submit();
}
You can use the below code to submit the form using JavaScript:
document.getElementById('FormID').submit();
<html>
<body>
<p>Enter some text in the fields below, and then press the "Submit form" button to submit the form.</p>
<form id="myForm" action="/action_page.php">
First name: <input type="text" name="fname"><br>
Last name: <input type="text" name="lname"><br><br>
<input type="button" onclick="myFunction()" value="Submit form">
</form>
<script>
function myFunction() {
document.getElementById("myForm").submit();
}
</script>
</body>
</html>
HTML
<!-- change id attribute to name -->
<form method="post" action="yourUrl" name="theForm">
<button onclick="placeOrder()">Place Order</button>
</form>
JavaScript
function placeOrder () {
document.theForm.submit()
}
If your form does not have any id, but it has a class name like theForm, you can use the below statement to submit it:
document.getElementsByClassName("theForm")[0].submit();
I have came up with an easy resolve using a simple form hidden on my website with the same information the users logged in with. Example: If you want a user to be logged in on this form, you can add something like this to the follow form below.
<input type="checkbox" name="autologin" id="autologin" />
As far I know I am the first to hide a form and submit it via clicking a link. There is the link submitting a hidden form with the information. It is not 100% safe if you don't like auto login methods on your website with passwords sitting on a hidden form password text area...
Okay, so here is the work. Let’s say $siteid is the account and $sitepw is password.
First make the form in your PHP script. If you don’t like HTML in it, use minimal data and then echo in the value in a hidden form. I just use a PHP value and echo in anywhere I want pref next to the form button as you can't see it.
PHP form to print
$hidden_forum = '
<form id="alt_forum_login" action="./forum/ucp.php?mode=login" method="post" style="display:none;">
<input type="text" name="username" id="username" value="'.strtolower($siteid).'" title="Username" />
<input type="password" name="password" id="password" value="'.$sitepw.'" title="Password" />
</form>';
PHP and link to submit form
<?php print $hidden_forum; ?>
<pre>Forum</pre>
I am working on reactive form like In my reactive form having 3 fields but in which 2 are mandatory and one is non mandatory but it has validation like if user enter a string in respective field it has minimum character limit example 10 character. but i faced issue when user has enter string it is showing error but submit button is not going to disable.
return FormBuilder.group({
'surveyDueDate': ['', Validators.required],
'rfsDueDate': [null, Validators.required],
'comment': [null]
});
<form (ngSubmit)="submit(form)" #form="ngForm">
<div>
Survey date:
<input name="surveyDueDate" [(ngModel)]="surveyDueDate">
</div>
<div>
Due Date :
<input name="rfsDueDate" [(ngModel)]="rfsDueDate">
</div>
<div>
Gift shipping address:
<input name="comment">
</div>
<button type="submit" [disabled]="form.invalid">Register now!</button>
</form>
thanks in advance.
In your component listen for the particular field changes. For example,
this.form.controls["comment"].valueChanges().subscribe((commentValue)=>{
if(commentValue && commentValue.length>10 && this.form.invalid===false){
this.form.controls["comment"].setErrors({invalid:true});
} else {
this.form.controls["comment"].setErrors(null);
}
});
In an effort to learn about realtime apps, I am trying to create a basic messageboard using Entangled.
I have an Angular app and a Rails backend with a Messages Controller that includes Entangled::Controller. This Rails controller successfully receives a request when a form is submitted from the Angular app - the form is submitted using Entangled. (On clicking submit, a function is triggered in an Angular controller which should create a new message in the backend and update all clients subscribed to that backend.)
I know the Angular function is being triggered on clicking submit, and I know the function receives the correct information from the form: console.log($scope.message) displays {socket: "ws://message-board-olliehm.c9users.io:8080/messages", username: "ggg", content: "gggggg"} where I submit "ggg" in the username field and "gggggg" in the content field.
The problem is that these fields are not arriving at the Rails controller. When I click submit, the correct action is triggered in the Rails controller, but the params don't contain the right information: p params in def create returns {"controller"=>"messages", "action"=>"create"}, with no "message" hash and no "username" or "content" keys.
I cannot work out what Entangled is doing with the username and content fields.
Redis is new to me so I'm not sure if the problem is there. I have Redis installed and the redis-server is running as required by Entangled. I have a redis initializer as below, which in the Rails console is successfully connecting and letting me put data in the database:
$redis = Redis.new(:host => $IP, :port => 6379)
Here's my Angular controller:
var controllers = angular.module('controllers');
controllers.controller('MessageboardController', ['$scope','Message', function($scope,Message){
$scope.message = Message.new();
$scope.post = function() {
console.log($scope.message);
$scope.message.$save(function() {
$scope.$apply(function() {
$scope.message = Message.new();
});
});
};
Message.all(function(err, messages) {
$scope.$apply(function() {
$scope.messages = messages;
});
});
}]);
Message here refers to this factory:
messageboard.factory('Message', function(Entangled){
return new Entangled('ws://message-board-olliehm.c9users.io:8080/messages');
});
And here's my Angular view:
<h1>Messageboard</h1>
<section class='row' ng-if='messages'>
<ul>
<li ng-repeat='message in messages'>
{{message.username}}
{{message.content}}
</li>
</ul>
</section>
<section class='row'>
<form ng-submit="post()">
<div class='form-group'>
<label for='username'>Message as</label>
<input ng-model='message.username' name='username' type='text'>
</div>
<div class='form-group'>
<input ng-model='message.content' name='message' type='text' placeholder='Write your message here'>
</div>
<div class='form-group'>
<input type="submit">
</div>
</form>
</section>
Advice would be hugely appreciated - this has caused prolonged frustration and I'm very keen to get stuck into creating something with realtime updates.
After much trial and error I realised the empty params apparently received by the backend controller were misleading. The params arrive properly and a new message object is created and broadcast as long as I do the following to the raw params the controller receives:
params.require(:message).permit(:content,:username)
i.e. exactly what you'd do with the form params arriving as you'd expect. The weird thing for me was that params doesn't include a 'message' hash until you require that hash as above. I guess this is something to do with it not being a regular http request, though a proper explanation would be appreciated...
I'm using the ng-token-auth module and the devise_token_auth gems.
The default behavior seems to be that when a user registers, the user gets sent an email with a confirmation link. I don't want this behavior; I just want the user to immediately be signed in following account creation, which is of course a really common way for account creation to work.
I'm so unsure how to achieve this that I don't even know what to ask. Would anyone happen to have used these libraries before who can provide some insight?
Jason, your answer is mostly correct. You will also need to instruct the server to bypass the email confirmation step. If this isn't done, the user won't be able to sign in until the link in the confirmation email has been visited. Here are the complete instructions:
1. Bypass email confirmation server-side
Assuming the model is called User, run the skip_confirmation! method as a pre-create callback. This really just sets the user's confirmed_at value to the current time, but the step is necessary to bypass email confirmation.
class User < ActiveRecord::Base
include DeviseTokenAuth::Concerns::User
before_create :skip_confirmation!
end
2. Sign in immediately after successful registration
Assuming the html form looks like this:
<form ng-submit="submitRegistration(registrationForm)" role="form" ng-init="registrationForm = {}">
<fieldset>
<div>
<label>email</label>
<input type="email" name="email" ng-model="registrationForm.email" required>
</div>
<div class="form-group">
<label>password</label>
<input type="password" name="password" ng-model="registrationForm.password" required>
</div>
<div class="form-group">
<label>password confirmation</label>
<input type="password" name="password_confirmation" ng-model="registrationForm.password_confirmation" required>
</div>
<button type="submit">Register</button>
</fieldset>
</form>
Update - as of devise_token_auth version 0.1.29.beta2, users will be automatically authenticated upon registration if the above before_create :skip_confirmation! callback is used. So the above code is all that is necessary.
Okay, I figured out the answer to my own question (natch).
I modified my controller to look like this:
'use strict';
/**
* #ngdoc function
* #name lunchHubApp.controller:UserRegistrationsCtrl
* #description
* # UserRegistrationsCtrl
* Controller of the lunchHubApp
*/
angular.module('lunchHubApp')
.controller('UserRegistrationsCtrl', ['$scope', '$rootScope', '$location', '$auth', function ($scope, $rootScope, $location, $auth) {
$scope.handleRegBtnClick = function() {
$auth.submitRegistration($scope.registrationForm)
.then(function() {
$auth.submitLogin({
email: $scope.registrationForm.email,
password: $scope.registrationForm.password
});
});
};
}]);
On a site it offers the option of changing your last name, to confirm this it sends a confirmation link to your email.
My question is, how do i figure out how the request is made (if it's POST or GET)? I monitored with live http headers, tamper data, fiddler and burp suite but all have shown there is 0 traffic. When i check my email, i have received the confirmation link.
Here is the html source code of the change lastname button:
<form>
<div class="m-lastname-updated">
<div class="m-h3">One more step</div><p>We have sent you a confirmation email. To change your last name click the sent link in your email!</p>
</div><div class="m-field m-lastname"><div class="m-h3">Last Name</div>
<span class="m-error"></span>
<input type="text" maxlength="100" class="m-input" name="lastname">
<p>Your last name is never shared</p></div><button style="display: inline-block;">Change</button>
</form>
Thanks to anyone who can help me understand how this request is made.
The url this is available on is in this example, http://example.com/profile/.
When a form is submitted, the request is done by default with method="GET" if the method is not specified as method="POST".
To see this, form example, if you use PHP script lastname.php as action:
<?php
echo "<pre>
\$_GET:";
print_r($_GET);
echo "</pre>";
echo "<pre>
\$_POST:";
print_r($_POST);
echo "</pre>";
?>
<form>
<div class="m-lastname-updated">
<div class="m-h3">One more step</div><p>We have sent you a confirmation email.
To change your last name click the sent link in your email!</p>
</div><div class="m-field m-lastname"><div class="m-h3">Last Name</div>
<span class="m-error"></span>
<input type="text" maxlength="100" class="m-input" name="lastname">
<p>Your last name is never shared</p></div><button style="display: inline- block;">Change</button>
</form>
You will see something like this:
$_GET:Array
(
[lastname] => mygod
)
$_POST:Array
(
)
$_GET is filled while $_POST contains no elements.