Step 4: Advanced Integration Techniques
Step 4: Advanced Integration Techniques
Handling WooCommerce Webhooks
WooCommerce webhooks can be used to receive real-time notifications about events in your WooCommerce stores:
namespace MyCompany\WooCommerce\Webhooks;
use WP_REST_Request;
use WP_REST_Response;
use Exception;
/**
* Register webhook handlers
*/
public function register_webhook_handlers() {
// Register webhook endpoint
add_action('rest_api_init', function() {
register_rest_route('mainwp-woocommerce/v1', '/webhook/(?P<website_id>\d+)', [
'methods' => 'POST',
'callback' => [$this, 'handle_webhook'],
'permission_callback' => [$this, 'verify_webhook'],
]);
});
}
/**
* Verify webhook request
*
* @param WP_REST_Request $request Request object
* @return bool Whether the request is valid
*/
public function verify_webhook($request) {
// Validate website ID
$website_id = absint($request->get_param('website_id'));
if ($website_id <= 0) {
return false;
}
$signature = $request->get_header('X-WC-Webhook-Signature');
if (empty($signature)) {
// Log missing signature if WP_DEBUG_LOG is enabled
if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
error_log(sprintf(
'[MainWP WooCommerce] Missing webhook signature for website ID: %d',
$website_id
));
}
return false;
}
// Get webhook secret for this site
$settings = get_option('mainwp_woocommerce_settings', []);
$site_settings = isset($settings[$website_id]) ? $settings[$website_id] : [];
if (empty($site_settings['webhook_secret'])) {
// Log missing webhook secret if WP_DEBUG_LOG is enabled
if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
error_log(sprintf(
'[MainWP WooCommerce] Webhook secret not configured for website ID: %d',
$website_id
));
}
return false;
}
// Verify signature with constant-time comparison to prevent timing attacks
$payload = $request->get_body();
$calculated_signature = hash_hmac('sha256', $payload, $site_settings['webhook_secret']);
return hash_equals($calculated_signature, $signature);
}
/**
* Handle webhook request
*
* @param WP_REST_Request $request Request object
* @return WP_REST_Response Response object
*/
public function handle_webhook($request) {
$website_id = absint($request->get_param('website_id'));
$payload = json_decode($request->get_body(), true);
if (!$payload || !isset($payload['topic'])) {
return new WP_REST_Response([
'success' => false,
'message' => 'Invalid payload or missing topic'
], 400);
}
try {
// Process webhook based on topic
switch ($payload['topic']) {
case 'order.created':
$this->process_new_order($website_id, $payload['data']);
break;
case 'product.updated':
$this->process_product_update($website_id, $payload['data']);
break;
default:
// Log unknown topic if WP_DEBUG_LOG is enabled
if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
error_log(sprintf(
'[MainWP WooCommerce] Unknown webhook topic: %s for website ID: %d',
$payload['topic'],
$website_id
));
}
return new WP_REST_Response([
'success' => false,
'message' => 'Unknown webhook topic'
], 400);
}
return new WP_REST_Response(['success' => true]);
} catch (Exception $e) {
// Log exception if WP_DEBUG_LOG is enabled
if (defined('WP_DEBUG_LOG') && WP_DEBUG_LOG) {
error_log(sprintf(
'[MainWP WooCommerce] Webhook processing error: %s for website ID: %d',
$e->getMessage(),
$website_id
));
}
return new WP_REST_Response([
'success' => false,
'message' => 'Error processing webhook: ' . $e->getMessage()
], 500);
}
}
/**
* Process new order webhook
*
* @param int $website_id Website ID
* @param array $data Order data
*/
private function process_new_order($website_id, $data) {
// Validate inputs
$website_id = absint($website_id);
if ($website_id <= 0 || empty($data) || !is_array($data)) {
return;
}
// Process new order
// For example, send notification, update dashboard, etc.
}
Implementing Background Processing
For operations that may take a long time, implement background processing:
namespace MyCompany\WooCommerce\Background;
use MainWP\Dashboard\MainWP_DB;
use MainWP\Dashboard\MainWP_Connect;
use WP_Error;
use Exception;
/**
* Schedule background sync
*/
public function schedule_background_sync() {
if (!wp_next_scheduled('mainwp_woocommerce_background_sync')) {
wp_schedule_event(time(), 'hourly', 'mainwp_woocommerce_background_sync');
}
// Hook into the scheduled event
add_action('mainwp_woocommerce_background_sync', [$this, 'do_background_sync']);
}
/**
* Perform background sync
*/
public function do_background_sync() {
// Get all websites with WooCommerce
$websites = MainWP_DB::instance()->get_websites_by_plugin_name('woocommerce/woocommerce.php');
foreach ($websites as $website) {
// Skip sites without API credentials
$api_client = $this->get_api_client($website->id);
if (!$api_client) {
continue;
}
// Sync products
$this->sync_products($website->id, $api_client);
// Sync orders
$this->sync_orders($website->id, $api_client);
// Sync other data as needed
}
}
/**
* Sync products for a site
*
* @param int $website_id Website ID
* @param WooCommerceAPIClient $api_client API client
*/
private function sync_products($website_id, $api_client) {
// Get products from the site
$products = $api_client->get_products(['per_page' => 100]);
if (is_wp_error($products)) {
// Log error
return;
}
// Process products
// For example, store in database, update inventory, etc.
}
Synchronizing Inventory Across Stores
Implement inventory synchronization across multiple stores:
namespace MyCompany\WooCommerce\Sync;
use WP_Error;
/**
* Synchronize inventory across stores
*
* @param array $website_ids Array of website IDs to sync
* @param array $product_data Array of product IDs and stock quantities
* @return array Results
*/
public function sync_inventory($website_ids, $product_data) {
$results = [];
foreach ($website_ids as $website_id) {
$api_client = $this->get_api_client($website_id);
if (!$api_client) {
$results[$website_id] = [
'success' => false,
'message' => 'API credentials not configured'
];
continue;
}
$product_manager = new ProductManager($api_client);
$site_results = [];
foreach ($product_data as $product_id => $stock_quantity) {
$result = $product_manager->update_stock($product_id, $stock_quantity);
$site_results[$product_id] = [
'success' => !is_wp_error($result),
'message' => is_wp_error($result) ? $result->get_error_message() : 'Success'
];
}
$results[$website_id] = $site_results;
}
return $results;
}
Common Challenges and Solutions
API Authentication Issues
If you encounter API authentication issues:
- Check API Keys: Ensure the Consumer Key and Consumer Secret are correct.
- Verify Permissions: Make sure the API keys have the necessary permissions.
- Check SSL: WooCommerce API requires SSL for secure connections.
namespace MyCompany\WooCommerce\Diagnostics;
use MainWP\Dashboard\MainWP_DB;
use WP_Error;
/**
* Troubleshoot API connection
*
* @param int $website_id Website ID
* @return array Troubleshooting results
*/
public function troubleshoot_api_connection($website_id) {
$results = [];
// Check if website exists
$website = MainWP_DB::instance()->get_website_by_id($website_id);
if (!$website) {
$results['website'] = 'Website not found';
return $results;
}
// Check if WooCommerce is active
$is_woocommerce_active = MainWP_DB::instance()->is_plugin_active_on_site($website_id, 'woocommerce/woocommerce.php');
$results['woocommerce'] = $is_woocommerce_active ? 'Active' : 'Not active';
// Check API credentials
$settings = get_option('mainwp_woocommerce_settings', []);
$site_settings = isset($settings[$website_id]) ? $settings[$website_id] : [];
$results['api_credentials'] = (!empty($site_settings['consumer_key']) && !empty($site_settings['consumer_secret'])) ? 'Configured' : 'Not configured';
// Test API connection
if ($results['api_credentials'] === 'Configured') {
$api_client = $this->get_api_client($website_id);
$test_result = $api_client->get_store_info();
$results['api_connection'] = !is_wp_error($test_result) ? 'Success' : 'Failed: ' . $test_result->get_error_message();
}
return $results;
}
Handling Large Product Catalogs
For stores with large product catalogs:
- Implement Pagination: Use pagination to retrieve products in batches.
- Optimize Caching: Cache product data to reduce API calls.
- Use Background Processing: Process large catalogs in the background.
namespace MyCompany\WooCommerce\Products;
use WP_Error;
/**
* Get all products with pagination
*
* @param int $website_id Website ID
* @return array|WP_Error Products or error
*/
public function get_all_products($website_id) {
$api_client = $this->get_api_client($website_id);
if (!$api_client) {
return new WP_Error('api_error', 'API credentials not configured');
}
$all_products = [];
$page = 1;
$per_page = 100;
while (true) {
$products = $api_client->get_products([
'page' => $page,
'per_page' => $per_page
]);
if (is_wp_error($products)) {
return $products;
}
if (empty($products)) {
break;
}
$all_products = array_merge($all_products, $products);
$page++;
}
return $all_products;
}
Managing Different WooCommerce Versions
To handle different WooCommerce versions across your network:
- Version Detection: Detect WooCommerce version on each site.
- Conditional Logic: Implement conditional logic based on version.
- Fallback Mechanisms: Provide fallback mechanisms for older versions.
namespace MyCompany\WooCommerce\Compatibility;
use MainWP\Dashboard\MainWP_DB;
use WP_Error;
/**
* Get WooCommerce version for a site
*
* @param int $website_id Website ID
* @return string|WP_Error WooCommerce version or error
*/
public function get_woocommerce_version($website_id) {
$website = MainWP_DB::instance()->get_website_by_id($website_id);
if (!$website) {
return new WP_Error('website_error', 'Website not found');
}
// Get plugin data from the site
$plugins = json_decode($website->plugins, true);
if (!$plugins) {
return new WP_Error('plugins_error', 'Unable to get plugins data');
}
// Find WooCommerce plugin
foreach ($plugins as $plugin) {
if ($plugin['slug'] === 'woocommerce/woocommerce.php') {
return $plugin['version'];
}
}
return new WP_Error('woocommerce_error', 'WooCommerce not found');
}
/**
* Check if WooCommerce version is compatible
*
* @param string $version WooCommerce version
* @param string $min_version Minimum required version
* @return bool Whether the version is compatible
*/
public function is_woocommerce_compatible($version, $min_version = '3.0.0') {
return version_compare($version, $min_version, '>=');
}
Next Steps and Resources
After implementing your WooCommerce integration, you might want to explore:
- Advanced Reporting: Implement more advanced reporting features.
- Custom Dashboards: Create custom dashboards for specific WooCommerce data.
- Bulk Operations: Implement more bulk operations for managing products and orders.
- Automated Tasks: Set up automated tasks for common WooCommerce operations.
Resources
这篇文档对你有帮助吗?
谢谢你的反馈!