So I have an e-commerce site using wordpress and woo-commerce, now using the smart-coupon woocommerce plugin extension is there a way for me to create a credit coupon/gift-card (that initially has no email restriction) and manually assign the email of the current user as the email restriction for it the first time the gift-card is being used.
I'm trying to create a vooucher system using the giftcard as vouchers to purchase products in my store.
Since you don't have any code to show what you were using, try this.
$coupon_code = 'some-code-I-created';
$user = wp_get_current_user();//Get the current user object
$coupon = new WC_Coupon( $coupon_code );//Get the coupon object
$emails = $coupon->get_email_restrictions();//Returns an empty array or array of emails
$emails[] = strtolower($user->billing_email);//Add user's billing email address to the array
$emails = array_filter($emails);//Remove empty values
array_unique($emails);//Remove any duplicate values
$coupon->set_email_restrictions($emails);//Set the coupon's array with the updated array
$coupon->save();//Save the coupon
In case I'm adding email addresses in bulk (like using array_merge() instead of adding one address at a time), it's always good to make sure the array is clean by removing any empty values or duplicate values before updating the coupon object with it.
Also, WooCommerce compares the billing address in all lowercase but not the restricted emails in the coupon, so be sure when adding it to your coupon that you add it as all lowercase so they validate correctly. Source. This bug may be fixed in the future, but until then...
Related
I am attempting to update WooCommerce products through notifications sent by a third party application. I have read the documentation on doing this and it seems easy enough, but it looks like the only way to use the API to update a product is by Product ID. Unfortunately, these are/were created incrementally while uploading the rather large product catalog into WooCommerce.
While making the .csv's and uploading to WooCommerce, we set the SKU's to be the same ID that the products have in the third-party software (book ISBN's). So I am able to send that number (the number that corresponds with SKU in WC) with the HTTP request, but that does not allow me to perform the product update.
It seems to me, the best way to accomplish this integration would be to change the product ID's of all my products in WooCommerce to be the same as this unique number that is currently the SKU. It doesn't appear as though this is possible to do in the dashboard or user interface, so I imagine I'll have to do it on a database level.
Does anyone know what tables will need to be modified or if there is a way to do this in the dashboard? Maybe even a tweak to my HTTP request to the API that will allow me to update by SKU?
Modifiy the Product IDs in the database directly is not a good choices.
This action is required to do every time when creating new products.
The most simplest and safe appoach is creating a new API,
which purpose for searching the product ID by SKU.
Here is a part of sample code.
function get_product_by_sku( $sku ) {
global $wpdb;
$product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $sku ) );
if ( $product_id ) return new WC_Product( $product_id );
return null;
}
I am currently using a code similar to what I need, from LoicTheAztec ( who should really be called "DaMan"). That code triggers Woo to send an email to a custom email address when order status is changed to "Processing". Without that code, a notification email only goes to the customer.
For my case I want to send a notification to both the customer, and the store owner. I was able to tweak previous code to do this - but the result was that both the customer and owner get the same email ( as in, they are both copied on exact same notice from Woo).
Here is what I am currently using in my functions.php:
// notify when order status set to processing
add_filter( 'woocommerce_email_recipient_customer_processing_order', 'processing_order_replacement_email_recipient', 10, 2 );
function processing_order_replacement_email_recipient( $recipient, $order ) {
// Set HERE your replacement recipient email(s)… (If multiple, separate them by a coma)
$recipient .= ',example#owneremail.com';
return $recipient;
}
How could I trigger this so that the customer gets their copy, and the owner gets her copy separately? Also typically the stock emails generated by WOO have slightly different text versions between customer and store owner.
If what I am asking can't be done, I'll stick with what I have. Just wondering if there is a cleaner way to achieve it. Thanks in advance for any assistance!
Hopefully there's a woocommerce veteran familiar with the checkout process that can help me with this. My store offers a sample product at a discounted price, but I want to limit this to a one-time order per customer. I've found a solution that works for registered users but I was wondering if there's another way to make this work without forcing guests to set up an account before ordering the product.
What I was thinking was if there's a way to check if the customer's billing email address has ordered this particular product at the checkout stage. So they'd fill out the checkout form and click "Proceed" but before the customer is taken through to the payment gateway their email address would be checked for ordering this particular product before, if so, direct them to a "order failed" page rather than through to the payment gateway.
Thanks in advance!
You have two of ways to achieve this functionality:
You can validate email on checkout page itself. Scan for orders with customer/guest's email address and if found with free product, then validate. This way an unnecessary order will not be recorded in the system.
Here is how you can have custom checkout validation.
/**
* Process the checkout
**/
add_action('woocommerce_checkout_process', 'my_custom_checkout_field_process');
function my_custom_checkout_field_process() {
global $woocommerce;
// Check if set, if its not set add an error. This one is only requite for companies
if ( $_POST['billing_country'] == "NO" )
if (!$_POST['notes'])
$woocommerce->add_error( __('Please add the required information in "Order notes"') );
}
Alternatively, you can let customer place order and when order is placed, then scan for it if it has already ordered a sample product. And if found, then you can make status of that order as failed. - But this seems a bit illogical.
Here's the sitch: I'm using a multi-page Gravity Form in conjunction with an external API.
On the first page of the form, the user supplies a phone number. On a subsequent page, I need to send the external API the phone number in order to retrieve the user's current settings, which then must be prepopulated in other fields.
I know how to use gform_post_paging, but since $entry hasn't been created yet I can't use it to pull fields from previous pages.
gform_pre_submission/gform_after_submission don't help me because I need to make the API call prior to users reaching the end of the form.
I've also tried handling this via jQuery, by pulling and storing the value of the phone field on page advancement (e.g. var phoneNum = jQuery('#input_2_25').attr('value');), but I get "undefined" no matter what when using field ids. (It works fine, in the same location, looking for other ids on the site, so the issue isn't with jQuery.) I'm guessing this means that between pages, the form elements don't exist in the view?
How can I accomplish this goal (i.e., retrieving a value from a previous page in a multi-page Gravity Form prior to the user reaching the end of the form)?
All of the data is stored in the $_POST variable on each page submission. Gravity Forms has a helper function for accessing $POST data. The format for the variable name will be 'input{fieldId}'.
$value = rgpost( 'input_1' ); // replace "1" with your field ID
I am building a subscription service that will add certain items to a user's cart automatically once per week, without their needing to log in. The problem is that WooCommerce seems to carry cart data in multiple spots, and I'm not sure which can serve as a "master" cart that will take precedence. The persistent cart held in user meta appears to be subservient to session cart data. However, I cannot figure out how to get/set session cart data without actually logging in as the user through a browser.
Should I try to somehow spoof a user login to get access to session variables? Or is there a way to do this directly through the WooCommerce API?
So I figured out that session data is stored as a site option in the options meta, and if I set both the persistent cart AND the session to the same thing, then it will always load the proper information. Here's a snippet that shows how to do this with serialization:
function add_products_programmatically($user_id) {
// Get the current session data and saved cart
$wc_session_data = get_option('_wc_session_'.$user_id);
// Get the persistent cart
$full_user_meta = get_user_meta($user_id,'_woocommerce_persistent_cart', true);
// Create a new WC_Cart instance and add products programmatically
$cart = get_new_cart_with_products();
// If there is a current session cart, overwrite it with the new cart
if($wc_session_data) {
$wc_session_data['cart'] = serialize($cart->cart_contents);
update_option('_wc_session_'.$user_id, $wc_session_data);
}
// Overwrite the persistent cart with the new cart data
$full_user_meta['cart'] = $cart->cart_contents;
update_user_meta($user_id, '_woocommerce_persistent_cart', $full_user_meta);
}
The get_new_cart_with_products() function is just creating a new WC_Cart() object and adding items, then returning the cart object.