WooCommerce支付网关后台文件上传选项支持性及实现方案咨询
Great question! Let's break this down clearly:
First off, WooCommerce's default payment gateway settings API does NOT support the file field type out of the box. The built-in field types are limited to text inputs, selects, checkboxes, and textareas—so your initial code won't render or function as expected in the admin settings page.
But don't worry, we can build this custom file upload functionality using WooCommerce's hooks and WordPress's native file handling tools. Here's a step-by-step solution tailored for your payment gateway plugin:
Step 1: Add Custom Hooks to Your Gateway Class
In your payment gateway class (the standard structure for WooCommerce gateways), add these two hooks to hook into the settings rendering and saving process:
// Hook to add our custom file field to the gateway settings add_action('woocommerce_settings_fields_' . $this->id, array($this, 'add_sandbox_private_key_field')); // Hook to handle saving the uploaded file add_action('woocommerce_update_options_' . $this->id, array($this, 'save_sandbox_private_key_file'));
(If you're not using a class-based gateway, replace $this->id with your gateway's unique ID string.)
Step 2: Render the Custom File Upload Field
Create the add_sandbox_private_key_field method to output the file input and display the current uploaded file (if any):
public function add_sandbox_private_key_field() { // Get the currently saved file path (if exists) $current_key_path = get_option('woocommerce_' . $this->id . '_sandbox_pvt_key'); ?> <tr valign="top"> <th scope="row" class="titledesc"> <label for="woocommerce_<?php echo esc_attr($this->id); ?>_sandbox_pvt_key"> <?php _e('Test Private Key', 'woocommerce-custom-gateway'); ?> </label> <span class="woocommerce-help-tip" data-tip="<?php esc_attr_e('Please upload the test private key file; this is needed in order to test payment.', 'woocommerce-custom-gateway'); ?>"></span> </th> <td class="forminp"> <input type="file" name="sandbox_pvt_key_file" id="woocommerce_<?php echo esc_attr($this->id); ?>_sandbox_pvt_key_file" accept=".pem,.key" <!-- Restrict to common key file types --> /> <?php if ($current_key_path) : ?> <p class="description"> <?php printf(__('Current uploaded file: <code>%s</code>', 'woocommerce-custom-gateway'), esc_html(basename($current_key_path))); ?> </p> <?php endif; ?> </td> </tr> <?php }
Step 3: Handle File Upload and Save
Create the save_sandbox_private_key_file method to validate, upload, and save the file details securely:
public function save_sandbox_private_key_file() { // Check if a file was uploaded if (!empty($_FILES['sandbox_pvt_key_file']['tmp_name'])) { // Define allowed file types for security $allowed_mime_types = array( 'application/x-pem-file', 'text/plain', 'application/octet-stream' ); $allowed_extensions = array('pem', 'key'); // Validate file type and extension $file_info = wp_check_filetype($_FILES['sandbox_pvt_key_file']['name'], array( 'pem' => 'application/x-pem-file', 'key' => 'text/plain', )); if (!in_array($file_info['type'], $allowed_mime_types) || !in_array($file_info['ext'], $allowed_extensions)) { wc_add_notice(__('Invalid file type. Please upload a .pem or .key file.', 'woocommerce-custom-gateway'), 'error'); return; } // Handle the file upload using WordPress's native function $upload_result = wp_handle_upload( $_FILES['sandbox_pvt_key_file'], array('test_form' => false) // Bypass form test since we're in admin ); // Check for upload errors if (isset($upload_result['error'])) { wc_add_notice(__('File upload failed: ', 'woocommerce-custom-gateway') . $upload_result['error'], 'error'); } else { // Save the file URL to WooCommerce options update_option( 'woocommerce_' . $this->id . '_sandbox_pvt_key', esc_url($upload_result['url']) ); // Optional: If you need the file content instead of the path, save it directly // $key_content = file_get_contents($upload_result['file']); // update_option('woocommerce_' . $this->id . '_sandbox_pvt_key_content', $key_content); } } }
Step 4: Use the Private Key in Your Payment Logic
When you need to use the private key for hashing requests, retrieve it like this:
// Get the file path/URL $private_key_path = get_option('woocommerce_' . $this->id . '_sandbox_pvt_key'); // Read the file content $private_key_content = file_get_contents($private_key_path); // Use $private_key_content for your hashing operation
Important Security Notes
- Restrict file types: We've limited uploads to
.pemand.keyfiles to reduce risk—never allow arbitrary file uploads. - File permissions: WordPress handles this automatically, but ensure your uploads directory has secure permissions (typically 755 for folders, 644 for files).
- Alternative: Save content to database: If you want to avoid storing files on the server, save the key content directly to the database (commented in the code above) instead of the file path.
内容的提问来源于stack exchange,提问作者Prajwol

