handling response and placing order in woocommerce after redirecting back from payment website - wordpress

I am developing a payment gateway plugin (For Cybersource Payment) for WooCommerce. I developed it to almost at the end, but one thing is intercepting me to finish and that is the part after redirecting from payment gateway website after successful payment back to my wordpress page (Purchase Confirmation Page - New Wordpress Page created using template in wp-content/themes/my-theme/order-confirm-template.php). But i dont know how to handle the response coming back from payment website. I looked for some woocommerce hooks but nothing worked. I found there is a hook woocommerce_thankyou but that is also not working for me.
Can somebody help me out here in these two points below
1) How to handle response and placed the order properly and remove the items from the cart when coming back after successful payment from gateway website.
2) which page should i redirect back from gateway website? back to the same checkout page or some custom page just like i did.
Any Help with code will be very appreciated. Thanks.

I have used the following code in my plugin, I hope this works for you too :)
First add this code,
function receipt_page($order){
echo $this -> ResponceHandler($order);
}
Now the code for ResponceHandler($order) function,
public function ResponceHandler($order_id){
if(!isset($_POST['ResponseCode'])){
global $woocommerce;
echo '<p>'.__('Thank you for your order, please click the button below to pay with XYZ', 'woocommerce').'</p>';
$order = new WC_Order($order_id);
$order_id = $order_id.'_'.date("ymds");
$post_data = get_post_meta($order_id,'_post_data',true);
update_post_meta($order_id,'_post_data',array());
###Your Form Code HERE###
echo '<form><input value="Proceed To Payment" type="submit" /> </form>';
}
###Haandle the response###
if(isset($_POST['ResponseCode']))
{
if($_POST['ResponseCode']==0){
global $woocommerce;
session_start();
$_SESSION['post']=$_POST;
$order = new WC_Order($order_id);
$order_id = $order_id.'_'.date("ymds");
$post_data = get_post_meta($order_id,'_post_data',true);
update_post_meta($order_id,'_post_data',array());
if($order->status != 'processing'){
$order ->status ='Processing';
$order->payment_complete();
$order -> add_order_note('XYZ Payment Gateway <br>Response message :'.$_POST['ResponseMessage'].'<br>Payment ID :'.$_POST['PaymentID'].'<br>Merchant Reference Number :'.$_POST['MerchantRefNo'].'<br>Transaction ID :'.$_POST['TransactionID'].'');
add_post_meta( $order->id, '_paymentid', sanitize_text_field( $_POST['PaymentID'] ) );
add_post_meta( $order->id, '_trno', sanitize_text_field( $_POST['TransactionID'] ) );
$woocommerce -> cart -> empty_cart();
wp_redirect( $order->get_checkout_order_received_url());
}
}
else {
if($order->status != 'failed'){
$order ->status ='failed';
echo "Payment failed!<br><br><br>Possible Error : ".$_POST['ResponseMessage']."<br>PaymentID: ".$_POST['PaymentID']."<br><br><br>We request you to save these details for further reference. <br>You can always pay for this order by clicking on your name in the top right corner and visiting your orders section."; }
}
}
}

Related

Backorder Notification Woocommerce

