WooCommerce Plugin

A complete WordPress plugin that integrates Flash Americas shipping rates directly into your WooCommerce store. This plugin adds real-time shipping calculations at checkout and provides order tracking capabilities.

Overview

This plugin provides:

  • Real-time shipping rates at checkout
  • Multiple carrier options (FedEx, UPS, USPS, LTL)
  • Admin configuration panel for easy setup
  • Order tracking integration with customer notifications
  • Cross-border shipping support for Mexico
  • Flexible shipping rules and rate modifications

Installation

Method 1: WordPress Admin Upload

  1. Download the plugin zip file
  2. Go to Plugins > Add New in your WordPress admin
  3. Click Upload Plugin and select the zip file
  4. Click Install Now and then Activate

Method 2: FTP Upload

FTP installationbash
# Upload the plugin folder to your WordPress installation
wp-content/plugins/flash-americas-shipping/

Method 3: WordPress CLI

WP-CLI installationbash
wp plugin install flash-americas-shipping.zip --activate

Configuration

1. Basic Setup

Navigate to WooCommerce > Settings > Shipping > Flash Americas and configure:

  • API Key: Your Flash Americas API key
  • Environment: Production or Sandbox
  • Default Package Size: Fallback dimensions for products without measurements
  • Enable Debug Mode: For troubleshooting

2. Shipping Zones

Configure shipping zones in WooCommerce > Settings > Shipping:

  1. Create or edit a shipping zone
  2. Add "Flash Americas" as a shipping method
  3. Configure method settings

Plugin Structure

Main plugin file: flash-americas-shipping.phpphp
<?php
/**
* Plugin Name: Flash Americas Shipping
* Plugin URI: https://flashamericas.com/integrations/woocommerce
* Description: Real-time shipping rates from Flash Americas for WooCommerce
* Version: 1.2.0
* Author: Flash Americas
* License: GPL v2 or later
* Text Domain: flash-americas-shipping
* Domain Path: /languages
* Requires at least: 5.0
* Tested up to: 6.4
* WC requires at least: 4.0
* WC tested up to: 8.5
*/

// Prevent direct access
if (!defined('ABSPATH')) {
  exit;
}

// Define plugin constants
define('FLASH_AMERICAS_SHIPPING_VERSION', '1.2.0');
define('FLASH_AMERICAS_SHIPPING_PLUGIN_URL', plugin_dir_url(__FILE__));
define('FLASH_AMERICAS_SHIPPING_PLUGIN_PATH', plugin_dir_path(__FILE__));

// Check if WooCommerce is active
if (!in_array('woocommerce/woocommerce.php', apply_filters('active_plugins', get_option('active_plugins')))) {
  return;
}

/**
* Initialize the plugin
*/
function flash_americas_shipping_init() {
  if (!class_exists('WC_Shipping_Method')) {
      return;
  }

  // Include required files
  require_once FLASH_AMERICAS_SHIPPING_PLUGIN_PATH . 'includes/class-flash-americas-api.php';
  require_once FLASH_AMERICAS_SHIPPING_PLUGIN_PATH . 'includes/class-flash-americas-shipping-method.php';
  require_once FLASH_AMERICAS_SHIPPING_PLUGIN_PATH . 'includes/class-flash-americas-admin.php';
  require_once FLASH_AMERICAS_SHIPPING_PLUGIN_PATH . 'includes/class-flash-americas-tracking.php';

  // Initialize admin if in admin area
  if (is_admin()) {
      new Flash_Americas_Admin();
  }

  // Initialize tracking
  new Flash_Americas_Tracking();
}

add_action('woocommerce_shipping_init', 'flash_americas_shipping_init');

/**
* Add the shipping method to WooCommerce
*/
function flash_americas_add_shipping_method($methods) {
  $methods['flash_americas'] = 'Flash_Americas_Shipping_Method';
  return $methods;
}

add_filter('woocommerce_shipping_methods', 'flash_americas_add_shipping_method');

