Skip Navigation

[Résolu] Posts don’t publish everytime after order payment

Ce fil est résolu. Voici une description du problème et la solution proposée.

Problem: I have a Commerce Form that is used to publish a post and connect it to an Order. The Commerce Form is configured to publish the post when the Order is completed. However, sometimes clients submit the same Form multiple times for the same Order. In this case, several posts are created but only the most recent post is published when the Order is completed. I would like to publish all the posts connected to the Order when the Order is completed.

Solution: Forms Commerce is not designed to support more than one post per Order, so custom code is required to make this work. See the example here using the cred_commerce_after_order_completed API:

// publish all posts created when one commerce form is submitted mutliple times in the same order
add_action( 'cred_commerce_after_order_completed', 'publish_all_ordered_posts', 10, 1 );
function publish_all_ordered_posts( $data ) {
  // which order was completed?
  $order_id = $data['transaction_id'];
  // which posts were created in this order?
  $all_order_posts = get_post_meta( $order_id, '_cred_post_id');
  // loop over all the created posts
  if( !is_array( $all_order_posts ) )
    return;
  foreach( $all_order_posts as $all_order_post ) {
    // check the post status
    $this_post_status = get_post_status( $all_order_post );
    // publish any unpublished posts
    if ( $this_post_status != 'publish' ) {
      $args = array(
        'ID' => $all_order_post,
        'post_status' => 'publish'
      );
      wp_update_post( $args );
    }
  }
}

Relevant Documentation:
https://toolset.com/documentation/programmer-reference/cred-commerce-api/#cred_commerce_after_order_completed

This is the technical support forum for Toolset - a suite of plugins for developing WordPress sites without writing PHP.

Everyone can read this forum, but only Toolset clients can post in it. Toolset support works 6 days per week, 19 hours per day.

Auteur
Publications
#1764061

Pat

Hello,

I have replaced the "add to cart" button in a product template by a forms in order to create a post each time somebody buys a product.
The forms is a WC form with a link to the product ID define by the page of the product where the form is inserted.
Until there, everything is fine and each time the form is used, the desired product is added to the cart and a post is created as a draft.

Now, the issue is that when the user finalise his order (payment completed), sometimes, some of the posts linked to this order (it is possible that several products have been bought during the same process) are not moved from draft to publish and stay draft !
This happends if several products are present in the cart, but if only one product is in the cart, then, it is published whitout any issue.
In case of several products, generally, only one is published nad the others stay draft.

Is there a way to solve this issue which is critical as we are not able to be sure that all bought products have a publish created post !

Regards
Pat

#1764075

Pat

Some complementory info :

I have different WC forms that are used (depending of the product category).
If I have in the cart 1 product related to form1 and 1 product related to form2, then, all products are published
If I have 2 (or more) products issued from the same form (1 or 2), then only one is published.

Another point is that I have a hook for these forms that enables to define the post title. Here is the code :

add_action('cred_save_data','func_custom_enseignement_title',10,2);
function func_custom_enseignement_title($post_id,$form_data) {

if (($form_data['id']==6147) OR ($form_data['id']==6182) OR ($form_data['id']==6131))
{ 
$anneeu = $_POST['wpcf-annee-universitaire'];
$nom_id = $_POST['wpcf-id-du-produit-achete'];
$user_id = $_POST['post_auteur'];
$titre_id = get_the_title( $nom_id );
$typeeven = get_post_meta( $nom_id, 'wpcf-type-d-evenement', true ); 

$stockavant = get_post_meta( $nom_id, '_stock', true );   
$stockapres = $stockavant -1;
update_post_meta( $nom_id, '_stock', $stockapres );
$tarifproduitachete = get_post_meta($nom_id, '_regular_price', true );
update_post_meta( $post_id, 'wpcf-tarif-du-produit-achete', $tarifproduitachete );
update_post_meta( $post_id, 'wpcf-nom-de-l-evenement', $titre_id );
update_post_meta( $post_id, 'wpcf-type-d-evenement', $typeeven );

  
$titre = $anneeu." - ".$nom_id." - ".$user_id;

$slug = strtolower($titre);
$slugstring = str_replace(' ', '-', $slug);
  
$args = array(
  'ID' => $post_id, 
  'post_title' => $titre, 
  'post_name' => $slugstring,
  'post_author' => $user_id
);

wp_update_post($args);
}
}

Hope this helps
Regards
Pat

#1764487

Christian Cox
Supporter

Languages: Anglais (English )

Timezone: America/New_York (GMT-04:00)

Hello, thank you for the detailed description of the problem and your custom code. It turns out that the behavior you described is a limitation of the Forms Commerce system. When the same Form is submitted multiple times during one Order, only the most recently created post will be published when the Order is completed. Another User noticed the same issue recently, and our team leader pointed out this ticket as a reference: https://toolset.com/forums/topic/continue-post-status-not-updated-properly-when-multiple-of-product-in-cart/

We have asked the developers to consider supporting multiple product purchases during the same Order using the same Commerce Form, but the changes are not trivial and will take some time to implement. Until then, the simplest and most effective solution is to choose the Form option "Clear the cart and include only the selected product". You may find it helpful to add a note for your site visitors explaining that these Products must be purchased independently, in separate Orders. This will ensure that all the created posts are published as expected and notifications are triggered appropriately when an Order is completed.

