I'm working on an android app based on a 3 Tier architecture. I have set up a products page and the Pay Now button integrated with PayPal. I also receive Success message after successful payment.
I'm now stuck at the order function. Which function of Woocommerce makes the order?
I'm simply trying to pass the price, product_id and other details to that particular function which will take care of the rest of the process.
Any help would be much appreciated. Thank you.
Here is some code that will generate an order. You'll have to substitute in your payment gateway class
// create a new checkout instance and order id
global $current_user;
$product_id = $_POST['productId'];
$product = wc_get_product($product_id);
$order = wc_create_order(array(
'customer_id' => $current_user->ID,
));
$order->add_product( $product, 1 );
$order->calculate_totals();
$my_gateway = new WC_Gateway_WhateverGatewayYouAreUsing();
$payment = $my_gateway->process_payment($order->id);
if($payment["result"] == "success") {
$order->update_status('completed');
wc_add_notice("Thank you!");
}
else {
$order->update_status("cancelled");
wc_add_notice("oh no! plz send me da moneez", 'notice');
}
Related
I need to know how to assign custom actions (or run custom code) when someone buys something in the website and the payment has been completed. I need this so our system can send order's data to an API.
i am using wordpress and woocommerce for the website.
how can i find the order dynamics variable to put it in my API's code ?
if there,s anyone who use wordpress and woocommerce, please tell me where can i find order's dynamic variables such as:
product id which the customer has been ordered
product count and etc.
You could write a function that connects to the woocommerce_order_status_processing hook. At this point, the payment has been accepted and WooCommerce is waiting for the store to fulfill the order.
add_action( 'woocommerce_order_status_processing', 'my_order_complete_function', 10, 1 );
function my_order_complete_function( $order_id ) {
$order = wc_get_order( $order_id );
foreach($order->get_items() as $item) {
$product_id = $item->get_product_id();
$product = wc_get_product( $product_id );
// Add your API call here.
}
}
I would like to add a function that is triggered every time that the stock quantity of a product will be changed in the admin product page, such that this function will not allow any reduce of the stock value - but only increase.
This is to prevent an admin user to reduce the stock quantity of the products.
Of course, this function should not be triggered if a product will be in an order, since then of course I would like the stock quantity to be reduced.
I tried the following function in the functions.php but unfortunately did not work.
Since I'm new to woocommerce and php, any ideas that could provide a solid solution to the problem?
// get old and new product stock quantity
function get_old_and_new_product_quantity_stock( $sql, $product_id_with_stock, $new_stock, $operation ) {
$product = wc_get_product( $product_id_with_stock );
$old_stock_quantity = $product->get_stock_quantity();
$new_stock_quantity = $new_stock;
echo $old_stock_quantity, $new_stock_quantity;
if ($new_stock_quantity < $old_stock_quantity) {
$new_stock = $old_stock_quantity;
$new_stock_quantity = $old_stock_quantity;
}
return $sql;
}
add_filter( 'woocommerce_update_product_stock_query', 'get_old_and_new_product_quantity_stock', 10, 4 );
You can use the update_post_meta action hook to check if the new value is less than the previous value and display error message.
This will work for quick edit and for product edit page. But the wp_die on product page will look bad so use the javascript to prevent submitting on product edit page (there was another question about it yesterday)
Be sure to test this snippet and create some orders that will reduce the stock automatically. I added is_admin() check but please do a good test.
add_action( 'update_post_meta', 'prevent_reducing_stock_metadata', 10, 4 );
function prevent_reducing_stock_metadata( $meta_id, $post_id, $meta_key, $meta_value ) {
// Check if the meta key is _stock and the new value is less than the previous value
if ( '_stock' == $meta_key && $meta_value < get_post_meta( $post_id, '_stock', true ) ) {
// Check if this is an update from the WordPress admin area
if ( is_admin() ) {
wp_die( __( 'Error: You cannot reduce the stock level for this product.' ), 'error' );
}
}
}
Good afternoon everyone.
I've been struggling for a couple of days with the following issue :
I have a woocommerce cart divided in X packages. Based on the sipping option selected for a package A, I wish to send an email to an email adress B. Each shipping option having a linked email adress.
Now, my issue is : I've found the code part in woocommerce where the recipient is given to the system I believe : class-wc-email.php. When I have 3 packages, I receive 4 emails on the same email adress at the moment, one global, and one with the content of each package. So my idea is that in this file, I'd like to test the shipping method selected for each package (assuming that each package = one order), and based on this information, adapt the email adress.
Something like :
public function get_recipient() {
if( $chosen_shipping == 'blabla' ){
$recipients = "recipient#gmail.com";
}
else if( $chosen_shipping == 'blablabla' ){
$recipients = "recipient2#gmail.com";
}
else {
$recipient = apply_filters( 'woocommerce_email_#recipient_' . $this->id, $this->recipient, $this->object, $this );
$recipients = array_map( 'trim', explode( ',', $recipient ) );
$recipients = array_filter( $recipients, 'is_email' );
$recipients = implode( ', ', $recipients );
}
return $recipients;
}
This type of problem has been adressed in the past, for instance in this topic : Woocommerce email notifications additional recipients based on user role
However, suggested solutions are often depreciated and I can't figure out a way of making it work.
Thank you in advance for your time and help :)
I'm writing a payment gateway that handles WooCommerce subscriptions. Here is the sample code that handles the renewal:
public function mcc_subscription_renewal($amount, $order) {
$tid = 123;
$order->payment_complete( $tid );
$order->update_status( 'completed' );
WC_Subscriptions_Manager::process_subscription_payments_on_order( $order );
}
This is for a simple subscription that charges the customer a fixed fee every year. When I manually run the renewal process, a new order and scheduled action are created successfully, but the date isn't updated to the next year. What am I missing? Why isn't a successfully completed renewal order updating the expiry date of a subscription?
Assuming you have not found an answer yet, a couple of things. Are you just writing the gateway OR are you writing the gateway and a subscription process?
Woocommerce has a addon called Woocommerce subscription. It does all the billing to a gateway, which at the moment are only Stripe/PayPal. If you are writing a new gateway and have a woocommerce subscription add on, then all you need to do is to look at the subscription id and the next payment date:
public function mcc_subscription_renewal($amount, $order)
{
$order = new WC_Order( $order );
$OrderNumber = $order->parent_id;
$ParentOrder = new WC_Order( $OrderNumber ); // ORDER NUMBER
$SubscriptionNumber = $order->get_order_number();
$PaymentDate = $order->get_date_created()->format ('Y-m-d');
$items = $order->get_items();
foreach( $items as $item_id => $product )
{
$ProductName = $product->get_name();
$ProductId = $product->get_product_id();
$ExpireDate = WC_Subscriptions_Order::get_next_payment_date ( $ParentOrder, $ProductId );
}
}
You don't have to do anything else. If you are writing your own subscription package, then you need to write the calls and store the purchases ..thus calculate your own expiration dates.
The woocommerce subscription, the length of time and the renewal period is all set under the products definition.
I am stuck on one problem, for my E-commerce website after placing order on i want to show random number for each product in order details section.
I have tried this : in theme(function.php)
add_action( 'woocommerce_order_status_processing', 'add_unique_id');
then
function add_unique_id($order_id) {
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ($items as $item_id => $product )
{
$gen_id ="Hi Dad!";
wc_add_order_item_meta($item_id, 'unique_id', $gen_id);
}
But by using this i am not getting unique number for each product.
I want to add random number in below red portion in image of Thank You page.
please help to resolve.
thanks in advance
If you have already done with the adding item_meta_data into the cart, hopefully, you can easily make it visible into cart too?
It is not that necessary but just for the testing purpose.
For this, you can use "woocommerce_get_item_data"
add_filter( 'woocommerce_get_item_data', 'mwb_wgm_woocommerce_get_item_data', 10, 2 );
function mwb_wgm_woocommerce_get_item_data($item_meta, $existing_item_meta){
//by using $existing_item_meta , find your unique_key (whether it is displaying or not)
foreach ($existing_item_meta as $key => $val ) {
if($key == 'unique_key') {
$item_meta [] = array (
'name' => __('RANDOM KEY','your_slug'),
'value' => stripslashes( $val ),
);
}
}
return $item_meta;
}
Let me know is your UNIQUE KEY is displaying there or not?
There are the various issue can be there
1. wc_add_order_item_meta (Woo version < 3.0.0)
If you're thinking to add item_meta to each of your product and then yes it will get displayed automatically on Thank You Order Page.
Please use "$item->add_meta_data('Your_Key',$order_val);" [WC_version >= 3.0.0]
Please make sure you've already set that "key" to your cart_item_meta by using this hook -> "woocommerce_add_cart_item_data".
Hope this may help you :)