1

我正在使用 WordPress 3.9.1 和最新版本的 WooCommerce (2.1.10),我正在尝试创建一个“支付发票”页面,人们在其中输入发票编号和金额,然后直接进入结帐页面。

我现在这样做的方式:

我有一个页面,其中包含人们输入金额的表格:

<form action="#" onsubmit="location.href = 'http://protexfs.co/invoicepage/?date=' + this.elements.date.value; return false;">
<input type="text" name="date">
<input type="submit" value="Go">
</form>

提交按钮指向一个页面,该页面自动生成相同数量的 Woocommerce 产品并将其添加到购物车并自动重定向到结帐页面(我使用 Insert PHP 插件来满足我所有的 PHP 需求):

[insert_php]
//empty cart
global $woocommerce;
$woocommerce->cart->empty_cart();
// Remove default cart message
$woocommerce->clear_messages();

//price
$invoiceprice = filter_input(INPUT_GET,"date",FILTER_SANITIZE_STRING);

//Generate title
$timestampedtitle = "Date: ".date("d/m/Y")." Amount: £".$invoiceprice;

//Generate message
$message = date_timestamp_get(date_create())." Date: ".date('m/d/Y h:i:s a', time())." Invoice amount: £".$invoiceprice;

$post = array(
'post_author' => '2',
'post_status' => "publish",
'post_title' => $timestampedtitle,
'post_content' => $message,
'post_parent' => '',
'post_type' => "product",
//'post_status' => 'private',
);

//Create post
$post_id = wp_insert_post( $post, $wp_error );
if($post_id){
$attach_id = get_post_meta($product->parent_id, "_thumbnail_id", true);
add_post_meta($post_id, '_thumbnail_id', $attach_id);
}
wp_set_object_terms($post_id, 'simple', 'product_type');
update_post_meta( $post_id, '_visibility', 'search' );
update_post_meta( $post_id, '_stock_status', 'instock');
update_post_meta( $post_id, '_virtual', 'yes');
update_post_meta( $post_id, '_regular_price', $invoiceprice );
update_post_meta( $post_id, '_sale_price', $invoiceprice );
update_post_meta( $post_id, '_purchase_note', "" );
update_post_meta( $post_id, '_featured', "no" );
update_post_meta( $post_id, '_weight', "" );
update_post_meta( $post_id, '_length', "" );
update_post_meta( $post_id, '_width', "" );
update_post_meta( $post_id, '_height', "" );
update_post_meta($post_id, '_sku', "");
update_post_meta( $post_id, '_product_attributes', array());
update_post_meta( $post_id, '_sale_price_dates_from', "" );
update_post_meta( $post_id, '_sale_price_dates_to', "" );
update_post_meta( $post_id, '_price', $invoiceprice );
update_post_meta( $post_id, '_sold_individually', "" );
update_post_meta( $post_id, '_manage_stock', "no" );
update_post_meta( $post_id, '_backorders', "no" );
update_post_meta( $post_id, '_stock', "" );
update_post_meta( $post_id, '_et_pb_page_layout', 'et_full_width_page' );

if( $woocommerce->cart ) {
     $woocommerce->cart->add_to_cart( $post_id, $quantity=1 );}

$url = $woocommerce->cart->get_checkout_url();
header("Location: $url");
[/insert_php]

只要我登录,这似乎就可以完美运行。但是,如果用户未登录,产品仍会生成但无法添加到购物车,显示以下消息:“对不起,该产品不能买了。” (这破坏了整个事情)。

奇怪的是,客人可以访问我通过 WooCommerce 界面创建的任何其他产品(因此,如果我有一个公开可用的产品并且我以编程方式更改其价格并将其添加到购物车,它可以工作 -> 但这会产生问题当 2 个人同时点击按钮时)。

在你问之前,我已经在 WooCommerce 设置中启用了访客结账。

有想法该怎么解决这个吗?(或者可能是一种完全不同的方式来实现我的目标?)

弗拉德

4

4 回答 4

1

我刚刚在复合产品上遇到了同样的问题。

我解决它的方法是从错误消息中向后工作。

我从在我的wp-content目录中开始:

$ ack "Sorry, this product cannot be purchased."

注意:ack很像grep,但更好。

这返回了以下结果(您的结果将因您安装的插件而异):

plugins/woocommerce/includes/class-wc-cart.php
825:                wc_add_notice( __( 'Sorry, this product cannot be purchased.', 'woocommerce' ), 'error' );

plugins/woocommerce-composite-products/includes/class-wc-cp-display.php
118:            'i18n_unavailable_text'                    => __( 'Sorry, this product cannot be purchased at the moment.', 'woocommerce-composite-products' ),

从那里,我注意到有一个 woocommerce i18n 映射i18n_unavailable_text到我的原始搜索字符串。

为了不错过任何其他事件,我努力ack编辑:

$ ack i18n_unavailable_text

结果是:

plugins/woocommerce/assets/js/frontend/add-to-cart-variation.js
392:                    $variation_form.find( '.single_variation' ).html( '<p>' + wc_add_to_cart_variation_params.i18n_unavailable_text + '</p>' );

plugins/woocommerce/includes/class-wc-frontend-scripts.php
197:                'i18n_unavailable_text'            => esc_attr__( 'Sorry, this product is unavailable. Please choose a different combination.', 'woocommerce' ),

plugins/woocommerce-composite-products/assets/js/add-to-cart-composite.js
2948:                       composite.disable_add_to_cart( wc_composite_params.i18n_unavailable_text );

