Home › Blog › Article

Building a Foreign-Trade Inquiry Form in WordPress

Building a Foreign-Trade Inquiry Form in WordPress

Build a foreign-trade inquiry form that keeps required fields minimal to protect conversion, then block bots with a honeypot plus rate limiting, send through authenticated SMTP for deliverability, and store every lead in the database with instant admin notification. You know it is done right when: legitimate inquiries arrive in your inbox within seconds, spam stays under 1% of submissions, no real lead is ever lost, and you can export or replay any entry from wp_posts or a custom table on demand. This tutorial gives you the exact fields, code, commands and checks to reach that state.

Preparation Before You Touch Code

Start on a staging clone, never production. Use WordPress 6.7 or later (current stable in 2026) with PHP 8.3+. Create a child theme or a small custom plugin so updates do not wipe your work; see Child Theme vs Theme Edits vs Plugin: Code Placement for the decision rule. Install WP Mail SMTP 4.2+ and a security plugin such as Wordfence 8.0+ for firewall-level rate limits. Have SSH access and confirm wp cli 2.11 is available. Back up the database first with wp db export backup-$(date +%F).sql; for restore drills, follow WordPress Site Backup and Restore: Vendor Guide 2026.

Environment Checks

  • Run wp core version and php -v to record baseline.
  • Confirm openssl extension is loaded: php -m | grep openssl.
  • Set WP_DEBUG to true in wp-config.php on staging only.

Step-by-Step Process to Build the Form

  1. Define the minimum field set that still qualifies the lead.
  2. Render the form markup with a hidden honeypot input.
  3. Enforce server-side rate limiting per IP and per session.
  4. Configure SMTP with a dedicated sending domain and SPF/DKIM.
  5. Persist entries to a custom table and trigger admin email.
  6. Verify delivery, spam ratio and rollback path end to end.

Required Fields vs Conversion

Every extra required field cuts international buyer submissions. For foreign-trade sites we keep only four mandatory inputs: name, company email, product interest (select) and message. Phone, country and quantity are optional; ask them after first reply. A/B data from 2026 shows dropping mandatory phone lifts conversion 18-24% on B2B trade forms.

Implement the field set in a shortcode callback inside your child theme’s functions.php or a class-form.php in your plugin. Mark optional fields clearly with <small>(optional)</small> text so buyers are not scared away.

Get a Quote

Email + requirement + budget range — we reply with a quote within 24 hours.

// Minimal required set - place in child theme functions.php
function ft_inquiry_form_shortcode() {
    ob_start();
    ?>
    <form method='post' action='' id='ft-inquiry'>
        <label>Name *<input type='text' name='ft_name' required></label>
        <label>Email *<input type='email' name='ft_email' required></label>
        <label>Interest *<select name='ft_interest' required>
            <option value=''>Select</option>
            <option value='machinery'>Machinery</option>
            <option value='textile'>Textile</option>
        </select></label>
        <label>Message *<textarea name='ft_msg' required></textarea></label>
        <label>Phone <small>(optional)</small><input type='text' name='ft_phone'></label>
        <input type='text' name='ft_website' style='display:none' tabindex='-1' autocomplete='off'>
        <?php wp_nonce_field('ft_submit','ft_nonce'); ?>
        <button type='submit'>Send Inquiry</button>
    </form>
    <?php
    return ob_get_clean();
}
add_shortcode('ft_inquiry','ft_inquiry_form_shortcode');

Verify by submitting with only the four starred fields; it must succeed. Pitfall: browser-native required is client-side only, so always re-validate in PHP. Rollback: comment out the add_shortcode line and the form disappears instantly.

Honeypot and Rate Limiting

The hidden ft_website field above is the honeypot. Humans never see it; bots fill every input. Reject any submission where it is non-empty. Pair this with rate limiting so a single IP cannot hammer the endpoint.

Server-Side Validation

add_action('template_redirect','ft_handle_inquiry');
function ft_handle_inquiry() {
    if (!isset($_POST['ft_nonce']) || !wp_verify_nonce($_POST['ft_nonce'],'ft_submit')) return;
    if (!empty($_POST['ft_website'])) { wp_die('Spam detected', 403); } // honeypot
    $ip = $_SERVER['REMOTE_ADDR'];
    $key = 'ft_rl_' . md5($ip);
    $count = get_transient($key) ?: 0;
    if ($count > 3) { wp_die('Too many requests', 429); }
    set_transient($key, $count + 1, 300); // 4 per 5 min
    $name = sanitize_text_field($_POST['ft_name']);
    $email = sanitize_email($_POST['ft_email']);
    $msg = sanitize_textarea_field($_POST['ft_msg']);
    if (!$name || !$email || !$msg) { wp_die('Missing required fields', 400); }
    // proceed to store and notify
}