/**
* Plugin activation hook
*/
function flash_americas_shipping_activate() {
  // Create tracking table
  global $wpdb;
  
  $table_name = $wpdb->prefix . 'flash_americas_tracking';
  
  $charset_collate = $wpdb->get_charset_collate();
  
  $sql = "CREATE TABLE $table_name (
      id mediumint(9) NOT NULL AUTO_INCREMENT,
      order_id bigint(20) NOT NULL,
      shipment_id varchar(100) NOT NULL,
      tracking_number varchar(100) NOT NULL,
      provider varchar(50) NOT NULL,
      status varchar(50) DEFAULT 'pending',
      created_at datetime DEFAULT CURRENT_TIMESTAMP,
      updated_at datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
      PRIMARY KEY (id),
      UNIQUE KEY order_id (order_id),
      KEY tracking_number (tracking_number)
  ) $charset_collate;";
  
  require_once(ABSPATH . 'wp-admin/includes/upgrade.php');
  dbDelta($sql);
}

register_activation_hook(__FILE__, 'flash_americas_shipping_activate');

/**
* Load plugin textdomain
*/
function flash_americas_shipping_load_textdomain() {
  load_plugin_textdomain('flash-americas-shipping', false, dirname(plugin_basename(__FILE__)) . '/languages');
}

add_action('plugins_loaded', 'flash_americas_shipping_load_textdomain');

API Client Class

includes/class-flash-americas-api.phpphp
<?php

class Flash_Americas_API {
  
  private $api_key;
  private $base_url;
  private $timeout;
  
  public function __construct($api_key, $environment = 'production') {
      $this->api_key = $api_key;
      $this->base_url = $environment === 'sandbox' 
          ? 'https://sandbox-ship.flashamericas.com/api/v1'
          : 'https://ship.flashamericas.com/api/v1';
      $this->timeout = 30;
  }
  
  /**
   * Get shipping quotes
   */
  public function get_quotes($request) {
      $endpoint = '/quotes';
      $response = $this->make_request('POST', $endpoint, $request);
      
      if (is_wp_error($response)) {
          return $response;
      }
      
      return $response['data'];
  }
  
  /**
   * Create a shipment
   */
  public function create_shipment($request) {
      $endpoint = '/shipments';
      $response = $this->make_request('POST', $endpoint, $request);
      
      if (is_wp_error($response)) {
          return $response;
      }
      
      return $response['data'];
  }
  
  /**
   * Get tracking information
   */
  public function get_tracking($shipment_id) {
      $endpoint = "/shipments/{$shipment_id}/track";
      $response = $this->make_request('GET', $endpoint);
      
      if (is_wp_error($response)) {
          return $response;
      }
      
      return $response['data'];
  }
  
  /**
   * Validate an address
   */
  public function validate_address($address) {
      $endpoint = '/addresses/validate';
      $response = $this->make_request('POST', $endpoint, $address);
      
      if (is_wp_error($response)) {
          return $response;
      }
      
      return $response['data'];
  }
  
  /**
   * Make HTTP request to Flash Americas API
   */
  private function make_request($method, $endpoint, $data = null) {
      $url = $this->base_url . $endpoint;
      
      $headers = array(
          'Authorization' => 'Bearer ' . $this->api_key,
          'Content-Type' => 'application/json',
          'User-Agent' => 'FlashAmericas-WooCommerce/' . FLASH_AMERICAS_SHIPPING_VERSION
      );
      
      $args = array(
          'method' => $method,
          'headers' => $headers,
          'timeout' => $this->timeout,
          'data_format' => 'body'
      );
      
      if ($data) {
          $args['body'] = wp_json_encode($data);
      }
      
      $response = wp_remote_request($url, $args);
      
      if (is_wp_error($response)) {
          return new WP_Error('api_error', 'Failed to connect to Flash Americas API: ' . $response->get_error_message());
      }
      
      $code = wp_remote_retrieve_response_code($response);
      $body = wp_remote_retrieve_body($response);
      $decoded = json_decode($body, true);
      
      if ($code >= 400) {
          $error_message = isset($decoded['error']['message']) ? $decoded['error']['message'] : 'API Error';
          return new WP_Error('api_error', $error_message, array('status' => $code));
      }
      
      if (!$decoded || !isset($decoded['success']) || !$decoded['success']) {
          return new WP_Error('api_error', 'Invalid API response');
      }
      
      return $decoded;
  }
}

