在 Woocommerce 中仅向 PayPal 发送订单号而不是商品名称

Posted

技术标签:

【中文标题】在 Woocommerce 中仅向 PayPal 发送订单号而不是商品名称【英文标题】:Sending only order number instead of item names to PayPal in Woocommerce 【发布时间】:2018-02-23 14:24:13 【问题描述】:

在 Woocommerce 的 PayPal 标准网关中,我想让 Woocommerce 仅发送“订单号”作为购物车中的唯一商品,而不是逐项列出的产品列表。

为此,我尝试在此处编辑负责发出 PayPal 请求的类: woocommerce/includes/gateways/paypal/includes/class-wc-gateway-paypal-request.php

我尝试编辑 get_order_item_names() 函数以返回 "invoice" . $order->get_order_number() 作为唯一商品的名称,但没有成功,因为如果有多个商品,则仅返回第一个带有订单号的商品,并且其他物品仍然存在。

另外,我钉了add_line_item()函数,因为为了接近目的,实际上应该只有“item_name_1”与卡的总金额。

$this->line_items[ 'item_name_' . $index ]   = $this->limit_length( $item['item_name'], 127 );
$this->line_items[ 'quantity_' . $index ]    = $item['quantity'];
$this->line_items[ 'amount_' . $index ]      = $item['amount'];
$this->line_items[ 'item_number_' . $index ] = $this->limit_length( $item['item_number'], 127 );

这里也没有成功。

感谢您的帮助。

【问题讨论】:

【参考方案1】:

建议:您确实应该避免覆盖 woocommerce 核心文件

相反,您可以在这种特殊情况下使用过滤器钩子woocommerce_paypal_args,其中您将能够操纵参数用于 get_request_url() 函数(将获取订单的 PayPal 请求 URL)。

1) 测试并获取数据发送

只是为了注册并获取发送到贝宝的参数,我已经这样使用了钩子:

add_filter('woocommerce_paypal_args', 'custom_paypal_args', 10, 2 );
function custom_paypal_args ( $args, $order ) 
    // Saving the data to order meta data (custom field)
    update_post_meta( $order->get_id(), '_test_paypal', $args );
    return $args;

代码进入您的活动子主题(或主题)的 function.php 文件或任何插件文件中。

现在我可以简单地使用它来获取数据(设置正确的订单 ID):

$order_id = 648;
$data_sent_to_paypal = get_post_meta( $order_id, '_test_paypal' );
echo '<pre>'; print_r( $data_sent_to_paypal ); echo '</pre>'; 

或者在一个钩子中(在这个例子中的商店页面中只对管理员可见):

// Only visible on shop pages by admins
add_action( 'woocommerce_before_main_content', function()
    // Only visible by admins
    if( ! current_user_can( 'manage_options' ) ) return;

    $order_id = 648;
    $data_sent_to_paypal = get_post_meta( $order_id, '_test_paypal' );
    echo '<pre>'; print_r( $data_sent_to_paypal ); echo '</pre>';
, 10, 0 );

这给了我这样的输出(对于 2 种产品和不同的数量):

Array
(
    [0] => Array
    (
        [cmd] => _cart
        [business] => email@example.com
        [no_note] => 1
        [currency_code] => EUR
        [charset] => utf-8
        [rm] => 2
        [upload] => 1
        [return] => https://example.com/checkout/order-received/8877?key=wc_order_55445ndfgbulfdf&utm_nooverride=1
        [cancel_return] => https://example.com/cart/?cancel_order=true&order=wc_order_55445ndfgbulfdf&order_id=8877&redirect&_wpnonce=34m7kl83455
        [page_style] => 
        [image_url] => https://example.com/wp-content/uploads/2012/06/logo.png
        [paymentaction] => sale
        [bn] => WooThemes_Cart
        [invoice] => pp-8877
        [custom] => "order_id":8877,"order_key":"wc_order_55445ndfgbulfdf"
        [notify_url] => https://example.com/wc-api/WC_Gateway_Paypal/
        [first_name] => John
        [last_name] => Doe
        [address1] => Test st.
        [address2] => 
        [city] => wef
        [state] => AR
        [zip] => 43242
        [country] => US
        [email] => myemail@example.com
        [night_phone_a] => 078
        [night_phone_b] => 653
        [night_phone_c] => 6216
        [no_shipping] => 1
        [tax_cart] => 16.55
        [item_name_1] => Test Product - Service
        [quantity_1] => 1
        [amount_1] => 71
        [item_number_1] => 
        [item_name_2] => Test Product 1
        [quantity_2] => 1
        [amount_2] => 66
        [item_number_2] => 
        [item_name_3] => Test Product 2
        [quantity_3] => 1
        [amount_3] => 120
        [item_number_3] => 
        [item_name_4] => Test Product 3
        [quantity_4] => 1
        [amount_4] => 45
        [item_number_4] => 
    )

)