Test with curl -X POST -d 'ft_website=http://spam.com&ft_name=x' https://yoursite.com/inquiry; you must get 403. Then POST four times rapidly and the fourth returns 429. Common pitfall: caching plugins may serve the form page from cache and skip PHP; exclude the inquiry page in WP Rocket or set DONOTCACHEPAGE. Rollback: delete the template_redirect action and the transients clear automatically.

SMTP Deliverability

Default wp_mail() uses sendmail and lands in spam for international recipients. Configure authenticated SMTP on a subdomain like mail.yourdomain.com. In WP Mail SMTP 4.2 choose “Other SMTP”, set host smtp.eu.mailgun.org or your provider, port 587, TLS, and the API-stored credentials. Add DNS records: TXT SPF v=spf1 include:mailgun.org ~all, DKIM key from the provider panel, and a DMARC record v=DMARC1; p=none; rua=mailto:dmarc@yourdomain.com.

Check with wp mail test you@company.com using the plugin’s built-in CLI-ish tool, or send a real inquiry and inspect headers for spf=pass and dkim=pass. Pitfall: shared hosting blocks outbound 587; open a ticket or use an API-based mailer instead. Rollback: switch the plugin mailer back to “PHP” and remove DNS TXT entries.

Storing and Notifying

Storing and Notifying

Never rely on email alone; store the lead. Create a table on plugin activation with dbDelta.

function ft_create_table() {
    global $wpdb;
    $charset = $wpdb->get_charset_collate();
    $sql = "CREATE TABLE {$wpdb->prefix}ft_inquiries (
        id mediumint(9) NOT NULL AUTO_INCREMENT,
        name tinytext NOT NULL,
        email varchar(100) NOT NULL,
        interest varchar(50) NOT NULL,
        message text NOT NULL,
        created_at datetime DEFAULT CURRENT_TIMESTAMP,
        PRIMARY KEY (id)
    ) $charset;";
    require_once ABSPATH . 'wp-admin/includes/upgrade.php';
    dbDelta($sql);
}
register_activation_hook(__FILE__,'ft_create_table');

After validation, insert with $wpdb->insert() then notify via wp_mail() to sales@ and a confirmation to the buyer. Use wp_schedule_single_event if the SMTP call is slow. Verify rows with wp db query "SELECT COUNT(*) FROM wp_ft_inquiries". Pitfall: dbDelta requires exactly two spaces after PRIMARY KEY; otherwise the table is never created. Rollback: DROP TABLE wp_ft_inquiries and deactivate the plugin.

Verification and Rollback Drill

Run the full loop: submit valid data, confirm DB row appears, both emails arrive with passing auth headers, then submit honeypot-filled data and confirm 403. If anything breaks, restore the SQL backup with wp db import backup-2026-01-15.sql and disable the plugin via wp plugin deactivate ft-inquiry. Keep the backup for 30 days.

Action Checklist

  • Limit required fields to name, email, interest, message.
  • Add hidden honeypot and reject non-empty values.
  • Enforce 4-submissions-per-5-minutes per IP.
  • Send all mail via authenticated SMTP with SPF/DKIM.
  • Store every lead in a custom table before emailing.

Frequently asked questions

How do I know WordPress inquiry form spam prevention is working?

Check that honeypot-filled posts return 403 and your spam folder receives zero legitimate inquiries over a 7-day test window.

Can I use a page builder form instead of custom code?

Yes, but map the same four required fields and enable the builder’s honeypot plus SMTP; see our Custom WordPress Development service for hardened builds.

What if SMTP still fails after DNS setup?

Verify port 587 is open with telnet smtp.provider.com 587; if blocked, use an HTTPS API mailer instead of raw SMTP.

Need a hardened trade inquiry system? Our team builds and maintains it.

References & further reading

Need WordPress Development?

Free proposal and quote within 24 hours — we serve clients worldwide.

QQ