plugins/woocommerce-composite-products/includes/class-wc-cp-display.php
118:            'i18n_unavailable_text'                    => __( 'Sorry, this product cannot be purchased at the moment.', 'woocommerce-composite-products' ),

有了这个列表,我启动了我的文本编辑器并查看了我认为相关的两个结果:

plugins/woocommerce-composite-products/assets/js/add-to-cart-composite.js
2948:                       composite.disable_add_to_cart( wc_composite_params.i18n_unavailable_text );
plugins/woocommerce/includes/class-wc-cart.php
825:                wc_add_notice( __( 'Sorry, this product cannot be purchased.', 'woocommerce' ), 'error' );

我在浏览器中为 js 文件设置了一个断点,顺便说一下,在我的情况下,我必须将其移动到位,因为浏览器当然使用的是缩小版本,没有源映射。那个断点没有被命中,所以我进入了 php 调试会话。这很成功,让我进一步陷入了兔子洞(请原谅我的 vim 行号 - 我set relativenumber在 vim 中使用 - 但相关的行号plugins/woocommerce/includes/class-wc-cart.php是 824-825):

   2       // Check product is_purchasable
   1       if ( ! $product_data->is_purchasable() ) {
825          wc_add_notice( __( 'Sorry, this product cannot be purchased.', 'woocommerce' ), 'error' );
   1         return false;
   2       }

文档:$product_data->is_purchasable()

我使用kint进行调试,因此我根据上面文档中的 if 语句添加了一些调试输出,以查看是什么导致可购买性检查失败:

   2       // Check product is_purchasable
   1       if ( ! $product_data->is_purchasable() ) {
825          d(! $product_data->exists());
   1         d($product_data->get_price() === '');
   2         d($product_data->post->post_status !== 'publish');
   3         d(! current_user_can( 'edit_post', $product_data->id ));
   4         wc_add_notice( __( 'Sorry, this product cannot be purchased.', 'woocommerce' ), 'error' );
   5         return false;
   6       }

这告诉我$product_data->post->post_status !== 'publish' bool FALSE。这当然意味着不知何故我的帖子没有发表。当我运行这个 sql 查询时,这导致另一个较低的梯级进入兔子洞(10962是罪魁祸首产品/帖子的 id,并且wp_4_posts是我的 wordpress 网络站点帖子表的表名,该帖子所在的位置:

SELECT post_status FROM wp_4_posts WHERE id = '10962'

那回来了post_status: publish。现在有人向我开枪是我的第一反应。但是,我也注意到:

$product_data->get_price() === '' bool FALSE

因此,该产品的价格计算不正确。

再次进入文档,这次是$product_data->get_price()

思考了几分钟后,这让我很快意识到我没有为产品添加底价,认为指定了“Per-Item-Pricing”,我就不必设置底价了。不幸的是我。事实证明,这在Composite Products 文档中有很好的记录:

每个项目的复合产品定价文档

于 2015-08-15T16:12:00.007 回答
0

我刚刚遇到了类似的问题,我想分享我为解决问题所做的工作。首先,我希望用户能够在网站上购买附加内容(就像 craigslist 一样),这些附加内容的价格取决于您选择的选项和附加内容的长度。所以很自然地,我不能创造人们可以购买的固定产品。这些添加将在以后发布(由于它与报纸的纸质版本相关联),因此添加将在“未来”状态下创建,并且当日期到达时,wordpress 会将它们呈现为“发布”。

当我以管理员身份登录时,一切正常,但以普通用户身份登录时,人们无法购买附加组件,出现“抱歉无法购买此产品”错误。我所做的是许多人根本不推荐的(甚至我自己),但这是我在有限的时间内找到的唯一解决方案。

Woocommerce 验证这些内容,以便了解产品是否可购买:

产品存在 产品有价格 (postmeta _price != "") 产品处于“发布”状态或当前用户可以编辑产品(例如管理员)

如果当前用户是产品的作者,我将验证添加到最后一个以允许购买产品(因此创建添加的人将能够购买它,但没有其他人)。

因此,在第 690 行的文件 woocommerce/includes/abstracts/abstract-wc-product.php (来自您的插件目录)中,您有这个

elseif ( $this->post->post_status !== 'publish' && ! current_user_can( 'edit_post', $this->id )

将其更改为

elseif ( $this->post->post_status !== 'publish' && ! current_user_can( 'edit_post', $this->id ) && $this->post->post_author != get_current_user_id()) {

如果您可以避免它,我不建议您这样做,因为它的缺点是如果更新了 woocommerce,它可能会重新下载此文件并且更改可能会丢失。但是,如果这是您唯一的解决方案,就像对我一样(主要是由于时间限制,并且没有想太多),那么...

于 2014-11-28T16:22:25.800 回答
0

我以前见过这个问题。有问题的产品缺少一些后期元数据。添加产品后比较您的 post_meta 表,然后编辑产品,保存并再次比较表。检查 WooCommerce 添加了哪些键。

它需要严格选择元密钥才能让您购买产品。

SELECT * FROM wp_postmeta WHERE post_id = '1234567' ORDER BY 'meta_key'

于 2014-07-31T13:36:28.853 回答
0

正如我上面的评论,解决这个问题的方法是:

我解决问题的方法是手动创建约 50 个产品(因此用户可以访问)。每当用户创建新发票时(在文本字段中输入一个值并按确定),就会随机挑选一个产品,并将其价格更改为输入的值。这样,用户就可以访问产品,并且不会在多人同时单击“确定”按钮时搞砸。

于 2017-02-01T22:31:04.520 回答