Shipping Method Class

includes/class-flash-americas-shipping-method.phpphp
<?php

class Flash_Americas_Shipping_Method extends WC_Shipping_Method {
  
  public function __construct($instance_id = 0) {
      $this->id = 'flash_americas';
      $this->instance_id = absint($instance_id);
      $this->method_title = __('Flash Americas', 'flash-americas-shipping');
      $this->method_description = __('Real-time shipping rates from Flash Americas', 'flash-americas-shipping');
      $this->supports = array(
          'shipping-zones',
          'instance-settings',
          'instance-settings-modal',
      );
      
      $this->init();
  }
  
  /**
   * Initialize settings
   */
  public function init() {
      $this->init_form_fields();
      $this->init_settings();
      
      $this->title = $this->get_option('title');
      $this->api_key = $this->get_option('api_key');
      $this->environment = $this->get_option('environment');
      $this->debug_mode = $this->get_option('debug_mode') === 'yes';
      $this->default_weight = $this->get_option('default_weight');
      $this->default_length = $this->get_option('default_length');
      $this->default_width = $this->get_option('default_width');
      $this->default_height = $this->get_option('default_height');
      $this->markup_type = $this->get_option('markup_type');
      $this->markup_amount = $this->get_option('markup_amount');
      
      add_action('woocommerce_update_options_shipping_' . $this->id, array($this, 'process_admin_options'));
  }
  
  /**
   * Define settings form fields
   */
  public function init_form_fields() {
      $this->instance_form_fields = array(
          'title' => array(
              'title' => __('Title', 'flash-americas-shipping'),
              'type' => 'text',
              'description' => __('This controls the title which the user sees during checkout.', 'flash-americas-shipping'),
              'default' => __('Flash Americas Shipping', 'flash-americas-shipping'),
              'desc_tip' => true,
          ),
          'api_key' => array(
              'title' => __('API Key', 'flash-americas-shipping'),
              'type' => 'password',
              'description' => __('Your Flash Americas API key.', 'flash-americas-shipping'),
              'desc_tip' => true,
          ),
          'environment' => array(
              'title' => __('Environment', 'flash-americas-shipping'),
              'type' => 'select',
              'default' => 'production',
              'options' => array(
                  'production' => __('Production', 'flash-americas-shipping'),
                  'sandbox' => __('Sandbox', 'flash-americas-shipping'),
              ),
              'description' => __('Select the API environment to use.', 'flash-americas-shipping'),
              'desc_tip' => true,
          ),
          'debug_mode' => array(
              'title' => __('Debug Mode', 'flash-americas-shipping'),
              'type' => 'checkbox',
              'label' => __('Enable debug mode', 'flash-americas-shipping'),
              'default' => 'no',
              'description' => __('Enable debug mode to log API requests and responses.', 'flash-americas-shipping'),
              'desc_tip' => true,
          ),
          'default_weight' => array(
              'title' => __('Default Weight (lbs)', 'flash-americas-shipping'),
              'type' => 'decimal',
              'default' => '1',
              'description' => __('Default weight for products without weight specified.', 'flash-americas-shipping'),
              'desc_tip' => true,
          ),
          'default_length' => array(
              'title' => __('Default Length (in)', 'flash-americas-shipping'),
              'type' => 'decimal',
              'default' => '12',
              'description' => __('Default length for products without dimensions.', 'flash-americas-shipping'),
              'desc_tip' => true,
          ),
          'default_width' => array(
              'title' => __('Default Width (in)', 'flash-americas-shipping'),
              'type' => 'decimal',
              'default' => '12',
              'description' => __('Default width for products without dimensions.', 'flash-americas-shipping'),
              'desc_tip' => true,
          ),
          'default_height' => array(
              'title' => __('Default Height (in)', 'flash-americas-shipping'),
              'type' => 'decimal',
              'default' => '12',
              'description' => __('Default height for products without dimensions.', 'flash-americas-shipping'),
              'desc_tip' => true,
          ),
          'markup_type' => array(
              'title' => __('Markup Type', 'flash-americas-shipping'),
              'type' => 'select',
              'default' => 'none',
              'options' => array(
                  'none' => __('No Markup', 'flash-americas-shipping'),
                  'fixed' => __('Fixed Amount', 'flash-americas-shipping'),
                  'percentage' => __('Percentage', 'flash-americas-shipping'),
              ),
              'description' => __('Add markup to shipping rates.', 'flash-americas-shipping'),
              'desc_tip' => true,
          ),
          'markup_amount' => array(
              'title' => __('Markup Amount', 'flash-americas-shipping'),
              'type' => 'decimal',
              'default' => '0',
              'description' => __('Amount to add as markup (fixed amount or percentage).', 'flash-americas-shipping'),
              'desc_tip' => true,
          ),
      );
  }
  
