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 );
Related
My customer wants to enable for some specific customers to pay afterwards via invoice.
So i've added an extra field in the user profiles, where he can select yes/no.
This field works fine and saves properly.
Depending on the choice:
no = default webshop behavior and customer needs to pay direct.
yes = customer can order items without paying, he'll get an invoice later on.
Also tried different payment methods, but they are available for everybody, i only want them for specific users.
Now i've tried based on that field in the functions.php to add a conditional filter like so:
if (esc_attr( get_the_author_meta( 'directbetalen', $user->ID ) ) == 'no') {
add_filter('woocommerce_cart_needs_payment', '__return_false');
}
But it doesn't seem to work?
I want payment to be skipped when the field is set to no.
Else proceed as normal and customer needs to pay.
Using WordPress get_user_meta() function, try the following :
add_filter( 'woocommerce_cart_needs_payment', 'disable_payment_for_specific_users' );
function show_specific_payment_method_for_specific_users( $needs_payment ) {
if ( get_user_meta( get_current_user_id(), 'directbetalen', true ) === 'no' ) {
$needs_payment = false;
}
return $needs_payment;
}
Code goes in functions.php file of your active child theme (or active theme). It should work.
My issue: The client has 12 locations, each location is a different corporation hence a different PayPal account per business. By default woocommerce only supports one email to be entered to process the payment. The goal is to use one installation of wordpress / woocommerce then direct the user to the PayPal account associated with the location they have selected upon checkout.
My Theory / Attempt: originally I thought of implementing this feature by setting up a variation so the user can select a location which will then pass a parameter to the URL. The parameter would later be used within the PHP to overwrite the default email.
My Problem: I am having trouble with overwriting the default email that is entered within the admin settings, I cant seem to locate this email in the database. I am assuming the file pertaining this modification is located at: wp-content/plugins/woocommerce/includes/gateways/paypal but would prefer doing this the wordpress way vs editing core files, for obvious reasons. After doing some research I have found the following action shown below, but this is for the proceed to checkout button, I am looking to interact with the proceed to PayPal button. I am fluent in PHP but not the best with WordPress development. I would think this is a popular issue since majority of franchises would deal with such a scenario, but I am unpleasantly surprised on the amount of information regarding this topic. If someone could point me in the right direction of conquering this task it would be greatly appreciated!
remove_action('woocommerce_proceed_to_checkout','woocommerce_button_proceed_to_checkout', 20);
add_action('woocommerce_proceed_to_checkout', 'change_url_to_checkout', 20);
function change_url_to_checkout(){
$extra_url = 'put_your_extra_page_url_here';
?>
<?php _e( 'Proceed to Checkout', 'woocommerce' ); ?>
<?php
}
I can see two functions to be written here.
1. To alter the order data when an order is created. This is where we save the email needed.
add_action( 'woocommerce_checkout_update_order_meta', 'woocommerce_checkout_update_order_meta' );
function woocommerce_checkout_update_order_meta( $order_id ) {
$email = 'paypal#location1.com';
// do something here as to use the right email.
// you have $order_id.
// can be used as:
// $order = wc_get_order( $order_id );
// $order->get_billing_address_1() to get the address to check order address.
// or use $_POST['location'] if ever you posted some data.
update_post_meta( $order_id, '_alternative_paypal_email', $email );
}
2. Then use woocommerce_paypal_args to alter the args that is being passed to paypal.
add_filter( 'woocommerce_paypal_args', 'woocommerce_paypal_args', 10, 2 );
function woocommerce_paypal_args( $paypal_args, $order ) {
$email = get_post_meta( $order->get_id(), '_alternative_paypal_email', true );
if ( !empty( $email ) ) {
$paypal_args['business'] = $email;
}
return $paypal_args;
}
To summarize, this is just an example. But these two hooks is enough to get what you need.
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 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);
I am currently building an ecommerce website that is used for 5 separate companies using woocommerce and authorize.net for the payment.
So far the authorization is working great for a single vendor, the issue comes in that once I have selected the vendor by location, I need to change the api_transaction_key and api_login_id to the correct vendor before payment is processed.
I have been searching the files for hours now and cannot find where the key and id are set.
Can someone help me find where I can overwrite the key and id values to what I need?
or would it be better to create a new payment gateway for each of the vendors and copy all of the authorize.net gateway information except the key and id?
This answer is here for if anyone is curious on how I was able to make this work.in the Authorize.net woocommerce payment gateway you'll find a file called
class-wc-authorize-net-cim-api.php
and it is in this file's contruct function that your hook needs to be placed.
public function __construct( $api_user_id, $api_transaction_key, $environment ) {
// File default code
}
This needs the follow three lines of code to be placed BEFORE the default file code
$custom_auth_info = apply_filters('get_custom_auth', $custom_auth_info );
$api_user_id = $custom_auth_info['api_user_id'];
$api_transaction_key = $custom_auth_info['api_transaction_key'];
The apply_filters refers to the following function that is placed in my plugin
add_filter('get_custom_auth', 'select_distributor_by_state');
function select_distributor_by_state($custom_auth_info = []) {
global $wpdb;
//Your Query is here to select the proper distributor from the DB
//and retrieve their custom Authorize.net ID and Transaction Key
$custom_auth_info['api_user_id'] = $your_query[0]['api_loginid'];
$custom_auth_info['api_transaction_key'] = $your_query[0]['api_transactionkey'];
$_SESSION['dealer'] = $vendor[0]['id'];
return $custom_auth_info;
}
This filter allows you to hook in, grab the data you need, then return it and apply it directly into the code before the payment is processed.