正如您现在所看到的,使用 woocommerce_paypal_args 您将能够更改或删除任何参数。

始终只有一个:'item_name_1''quantity_1''amount_1''item_number_1',始终将索引 1 发送到贝宝。 p>


2 处理发送的数据 (示例)

我们仍然可以使用 woocommerce_paypal_args,例如 'item_name_1' 键上的过滤钩子,将商品名称替换为订单号,就像你想要的那样:

add_filter('woocommerce_paypal_args', 'custom_paypal_args', 10, 2 );
function custom_paypal_args ( $args, $order ) 
    $$args_keys = array_keys($args);
    $i = 0;
    // Iterating through order items
    foreach( $order->get_items() as $item_id => $item_product )
        $i++; // updating count.
        if( ! empty($args["item_name_$i"]) )
            // Returning the order invoice in the item name
            $args["item_name_$i"] = "invoice #" . $order->get_id();
        
    
    return $args;

代码进入您的活动子主题(或主题)的 function.php 文件或任何插件文件中。

代码经过测试,可在 WooCommerce 3+ 上运行

完成:当您在挂钩函数中获取 WC_Order 对象作为参数时,您可以使用它从订单中获取任何数据,并根据需要操作发送到贝宝网关的数据。

查看此相关答案:How to get WooCommerce order details

【讨论】:

感谢亲爱的 Loic,关于操纵$args,需要删除卡中第一项之后的所有其他项目。另外,将第一个商品的价格设置为购物车的全部价格(因为只有一个商品)。所以这是编辑后的自定义函数。您可以在答案中添加:Custom function to modify $args 1. 你在哪里运行上面的代码(在测试部分)给你数组?我可以在 WordPress/Woocommerce 中的哪个文件中放置代码以检索 post_meta 并打印您显示的数组? 2. 如果没有woocommerce_paypal_args 过滤钩子,我们如何覆盖我们编写的插件或主题的function.php 中的get_request_url()?我的问题是在我们的自定义插件或主题的 function.php 中覆盖任何插件的功能。 谢谢,关于答案 2 :如果没有可用的钩子,我想知道如何覆盖插件(例如 woocommerce)中的函数。我们如何在不更改插件更新后会丢失的插件核心的情况下覆盖该功能并更改其功能? ... 关于答案 3 :当我在购物车中有多个商品时,还会有 item_name_2item_name_3item_name_4 .... Woocommerce 版本:3.1.2 我已经更新了关于(第 1 点)的答案……2。 总是有一个钩子或技巧可以覆盖所有内容。对于已关闭的第三方插件,这是另一回事。此外,您可以扩展类... 3. 名称添加在同一字符串中,金额相加,索引始终为1 ...它不会发送每个项目,而是合并项目数据。你会看到……测试一下。 谢谢。关于包含订单总价的索引1 的项目,对我来说不是这样。我用一个订单测试了 4 个项目,并将参数保存在 post_meta 中(您在答案中提供的测试程序);这是具有索引 4: paste.ubuntu.com/25568072 的四个项目的输出,每个项目都有其特定的价格。 ... 另一件事是,在最新版本的 Woocommerce 中,我的产品末尾添加了一个 - Service 关键字。怎么了?【参考方案2】:

我正在使用以下函数来获取订单 ID,您可以根据需要编辑和使用以下函数。

public function process_payment( $order_id ) 
    global $woocommerce;
    $order = new WC_Order( $order_id );
    return array(
        'result'  => 'success',
        'redirect' => $order->get_checkout_payment_url( true )
    );

【讨论】:

这个回复完全没用:问题不在于如何获取订单ID,而是如何将订单ID而不是物品传递给PayPal。

以上是关于在 Woocommerce 中仅向 PayPal 发送订单号而不是商品名称的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Oro CRM 中仅向一个布局更新操作添加条件?

PayPal 直接支付 PHP 代码

如何在 Laravel 中仅向访客用户显示或隐藏我的表的一部分?

sql WooCommerce仅向欧盟国家发货

在 Woocommerce 商店页面中仅显示特色产品

在 WooCommerce 的产品网址中仅使用 ID?