  /**
   * Calculate shipping rates
   */
  public function calculate_shipping($package = array()) {
      if (empty($this->api_key)) {
          return;
      }
      
      $origin_address = $this->get_origin_address();
      $destination_address = $this->get_destination_address($package);
      $cargo = $this->get_cargo_from_package($package);
      
      if (!$cargo) {
          $this->debug('No valid cargo found in package');
          return;
      }
      
      $quote_request = array(
          'originAddress' => $origin_address,
          'destinationAddress' => $destination_address,
          'cargo' => $cargo,
          'shipDate' => date('Y-m-d', strtotime('+1 day')),
      );
      
      $this->debug('Quote request: ' . wp_json_encode($quote_request));
      
      $api = new Flash_Americas_API($this->api_key, $this->environment);
      $response = $api->get_quotes($quote_request);
      
      if (is_wp_error($response)) {
          $this->debug('API Error: ' . $response->get_error_message());
          return;
      }
      
      $this->debug('API Response: ' . wp_json_encode($response));
      
      if (isset($response['rates']) && is_array($response['rates'])) {
          foreach ($response['rates'] as $rate) {
              $cost = $this->apply_markup($rate['totalCost']);
              
              $this->add_rate(array(
                  'id' => $this->id . '_' . sanitize_title($rate['provider'] . '_' . $rate['service']),
                  'label' => $this->format_rate_label($rate),
                  'cost' => $cost,
                  'meta_data' => array(
                      'provider' => $rate['provider'],
                      'service' => $rate['service'],
                      'transit_days' => $rate['transitDays'],
                      'delivery_date' => $rate['deliveryDate'],
                      'is_guaranteed' => $rate['isGuaranteed'],
                      'quote_id' => $response['quoteId'],
                  ),
              ));
          }
      }
  }
  
  /**
   * Get origin address from WooCommerce settings
   */
  private function get_origin_address() {
      $base_location = wc_get_base_location();
      
      return array(
          'address1' => WC()->countries->get_base_address(),
          'address2' => WC()->countries->get_base_address_2(),
          'city' => WC()->countries->get_base_city(),
          'state' => $base_location['state'],
          'postalCode' => WC()->countries->get_base_postcode(),
          'country' => $base_location['country'],
      );
  }
  
  /**
   * Get destination address from package
   */
  private function get_destination_address($package) {
      return array(
          'address1' => $package['destination']['address_1'] ?? '',
          'address2' => $package['destination']['address_2'] ?? '',
          'city' => $package['destination']['city'] ?? '',
          'state' => $package['destination']['state'] ?? '',
          'postalCode' => $package['destination']['postcode'] ?? '',
          'country' => $package['destination']['country'] ?? '',
      );
  }
  