If multiple product purchases in the same Order are a priority for your Users, a more complex workaround uses the Commerce Forms API hook cred_commerce_after_order_completed. You can use this hook to trigger your own custom code upon Order completion. Use the WordPress get_post_meta function to find all post meta keys "_cred_post_id" for the same completed Order ID. The completed Order ID is noted in the hook callback $data parameter as transaction_id (see link below for documentation of the callback parameters). Each of those post meta values correspond to one of the created post IDs. You could then loop over those post IDs and trigger a post status change on any of those posts that are still unpublished.

See the documentation for that hook available here: https://toolset.com/documentation/programmer-reference/cred-commerce-api/#cred_commerce_after_order_completed
See the documentation for get_post_meta here: https://developer.wordpress.org/reference/functions/get_post_meta/

Let me know if you have questions about that and I can offer more guidance.

#1764569

Pat

Hi Christian and thanks to confirm the issue.

I would like to propose than Toolset gives us (the Toolset members that have to face with this issue), a hook to make it work as I understand this is not a really easy thing to manage from the development point of view (in other words, that could take a certain time !).
So, that would be good that Toolset propose a hook (based on cred_commerce_after_order_completed) that will publish all posts that are linked to this order.
Do you thing this is something feasible?

Regards
Pat

#1765375

Christian Cox
Supporter

Languages: Anglais (English )

Timezone: America/New_York (GMT-04:00)

I'll look for an example today and give you an update.

#1765631

Pat

Thanks CHristian,

Please make sure that the post will all be published, but also that the stock related to each product decrease.
Regards
Pat

#1768505

Shane
Supporter

Languages: Anglais (English )

Timezone: America/Jamaica (GMT-05:00)

Hi Pat,

Christian is currently on a Public Holiday today but he will be back tomorrow to continue assisting.

Thank you for the continued patience.

#1769557

Christian Cox
Supporter

Languages: Anglais (English )

Timezone: America/New_York (GMT-04:00)

Please make sure that the post will all be published, but also that the stock related to each product decrease.
Can you explain this in more detail? Normally WooCommerce will remove product stock when the order is submitted, and "hold" it based on the "hold stock" setting. In other words, adding code to deduct stock when the order is completed might result in inaccurate stock quantities, since the quantity is deducted from stock twice. Are you saying that your system does not hold stock initially when the order is created?

Here is an example that publishes all unpublished posts created by a single Order, without any stock manipulation:

// publish all posts created when one commerce form is submitted mutliple times in the same order
add_action( 'cred_commerce_after_order_completed', 'publish_all_ordered_posts', 10, 1 );
function publish_all_ordered_posts( $data ) {
  // which order was completed?
  $order_id = $data['transaction_id'];
  // which posts were created in this order?
  $all_order_posts = get_post_meta( $order_id, '_cred_post_id');
  // loop over all the created posts
  if( !is_array( $all_order_posts ) )
    return;
  foreach( $all_order_posts as $all_order_post ) {
    // check the post status
    $this_post_status = get_post_status( $all_order_post );
    // publish any unpublished posts
    if ( $this_post_status != 'publish' ) {
      $args = array(
        'ID' => $all_order_post,
        'post_status' => 'publish'
      );
      wp_update_post( $args );
    }
  }
}
#1773193

Pat

Hi Christian,

Thanks for your feedback.
Concerning the stock decrease, I just wanted to be sure that even if several products where published in the same time, the normal way of doing of WC will be conserved, that means, each product will have its own stock decrease by the number of unit bought !

Now, concerning the validation of your proposal, I need to wait some time (when the site will not be under pressure like today). So, I propose to let the ticket open for feedback and I will confirm as soon as I will be able to test it.

Regards
Pat

#1774901

Christian Cox
Supporter

Languages: Anglais (English )

Timezone: America/New_York (GMT-04:00)

Of course, I will stand by for your update.

#1783107

Pat

Hi Christian,
Do you have any idea when this could be integrated in a new version of Form commerce plugin?
Was it always managed like this in the Form plugin (ie : only the last post published) as I had created a ticket some years ago discribing this issue?

Regards
Pat

#1783281

Christian Cox
Supporter

Languages: Anglais (English )

Timezone: America/New_York (GMT-04:00)

I would not expect this behavior to change in the near future. The Forms Commerce plugin was not designed to work with mulitple products per Order, as only one Product ID was ever added to the database related to a given Order. For best results, we recommend using the option "clear the cart and add the product to cart".

#1784237

Pat

Hi Christian,

Thanks for your feedback.
I'm not sure to share this feeling as for me, this is a clearly weakness in the Toolset plugins !!! I have tried to find any warning from Toolset on this point but did not find any (which means that the use of Forms WC with several products in the cart was not a current issue !!!).
You can imagine that users will not accept to place as many orders as they have products to buy (which means many payments also !).
I count on you to push Toolset developers to integrate this evolution in the near future.

Regards
Pat

#1784867

Christian Cox
Supporter

Languages: Anglais (English )

Timezone: America/New_York (GMT-04:00)

Thank you for your feedback. Hopefully the software will continue to improve and include this feature for you and the other reporter, because I have little influence on the priorities of new feature development. I find that Amir is most engaged with those customers who participate in the Toolset blog, so I would like to push you to utilize that most effective line of communication with the man in charge 🙂