Skip to main content

BigCommerce Integration

Muddy uses BigCommerce for WordPress (Suma Fork v5.0.7.10), a custom version of the official BigCommerce WordPress plugin maintained by Rhino Group with enhancements for GSM Outdoors brands.

Plugin Overview

Base Plugin: BigCommerce for WordPress

The official BigCommerce for WordPress plugin provides headless commerce integration:

  • Official Version: Based on 5.0.x series
  • Suma Fork: v5.0.7.10 with custom enhancements
  • Repository: Private Rhino Group fork
  • License: Proprietary (based on GPL v2)

Suma Fork Enhancements

Key customizations in the Suma fork:

  1. Bi-Directional Sync Control: Granular control over what data syncs between platforms
  2. Pricing Nonce Bypass: Performance optimization for high-traffic scenarios
  3. Advanced Import Features: Bulk import tools and scheduling
  4. HuntStand Integration Hooks: Custom hooks for cross-platform functionality
  5. Promo Flag Support: Integration with custom promotional messaging system
  6. Performance Optimizations: Database query optimization, caching improvements

Installation & Setup

Prerequisites

  • WordPress 6.0+
  • PHP 8.1+
  • BigCommerce store (any plan)
  • MySQL 5.7+ or MariaDB 10.3+

BigCommerce Store Configuration

1. Create API Account

Navigate to Advanced Settings → API Accounts in BigCommerce admin:

API Account Name: WordPress - Muddy Production
OAuth Scopes:
- Carts: Modify
- Checkout Content: Modify
- Customers: Modify
- Customer Login: Login
- Information & Settings: Read-only
- Marketing: Modify
- Orders: Modify
- Order Transactions: Read-only
- Products: Modify
- Themes: Read-only
- Channel Settings: Modify
- Channel Listings: Modify
- Sites & Routes: Modify

2. Create WordPress Channel

In BigCommerce admin, go to Channel Manager:

Channel Type: WordPress
Channel Name: Muddy - gomuddy.com
Status: Active
Domain: gomuddy.com

Note: The channel ID will be used in WordPress configuration.

WordPress Plugin Installation

Manual Installation

# Upload plugin to WordPress
wp plugin install /path/to/bigcommerce-suma-v5.0.7.10.zip --activate

# Or via git (private repo access required)
cd wp-content/plugins
git clone [email protected]:rhino-group/bigcommerce-wordpress-suma.git bigcommerce
cd bigcommerce
composer install --no-dev

Configuration

Add BigCommerce credentials to wp-config.php:

// BigCommerce API Credentials
define( 'BIGCOMMERCE_CLIENT_ID', 'your_client_id' );
define( 'BIGCOMMERCE_CLIENT_SECRET', 'your_client_secret' );
define( 'BIGCOMMERCE_ACCESS_TOKEN', 'your_access_token' );
define( 'BIGCOMMERCE_CHANNEL_ID', 123456 );

// Optional: Custom configuration
define( 'BIGCOMMERCE_API_URL', 'https://api.bigcommerce.com' );
define( 'BIGCOMMERCE_IMPORT_BATCH_SIZE', 50 );
define( 'BIGCOMMERCE_CACHE_TTL', 900 ); // 15 minutes

Product Synchronization

Initial Product Import

# Import all products
wp bigcommerce import products --all

# Import specific categories
wp bigcommerce import products --category=12,34,56

# Import with progress output
wp bigcommerce import products --all --verbose

# Dry run (preview import)
wp bigcommerce import products --all --dry-run

Via WordPress Admin

Navigate to BigCommerce → Settings → Import and click Import Products.

Import Process:

  1. Fetches product data from BigCommerce API
  2. Creates WordPress custom post type bigcommerce_product
  3. Imports product images to WordPress media library
  4. Creates product categories and tags
  5. Indexes products for search (Algolia, FacetWP)

Import Duration: ~5-10 minutes for 500 products

Incremental Updates (Webhooks)

The plugin registers webhooks with BigCommerce for real-time updates:

// Registered webhook endpoints
/wp-json/bigcommerce/v1/webhooks/product-update
/wp-json/bigcommerce/v1/webhooks/product-delete
/wp-json/bigcommerce/v1/webhooks/inventory-update
/wp-json/bigcommerce/v1/webhooks/order-created

Webhook Flow:

BigCommerce Event (e.g., product updated)

│ POST request with HMAC signature


WordPress Webhook Endpoint

│ Verify HMAC signature


Add to Import Queue