  /**
   * Convert WooCommerce package to Flash Americas cargo format
   */
  private function get_cargo_from_package($package) {
      $cargo = array();
      $total_weight = 0;
      
      foreach ($package['contents'] as $item) {
          $product = $item['data'];
          $quantity = $item['quantity'];
          
          $weight = $product->get_weight() ?: $this->default_weight;
          $length = $product->get_length() ?: $this->default_length;
          $width = $product->get_width() ?: $this->default_width;
          $height = $product->get_height() ?: $this->default_height;
          
          // Convert dimensions to inches if needed
          $weight = wc_get_weight($weight, 'lbs');
          $length = wc_get_dimension($length, 'in');
          $width = wc_get_dimension($width, 'in');
          $height = wc_get_dimension($height, 'in');
          
          $cargo[] = array(
              'weight' => (float) $weight,
              'length' => (float) $length,
              'width' => (float) $width,
              'height' => (float) $height,
              'quantity' => $quantity,
              'description' => $product->get_name(),
              'value' => $product->get_price() * $quantity,
              'currency' => get_woocommerce_currency(),
          );
          
          $total_weight += $weight * $quantity;
      }
      
      // If no valid cargo found, return null
      if (empty($cargo) || $total_weight <= 0) {
          return null;
      }
      
      return $cargo;
  }
  
  /**
   * Format rate label for display
   */
  private function format_rate_label($rate) {
      $label = $rate['provider'] . ' - ' . $rate['service'];
      
      if ($rate['transitDays'] > 0) {
          $label .= sprintf(' (%d day%s)', $rate['transitDays'], $rate['transitDays'] > 1 ? 's' : '');
      }
      
      if ($rate['isGuaranteed']) {
          $label .= ' (Guaranteed)';
      }
      
      return $label;
  }
  
  /**
   * Apply markup to shipping rate
   */
  private function apply_markup($cost) {
      if ($this->markup_type === 'fixed') {
          return $cost + (float) $this->markup_amount;
      } elseif ($this->markup_type === 'percentage') {
          return $cost * (1 + (float) $this->markup_amount / 100);
      }
      
      return $cost;
  }
  
  /**
   * Debug logging
   */
  private function debug($message) {
      if ($this->debug_mode) {
          $logger = wc_get_logger();
          $logger->debug($message, array('source' => 'flash_americas_shipping'));
      }
  }
}

Features

Admin Configuration

The plugin provides a comprehensive admin interface:

  • API Settings: Configure API key and environment
  • Default Dimensions: Set fallback package dimensions
  • Rate Markup: Add fixed or percentage markup
  • Debug Mode: Enable detailed logging
  • Shipping Rules: Configure zone-specific settings

Real-time Rate Calculation

The plugin calculates shipping rates in real-time at checkout:

  1. Package Analysis: Combines all cart items into optimized packages
  2. Address Validation: Validates shipping addresses
  3. Rate Retrieval: Gets live rates from multiple carriers
  4. Rate Display: Shows formatted rates with transit times

Order Tracking Integration

Order tracking functionalityphp
// Add tracking information to order emails
add_action('woocommerce_email_order_meta', 'flash_americas_add_tracking_to_email', 10, 3);

function flash_americas_add_tracking_to_email($order, $sent_to_admin, $plain_text) {
  $tracking = get_post_meta($order->get_id(), '_flash_americas_tracking', true);
  
  if ($tracking) {
      if ($plain_text) {
          echo "\n\nTracking Information:\n";
          echo "Tracking Number: " . $tracking['tracking_number'] . "\n";
          echo "Carrier: " . $tracking['provider'] . "\n";
          echo "Track at: https://track.flashamericas.com/" . $tracking['tracking_number'] . "\n";
      } else {
          echo '<h3>Tracking Information</h3>';
          echo '<p><strong>Tracking Number:</strong> ' . $tracking['tracking_number'] . '</p>';
          echo '<p><strong>Carrier:</strong> ' . $tracking['provider'] . '</p>';
          echo '<p><a href="https://track.flashamericas.com/' . $tracking['tracking_number'] . '" target="_blank">Track Your Package</a></p>';
      }
  }
}

Customization

Hooks and Filters

The plugin provides several hooks for customization:

Available hooksphp
// Modify quote request before sending to API
add_filter('flash_americas_quote_request', 'custom_modify_quote_request', 10, 2);
function custom_modify_quote_request($request, $package) {
  // Add custom accessorials
  $request['accessorials'] = array('LIFTGATE_PICKUP', 'LIFTGATE_DELIVERY');
  return $request;
}

