I need to add "something" to the Woocommerce payfast plugin to enable it to process split payments, as per the Payfast website it would look like this:
{ "split_payment" : { "merchant_id":10000105, "percentage":10, "amount":500, "min":100, "max":100000 } }
and it is submitted by form like this:
<input type="hidden" name="setup" value='{ "split_payment" : {
"merchant_id":10000105,
"percentage":10,
"min":100,
"max":100000}}' >
I have looked at the class-wc-gateway-payfast.php file and cannot see where this could be "injected" and I have looked for the html form and cannot find that either .... My gut tells me this is simple yet I cannot get my head around it :
The Payfast link giving me the instructions can be found here (in case I am not reading it properly) : https://developers.payfast.co.za/documentation/?html#direct-request-method
Am I not correct in my thinking that it must go here :
/**
* Generate the PayFast button link.
*
* #since 1.0.0
*/
public function generate_payfast_form( $order_id ) {
$order = wc_get_order( $order_id );
// Construct variables for post
$this->data_to_send = array(
// Merchant details
'merchant_id' => $this->merchant_id,
'merchant_key' => $this->merchant_key,
'return_url' => $this->get_return_url( $order ),
'cancel_url' => $order->get_cancel_order_url(),
'notify_url' => $this->response_url,
// Billing details
'name_first' => self::get_order_prop( $order, 'billing_first_name' ),
'name_last' => self::get_order_prop( $order, 'billing_last_name' ),
'email_address' => self::get_order_prop( $order, 'billing_email' ),
// Item details
'm_payment_id' => ltrim( $order->get_order_number(), _x( '#', 'hash before order number', 'woocommerce-gateway-payfast' ) ),
'amount' => $order->get_total(),
'item_name' => get_bloginfo( 'name' ) . ' - ' . $order->get_order_number(),
/* translators: 1: blog info name */
'item_description' => sprintf( __( 'New order from %s', 'woocommerce-gateway-payfast' ), get_bloginfo( 'name' ) ),
// Custom strings
'custom_str1' => self::get_order_prop( $order, 'order_key' ),
'custom_str2' => 'WooCommerce/' . WC_VERSION . '; ' . get_site_url(),
'custom_str3' => self::get_order_prop( $order, 'id' ),
'source' => 'WooCommerce-Free-Plugin',
);
The form gets generated based on the associative array. You would have to add the following to the array for split payments:
'setup' => json_encode(['split_payment' => ['merchant_id' => 10000105, 'percentage'=>10, 'min' => 100, 'max' => 100000]]),
The json_encode() function is used to convert the PHP multidimensional array into a JSON object. More information on the json_encode() function can be found here.
The complete array will be as follows:
$this->data_to_send = array(
// Merchant details
'merchant_id' => $this->merchant_id,
'merchant_key' => $this->merchant_key,
'return_url' => $this->get_return_url( $order ),
'cancel_url' => $order->get_cancel_order_url(),
'notify_url' => $this->response_url,
// Billing details
'name_first' => self::get_order_prop( $order, 'billing_first_name' ),
'name_last' => self::get_order_prop( $order, 'billing_last_name' ),
'email_address' => self::get_order_prop( $order, 'billing_email' ),
// Item details
'm_payment_id' => ltrim( $order->get_order_number(), _x( '#', 'hash before order number', 'woocommerce-gateway-payfast' ) ),
'amount' => $order->get_total(),
'item_name' => get_bloginfo( 'name' ) . ' - ' . $order->get_order_number(),
/* translators: 1: blog info name */
'item_description' => sprintf( __( 'New order from %s', 'woocommerce-gateway-payfast' ), get_bloginfo( 'name' ) ),
//Split Payment
'setup' => json_encode(['split_payment' => ['merchant_id' => 10000105, 'percentage'=>10, 'min' => 100, 'max' => 100000]]),
// Custom strings
'custom_str1' => self::get_order_prop( $order, 'order_key' ),
'custom_str2' => 'WooCommerce/' . WC_VERSION . '; ' . get_site_url(),
'custom_str3' => self::get_order_prop( $order, 'id' ),
'source' => 'WooCommerce-Free-Plugin',
);
Related
We needed another field in our products for Prod ref/Cat numbers and I found the bit of code below which works perfectly.
I now need to add a second field for Nominal Codes used by the accountants software.
I tried using the below code again, adjusted for the new field, but it didn't work.
function jk_add_custom_sku() {
$args = array(
'label' => __( 'Custom SKU', 'woocommerce' ),
'placeholder' => __( 'Enter custom SKU here', 'woocommerce' ),
'id' => 'jk_sku',
'desc_tip' => true,
'description' => __( 'This SKU is for internal use only.', 'woocommerce' ),
);
woocommerce_wp_text_input( $args );
}
add_action( 'woocommerce_product_options_sku', 'jk_add_custom_sku' );
function jk_save_custom_meta( $post_id ) {
// grab the SKU value
$sku = isset( $_POST[ 'jk_sku' ] ) ? sanitize_text_field( $_POST[ 'jk_sku' ] ) : '';
// grab the product
$product = wc_get_product( $post_id );
// save the custom SKU meta field
$product->update_meta_data( 'jk_sku', $sku );
$product->save();
}
add_action( 'woocommerce_process_product_meta', 'jk_save_custom_meta' );
Adding extra fields can be done in a very simple way:
function jk_add_custom_sku() {
$args_1 = array(
'label' => __( 'Custom SKU', 'woocommerce' ),
'placeholder' => __( 'Enter custom SKU here', 'woocommerce' ),
'id' => 'jk_sku',
'desc_tip' => true,
'description' => __( 'This SKU is for internal use only.', 'woocommerce' ),
);
woocommerce_wp_text_input( $args_1 );
// Extra field
$args_2 = array(
'label' => __( 'Nominal codes', 'woocommerce' ),
'placeholder' => __( 'Enter nominal codes here', 'woocommerce' ),
'id' => '_nominal_codes',
'desc_tip' => true,
'description' => __( 'This is for nominal codes.', 'woocommerce' ),
);
woocommerce_wp_text_input( $args_2 );
}
add_action( 'woocommerce_product_options_sku', 'jk_add_custom_sku' );
// Save
function jk_save_custom_meta( $product ){
if( isset($_POST['jk_sku']) ) {
$product->update_meta_data( 'jk_sku', sanitize_text_field( $_POST['jk_sku'] ) );
}
// Extra field
if( isset($_POST['_nominal_codes']) ) {
$product->update_meta_data( '_nominal_codes', sanitize_text_field( $_POST['_nominal_codes'] ) );
}
}
add_action( 'woocommerce_admin_process_product_object', 'jk_save_custom_meta', 10, 1 );
I'm trying to add a custom settings tab to the WooCommerce settings screen. Basically I want to achieve a similar thing to the Products settings tab, with the subsections/subtabs:
I haven't been able to find any decent documentation on how to do this but I've been able to add a custom tab using this snippet:
class WC_Settings_Tab_Demo {
public static function init() {
add_filter( 'woocommerce_settings_tabs_array', __CLASS__ . '::add_settings_tab', 50 );
}
public static function add_settings_tab( $settings_tabs ) {
$settings_tabs['test'] = __( 'Settings Demo Tab', 'woocommerce-settings-tab-demo' );
return $settings_tabs;
}
}
WC_Settings_Tab_Demo::init();
Based on what I've dug up from various threads/tutorials, I've been trying to add the sections/subtabs to the new settings tab something like this:
// creating a new sub tab in API settings
add_filter( 'woocommerce_get_sections_test','add_subtab' );
function add_subtab( $sections ) {
$sections['custom_settings'] = __( 'Custom Settings', 'woocommerce-custom-settings-tab' );
$sections['more_settings'] = __( 'More Settings', 'woocommerce-custom-settings-tab' );
return $sections;
}
// adding settings (HTML Form)
add_filter( 'woocommerce_get_settings_test', 'add_subtab_settings', 10, 2 );
function add_subtab_settings( $settings, $current_section ) {
// $current_section = (isset($_GET['section']) && !empty($_GET['section']))? $_GET['section']:'';
if ( $current_section == 'custom_settings' ) {
$custom_settings = array();
$custom_settings[] = array( 'name' => __( 'Custom Settings', 'text-domain' ),
'type' => 'title',
'desc' => __( 'The following options are used to ...', 'text-domain' ),
'id' => 'custom_settings'
);
$custom_settings[] = array(
'name' => __( 'Field 1', 'text-domain' ),
'id' => 'field_one',
'type' => 'text',
'default' => get_option('field_one'),
);
$custom_settings[] = array( 'type' => 'sectionend', 'id' => 'test-options' );
return $custom_settings;
} else {
// If not, return the standard settings
return $settings;
}
}
I've been able to add new subsections to the Products tab using similar code to the above, but it isn't working for my new custom tab. Where am I going wrong here?
1) To add a setting tab with sections, you can firstly use the woocommerce_settings_tabs_array filter hook:
// Add the tab to the tabs array
function filter_woocommerce_settings_tabs_array( $settings_tabs ) {
$settings_tabs['my-custom-tab'] = __( 'My custom tab', 'woocommerce' );
return $settings_tabs;
}
add_filter( 'woocommerce_settings_tabs_array', 'filter_woocommerce_settings_tabs_array', 99 );
2) To add new sections to the page, you can use the woocommerce_sections_{$current_tab} composite hook where {$current_tab} need to be replaced by the key slug that is set in the first function:
// Add new sections to the page
function action_woocommerce_sections_my_custom_tab() {
global $current_section;
$tab_id = 'my-custom-tab';
// Must contain more than one section to display the links
// Make first element's key empty ('')
$sections = array(
'' => __( 'Overview', 'woocommerce' ),
'my-section-1' => __( 'My section 1', 'woocommerce' ),
'my-section-2' => __( 'My section 2', 'woocommerce' )
);
echo '<ul class="subsubsub">';
$array_keys = array_keys( $sections );
foreach ( $sections as $id => $label ) {
echo '<li>' . $label . ' ' . ( end( $array_keys ) == $id ? '' : '|' ) . ' </li>';
}
echo '</ul><br class="clear" />';
}
add_action( 'woocommerce_sections_my-custom-tab', 'action_woocommerce_sections_my_custom_tab', 10 );
3) For adding the settings, as well as for processing/saving, we will use a custom function, which we will then call:
// Settings function
function get_custom_settings() {
global $current_section;
$settings = array();
if ( $current_section == 'my-section-1' ) {
// My section 1
$settings = array(
// Title
array(
'title' => __( 'Your title 1', 'woocommerce' ),
'type' => 'title',
'id' => 'custom_settings_1'
),
// Text
array(
'title' => __( 'Your title 1.1', 'text-domain' ),
'type' => 'text',
'desc' => __( 'Your description 1.1', 'woocommerce' ),
'desc_tip' => true,
'id' => 'custom_settings_1_text',
'css' => 'min-width:300px;'
),
// Select
array(
'title' => __( 'Your title 1.2', 'woocommerce' ),
'desc' => __( 'Your description 1.2', 'woocommerce' ),
'id' => 'custom_settings_1_select',
'class' => 'wc-enhanced-select',
'css' => 'min-width:300px;',
'default' => 'aa',
'type' => 'select',
'options' => array(
'aa' => __( 'aa', 'woocommerce' ),
'bb' => __( 'bb', 'woocommerce' ),
'cc' => __( 'cc', 'woocommerce' ),
'dd' => __( 'dd', 'woocommerce' ),
),
'desc_tip' => true,
),
// Section end
array(
'type' => 'sectionend',
'id' => 'custom_settings_1'
),
);
} elseif ( $current_section == 'my-section-2' ) {
// My section 2
$settings = array(
// Title
array(
'title' => __( 'Your title 2', 'woocommerce' ),
'type' => 'title',
'id' => 'custom_settings_2'
),
// Text
array(
'title' => __( 'Your title 2.2', 'text-domain' ),
'type' => 'text',
'desc' => __( 'Your description 2.1', 'woocommerce' ),
'desc_tip' => true,
'id' => 'custom_settings_2_text',
'css' => 'min-width:300px;'
),
// Section end
array(
'type' => 'sectionend',
'id' => 'custom_settings_2'
),
);
} else {
// Overview
$settings = array(
// Title
array(
'title' => __( 'Overview', 'woocommerce' ),
'type' => 'title',
'id' => 'custom_settings_overview'
),
// Section end
array(
'type' => 'sectionend',
'id' => 'custom_settings_overview'
),
);
}
return $settings;
}
3.1) Add settings, via the woocommerce_settings_{$current_tab} composite hook:
// Add settings
function action_woocommerce_settings_my_custom_tab() {
// Call settings function
$settings = get_custom_settings();
WC_Admin_Settings::output_fields( $settings );
}
add_action( 'woocommerce_settings_my-custom-tab', 'action_woocommerce_settings_my_custom_tab', 10 );
3.2) Process/save the settings, via the woocommerce_settings_save_{$current_tab} composite hook:
// Process/save the settings
function action_woocommerce_settings_save_my_custom_tab() {
global $current_section;
$tab_id = 'my-custom-tab';
// Call settings function
$settings = get_custom_settings();
WC_Admin_Settings::save_fields( $settings );
if ( $current_section ) {
do_action( 'woocommerce_update_options_' . $tab_id . '_' . $current_section );
}
}
add_action( 'woocommerce_settings_save_my-custom-tab', 'action_woocommerce_settings_save_my_custom_tab', 10 );
Result:
Based on:
Implement a custom WooCommerce settings page, including page sections
woocommerce/includes/admin/settings/
I am using the following code to display an additional input field on the edit account page of WooCommerce.
/**
* Step 1. Add your field - Age Range
*/
add_action( 'woocommerce_edit_account_form', 'misha_add_age_range_field_account_form' );
function misha_add_age_range_field_account_form() {
echo "<h4> Please fill in the following details to complete your profile for review </h4>";
woocommerce_form_field(
'certified_age_range',
array(
'type' => 'text',
'required' => true, // remember, this doesn't make the field required, just adds an "*"
'label' => 'Your Age',
'description' => '',
),
get_user_meta( get_current_user_id(), 'certified_age_range', true ) // get the data
);
}
/**
* Step 2. Save field value
*/
add_action( 'woocommerce_save_account_details', 'misha_save_age_range_account_details' );
function misha_save_age_range_account_details( $user_id ) {
update_user_meta( $user_id, 'certified_age_range', sanitize_text_field( $_POST['certified_age_range'] ) );
}
/**
* Step 3. Make it required
*/
add_filter('woocommerce_save_account_details_required_fields', 'misha_make_field_required');
function misha_make_age_range_field_required( $required_fields ){
$required_fields['certified_age_range'] = 'Age';
return $required_fields;
}
add_filter( 'woocommerce_customer_meta_fields', 'misha_admin_age_range_field' );
function misha_admin_age_range_field( $admin_fields ) {
$admin_fields['billing']['fields']['certified_age_range'] = array(
'label' => 'Age',
'description' => 'Get Certified Form Field',
);
return $admin_fields;
}
The code above works perfectly, and this is how the 'Age' field appears on the page:
But now I need to make this field into a dropdown one instead of a simple text field.
This said, I tried doing the above customisation with the following code but without the desired result. Any advice?
add_filter( 'woocommerce_save_account_details_required_fields' , 'custom_override_age_field' );
function custom_override_age_field( $account_fields ) {
$option_age = array(
'' => __( 'Select your Age Range' ),
'18-24' => '18-24',
'25-34' => '25-34',
'35-44' => '35-44',
'45-54' => '45-54',
'55-64' => '55-64',
'65+' => '65+',
);
$account_fields['account_first_name']['type'] = 'select';
$account_fields['account_first_name']['options'] = $option_age;
return $account_fields;
}
Your code says: Step 1. Add your field - in your attempt you are using the hook from step 3.. while step 3 indicates Make it required so that's your first mistake.
The bottom line is that in the first step you have to edit the woocommerce_form_field settings. In your code the type is 'text' and you have to change this to 'select'.
So you get:
/**
* Step 1. Add your field - Age Range
*/
function action_woocommerce_edit_account_form() {
echo "<h4> Please fill in the following details to complete your profile for review </h4>";
// Select field
woocommerce_form_field( 'certified_age_range', array(
'type' => 'select',
'class' => array( 'form-row-wide' ),
'label' => __( 'Your age', 'woocommerce' ),
'required' => true, // remember, this doesn't make the field required, just adds an "*"
'options' => array(
'' => __( 'Select your age range', 'woocommerce' ),
'18-24' => '18-24',
'25-34' => '25-34',
'35-44' => '35-44',
'45-54' => '45-54',
'55-64' => '55-64',
'65+' => '65+',
)
), get_user_meta( get_current_user_id(), 'certified_age_range', true ) );
}
add_action( 'woocommerce_edit_account_form', 'action_woocommerce_edit_account_form', 10, 0 );
/**
* Step 2. Make it required
*/
function filter_woocommerce_save_account_details_required_fields( $required_fields ) {
$required_fields['certified_age_range'] = __( 'Age', 'woocommerce' );
return $required_fields;
}
add_filter( 'woocommerce_save_account_details_required_fields', 'filter_woocommerce_save_account_details_required_fields', 10, 1 );
/**
* Step 3. Save field value
*/
function action_woocommerce_save_account_details( $user_id ) {
if ( isset( $_POST['certified_age_range'] ) ) {
// Update field
update_user_meta( $user_id, 'certified_age_range', sanitize_text_field( $_POST['certified_age_range'] ) );
}
}
add_action( 'woocommerce_save_account_details', 'action_woocommerce_save_account_details', 10, 1 );
/**
* Step 4. Get address fields for the edit user pages.
*/
function filter_woocommerce_customer_meta_fields( $args ) {
$args['billing']['fields']['certified_age_range'] = array(
'label' => __( 'Age', 'woocommerce' ),
'description' => __( 'Get Certified Form Field', 'woocommerce' ),
);
return $args;
}
add_filter( 'woocommerce_customer_meta_fields', 'filter_woocommerce_customer_meta_fields', 10, 1 );
I want to import a large quantity of products, the plugin is there and everything works, but I want to replace one word (different) in the product names with another word. 32,000 products, one product cannot be made.
I've tried different options, the only one that doesn't get into the wordpress error is the code below, but it doesn't work, I won't actually import the products.
** part between invalid
protected function generate_product_data($product){
$categories = array_values(array_unique(array_map('trim', explode('>', $product['Category']))));
$sku_prefix = get_option(PREFIX . '_sku_prefix', '');
$images = $this->get_images($product);
$sku_raw = $product['SKU'];
$sku = empty($sku_prefix) ? $sku_raw : "{$sku_prefix}{$sku_raw}";
$webshop_price = empty(Utility::rgar($product, 'Webshop_price')) ? null : Utility::clean_price( $product['Webshop_price'] );
$drop_price = empty(Utility::rgar($product, 'drop_Price')) ? $webshop_price : Utility::clean_price( $product['drop_Price'] );
$price = $this->get_price($product);
**
function replace_text($replace){
$replace = str_replace("badword", "goodword",$replace);
$replace = str_replace("badword1", "goodword1",$replace);
return $replace;}
$data = array(
'title' => $product[replace_text('Product_title')],**
'description' => $product['HTML_description'],
'excerpt' => $product['Properties'],
'categories' => $categories,
'images' => $images,
'attributes' => array(
'Color' => $product['Color'],
'Gender' => $product['Gender'],
'Diameter' => Product::measurements_number( $product['Diameter'] ),
'Size' => Product::measurements_number( $product['Size'] ),
'Shipping_time' => $this->get_shipping_time($product),
'Number_of_packages' => $product['Number_of_packages'],
),
'meta' => array(
'_regular_price' => $price,
'_price' => $price,
'B2B_price' => Utility::clean_price( $product['B2B_price'] ),
'RRP_price' => Utility::clean_price( $product['RRP'] ),
'drop_price' => $drop_price,
'_sku' => $sku,
'_manage_stock' => 'yes',
'_stock' => $product['Stock'],
'_stock_status' => $product['Stock'] == '0' ? 'outofstock' : 'instock',
'_weight' => Product::measurements_number( $product['Weight'] ),
PREFIX . '_ean' => $product['EAN'],
PREFIX . '_sku_raw' => $sku_raw,
PREFIX . '_image_urls' => $images,
PREFIX . '_shipping_time' => $this->get_shipping_time($product),
PREFIX . '_parcel_or_pallet' => $product['Parcel_or_pallet'],
PREFIX . '_number_of_packages' => $product['Number_of_packages'],
)
);
return $data;
}
I am using woocommerce for my site. I wanna to add some extra fields in add product page following to SKU, Regular Price, Sale Price.. Extra fields contains default values like 2% or 5%. when user enters Product price it should be calculated with default field values & result should be displayed in another field..
For Example:
SKU : 001
Regular Price(Rs) : 100
Added Text Field1 : 5% (5% of 100 = 5)
Added Text Field2 : 2% (2% of 100 = 2)
Answer Field : 107 (100 + 5 + 2)
Note: Answer field should be automatically calculated from values present in Regular Price/Sale Price + added text field1 + added text field2.
How to do this???
I have created fields using following function...
// Display Fields
add_action( 'woocommerce_product_options_general_product_data', 'woo_add_custom_general_fields' );
// Save Fields
add_action( 'woocommerce_process_product_meta', 'woo_add_custom_general_fields_save' );
function woo_add_custom_general_fields() {
global $woocommerce, $post;
echo '<div class="options_group">';
// Custom fields will be created here...
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_text_field',
'label' => __( 'Our Commision', 'woocommerce' ),
'placeholder' => '5%',
'desc_tip' => 'true',
'description' => __( 'Commision will be added to Product Actual Price', 'woocommerce' )
)
);
// Text Field
woocommerce_wp_text_input(
array(
'id' => '_text_field',
'label' => __( 'Payment Gateway Charges', 'woocommerce' ),
'placeholder' => '2%',
'desc_tip' => 'true',
'description' => __( 'Payment Gateway Charges will be added to Product Actual Price', 'woocommerce' )
)
);
echo 'Selling Price = Your Price + Our Commision + Payment Gateway Charges.';
echo '</div>';
}
Add below code to your theme's functions.php :
add_action( 'woocommerce_product_options_general_product_data', 'so28712303_rohil_add_custom_general_fields' );
// Save Fields
add_action( 'woocommerce_process_product_meta', 'so28712303_rohil_add_custom_general_fields_save' );
function so28712303_rohil_add_custom_general_fields() {
global $woocommerce, $post;
echo '<div class="options_group">';
woocommerce_wp_text_input(
array(
'id' => 'field_1',
'label' => __( '<strong>Extra Field 1</strong>', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Please enter a number', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
echo '</div>';
echo '<div class="options_group">';
woocommerce_wp_text_input(
array(
'id' => 'field_2',
'label' => __( '<strong>Extra Field 2</strong>', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Please enter a number', 'woocommerce' ),
'type' => 'number',
'custom_attributes' => array(
'step' => 'any',
'min' => '0'
)
)
);
echo '</div>';
echo '<div class="options_group">';
woocommerce_wp_text_input(
array(
'id' => 'result_field',
'label' => __( '<strong style="color:#239804">Result</strong>', 'woocommerce' ),
'placeholder' => '',
'description' => __( 'Percentage of Price', 'woocommerce' ),
'type' => 'number',
'readonly' => 'readonly',
'custom_attributes' => array(
'step' => 'any',
'min' => '0',
'readonly' => 'readonly'
)
)
);
echo '</div>';
}//so28712303_rohil_add_custom_general_fields
function so28712303_rohil_add_custom_general_fields_save( $post_id ){
$woocommerce_field_1 = $_POST['field_1']; //Value of Extra field 1
$woocommerce_field_2 = $_POST['field_2']; //Value of Extra field 2
$woocommerce_result_field = $_POST['result_field']; //No use of this..you can delete
$regular_price = $_POST['_regular_price']; //Value of regular price
if( !empty( $woocommerce_field_1 ) || !empty( $woocommerce_field_2 ) ):
update_post_meta( $post_id, 'field_1', esc_attr( $woocommerce_field_1 ) ); //Save value of Extra Field 1
update_post_meta( $post_id, 'field_2', esc_attr( $woocommerce_field_2 ) ); //Save value of Extra Field 2
endif;
$result_field = ( $woocommerce_field_1 * $regular_price ) / 100 ; //Calculation goes here ...
//if(empty($woocommerce_result_field))
update_post_meta( $post_id, 'result_field', esc_attr( $result_field ) ); //Save result here ...
}
Let me know if you have any doubt.
Screen shot :