I have a little problem with the backorder notification on my woocommerce shop.
What it is now: I set in the product backorders: allowed, but notify customer. When I press a variaton on the product page it will show available for backorder. So far so good. When someone place the order it will show the text backorderer: 1 on the order confirmation, on the pdf invoice, on the e-mail.
What I want: Show the notification only on the product information page. Not on the e-mails, order confirmation, etc. But when I set up backorders only to allow. There is also no notification on the Product Page for the customer.
So do someone of you know, how I can change this? Is there a custom code or something else I can use.
This is really important for me. I tried to find a solution about 1 week without any luck. So please help me.
Can you try this?
Just copy and paste this block of code to your functions.php file in your child theme.
add_filter( 'woocommerce_get_availability', 'wcs_custom_get_availability', 1, 2); function wcs_custom_get_availability( $availability, $_product ) { // Change In Stock Text if ( $_product->is_in_stock() && ! $_product->backorders_allowed() ) { $availability['availability'] .= __('<br />Shipped immediately', 'custom'); } if ( $_product->is_in_stock() && $_product->backorders_allowed() ) { $availability['availability'] = __('<br />We will inform you via email when the product is back in stock. Please send us your contact info via the form below.', 'custom'); } // Change Out of Stock Text if ( ! $_product->is_in_stock() ) { $availability['availability'] .= __('<br />We will inform you via email when the product is back in stock. Please send us your contact info via the form below.', 'custom'); } return $availability; }
And let me know whether it worked for you or not.
Thank you

How to notify through email in wordpress

How to notify through email in wordpress when visitor clicks on a link that this link was pressed and/or user ip, city and country was this?
I have given the link a class 'email-link'.
something like this should get you started
// functions.php
// HTML form markup
function mail_form_stuff() {
echo '<form action="' . esc_url( $_SERVER['REQUEST_URI'] ) . '" method="post">';
echo '<p><input type="submit" name="send_the_email_to_admin" value="Click this button"></p>';
echo '</form>';
}
// make sure the email will allow for html -- not just plain text
add_filter( 'wp_mail_content_type', 'send_the_email_to_admin_content_type' );
function send_the_email_to_admin_content_type() {
return 'text/html';
}
// if the button is clicked, send the email
function deliver_mail_link_stuff() {
$admin_email = get_option( 'admin_email' );
if ( isset($_POST["send_the_email_to_admin"]) ) {
$_user = wp_get_current_user();
$_name = esc_html( $_user->user_firstname );
$_email = esc_html( $_user->user_email );
$to = $admin_email;
$subject = "Some person clicked my link";
$message = 'Hey this person clicked on that button'.'<br>';
$message .= "the persons email address was: $_email";
$headers[] = "From: $_name <$_email>" . "\r\n";
// $headers[] = "Bcc: John Smith <jsmith#gmail.com>" . "\r\n";
// If everything worked -- display a success message
if ( wp_mail( $to, $subject, $message, $headers ) ) {
echo '<p>sent</p>';
} else {
echo 'An unexpected error occurred';
}
// reset wp_mail_content_type
remove_filter( 'wp_mail_content_type', 'send_the_email_to_admin_content_type' );
}
}
function add_short_code_stuff() {
ob_start();
deliver_mail_link_stuff();
mail_form_stuff();
return ob_get_clean();
}
add_shortcode( 'EMAIL_BUTTON', 'add_short_code_stuff' );
this will add a short code for you
you can then call the shortcode in your theme with
echo do_shortcode('[EMAIL_BUTTON]');
You can't do this as a direct consequence of WordPress since a link is HTML and has no correlation to or integration with anything controlled or processed directly by WordPress. WordPress is merely a structure/processes through which you can add info to a database and then later retrieve it.
If you question is actually meant in a more generic and not specifically wordPress sense, then the answer is any number of ways. You could for example create some JQuery or JS that would add that info everytime a link was clicked. But, you would need to interact with the page headers to try and get all the required info.
But, why bother doing that when a free & arguably market leading tool that does this is already available?
The logical process to this is to use Google Analytics (or a rival tool) as this already collects this kind of info with very little work required to set it up. If you want more specific "event" triggered data (eg a link is clicked), then you can also do this fairly easily too.
https://analytics.google.com
UPDATE
In your comment, you clarify that you want a real time email to be sent to you when a link is clicked, and thus analytics isn't going to fit the bill. In that case you will need to do some work using JQuery & AJAX.
In simple terms you'll need to do something this:
1) Create some JQuery to intercept the url of the link clicked
2) Pass the link (and header info) to a function via an AJAX call
3) Process the header data / send the email
4) Redirect user to the url passed from the link
Here's a tutorial on creating a simple AJAX process in WordPress: https://www.makeuseof.com/tag/tutorial-ajax-wordpress/

WooCommerce check and redirect to login before checkout