// Modify rate display
add_filter('flash_americas_rate_label', 'custom_rate_label', 10, 2);
function custom_rate_label($label, $rate) {
  // Add delivery date to label
  $delivery_date = date('M j', strtotime($rate['deliveryDate']));
  return $label . ' - Delivery by ' . $delivery_date;
}

// Modify rate cost
add_filter('flash_americas_rate_cost', 'custom_rate_cost', 10, 3);
function custom_rate_cost($cost, $rate, $package) {
  // Add handling fee for expedited services
  if (strpos($rate['service'], 'EXPRESS') !== false) {
      $cost += 5.00;
  }
  return $cost;
}

Custom Packaging Rules

Custom packaging logicphp
// Override default packaging
add_filter('flash_americas_package_cargo', 'custom_package_cargo', 10, 2);
function custom_package_cargo($cargo, $package) {
  // Combine small items into single package
  $total_weight = 0;
  $total_value = 0;
  $descriptions = array();
  
  foreach ($cargo as $item) {
      if ($item['weight'] < 5) { // Items under 5 lbs
          $total_weight += $item['weight'] * $item['quantity'];
          $total_value += $item['value'];
          $descriptions[] = $item['description'];
      }
  }
  
  if ($total_weight > 0) {
      // Create combined package
      $combined_cargo = array(
          'weight' => $total_weight,
          'length' => 12,
          'width' => 12,
          'height' => 8,
          'quantity' => 1,
          'description' => 'Multiple items: ' . implode(', ', $descriptions),
          'value' => $total_value,
          'currency' => get_woocommerce_currency()
      );
      
      // Remove small items and add combined package
      $cargo = array_filter($cargo, function($item) {
          return $item['weight'] >= 5;
      });
      $cargo[] = $combined_cargo;
  }
  
  return $cargo;
}

Installation Package

The complete plugin structure:

Plugin directory structuretext
flash-americas-shipping/
├── flash-americas-shipping.php
├── readme.txt
├── includes/
│   ├── class-flash-americas-api.php
│   ├── class-flash-americas-shipping-method.php
│   ├── class-flash-americas-admin.php
│   └── class-flash-americas-tracking.php
├── assets/
│   ├── css/
│   │   └── admin.css
│   ├── js/
│   │   └── admin.js
│   └── images/
│       └── logo.png
├── languages/
│   ├── flash-americas-shipping.pot
│   └── flash-americas-shipping-en_US.po
└── templates/
  ├── tracking-info.php
  └── rate-calculator.php

Testing

Test Different Scenarios

Testing checklistphp
// Test scenarios to verify plugin functionality:

1. **Basic Rate Calculation**
 - Add products to cart
 - Proceed to checkout
 - Verify rates appear

2. **Address Validation**
 - Test with invalid addresses
 - Verify error handling

3. **International Shipping**
 - Test US to Mexico shipments
 - Verify customs handling

4. **Large Orders**
 - Test with multiple packages
 - Verify package consolidation

5. **Error Handling**
 - Test with invalid API key
 - Test API timeout scenarios

6. **Order Completion**
 - Complete test orders
 - Verify tracking integration

Support and Updates

Automatic Updates

The plugin includes automatic update functionality:

Update checkerphp
// Check for plugin updates
add_action('init', 'flash_americas_check_for_updates');

function flash_americas_check_for_updates() {
  if (is_admin()) {
      $updater = new Flash_Americas_Plugin_Updater(
          'https://api.flashamericas.com/plugins/woocommerce',
          __FILE__,
          array(
              'version' => FLASH_AMERICAS_SHIPPING_VERSION,
              'license' => get_option('flash_americas_license_key'),
              'item_name' => 'Flash Americas WooCommerce Plugin'
          )
      );
  }
}

Download and Installation

  1. Download: Flash Americas WooCommerce Plugin
  2. Documentation: Complete setup guide
  3. Support: Get help with installation

Related Examples