@105EOC the way I was able to accomplish this is by hooking into the woocommerce_order_status_processing
action. This event is triggered once an order payment is complete, which in effect means that when someone submits the credit card payment, the action is triggered. The following code catches the order, and then loops through the shipping line items associated with it. Based on the product ids, it finds the vendor, and writes a “commission” line item to the WC Vendors commission table.
Important note: You must configure your WooCommerce to group the shopping cart into multiple “shipping packages” by vendor/product owner id. I’m using this: https://github.com/academe/wc-multiple-packages. If you skip this step, the values calculated by the below code will likely be wrong.
// Give vendors any shipping costs collected from the customer
function give_vendor_shipping_cost( $order_id, $vendor_id, $shipping_cost, $shipping_tax ) {
global $wpdb;
$insert_query = "INSERT INTO 'wp_pv_commission' ('order_id', 'vendor_id', 'qty', 'total_shipping', 'tax', 'status', 'time') VALUES (%d, %d, %d, %f, %f, %s, %s)";
$results = $wpdb->get_results( $wpdb->prepare( $insert_query,
$order_id,
$vendor_id,
0, // qty always 0 for a shipping line item, since it's not really relevant as it's a sum of total shipping
$shipping_cost,// total shipping
$shipping_tax,// total tax on shipping
"due", // finally, the status. need to be "due"
current_time('mysql', false)
) );
}
add_action( 'woocommerce_order_status_processing', 'give_shipping_costs_to_vendors' );
function give_shipping_costs_to_vendors( $order_id ) {
// TODO: add error checking to make sure that vendor doesn't get paid
// shipping twice or more for the same order
$order = new WC_Order( $order_id );
error_log("Adding shipping costs to commission table");
$shipping_line_items = $order->get_items( 'shipping' );
foreach ($shipping_line_items as $shipping) {
$shipping_cost = array_sum($shipping['item_meta']['cost']);
$shipping_tax = 0.0;
$shipping_tax_costs = unserialize($shipping['item_meta']['taxes'][0]);
foreach ($shipping_tax_costs as $rate_id => $value) {
$shipping_tax += floatval($value);
}
$product_ids = $shipping['item_meta']['_product_ids'];
// error_log(print_r($product_ids, true));
// in theory, we should make sure that there isn't more than one post_author regardless of the number of produts
// in practice, cart is grouped by vendor id anyhow, so any product_id associated with a shipping line
// should already be from the same vendor id
$vendor_id = get_post_field( 'post_author', reset($product_ids) ); // reset() gets first element
// error_log($vendor_id);
// TODO: get vendor_id from split($pduct)
give_vendor_shipping_cost( $order_id, $vendor_id, $shipping_cost, $shipping_tax );
}
return $order_id; // seems kinda pointless, but whatever
}