如何将指定状态的WooCommerce会员邮箱有效发送至外部API端点?
问题描述
我在用WooCommerce Subscriptions插件,想把Active、Pending Cancellation和Complementary状态的会员邮箱同步到合作方的外部API,但写的WordPress代码片段完全没反应,也不报错——已经开了调试,日志里啥相关信息都没有。另外,我用Postman直接测过API端点和授权,数据能正常发送,所以问题肯定出在代码或者WordPress/WooCommerce的配置上。
原代码如下(已隐去敏感信息):
// Hook into the WooCommerce Memberships event when a user membership is updated or created. add_action('wc_memberships_user_membership_saved', 'send_membership_email_to_external', 10, 1); // Function to handle real-time sync when membership is saved function send_membership_email_to_external($user_membership) { // Ensure the passed object is of the correct type if (!($user_membership instanceof WC_Memberships_User_Membership)) { error_log('Unexpected object type in send_membership_email_to_external'); return; } // Get user details $user_id = $user_membership->get_user_id(); $user_info = get_userdata($user_id); $user_email = $user_info->user_email; // Get the membership status $membership_status = $user_membership->get_status(); // Check if the membership is 'wc-active', 'wc-pending-cancel', or 'wc-complementary' if (in_array($membership_status, array('wc-active', 'wc-pending-cancel', 'wc-complementary'))) { // Proceed to sync the email to the API sync_emails_to_api(array($user_email)); } } // Function to sync emails to the API function sync_emails_to_api($email_array) { // Set the API endpoint and auth token $api_url = 'exampleurl.php'; $auth_token = 'exampleauthtoken'; // Your provided auth token // Prepare the data to send $api_body = array( 'action' => 'departmentEmails', // As specified by the API docs 'arrayEmails' => $email_array, // Emails to sync ); // Set up the request arguments $args = array( 'method' => 'POST', 'headers' => array( 'Authorization' => $auth_token, 'Content-Type' => 'application/json', ), 'body' => json_encode($api_body), 'timeout' => 45, ); // Send the request using wp_remote_post() $response = wp_remote_post($api_url, $args); // Check for errors if (is_wp_error($response)) { // Log the error for debugging purposes error_log('API Sync Error: ' . $response->get_error_message()); } else { // Optionally, handle the API response $api_response = json_decode(wp_remote_retrieve_body($response), true); if (isset($api_response['success']) && $api_response['success']) { // Successful sync (you can log this if needed) error_log('API Sync Success'); } else { // Handle an unsuccessful response from the API error_log('API Sync Failed: ' . wp_remote_retrieve_body($response)); } } }
问题排查与修复方案
1. 钩子事件不匹配
你用的wc_memberships_user_membership_saved是WooCommerce Memberships插件的钩子,但你实际用的是WooCommerce Subscriptions——这俩是独立插件,订阅状态变更时这个钩子根本不会触发。
- 替换为Subscriptions对应的钩子:
- 订阅状态变更时触发:
woocommerce_subscription_status_updated - 订阅保存(创建/更新)时触发:
woocommerce_subscription_saved
- 订阅状态变更时触发:
2. 状态值校验错误
WooCommerce Subscriptions的状态没有wc-前缀,直接用active、pending-cancel、complementary即可。原代码里的wc-active这类值完全不匹配,导致条件判断不通过,根本没走到API调用逻辑。
3. 调试日志增强
原代码日志输出太少,加几个关键调试点,确认代码执行路径:
- 在
send_membership_email_to_external开头加:error_log('Hook triggered: send_membership_email_to_external'); - 在获取状态后加:
error_log('Current subscription status: ' . $membership_status); - 在进入API调用分支时加:
error_log('Syncing email: ' . $user_email);
4. 用户数据容错处理
原代码没处理get_userdata($user_id)返回false的情况(比如用户已删除),会直接中断执行,新增判断:
if (!$user_info) { error_log('User not found for ID: ' . $user_id); return; }
修复后的完整代码示例
// 替换为Subscriptions的钩子 add_action('woocommerce_subscription_saved', 'send_subscription_email_to_external', 10, 1); function send_subscription_email_to_external($subscription) { error_log('Hook triggered: send_subscription_email_to_external'); // 验证对象类型 if (!($subscription instanceof WC_Subscription)) { error_log('Unexpected object type in send_subscription_email_to_external'); return; } // 获取用户信息并容错 $user_id = $subscription->get_user_id(); $user_info = get_userdata($user_id); if (!$user_info) { error_log('User not found for ID: ' . $user_id); return; } $user_email = $user_info->user_email; // 获取订阅状态(Subscriptions状态无前缀) $subscription_status = $subscription->get_status(); error_log('Current subscription status: ' . $subscription_status); // 修正状态值判断 $target_statuses = array('active', 'pending-cancel', 'complementary'); if (in_array($subscription_status, $target_statuses)) { error_log('Syncing email: ' . $user_email); sync_emails_to_api(array($user_email)); } else { error_log('Status not in target list: ' . $subscription_status); } } // 保留原API同步函数,注意替换真实的api_url和auth_token function sync_emails_to_api($email_array) { $api_url = '你的真实API端点'; $auth_token = '你的真实授权令牌'; $api_body = array( 'action' => 'departmentEmails', 'arrayEmails' => $email_array, ); $args = array( 'method' => 'POST', 'headers' => array( // 注意:部分API要求格式为Bearer {token},需根据实际调整 'Authorization' => $auth_token, 'Content-Type' => 'application/json', ), 'body' => json_encode($api_body), 'timeout' => 45, 'sslverify' => false, // 如果API是自签证书,临时关闭验证,上线后建议开启 ); $response = wp_remote_post($api_url, $args); if (is_wp_error($response)) { error_log('API Sync Error: ' . $response->get_error_message()); } else { $api_response = json_decode(wp_remote_retrieve_body($response), true); if (isset($api_response['success']) && $api_response['success']) { error_log('API Sync Success for emails: ' . implode(',', $email_array)); } else { error_log('API Sync Failed: ' . wp_remote_retrieve_body($response)); } } }
额外配置检查
- 确认WordPress的
wp-config.php已开启调试:define('WP_DEBUG', true); define('WP_DEBUG_LOG', true); define('WP_DEBUG_DISPLAY', false); - 检查服务器是否允许
wp_remote_post对外请求,部分主机可能禁用了curl或fsockopen,可通过phpinfo()查看相关配置。 - 确认API的Authorization格式是否正确,有些API要求
Bearer {token},需调整代码中的请求头。
内容的提问来源于stack exchange,提问作者Joe
相关产品推荐
相关产品推荐