│ Background processing (cron)


Update WordPress Product

│ Update post meta, taxonomies


Clear Caches & Reindex

Webhook Security:

// Verify webhook signature
function verify_bigcommerce_webhook( $payload, $signature ) {
$secret = BIGCOMMERCE_CLIENT_SECRET;
$calculated = base64_encode( hash_hmac( 'sha256', $payload, $secret, true ) );

return hash_equals( $calculated, $signature );
}

Scheduled Synchronization

Daily cron job for full reconciliation:

// wp-content/mu-plugins/bigcommerce-cron.php
add_action( 'bigcommerce_daily_sync', 'muddy_sync_all_products' );

function muddy_sync_all_products() {
// Fetch all product IDs from BigCommerce
$bc_products = get_bigcommerce_product_ids();

// Get WordPress product IDs
$wp_products = get_wordpress_bigcommerce_ids();

// Find products to update
$to_update = array_intersect( $bc_products, $wp_products );

// Find products to delete (removed from BC)
$to_delete = array_diff( $wp_products, $bc_products );

// Queue updates
foreach ( $to_update as $product_id ) {
BigCommerce\Import\Import_Queue::add_product( $product_id );
}

// Delete removed products
foreach ( $to_delete as $product_id ) {
wp_delete_post( $product_id, true );
}
}

// Schedule the cron job
if ( ! wp_next_scheduled( 'bigcommerce_daily_sync' ) ) {
wp_schedule_event( strtotime( '3:00 AM' ), 'daily', 'bigcommerce_daily_sync' );
}

Cart & Checkout

Cart Management

Cart operations use BigCommerce's Cart API with WordPress as a proxy.

Add to Cart:

// Frontend JavaScript (simplified)
jQuery('.buy-button').on('click', function(e) {
e.preventDefault();

const productId = $(this).data('product-id');
const variantId = $(this).data('variant-id');
const quantity = $('#quantity').val();

$.ajax({
url: muddy_cart.ajax_url,
method: 'POST',
data: {
action: 'bigcommerce_add_to_cart',
product_id: productId,
variant_id: variantId,
quantity: quantity,
nonce: muddy_cart.nonce
},
success: function(response) {
if (response.success) {
// Update cart count
$('.cart-count').text(response.data.item_count);

// Show success message
showNotification('Product added to cart');
}
}
});
});

PHP Handler:

add_action( 'wp_ajax_bigcommerce_add_to_cart', 'muddy_ajax_add_to_cart' );
add_action( 'wp_ajax_nopriv_bigcommerce_add_to_cart', 'muddy_ajax_add_to_cart' );

function muddy_ajax_add_to_cart() {
check_ajax_referer( 'bigcommerce_cart_nonce', 'nonce' );

$product_id = intval( $_POST['product_id'] );
$variant_id = intval( $_POST['variant_id'] );
$quantity = intval( $_POST['quantity'] );

// Get or create cart
$cart = BigCommerce\Cart\Cart::get_cart();

// Add item to cart via BC API
$result = $cart->add_item( $product_id, $variant_id, $quantity );

if ( is_wp_error( $result ) ) {
wp_send_json_error( $result->get_error_message() );
}

wp_send_json_success( [
'item_count' => $cart->get_item_count(),
'subtotal' => $cart->get_subtotal(),
'cart_url' => get_permalink( get_option( 'bigcommerce_cart_page_id' ) )
] );
}

Cart Page

WordPress template displays cart contents fetched from BigCommerce:

// templates/cart/cart.php (simplified)
$cart = BigCommerce\Cart\Cart::get_cart();
$items = $cart->get_items();

if ( empty( $items ) ) {
echo '<p>Your cart is empty.</p>';
return;
}

foreach ( $items as $item ) :
?>
<div class="cart-item" data-item-id="<?php echo esc_attr( $item['id'] ); ?>">
<img src="<?php echo esc_url( $item['image_url'] ); ?>" alt="">
<h3><?php echo esc_html( $item['name'] ); ?></h3>
<span class="price"><?php echo esc_html( $item['sale_price'] ?: $item['list_price'] ); ?></span>
<input type="number" class="quantity" value="<?php echo esc_attr( $item['quantity'] ); ?>" min="1">
<button class="remove-item">Remove</button>
</div>
<?php
endforeach;

echo '<div class="cart-total">Total: ' . esc_html( $cart->get_total() ) . '</div>';
echo '<a href="' . esc_url( $cart->get_checkout_url() ) . '" class="checkout-button">Checkout</a>';

