I have a store working with woocommerce plugin for wordpress and everytime a customer purchase something I record that sale in an internal software I'm using to track my shipments and inventory. To do this I'm using the webkooks feature of woocommerce and everything works fine, but now, I want to send some custom data in the webhook request. I have tried using "custom fields" or "product attributes" in my product but neither those fields are sent by the webhook request. So my question is, is there a way I can send aditional data in the webhook?
Thanks in advance.
I got it working, I used the following code to achieved it:
function add_order_item_meta($item_id, $values) {
$key = 'an_identifier';
$value = get_post_meta( $values['product_id'], 'custom_field_name', true );
woocommerce_add_order_item_meta($item_id, $key, $value);
}
add_action('woocommerce_add_order_item_meta', 'add_order_item_meta', 10, 2);
Related
I am using wordpress to build a website that uses Stripe as its payment gateway.
Through the Paid Membership Pro plugin I have configured my Stripe connection.
The issue I am faced with is that I need to append a custom field, in this case a unique identifier for the customer, to the payment information for it to be available to send via my webhook to my server for processing.
I have come across a load of answers but none seem to be doing exactly what I am looking for.
I noticed in the PMPro plugin it allows you to add User Fields which I presumed would be a way to add custom data to the information but after checking the JSON payloads in Stripe none of the user field information is available.
I then tried adding the code from this answer to my functions.php file in word press just using a test meta key but again this information was not available in the payloads.
I am not using woocommerce.
How can I achieve this?
So I was able to crack this using a php script that intercepts the Stripe checkout event.
I added this as a snippet to my Wordpress site and to read in a custom field from the post submit.
Stripe allows you to add custom filed data to the metadata block and once populated this was successfully sent to my webhook.
function my_pmpro_stripe_params_send_user_id( $params, $order = null ) {
global $my_pmpro_checkout_order;
if ( empty( $params['metadata'] ) ) {
$params['metadata'] = array();
}
if ( empty ( $order ) ) {
// Save order while creating payment intent.
$order = $my_pmpro_checkout_order;
} else {
// Use saved order while creating subscription.
$my_pmpro_checkout_order = $order;
}
$params['metadata']['my_custom_field'] = $_POST['my_custom_value'];
return $params;
}
add_filter( 'pmpro_stripe_payment_intent_params', 'my_pmpro_stripe_params_send_user_id', 10, 2 );
add_filter( 'pmpro_stripe_create_subscription_array', 'my_pmpro_stripe_params_send_user_id', 10, 1 );
My PHP skills are not good but I learn by code example because I am not familiar with the syntax, but in this case I can not find a code example that works.
I want to set a Product Option Radio Button Field's selected value during a gform_pre_submission add_action based on another field's value. I've tried something like this (there are other functions and variables are defined elsewhere in advance, this is an abstract) but this approach isn't working for me and I am wondering what I am missing:
add_action( 'gform_pre_submission_FORMIDhere', 'select_radio_button' );
function select_radio_button( $form) {
foreach( $form['fields'] as &$field ) {
if( 53 === $field->id ) {
foreach( $field->choices as &$choice ) {
echo($aag_kg_nummorn.' / /'.$choice['value']);
if( $aag_kg_nummorn == $choice['value'] ) {
echo('Bingo!');
$choice['isSelected'] = true; // <- THIS line doesn't work for me
}
}
}
}
return $form;
}
Thank you for helping me in advance.
There are a couple of things I want to point out before answering
You should be modifying $_POST instead of the field, I can see you already figured this out.
gform_pre_submission is an action, not a filter, so returning the form here doesn't do anything.
The Answer
Say you have a product option field that has the ID of 2, and it has 3 options
First Option|1
Second Option|2
Third Option|3
Then the code will look like
add_action( 'gform_pre_submission_FORMIDhere', 'select_radio_button' );
function select_radio_button( $form ) {
$_POST['input_2'] = 'New Option|6';
}
I assume you are using this with a payment form that utilizes one of the gravityforms payment add-ons like stripe or Paypal, some of these add-ons (like PayPal Checkout) sends the total value to the payment gateway using JS before this action is fired, so the total value sent to the payment gateway will be the value of the option the user has already selected, but the total value on the entry will use the value you set in the code.
If you need help on how to override this from the JS side as well so you can send the overridden value to the payment gateway, I can write that in a separate answer.
Is there a simple way or a plugin to retain checkout information entered by the client after he/she leaves and comes back?
This plugin retains "fields information for customers when they navigate back and forth" however it has quite a lot of recent bad reviews so I don't think I'll use that for production. Any alternative suggestion?
---- Update ----
The code below is working, but only if data is submitted!
The only possible ways are javascript/jQuery form event detection on checkout fields and worpress Ajax:
Using ajax connected to some session transients function (as in code below).
Using (javascript) web Storage: localStorage, sessionStorage…
I have found some real interesting code in this thread that is using sessions transients to store checkout data.
// this function sets the checkout form data as session transients whenever the checkout page validates
function set_persitent_checkout ( $a ) {
$arr = array();
foreach ( $a as $key => $value )
if ( ! empty($value) )
$arr[$key] = $value;
WC()->session->set( 'form_data', $arr );
return $a;
}
add_action( 'woocommerce_after_checkout_validation', 'set_persitent_checkout' );
// this function hooks into woocommerce_checkout_get_value to substitute standard values with session values if present
function get_persistent_checkout ( $value, $index ) {
$data = WC()->session->get('form_data');
if ( ! $data || empty($data[$index]) )
return $value;
return is_bool($data[$index]) ? (int) $data[$index] : $data[$index];
}
add_filter( 'woocommerce_checkout_get_value', 'get_persistent_checkout', 10, 2 );
// This is a fix for the ship_to_different_address field which gets it value differently if there is no POST data on the checkout
function get_persitent_ship_to_different ( $value ) {
$data = WC()->session->get('form_data');
if ( ! $data || empty($data['ship_to_different_address']) )
return $value;
return is_bool($data['ship_to_different_address']) ? (int) $data['ship_to_different_address'] : $data['ship_to_different_address'];
}
add_action( 'woocommerce_ship_to_different_address_checked', 'get_persitent_ship_to_different' );
Add this code to the functions.php file located in your active child theme or theme.
Explanations from the author:
1. Save the form data:
The first function set_persitent_checkout hooks into woocommerce_after_checkout_validation.
Whenever that hook is fired, any current form data is saved as a WordPress transient via the WC_Session_Handler class (which was recently updated in version 2.5 to be a lot more efficient).
2. Check the saved data on reload:
Next we hook woocommerce_checkout_get_value with get_persitent_checkout. As the name suggests, here we check the session transients and return any matches for the current field if found.
3. Make ship_to_different_address work:
The only difficult was the ship_to_different_address field, which gets its value through a different method.
To get around this the final function was added. This works exactly the same as the previous function, but hooks into woocommerce_ship_to_different_address_checked.
There you have it. It would be nice if the data was saved after every field update on checkout, but the woocommerce_after_checkout_validation hook fires enough to capture the data at all the important points.
Functions.php snipped posted by LoicTheAztec didn't work for me.
I found this plugin which remembers everything I type or select in Woocommerce checkout, including shipping fields and my custom additions to the template:
Save Abandoned Carts – WooCommerce Live Checkout Field Capture
Account passwords, if creating during checkout, are naturally not remembered.
I am a WP noob but very comfortable in PHP.
I am working with a client and we have built a product customization tool as an Angular.js single page application. When the product is finished being customized we are seeking to inject it into a WooCommerce cart so the client can check out. To do this we are $_POSTing the data to a PHP file in the root directory of the WP install. The code to catch it looks like:
require_once('./wp-load.php' );
global $woocommerce;
$woocommerce->session->set_customer_session_cookie(true);
$woocommerce->cart->empty_cart();
$id_arr = $_GET['productID'];
$pdfName = $_GET['pdfName'];
for($i=0; $i<count($id_arr); $i++){
$id = $id_arr[$i];
if ($id==0) continue;
if ($i==0){
$ret = $woocommerce->cart->add_to_cart($id, 1, '', '', array('pdfName'=>$pdfName));
}else{
$ret = $woocommerce->cart->add_to_cart($id);
}
}
wp_redirect(site_url().'/cart/');
The products are all correctly added to the cart but after checkout there is no sign of the metadata. After extensive research, I have found an article here: https://wpml.org/forums/topic/woocommerce-add-to-cart-does-not-work-with-wpml-activated/ that shows me that plugins can cause this behavior. So I have two specific questions?
Does my code make sense, am I creating the metadata array correctly?
Do I need to create something in WooCommerce called pdfName before I can do this?
Is there another way that metadata can be added to an order in
WooCommerce that may work around this problem?
It looks like you are adding the metadata correctly. However, as soon as you refresh, WooCommerce re-creates the cart data. Therefore you have to tell WooCommerce to maintain the metadata when it is pulling the cart from the stored session. Well, at least that is my understanding of it. So I think you need to filter thee $cart_item as it is run through the woocommerce_get_cart_item_from_session filter:
add_filter( 'woocommerce_get_cart_item_from_session', 'so_29660316_get_cart_item_from_session', 11, 2 );
function so_29660316_get_cart_item_from_session( $cart_item, $values ) {
if ( isset( $values['pdfName'] ) ) {
$cart_item['pdfName'] = $values['pdfName'];
}
return $cart_item;
}
I have a problem that I am not sure how to fix.
I have a formstack form on my wordpress site. It allows people to buy a product. For this
particular page, there is only one item available for sale, so once the
form is processed (data sent to Formstack->Stripe and payment confirmation received),
the page needs to "turn off" so others can't purchase the item.
Before I used formstack, I used gravity forms plugin.
When the form submitted, I had a add_action filter in my functions.php in
wordpress. It fired when gravity forms completed the submission process and
ran a function that turned off the page.
Here is that code that worked beautifully.
add_action("gform_after_submission", "set_post_content", 10, 2);
function set_post_content(){
global $cfs;
$field_data = array('sold' => '1');
$post_data = array('ID' => get_the_ID()); // the ID is required
$cfs->save($field_data, $post_data);
}
I see formstack has a webhook function.
I cannot seem to find code on how to parse the data the formstack webhook sends. I used http://requestb.in/ to see the data that was being sent.
I believe I need to use php://input, but once I read the data, I am not sure how to say
If formstack webhook fires, then run this code
function set_post_content(){
global $cfs;
$field_data = array('sold' => '1');
$post_data = array('ID' => get_the_ID()); // the ID is required
$cfs->save($field_data, $post_data);
}
I also believe the code needs to be in the functions.php in my theme file because otherwise it won't understand the $cfs variable that is from another wordpress plugin.
I saw this new formstack function the other day - it sounds like it could solve your problem?http://support.formstack.com/customer/portal/articles/1444519-event-fields
Event handling options
When your Event has filled to capacity, you can mark the Event as "Sold Out" so new submitters will see the item is no longer available. You may also choose to hide this field on the Form once the items have sold out. Additionally, you can deactivate the whole Form when the Event has sold out; this is done through the Form Settings tab > General > Deactivate Form settings.