WooCommerce 按订单商品标签切换PayPal收款邮箱的实现与语法报错解决
WooCommerce 基于产品标签的PayPal收款邮箱动态切换实现
语法错误直接原因
你触发的syntax error, unexpected 'array' (T_ARRAY), expecting ')'报错是因为in_array函数调用少了参数分隔逗号:
// 你的错误代码:$receiver_email 和后面的数组中间漏了逗号 if ( ! in_array( $receiver_email array('paypal1@domain.com', 'paypal2@domain.com') ) // 修正后的基础语法结构 if ( ! in_array( $receiver_email, array('paypal1@domain.com', 'paypal2@domain.com') )
完整可运行适配代码
以下代码替换你当前的自定义逻辑,直接实现按订单商品标签匹配切换收款邮箱,同时修正IPN校验白名单,避免换邮箱后触发订单状态校验失败:
// 1. 基于订单商品标签动态切换PayPal收款邮箱 add_filter( 'woocommerce_paypal_args' , 'switch_paypal_email_based_on_product_tag', 9999, 2 ); function switch_paypal_email_based_on_product_tag( $paypal_args, $order ) { // 自定义标签与收款邮箱映射规则(可根据实际站点标签调整匹配值) $tag_email_map = [ // 第一组匹配标签:服装、鞋履、箱包类,对应邮箱 emailpaypal1@domain.com 'group_1' => [ 'tags' => ['clothing', 'shoes', 'bags'], // 替换为你站点实际的产品标签slug 'email' => 'emailpaypal1@domain.com' ], // 第二组匹配标签:滑雪、防晒、园艺类,对应邮箱 paypal2@domain.com 'group_2' => [ 'tags' => ['ski', 'sun_protection', 'gardening'], // 替换为你站点实际的产品标签slug 'email' => 'paypal2@domain.com' ] ]; foreach ( $order->get_items() as $item_id => $item ) { $product = $item->get_product(); // 兼容变体产品:如果是规格变体,取父产品ID关联的标签 $product_id = $product->is_type('variation') ? $product->get_parent_id() : $product->get_id(); // 获取产品关联的所有标签slug,避免中文编码问题导致匹配失效 $product_tag_slugs = wp_get_post_terms( $product_id, 'product_tag', ['fields' => 'slugs'] ); // 遍历匹配规则组 foreach ( $tag_email_map as $rule_group ) { // 判断产品是否命中当前组的任意标签 if ( array_intersect( $product_tag_slugs, $rule_group['tags'] ) ) { $paypal_args['business'] = $rule_group['email']; break 2; // 命中后跳出两层循环,不再遍历后续订单项 } } } return $paypal_args; } // 2. 扩展PayPal IPN校验逻辑,支持多收款邮箱白名单 require_once WC()->plugin_path() . '/includes/gateways/paypal/includes/class-wc-gateway-paypal-ipn-handler.php'; class WC_Gateway_Paypal_IPN_Handler_Switch extends WC_Gateway_Paypal_IPN_Handler { protected function validate_receiver_email( $order, $receiver_email ) { // 配置所有支持的PayPal收款邮箱白名单 $allowed_receiver_emails = [ $this->receiver_email, // 站点后台设置的默认PayPal邮箱 'emailpaypal1@domain.com', // 动态切换的第一个收款邮箱 'paypal2@domain.com' // 动态切换的第二个收款邮箱 ]; // 统一格式化邮箱地址做不区分大小写的匹配 $normalized_receiver_email = trim( strtolower( $receiver_email ) ); $normalized_whitelist = array_map( function( $email ) { return trim( strtolower( $email ) ); }, $allowed_receiver_emails ); if ( ! in_array( $normalized_receiver_email, $normalized_whitelist, true ) ) { WC_Gateway_Paypal::log( "IPN Response is for another account: {$receiver_email}. Allowed emails: " . implode(', ', $allowed_receiver_emails ) ); $order->update_status( 'on-hold', sprintf( __( 'Validation error: PayPal IPN response from a different email address (%s).', 'woocommerce' ), $receiver_email ) ); exit; } } } new WC_Gateway_Paypal_IPN_Handler_Switch();
使用注意事项
- 代码中
$tag_email_map里的标签值需要替换为你站点实际使用的产品标签slug(可在Word后台产品标签列表页查看每个标签的slug),不要直接用中文标签名做匹配,避免字符编码问题导致匹配失效 - 代码已经做了变体产品兼容,服装、鞋履类带规格变体的商品也能正常匹配关联标签
- 如果订单中同时存在命中不同标签组的商品,会按照规则组的排序优先应用排在前面的邮箱配置,可通过调整
$tag_email_map的数组顺序调整优先级 - IPN校验部分已经自动做了邮箱大小写兼容,不会因为PayPal返回的邮箱大小写和配置不一致触发校验失败
内容的提问来源于stack exchange,提问作者Mattia Truzzi
相关产品推荐
相关产品推荐