Checkout Flow

Redirect to BigCommerce:

// When customer clicks "Checkout", redirect to BC hosted checkout
function get_checkout_url() {
$cart = BigCommerce\Cart\Cart::get_cart();
$cart_id = $cart->get_cart_id();

// Generate checkout URL
$channel_id = BIGCOMMERCE_CHANNEL_ID;
$checkout_url = "https://store-{hash}.mybigcommerce.com/checkout/{$cart_id}";

// Optional: Add embedded checkout
// $checkout_url = "https://gomuddy.com/checkout?cart_id={$cart_id}";

return $checkout_url;
}

Post-Checkout Redirect:

Configure in BigCommerce admin (Channel Manager → WordPress → Settings):

Checkout Return URL: https://gomuddy.com/thank-you
Order Status Page URL: https://gomuddy.com/account/orders

HuntStand Integration

Custom integration for cross-platform product recommendations between Muddy website and HuntStand mobile app.

API Endpoint

// wp-content/plugins/bigcommerce-suma/includes/huntstand-api.php

add_action( 'rest_api_init', function() {
register_rest_route( 'huntstand/v1', '/products', [
'methods' => 'GET',
'callback' => 'muddy_huntstand_products',
'permission_callback' => 'muddy_huntstand_authenticate'
] );
} );

function muddy_huntstand_authenticate( $request ) {
$auth_header = $request->get_header( 'Authorization' );

if ( empty( $auth_header ) ) {
return new WP_Error( 'missing_auth', 'Authorization header required', [ 'status' => 401 ] );
}

// Verify Bearer token
$token = str_replace( 'Bearer ', '', $auth_header );
$valid = verify_huntstand_token( $token );

return $valid;
}

function muddy_huntstand_products( $request ) {
$category = $request->get_param( 'category' );
$limit = $request->get_param( 'limit' ) ?: 20;

// Query BigCommerce products
$args = [
'post_type' => 'bigcommerce_product',
'posts_per_page' => $limit,
'meta_query' => [
[
'key' => 'bigcommerce_inventory',
'value' => 0,
'compare' => '>'
]
]
];

if ( $category ) {
$args['tax_query'] = [
[
'taxonomy' => 'bigcommerce_category',
'field' => 'slug',
'terms' => $category
]
];
}

$products = get_posts( $args );
$response = [];

foreach ( $products as $product ) {
$bc_id = get_post_meta( $product->ID, 'bigcommerce_id', true );
$price = get_post_meta( $product->ID, 'bigcommerce_price', true );
$sale_price = get_post_meta( $product->ID, 'bigcommerce_sale_price', true );
$inventory = get_post_meta( $product->ID, 'bigcommerce_inventory', true );
$sku = get_post_meta( $product->ID, 'bigcommerce_sku', true );

$response[] = [
'id' => $bc_id,
'name' => $product->post_title,
'description' => wp_trim_words( $product->post_content, 50 ),
'sku' => $sku,
'price' => (float) $price,
'sale_price' => $sale_price ? (float) $sale_price : null,
'inventory' => (int) $inventory,
'category' => get_primary_category( $product->ID ),
'image_url' => get_the_post_thumbnail_url( $product->ID, 'large' ),
'url' => get_permalink( $product->ID )
];
}

return rest_ensure_response( $response );
}

Authentication

OAuth 2.0 token exchange:

// HuntStand service generates access token
// Token stored in wp_options for verification
function verify_huntstand_token( $token ) {
$stored_token = get_option( 'huntstand_api_token' );
$expiry = get_option( 'huntstand_token_expiry' );

if ( $token !== $stored_token ) {
return false;
}

if ( time() > $expiry ) {
return false; // Token expired
}

return true;
}

Promo Flags

Custom promotional messaging system integrated with BigCommerce products.

Data Structure

// Custom post type: promo_flag
register_post_type( 'promo_flag', [
'labels' => [
'name' => 'Promo Flags',
'singular_name' => 'Promo Flag'
],
'public' => false,
'show_ui' => true,
'supports' => [ 'title' ],
'menu_icon' => 'dashicons-flag'
] );

// Meta fields
$promo_meta = [
'flag_type' => 'sale|new|exclusive|featured',
'message' => 'Free Shipping!',
'product_ids' => [ 123, 456, 789 ], // BigCommerce product IDs
'priority' => 10,
'start_date' => '2026-04-01',
'end_date' => '2026-04-30'
];

Display Logic

