If you are envolved of WooCommerce payment gateway’s development you’re probably familiar of how to define fields with an array for payment gateway’s settings page. But if you want to add a custom field you have to implement a function for it.
There are many posts on the web for how to extend WooCommerce admin fields with a custom field hook. But extending WooCommerce payment gateway’s settings page with a custom field is little bit different. Nothing was found in the web, so inspectation of WooCommerce itself was needed. After research of the abstract class WC_Payment_Gateway and his ancestor WC_Settings_API the solution was found. The method WC_Settings_API::generate_settings_html() is responsible for rendering content of the settings page. More info here:
The method checks for existence of generate_’ . $type . ‘_html() method and if you want to display and handle custom field you have to write such method in your payment gateway’s class. In this example we’re adding a custom icon field.
Step 1: Define the field in array passed to $this->form_fields.
array(
...
'icon' => array(
'title' => esc_html__( 'Logo', 'text-domain' ),
'desc' => esc_html__( 'This controls the image which the user sees during checkout.', 'text-domain' ),
'type' => 'icon',
'default' => '',
'desc_tip' => true,
)
...
)
Step 2: Provide a method with field type.
public function generate_icon_html( $key, $data ) {
$field_key = $this->get_field_key( $key );
$defaults = array(
'title' => '',
'disabled' => false,
'class' => '',
'css' => '',
'placeholder' => '',
'type' => 'text',
'desc_tip' => false,
'description' => '',
'custom_attributes' => array(),
);
$data = wp_parse_args( $data, $defaults );
$data['id'] = 'woocommerce_' . $this->id . '_icon';
$data['value'] = $this->get_option( 'icon' );
ob_start();
?>
<tr valign="top">
<th scope="row" class="titledesc">
<label for="<?php echo esc_attr( $data['id'] ); ?>">
<?php echo esc_html( $data['title'] ); ?>
<span class="woocommerce-help-tip" data-tip="<?php echo esc_html( $data['desc'] ); ?>"></span>
</label>
</th>
<td class="forminp forminp-<?php echo esc_attr( $data['type'] ) ?>">
<input
type="hidden"
id="<?php echo esc_attr( $data['id'] ); ?>"
name="<?php echo esc_attr( $data['id'] ); ?>"
value="<?php echo esc_attr( $data['value'] ); ?>"
>
<img src="<?php echo ! empty( $data['value'] ) ? esc_url( wp_get_attachment_image_url( $data['value'], 'medium' ) ) : ''; ?>">
<p class="controls">
<button class="button-primary add-media">
<?php esc_html_e( 'Add Logo', 'text-domain' ); ?>
</button>
<button class="button-secondary remove-media">
<?php esc_html_e( 'Remove Logo', 'text-domain' ); ?>
</button>
</p>
</td>
</tr>
<?php
return ob_get_clean();
}
Step 3. Load wp.media object in Javascript and implement it with buttons click listeners to upload/browse the files library and set the value of the hidden input.
Hope you enjoy the article!