The default Woocommerce checkout behavior breaks a lot of web conventions by showing the "Create Account" boxes on the checkout page if it detects the user is not logged in. New users may not know what to do without any added instructions.
My desired sequence would be:
User Checkout > Check login >
Proceed to checkout if logged in.
Redirect to login/register page if not logged in > proceed to the checkout page.
This is EXACTLY the case in WooCommerce login redirect based on cart
However, what I feel uncomfortable is that, in the above case, once the user logged in, he/she will be redirected to the checkout page if the cart is not empty. If the user's cart is not empty, he/she will not be able to go to MyAccount at all even though he/she does not want to checkout yet.
Any idea on this one?
Try this no need to change core code
add_action('template_redirect','check_if_logged_in');
function check_if_logged_in()
{
$pageid = get_option( 'woocommerce_checkout_page_id' );
if(!is_user_logged_in() && is_page($pageid))
{
$url = add_query_arg(
'redirect_to',
get_permalink($pagid),
site_url('/my-account/') // your my account url
);
wp_redirect($url);
exit;
}
if(is_user_logged_in())
{
if(is_page(get_option( 'woocommerce_myaccount_page_id' )))
{
$redirect = $_GET['redirect_to'];
if (isset($redirect)) {
echo '<script>window.location.href = "'.$redirect.'";</script>';
}
}
}
}
In the second answer there is a problem, after loging in the user always redirects checkout page, it does not stand on my-account page until the cart become empty!!
This code redirects the user to my-account page for login instead of checkout if the user is not logged in, then after loging in it automatically redirects to checkout page.
STEP 1:
Add this code in function.php
add_action('template_redirect','check_if_logged_in');
function check_if_logged_in()
{
$pageid = get_option( 'woocommerce_checkout_page_id' );// your checkout page id
if(!is_user_logged_in() && is_page($pageid))
{
$url = add_query_arg(
'redirect_to',
get_permalink($pageid),
site_url('/my-account/') // your my acount url
);
wp_redirect($url);
exit;
}
}
STEP 2:
Add this code at the end of /wp-content/plugins/woocommerce/templates/myaccount/my-account.php
<?php
$quark_web_solution_redirect = $_GET['redirect_to'];
if (isset($quark_web_solution_redirect)) {
echo '<script>
window.location.href = "'.$quark_web_solution_redirect.'";
</script>';
}
?>
after reading this post and others in Stackoverflow, i came up with a simple solution (more than i thought at first) that is working for me... Maybe theres something i have missed up in the process, but i have tested several combinations and it works for me. So we want to:
Customer goes to checkout
If Logged In, continue to checkout. If not logged in, go to a page with login and register forms.
Once in this page, if customer logs in or register, continue to Checkout.
First, i created a custom page with [woocommerce_my_account] shortcode. Here i customized the texts etc... in the forms, so its a little bit different that my account page. URL path of this page is -> /iniciar-sesion-registrarse.
Then, i put this code in functions.php of my child theme:
function custom_woocommerce_login_redirect_to_checkout_page() {
// Caso 1: Usuario no identificado intenta acceder a Finalizar Compra
if ( !is_user_logged_in() && is_checkout() )
wp_redirect( get_permalink( get_page_by_path('iniciar-sesion-registrarse') ) );
// Caso 2: Si en la página de identificarse, el cliente ha accedido o se ha registrado, o tiene el carrito vacío, continuar a Finalizar Compra.
if ( is_page('iniciar-sesion-registrarse') ) {
if( is_user_logged_in() || WC()->cart->is_empty() ) {
wp_redirect( get_permalink( get_page_by_path('finalizar-comprar') ) );
}
}
}
add_action( 'template_redirect', 'custom_woocommerce_login_redirect_to_checkout_page' );
So in Case 1: If user is not logged in and tries to go to checkout, it redirects to my custom login page 'iniciar-sesion-registrarse'.
Then in Case 2: If user loggin or register in this page, normal my account page would be displayed in this page, then i redirect users who are logged in and are in this page to checkout. I also redirect them to checkout if someones access this custom page directly and has nothing in their carts (so woocommerce message: u cant checkout without items in ur cart is displayed).
This way, while loggin in or registering in this custom page, error messages will display normally as if it was real 'my-account' page, but once logged in, it will redirect to checkout.
I hope someone can tell me if i have missed something in the process. Thx
Actually had this problem today & now have a solution.
Context: our site has a separate user registration system than WooCommerce, so we didn't want a duplicative process prompting users to signup twice.
First I'll give the brief solution then list the full steps for my situation.
Brief solution: enable guest checkout, (trust me) enable account creation during checkout, automatically generate username and password (most important). Then disable in email settings the "New Account" message. Now "users" can checkout with account details auto-generated, but they never know about it and that information is essentially dumped.
Screenshot of my Accounts & Privacy settings. Please note I also disabled the "New Account" message triggered in the Email settings for WC.
Add this code in function.php
add_action('template_redirect','check_if_logged_in');
function check_if_logged_in()
{
$pageid = get_option( 'woocommerce_checkout_page_id' );
if(!is_user_logged_in() && is_page($pageid))
{
$url = add_query_arg(
'redirect_to',
get_permalink($pagid),
site_url('/my-account/') // your my acount url
);
wp_redirect($url);
exit;
}
}

WooCommerce - Redirecting a User after They've Reset Their Password

