I am trying to get Stripe's Checkout Custom Button to charge a credit card but all it does is minimize after I enter the credit card details. I am using the code found in the documentation but I can't get it to work. The simple button is easy to use and I figured it would be as easy as just customizing that one but it's very different.
Here's the code:
Payment Page
<form action="charge.php" method="post">
<script src="https://checkout.stripe.com/checkout.js"></script>
<input type="submit" value="Pay with card" id="customButton"/>
<?php require_once('./config.php'); ?>
<script>
var handler = StripeCheckout.configure({
key: '<?php echo $stripe['publishable_key']; ?>',
image: 'favicon.png',
token: function(token, args) {
// Use the token to create the charge with a server-side script.
// You can access the token ID with `token.id`
}
});
document.getElementById('customButton').addEventListener('click', function(e) {
// Open Checkout with further options
handler.open({
name: 'Imprintnation',
description: 'Decals',
amount: <?php echo $stripeTotal; ?>
});
e.preventDefault();
});
</script>
</form>
Charge Page(charge.php)
<?php
require_once(dirname(__FILE__) . '/config.php');
$token = $_POST['stripeToken'];
$customer = Stripe_Customer::create(array(
'email' => 'customer#example.com',
'card' => $token
));
$charge = Stripe_Charge::create(array(
'customer' => $customer->id,
'amount' => 5000,
'currency' => 'usd'
));
echo '<h1>Successfully charged $5!</h1>';
?>
Configuration Page(config.php)
<?php
require_once('./lib/Stripe.php');
$stripe = array(
secret_key => 'sk_test_************************',
publishable_key => 'pk_test_************************'
);
Stripe::setApiKey($stripe['secret_key']);
?>
What am I missing here? I can't even get it to retrieve a token.
How can I retrieve a token and charge a card?
Finally got it to work. Had to change a bunch of it. Here is the code:
Payment page
<form action="charge.php" method="post">
<script src="https://checkout.stripe.com/checkout.js"></script>
<script src="http://code.jquery.com/jquery-latest.min.js"></script>
<button id="customButton">Pay with Card</button>
<style>
#customButton{
width:300px;
height:50px;
background-color:orange;
color:white;
border:2px solid green;
}
</style>
<script>
$('#customButton').click(function(){
var token = function(res){
var $input = $('<input type=hidden name=stripeToken />').val(res.id);
$('form').append($input).submit();
};
StripeCheckout.open({
key: '<?php echo $stripe['publishable_key']; ?>',
address: false,
amount: '<?php echo $price; ?>',
currency: 'usd',
name: 'test',
description: '<?php echo $desc; ?>',
panelLabel: 'Checkout',
token: token
});
return false;
});
</script>
<input type="hidden" name="desc" value="<?php echo $desc; ?>"/>
<input type="hidden" name="totalPrice" value="<?php echo $price; ?>"/>
</form>
charge.php
<?php
require_once(dirname(__FILE__) . '/config.php');
$token = $_POST['stripeToken'];
$amount = $_POST['totalPrice'];
$desc = $_POST['desc'];
$percent = "0.01";
$realAmount = $amount * $percent;
try {
$charge = Stripe_Charge::create(array(
'card' => $token,
'amount' => $amount,
'currency' => 'usd',
'description' => $desc
));
} catch(Stripe_CardError $e) {
// The card has been declined
}
echo "<h1>Successfully charged $$realAmount!</h1>";
?>
I wish Stripe's documentation was more straightforward but this code handles the charge and it logs it on your dashboard.
#BlueSix is right, why do you have:
<input type="hidden" name="totalPrice" value="<?php echo $price; ?>"/>
Just because the value is hidden, does not mean it cannot be edited by the end user.
It would be much better to set $amount = $price directly, passing the variable through your application backend.
Related
I used ckeditor 5 zip in my laravel project. but it was not working when I add image upload plugin from ckeditor cloudServices.
Here is the documentation
https://ckeditor.com/docs/ckeditor5/latest/features/image-upload/image-upload.html
my html code in blade.
<div class="form-group">
<label for="description">Description</label>
<textarea class="form-control" name="description" id="description"
rows="3">{{ old('description') }}</textarea>
</div>
here is my script
<script>
ClassicEditor
.create(document.querySelector('#description'), {
cloudServices: {
tokenUrl: '{{ csrf_token() }}',
uploadUrl: '{{ public_path('../../img/desc-img') }}'
}
})
.then(editor => {
window.editor = editor;
})
.catch(err => {
console.error(err.stack);
});
</script>
define your textarea
<textarea class="form-control" id="ckeditor" name="ckeditor"></textarea>
and instantiate the ckeditor using this code.
CKEDITOR.replace('ckeditor ', {
filebrowserUploadUrl: "{{route('ckeditor.image-upload', ['_token' => csrf_token() ])}}",
filebrowserUploadMethod: 'form'
});
then create the action for uploading images and define your route like so:
/**
* upload images from ckeditor.
*
* #param Request $request
* #return \Illuminate\Http\Response
*/
public function upload_images(Request $request)
{
$request->validate([
'upload' => 'image',
]);
if ($request->hasFile('upload')) {
$url = $request->upload->store('images');
$CKEditorFuncNum = $request->input('CKEditorFuncNum');
$url = asset('storage/' . $url);
$msg = 'Image successfully uploaded';
$response = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')</script>";
#header('Content-type: text/html; charset=utf-8');
return $response;
}
}
And that is it.
use these script to call Ckeditor
<script src="https://cdn.ckeditor.com/ckeditor5/22.0.0/classic/ckeditor.js"></script>
<script type="text/javascript">
CKEDITOR.replace('editor1', {
filebrowserUploadUrl: "{{route('ckeditor.upload', ['_token' => csrf_token() ])}}",
filebrowserUploadMethod: 'form'
});
</script>
and after put these code in your imageUploaderController
if($request->hasFile('upload')) {
$originName = $request->file('upload')->getClientOriginalName();
$fileName = pathinfo($originName, PATHINFO_FILENAME);
$extension = $request->file('upload')->getClientOriginalExtension();
$fileName = $fileName.'_'.time().'.'.$extension;
$request->file('upload')->move(public_path('images'), $fileName);
$CKEditorFuncNum = $request->input('CKEditorFuncNum');
$url = asset('images/'.$fileName);
$msg = 'Image uploaded successfully';
$response = "<script>window.parent.CKEDITOR.tools.callFunction($CKEditorFuncNum, '$url', '$msg')</script>";
#header('Content-type: text/html; charset=utf-8');
echo $response;
}
It works for me, try it.
And don't forget to stop script execution with exit.
if ($request->hasFile('upload')) {
//some code for uploading
echo $response;
exit;
}
I can save records in my custom table using $wpdb. One input of type submit is handled in javascript witch then uses fetch to send the data action and nonce to admin-ajax. My plugin has the add action function to sanitize and save the record in the database table.
I need to add a button that can delete that record which is where I am having problems. I have tried a separate php file but that cant find wpdb. So I am trying two buttons calling different actions but am unable to find suitable examples for wordpress ajax. My code is as follows
Form
<form id="changeCustAddr" action="#" method="post" data-url="<?php echo admin_url('/admin-ajax.php'); ?>">
<input type="hidden" name="action" value="cust_address">
<input type="hidden" name="nonce" value="<?php echo wp_create_nonce( 'cust_address_nonce' )?>">
<input type="hidden" id="record" name="record" value="<?php echo (!$newone) ? $rec : $max+1 ?>">
<input type="hidden" id="custno" name="custno" value="<?php echo $custno ?>">
input fields for addresses
Prev, Next and New buttons etc have been removed for clarity
<input type="submit" id="CustAddrDelete" name="delete" class="btn" value="Delete" data-url="<?php echo bloginfo('template_directory') ?>/scripts/deleteCustAddrform.php?cust=<?php echo $custno ?>&record=<?php echo $rec ?>" >
<input type="button" id="CustAddrNew" name="new" class="btn" value="New" data-url="<?php echo get_page_link( $post->ID ),'?cust=', $custno, '&record=new' ?>" >
<small class="field-msg js-form-submission">Submission in progress, Please wait …</small>
<small class="field-msg success js-form-success">Details Successfully submitted, thank you!</small>
<small class="field-msg error js-form-error">Could not update database. Please try again.</small>
<input type="submit" id="CustAddrSave" name="save" class="btn btn-blue" value="<?php echo (!$newone) ? 'Save' : 'Add New' ?>" data-action="cust_address">
<input type="button" id="CustAddrClose" name="close" class="btn btn-blue" value="<?php echo (!$newone) ? 'Close' : 'Discard Changes' ?>" data-url="<?php echo get_page_link( get_page_by_title( 'dojo details' )->ID ),'?cust=', $custno, '&record=1' ?>">
the javascript
document.addEventListener('DOMContentLoaded', function (e) {
const changeCustAddrFrm = document.getElementById('changeCustAddr');
if (changeCustAddrFrm) {
changeCustAddrFrm.addEventListener('submit', (e) => {
e.preventDefault();
let data = {
custno: changeCustAddrFrm.querySelector('[name="custno"]').value,
priority: changeCustAddrFrm.querySelector('[name="record"]').value,
address1: changeCustAddrFrm.querySelector('[name="address1"]').value,
... more address lines ...
postcode: changeCustAddrFrm.querySelector('[name="postcode"]').value,
}
// ajax http post request
let url = changeCustAddrFrm.dataset.url;
console.log(url);
let params = new URLSearchParams(new FormData(changeCustAddrFrm));
console.log(params);
changeCustAddrFrm.querySelector('.js-form-submission').classList.add('show');
fetch(url, {
method: "POST",
body: params
}).then(res => res.json())
.catch(error => {
resetMessages();
changeCustAddrFrm.querySelector('.js-form-error').classList.add('show');
})
.then(response => {
resetMessages();
if (response === 0 || response.status === 'error') {
changeCustAddrFrm.querySelector('.js-form-error').classList.add('show');
return;
}
changeCustAddrFrm.querySelector('.js-form-success').classList.add('show');
})
});
and the ajax called function
public function cust_address() {
if (!DOING_AJAX || !check_ajax_referer('cust_address_nonce', 'nonce')) {
return $this->return_json('error');
}
$custno = $_POST['custno'];
$addressno = $_POST['record'];
$max = $_POST['max'];
$servername = "localhost";
$username = "uuuu";
$password = "pppp";
$dbname = "db";
$mydb = new wpdb($username, $password, $dbname, $servername);
$table = 'mem_custaddress';
$data = [
'Address1' => sanitize_text_field($_POST['address1']),
// ... other address lines ...
'Postcode' => sanitize_text_field($_POST['postcode']),
];
$format = [ '%s', ... , '%s' ];
$where = [
'Custno' => $_POST['custno'],
'Priority' => $_POST['record']
];
$where_format = ['%d', '%d'];
if ($addressno <= $max) {
$result = $mydb->update($table, $data, $where, $format, $where_format);
} else {
$dataInsert = [
'Custno' => $_POST['custno'],
'Priority' => $_POST['record'],
'Address1' => $_POST['Address1'],
// ...
'Postcode' => $_POST['Postcode'],
];
$formatInsert = ['%d', '%d', '%s', ... , '%s'];
$result = $mydb->insert($table, $dataInsert, $formatInsert);
}
if ($result) {
return $this->return_json('success');
wp_die();
}
return $this->return_json('error');
wp_die();
}
public function return_json($status) {
$return = [
'status' => $status
];
wp_send_json($return);
wp_die();
}
How can I get the delete record to work?
after much searching I have come up with a solution. I hope someone can help tidy up the javascript. but the form data is now going to separate functions depending on the button pressed.
The form:
<form id="form1" data-url="<?php echo admin_url('/admin-ajax.php'); ?>">
<input type="text" name="field1" class="m-2 border-2">
<input type="text" name="field2" class="m-2 border-2">
<input id="s1" type="submit" name="press" value="Press" class="btn">
<input id="s2" type="submit" name="other" value="otherPress" class="btn">
</form>
The javascript:
const form1 = document.getElementById('form1'),
s1 = document.getElementById('s1'),
s2 = document.getElementById('s2');
s1.addEventListener('click', (e) =>{
e.preventDefault();
let f1data = new FormData(form1);
f1data.append('action', 'test');
let params = new URLSearchParams(f1data);
let url = form1.dataset.url;
fetch(url, {
method: 'post',
body: params
}).then(function (response){
return response.text();
}).then(function (text){
console.log('me', text);
}).catch(function (error){
console.error(error);
})
})
s2.addEventListener('click', (e) =>{
e.preventDefault();
let f1data = new FormData(form1);
f1data.append('action', 'other');
let params = new URLSearchParams(f1data);
let url = form1.dataset.url;
fetch(url, {
method: 'post',
body: params
}).then(function (response){
return response.text();
}).then(function (text){
console.log('me', text);
}).catch(function (error){
console.error(error);
})
})
and the ajax called functions:
add_action( 'wp_ajax_test', array($this, 'test') );
add_action( 'wp_ajax_other', array($this, 'other') );
public function test() {
var_dump($_POST);
}
public function other() {
var_dump($_POST);
}
So i just found out about the jquery auto complete and i would like to add it to my web-page. I want to hook it up to my php code so i can search my sql database. However Whenever i try to run my auto complete,it doesnt seem to find the php array im passing ( im just trying to get an array to work for now) . Can someone help?
Jquery Code
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>jQuery UI Autocomplete - Default functionality</title>
<link rel="stylesheet" href="//code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<script src="//code.jquery.com/jquery-1.10.2.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<script>
$(function() {
$( "#tags" ).autocomplete({
source: "test.php"
});
});
</script>
</head>
<body>
<div class="ui-widget">
<label for="tags">Tags: </label>
<input id="tags">
</div>
</body>
</html>
PHP code
<?php
$data[] = array(
'c++','Java','JavScript',"c#" );
echo json_encode($data);
?>
This is an updated version of your answer which should resolve the deprecated SQL driver and the injection issue. You need to replace the SECOND_COLUMNNAME with your actual column's name. Aside from that I think this should work.
<?php
try {
$dbh = new PDO('mysql:host=localhost;dbname=DB','username','password');
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
if(empty($_REQUEST['term']))
exit();
//require_once('connect.php'); connection to db is in this file so connection is not needed
$query = 'SELECT name, SECOND_COLUMNNAME FROM locations
WHERE name
LIKE ?
ORDER BY id ASC
LIMIT 0,10';
$stmt = $dbh->prepare($query);
$stmt->execute(array(ucfirst($_REQUEST['term']) . '%'));
$data = array();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$data[] = array(
'label' => $row['name'],
'value' => $row['SECOND_COLUMNNAME']
);
}
echo json_encode($data);
flush();
Links:
http://php.net/manual/en/pdo.prepared-statements.php
http://php.net/manual/en/pdo.connections.php
https://www.owasp.org/index.php/SQL_Injection_Prevention_Cheat_Sheet
How can I prevent SQL injection in PHP?
Also not sure if there was anything else inside connect.php, you might need to bring that back.
The array pattern used here should be as below.
<?php
$data = array(
array("value"=>'C++'),
array("value"=>'Java'),
array("value"=>'Javascript'),
array("value"=>'C#'),
);
echo json_encode($data);
If you're using PHP >= 5.4:
$data = [
[ 'value' => 'C++' ],
[ 'value' => 'Java' ],
[ 'value' => 'Javascript' ],
[ 'value' => 'C#' ]
];
echo json_encode( $data );
Here's a working example of my autocomplete code:
function get_data(type, target, min_length )
{
$(target).autocomplete({
source: function( request, response ) {
var submit = {
term: request.term,
type: type
};
$.ajax({
url: '/request/get',
data: { thisRequest: submit},
dataType: "json",
method: "post",
success: function( data ) {
response($.map( data.Data, function( item ) {
return {
label: item.label,
value: item.label
}
}));
}
});
},
minLength: min_length
})
}
<?php
$data = array(
'c++',
'Java',
'JavScript',"c#" );
echo json_encode($data);
?>
So i want with Pratik Soni advice and did a search. Here is the php code if anyone wants to use it
<?php
// Connect to server and select databse.
$dblink = mysql_connect('localhost','username','password') or die(mysql_error());
mysql_select_db('DB');
?>
<?php
if(!isset($_REQUEST['term']))
exit();
require('connect.php');
$term =
$query = mysql_query('
SELECT * FROM locations
WHERE name
LIKE "'.ucfirst($_REQUEST['term']).'%"
ORDER BY id ASC
LIMIT 0,10', $dblink
);
$data = array();
while($row = mysql_fetch_array($query, MYSQL_ASSOC)){
$data[] = array(
'label' => $row['name'],
'value' => $row['name'],
);
}
echo json_encode($data);
flush();
The below is my code I'm using for my Stripe Subscription Payments, because the site I'm implementing this into is AngularJS I want to keep the site from Refreshing so I'm opting for this AJAX option.
I have commented out a piece of the PHP which is
$charge = Stripe_Charge::create(array(
'customer' => $customer->id,
'amount' => $amount,
'currency' => 'gbp'
));
If I exclude this, the payment goes through once and I'm unsure how this application is able to process the charge if there is no call for it in the PHP file.
If I include the above snippet then the charge goes through twice.
My config.php only has require_once('Stripe.php'); along with my API keys.
So I'm hoping someone could explain why the charge goes through without the charge code piece in there if my code is actually okay for me to continue with.
HTML
<button id="proBtn">Subscribe</button>
JavaScript
Stripe.setPublishableKey('HIDDEN');
$('#proBtn').click(function(){
var token = function(res){
var $input = $('<input type="hidden" name="stripeToken" />').val(res.id);
var tokenId = $input.val();
var email = res.email;
setTimeout(function(){
$.ajax({
url:'/assets/lib/charge.php',
cache: false,
data:{ stripeEmail : email, stripeToken:tokenId, stripePlan: 'pro' },
type:'POST'
})
.done(function(data){
// If Payment Success
console.log(data);
$('#proBtn').html('Thank You').addClass('disabled');
})
.error(function(){
$('#proBtn').html('Error, Unable to Process Payment').addClass('disabled');
});
},500);
//$('form:first-child').append($input).submit();
};
StripeCheckout.open({
key: 'HIDDEN', // Your Key
address: false,
amount: 500,
currency: 'gbp',
name: 'Pro Account',
description: '',
panelLabel: 'Checkout',
allowRememberMe: false,
token: token
});
return false;
});
charge.php
<?php
require_once($_SERVER['DOCUMENT_ROOT'].'/assets/lib/config.php');
$token = $_POST['stripeToken'];
$email = $_POST['stripeEmail'];
$plan = $_POST['stripePlan'];
if ( $plan == 'pro' ) {
$amount = 500;
$amountFormat = number_format( $amount / 100, 2) ;
$plan = 'pro';
}
if ( $plan == 'team' ) {
$amount = 2000;
$amountFormat = number_format( $amount / 100, 2) ;
$plan = 'team';
}
Stripe_Plan::retrieve("pro");
Stripe_Plan::retrieve("team");
$customer = Stripe_Customer::create(array(
'email' => $email,
'card' => $token,
'plan' => $plan
));
try {
/*
$charge = Stripe_Charge::create(array(
'customer' => $customer->id,
'amount' => $amount,
'currency' => 'gbp'
));*/
echo 'success';
} catch(Stripe_CardError $e) {
echo "The card has been declined";
echo $token;
}
print_r($token);
echo '<br/>';
print_r($email);
echo '<br/>';
echo $customer->id;
echo '<h1>Successfully charged '.$amountFormat.'!</h1>';
?>
When you create a customer in Stripe it automatically charges them if you pass in a plan. You're basically saying create this customer and sign them up for this plan. That's why you are charging them twice.
Here's a link to the Customer API:
https://stripe.com/docs/api#create_customer
I have just discovered this awesome wordpress function
<?php echo 'Number of posts published by user: ' . count_user_posts( ); ?>
Im busy making a graph which displays on a pie chart how many posts the user has done per category. (chars.js)
Is there any way to make a loop almost where i could get the values for each category the user has posted in.
Id like to future proof it so if more categories are added i dont have to go and write something like this
<?php echo 'Number of posts published by user: ' . count_user_posts( 5 ); ?>
<?php echo 'Number of posts published by user: ' . count_user_posts( 7 ); ?>
<?php echo 'Number of posts published by user: ' . count_user_posts( 8 ); ?>
Is there a way where i can just get a category breakdown of how many posts a user has posted in all categories
Thanks for any help
Try this code:
Just set which type of user's do you want at array:
<?php $args = array(
'blog_id' => $GLOBALS['blog_id'],
'role' => 'subscriber',//"Super Admin" or "Administrator" or "Editor" or "Author" or "Contributor"
'meta_key' => '',
'meta_value' => '',
'meta_compare' => '',
'meta_query' => array(),
'include' => array(),
'exclude' => array(),
'orderby' => 'login',
'order' => 'ASC',
'offset' => '',
'search' => '',
'number' => '',
'count_total' => false,
'fields' => 'all',
'who' => ''
);
php get_users( $args );
foreach ($blogusers as $user) { ?>
<li>
<?php $user_id = $user->ID ?>
<?php echo 'Number of posts published by user: ' . count_user_posts( $user_id ); ?>
</li>
<?php } ?>
Thanks.
I think you are misunderstanding the count_user_posts function. It's argument is for user id and not for category id.
Anyways, once you have the desired user id (if i understood well, you want to display the post count for every category where the user was the post author) you can do something like this:
$user_id = 124;
/* Get all categories */
$categories = get_terms("category");
/* Loop for each category to count the posts of the user */
foreach($categories as $category)
{
$cat_name = $category->name;
$cat_id = $category->term_id;
$post_count = count(get_posts("cat=$cat_id&post_author=$user_id"));
echo "The user $user_id has $post_count posts in the $cat_name category";
}
Here is the completed code, thanks for the help everyone
<script type="text/javascript">
var pieData = [
<?php
$user_id = get_query_var('author');
$rand = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f');
//get all posts from author
$args = array(
'post_type' => 'post',
'author'=> $queried_object->ID
);
$the_query = new WP_Query( $args );
if ( $the_query->have_posts() ) :
while ( $the_query->have_posts() ) : $the_query->the_post();
//put categories in array
$cat = get_the_category( get_the_ID() );
$terms[] = $cat[0]->term_id;
endwhile;
wp_reset_query();
endif;
//count matching categories (array vals)
$countVal = array_count_values($terms);
foreach($countVal as $count){
$color = '#'.$rand[rand(0,15)].$rand[rand(0,15)].$rand[rand(0,15)].$rand[rand(0,15)].$rand[rand(0,15)].$rand[rand(0,15)];
echo " {
value: ".$count.",
color:'".$color."'
},";
}
?>
]
var myPie = new Chart(document.getElementById("piec").getContext("2d")).Pie(pieData);
</script>