// Get active promo flags for product
function get_product_promo_flags( $bigcommerce_id ) {
$now = current_time( 'timestamp' );

$args = [
'post_type' => 'promo_flag',
'posts_per_page' => -1,
'meta_query' => [
[
'key' => 'product_ids',
'value' => sprintf( ':"%d";', $bigcommerce_id ),
'compare' => 'LIKE'
],
[
'key' => 'start_date',
'value' => $now,
'compare' => '<=',
'type' => 'NUMERIC'
],
[
'key' => 'end_date',
'value' => $now,
'compare' => '>=',
'type' => 'NUMERIC'
]
],
'orderby' => 'meta_value_num',
'meta_key' => 'priority',
'order' => 'DESC'
];

return get_posts( $args );
}

// Display on product page
add_action( 'bigcommerce/template/product/before_title', 'muddy_display_promo_flag' );

function muddy_display_promo_flag() {
global $post;
$bc_id = get_post_meta( $post->ID, 'bigcommerce_id', true );
$flags = get_product_promo_flags( $bc_id );

if ( empty( $flags ) ) {
return;
}

$flag = $flags[0]; // Highest priority
$type = get_post_meta( $flag->ID, 'flag_type', true );
$message = get_post_meta( $flag->ID, 'message', true );

printf(
'<div class="promo-flag promo-flag--%s">%s</div>',
esc_attr( $type ),
esc_html( $message )
);
}

CSS Styling

.promo-flag {
display: inline-block;
padding: 0.5rem 1rem;
border-radius: 4px;
font-weight: 600;
font-size: 0.875rem;
text-transform: uppercase;
margin-bottom: 1rem;
}

.promo-flag--sale {
background-color: #ef4444;
color: white;
}

.promo-flag--new {
background-color: #3b82f6;
color: white;
}

.promo-flag--exclusive {
background-color: #8b5cf6;
color: white;
}

.promo-flag--featured {
background-color: #f59e0b;
color: white;
}

Performance Optimization

API Response Caching

// Cache BigCommerce API responses
function muddy_get_bc_product( $product_id ) {
$cache_key = 'bc_product_' . $product_id;
$cached = wp_cache_get( $cache_key, 'bigcommerce' );

if ( false !== $cached ) {
return $cached;
}

// Fetch from API
$product = BigCommerce\Api\Products::get_product( $product_id );

// Cache for 15 minutes
wp_cache_set( $cache_key, $product, 'bigcommerce', 15 * MINUTE_IN_SECONDS );

return $product;
}

Database Query Optimization

// Index for fast BigCommerce ID lookups
global $wpdb;
$wpdb->query( "
CREATE INDEX idx_bc_id ON {$wpdb->postmeta}(meta_key, meta_value(50))
WHERE meta_key = 'bigcommerce_id'
" );

Pricing Nonce Bypass

Suma fork optimization that bypasses nonce verification for pricing updates in high-traffic scenarios:

// wp-content/plugins/bigcommerce-suma/includes/pricing-nonce-bypass.php

// CAUTION: Only enable if you understand the security implications
define( 'BIGCOMMERCE_BYPASS_PRICING_NONCE', true );

add_filter( 'bigcommerce/pricing/verify_nonce', function( $verify ) {
if ( defined( 'BIGCOMMERCE_BYPASS_PRICING_NONCE' ) && BIGCOMMERCE_BYPASS_PRICING_NONCE ) {
// Skip nonce verification for pricing AJAX requests
// This improves performance but reduces CSRF protection
return false; // Don't verify
}
return $verify;
} );

Security Note: This optimization should only be used on high-traffic sites where nonce verification causes performance bottlenecks. Ensure proper security measures are in place (rate limiting, IP whitelisting, etc.).

Troubleshooting

Common Issues

Products not importing:

# Check import queue
wp bigcommerce queue status

# Clear and restart import
wp bigcommerce queue clear
wp bigcommerce import products --all

Webhook failures:

# Check webhook logs
wp bigcommerce webhooks list

# Re-register webhooks
wp bigcommerce webhooks register

Cart issues:

# Clear cart cache
wp cache flush
wp transient delete --all

# Test cart API connection
wp bigcommerce test cart-api

Debug Mode

Enable debug logging:

// wp-config.php
define( 'BIGCOMMERCE_DEBUG', true );
define( 'BIGCOMMERCE_LOG_FILE', WP_CONTENT_DIR . '/bigcommerce-debug.log' );

View logs:

tail -f wp-content/bigcommerce-debug.log