I'm setting up a WooCommerce shop for a client and he has requested that the user be redirected back to the login form after the reset password form has been submitted.
Is this possible? Which function controls this?
Thanks in advance.
A much cleaner solution is to redirect using the woocommerce_customer_reset_password action:
function woocommerce_new_pass_redirect( $user ) {
wp_redirect( get_permalink(woocommerce_get_page_id('myaccount')));
exit;
}
add_action( 'woocommerce_customer_reset_password', 'woocommerce_new_pass_redirect' );
This code can be placed in functions.php.
Someone asked me about doing this and I think I'm going to talk them out of it, but here's what I came up with so that you could see the message and then be redirected in 5 seconds. Add a message/link to let them know you'll be redirecting. Plus, this will last through a WooCommerce upgrade if you add the template file to your theme
Add the form-lost-password.php template file to your theme and add the following code:
if ( $_GET[reset] = true && ( 'lost_password' == $args['form']) ) {
$my_account_url = get_site_url() . '/my-account';
echo "<script>window.setTimeout(function(){window.location.replace('$my_account_url')}, 5000)</script>";
}
If you dont want the time delay get rid of the window.setTimeout() and just use window.location.replace('$my_account_url').
I'm just facing the same question. I think the function that controls this is in the file woocommerce/includes/class-wc-form-handler.php. I changed the following line:
wp_redirect( add_query_arg( 'reset', 'true', remove_query_arg( array( 'key', 'login' ) ) ) );
with
wp_redirect( get_permalink( get_option('woocommerce_myaccount_page_id') ) );
With that change, you get redirected to the my-account page, where the customer can log in, but of course there are two problems doing that:
The customer gets no message the the password recovery was successful
Doing a WooCommerce update, the file gets overwritten with the original file
Would be great, if someone could come up with a "update-secure" solution.
Best regards
Christoph

woocommerce check zip code before placing order

As local delivery is the only option (due to product delivery restrictions) I do not want a customer to get to the checkout page and have to fill out all their details and only then discover we do not deliver to their postcode.
Therefore, I require the same functionality of the Local Delivery postcode check at the Checkout page, but to be added at an earlier stage in the checkout process, such as on the Cart page? Or any other page, for that matter. Best place can be in product page before add to cart option.
i.e.
Enter your postcode to see if we deliver to your area:
Result - a yes or no message appears with further instructions
You can add a new field to the cart by using the woocommerce_cart_coupon hook and then you can create a handler using the template_redirect hook.
Something like the below which we have used on our sites before:
add_action( 'woocommerce_cart_coupon', array(&$this, 'new_woocommerce_cart_coupon'), 10, 0 );
add_action( 'template_redirect', array(&$this, 'new_post_code_cart_button_handler') );
public function new_woocommerce_cart_coupon() {
?>
<br/><br/><p>Enter your postcode</p><label for="post_code">Post Code</label> <input type="text" name="post_code" class="input-text" id="post_code" value="" /> <input type="submit" class="button" name="apply_post_code" value="Check Post Code" />
<?php
}
public function new_post_code_cart_button_handler() {
if( is_cart() && isset( $_POST['post_code'] ) && $_SERVER['REQUEST_METHOD'] == "POST" && !empty( $_POST['post_code'] ) ) {
//validate post code here
}
}
Sounds like your best option is to put the PostCode field at the top of your Billing Details form.
This way, once the PostCode is filled up, the shipping methods will adjust accordingly. As soon as the user goes down the form, the Local Shipping method will no longer be available if their postcode don't allow it.
This solution will only work if you place all the postcodes that you actually deliver to in the PostCode section in the Local Delivery settings in the WooCommerce dashboard:
This will ensure that Local Delivery option will only appear to the postcodes in your list. If the postcode entered is not on the list, the Local Delivery option will disappear on the shipping methods options below the form.
Just add this to your functions.php file:
//Rearrange the Fields in the Checkout Billing Details Form
add_filter("woocommerce_checkout_fields", "new_order_fields");
function new_order_fields($fields) {
$order_list = array(
"billing_postcode",
"billing_first_name",
"billing_last_name",
"billing_email",
"billing_phone",
"billing_company",
"billing_address_1",
"billing_address_2",
"billing_country"
);
foreach($order_list as $field)
{
$ordered_fields[$field] = $fields["billing"][$field];
}
$fields["billing"] = $ordered_fields;
return $fields;
}
Just rearrange the $order_list array according to your preference.

Resources