如何实现WooCommerce与WorldPay的订单状态同步?
Absolutely, you can get WooCommerce order statuses to sync perfectly with WorldPay's AUTHORISED and CAPTURED states—let’s break down the most reliable ways to make this happen:
方法一:使用WorldPay Webhooks(推荐实时同步方案)
Webhooks are the gold standard here because they let WorldPay actively notify your WooCommerce site the second an order status changes, ensuring near-instant syncing.
Step 1: Configure Webhooks in WorldPay
Log into your WorldPay account, navigate to the Webhooks settings page, and add a new webhook endpoint pointing to a custom URL on your site (e.g.,https://your-store.com/worldpay-webhook/).
Make sure to enable trigger events for bothAUTHORISEDandCAPTUREDstatus changes—this tells WorldPay to send a notification every time an order moves between these states.Step 2: Add Webhook Handling Logic to WooCommerce
You’ll need to add code to your theme’sfunctions.phpfile or a custom plugin to receive and process WorldPay’s webhook requests. Here’s a basic working example:add_action('rest_api_init', function () { register_rest_route('worldpay/v1', '/webhook', array( 'methods' => 'POST', 'callback' => 'handle_worldpay_webhook', 'permission_callback' => '__return_true', // ⚠️ Replace with signature verification in production! )); }); function handle_worldpay_webhook($request) { // Critical: In production, validate WorldPay's webhook signature to block fake requests // Follow WorldPay's official docs to implement signature checks here $payload = $request->get_json_params(); $wc_order_id = $payload['orderCode']; // Adjust this to match how WorldPay sends your order IDs $worldpay_status = $payload['paymentStatus']; $wc_order = wc_get_order($wc_order_id); if (!$wc_order) return new WP_Error('invalid_order', 'Order not found', array('status' => 404)); // Map WorldPay statuses to WooCommerce statuses switch ($worldpay_status) { case 'AUTHORISED': $wc_order->update_status('processing', 'Order marked as AUTHORISED via WorldPay webhook'); break; case 'CAPTURED': // Use default 'completed' status, or a custom one (see Step 3 below) $wc_order->update_status('completed', 'Order marked as CAPTURED via WorldPay webhook'); break; default: break; } $wc_order->save(); return new WP_REST_Response('Status synced successfully', 200); }Step 3: Add a Custom "CAPTURED" Status (Optional)
If you don’t want to use WooCommerce’s defaultcompletedstatus for CAPTURED orders, register a custom status:add_action('init', 'register_wc_captured_status'); function register_wc_captured_status() { register_post_status('wc-captured', array( 'label' => 'Captured', 'public' => true, 'show_in_admin_all_list' => true, 'show_in_admin_status_list' => true, 'label_count' => _n_noop('Captured <span class="count">(%s)</span>', 'Captured <span class="count">(%s)</span>'), )); } add_filter('wc_order_statuses', 'add_captured_to_order_statuses'); function add_captured_to_order_statuses($statuses) { $updated_statuses = array(); foreach ($statuses as $key => $label) { $updated_statuses[$key] = $label; // Insert "Captured" after the "Processing" status if ('wc-processing' === $key) { $updated_statuses['wc-captured'] = 'Captured'; } } return $updated_statuses; }Then update the
CAPTUREDcase in the webhook code to use'captured'instead of'completed'.
方法二:定时任务轮询(备选方案)
If webhooks aren’t feasible for your setup, you can set up a scheduled cron job to periodically check WorldPay’s API for status changes.
Step 1: Set Up a Scheduled Cron Job
Add this code to create a 15-minute interval task (matching your 15-30 minute window):add_action('wp', 'setup_worldpay_sync_cron'); function setup_worldpay_sync_cron() { if (!wp_next_scheduled('worldpay_order_sync_task')) { wp_schedule_event(time(), 'fifteen_minutes', 'worldpay_order_sync_task'); } } // Register the 15-minute cron interval add_filter('cron_schedules', 'add_fifteen_minute_interval'); function add_fifteen_minute_interval($schedules) { $schedules['fifteen_minutes'] = array( 'interval' => 900, // 15 minutes in seconds 'display' => __('Every 15 Minutes'), ); return $schedules; }Step 2: Add Sync Logic to the Cron Job
This code will pull statuses from WorldPay and update matching WooCommerce orders:add_action('worldpay_order_sync_task', 'sync_worldpay_order_statuses'); function sync_worldpay_order_statuses() { // Fetch WooCommerce orders that are still in "processing" (AUTHORISED) and were created in the last 30 mins $orders = wc_get_orders(array( 'status' => 'processing', 'date_created' => '>-30 minutes', )); foreach ($orders as $order) { $order_id = $order->get_id(); // Call WorldPay's API to get the latest status (replace with your API key) $api_url = "https://api.worldpay.com/v1/orders/{$order_id}"; $headers = array( 'Authorization' => 'Bearer YOUR_WORLDPAY_API_KEY', 'Content-Type' => 'application/json', ); $response = wp_remote_get($api_url, array('headers' => $headers)); if (is_wp_error($response)) continue; $body = json_decode(wp_remote_retrieve_body($response), true); $current_status = $body['paymentStatus']; if ($current_status === 'CAPTURED') { $order->update_status('captured', 'Order synced to CAPTURED via WorldPay API poll'); $order->save(); } } }
Key Notes for Production
- Always Validate Webhook Signatures: Don’t skip this! It prevents malicious actors from faking status updates. Follow WorldPay’s official docs to implement this.
- Match Order IDs Correctly: Ensure the
orderCodefrom WorldPay maps to your WooCommerce order ID. If you use custom order numbers, store the link between them at checkout. - Test in Sandbox First: Test the full flow (AUTHORISED → CAPTURED) in WorldPay’s sandbox environment before going live.
内容的提问来源于stack exchange,提问作者Ali

