wp-graphql-woocommerce
wp-graphql-woocommerce copied to clipboard
Order properties empty with guest checkout
Describe the bug
When checking out a cart as a guest the orders
and lastOrder
property is empty, even though the billing_email is set with the updateCustomer
mutation and the same billing_email is submitted with the checkout.
To Reproduce Steps to reproduce the behavior:
First of all, i took a clean clone of this repo and spun up the docker-compose file as described in the development guidelines. As second i've made a small adjustment to the docker-compose.yml to allow access to port 80 from outside and mapped port 9002 to port 80 for the testable_app service. This way i can interact with the service from my Docker host. Also i've added 2 defines to the wp-config.php:
define('WP_SITEURL', 'http://localhost:9002');
define('WP_HOME', 'http://localhost:9002');
Then the steps i've taken in order to come to this result:
- I added a dummy simple product to the woocommerce store.
- I've enabled the pay on delivery method and added free shipping worldwide in the Woocommerce store settings.
- I opened Postman and first ran the
getCart
query:
query GetCart {
cart {
total
}
}
I get a 200 response with a JSON payload telling me the cart value is 0, which is correct. Also a woocommerce-session header is returned with a JWT payload. From now i use this header on each following request!
- I update my customer details with the
updateCustomer
mutation:
mutation UpdateCustomer {
__typename
updateCustomer(
input: {
billing: {
email: "[email protected]"
firstName: "John"
lastName: "Doe"
address1: "221 Bakerstreet"
country: GB
city: "London"
}
shippingSameAsBilling: true
}
) {
customer {
billing {
email
firstName
lastName
address1
city
country
}
shipping {
email
firstName
lastName
address1
city
country
}
}
}
}
Here i also get a 200 response with the expected payload, telling me the billing and shipping address is setup.
- I add a product to my cart using the
addToCart
mutation:
mutation AddToCart {
addToCart(input: { productId: 10, quantity: 1 }) {
cart {
total
}
}
}
- I run the checkout mutation as following:
mutation Checkout {
checkout(
input: {
paymentMethod: "cod"
billing: {
email: "[email protected]"
firstName: "John"
lastName: "Doe"
}
}
) {
clientMutationId
order {
id
orderNumber
orderKey
status
billing {
email
}
}
result
redirect
}
}
And the response i get:
{
"data": {
"checkout": {
"clientMutationId": null,
"order": {
"id": "c2hvcF9vcmRlcjoxMQ==",
"orderNumber": "11",
"orderKey": "wc_order_ghCw1AlrSaru0",
"status": "PROCESSING",
"billing": {
"email": "[email protected]"
}
},
"result": "success",
"redirect": "http://localhost:9002/checkout/order-received/11/?key=wc_order_ghCw1AlrSaru0"
}
},
"extensions": {
"debug": []
}
}
- Finally with still the same wc-session i try to fetch the latest order details using the
customer
query:
query GetCustomer {
customer {
id
orderCount
email
shipping {
address1
city
company
country
email
firstName
lastName
phone
}
billing {
address1
city
company
country
email
firstName
lastName
phone
}
sessionToken
lastOrder {
id
}
orders {
nodes {
id
}
}
}
}
Now i would expect that the response i get on the lastOrder, orders and orderCount property would be something different then 0, null or {}. However i get the following response:
{
"data": {
"customer": {
"id": "guest",
"orderCount": 0,
"email": null,
"shipping": {
"address1": null,
"city": null,
"company": null,
"country": "GB",
"email": null,
"firstName": "John",
"lastName": "Doe",
"phone": null,
},
"billing": {
"address1": "221 Bakerstreet",
"city": "London",
"company": null,
"country": "GB",
"email": "[email protected]",
"firstName": "John",
"lastName": "Doe",
"phone": null,
},
"sessionToken": null,
"lastOrder": null,
"orders": {
"nodes": []
}
}
},
"extensions": {
"debug": []
}
}
Expected behavior
I would expect that the orderCount, lastOrder and orders property of the customer
query at step 7 would be filled with data.
Plugin Versions
- WooGraphQL Version: Dev branch and 0.8.1.
- WPGraphQL Version: 1.3.4
- WordPress Version: 5.7
- WooCommerce Version: 5.1.0
I have the same issue! Help appreciated
@wcoppens @sidyes Have you tried setting the guest user's email to the session using the updateCustomer
mutation. This will give the guest user access to the order data.
@kidunot89 I think i am doing that at step 4 in the "steps to reproduce" content, or am i doing it the wrong way?
I have the same issue!
It seems like when the customer is a guest woocommerce use WC_Customer_Data_Store_Session
which return false
by default for get_last_order()
.
It also return 0
for get_order_count()
and get_total_spent()
as well.
in class-wc-customer-data-store-session.php.
...
public function get_last_order( &$customer ) {
return false;
}
public function get_order_count( &$customer ) {
return 0;
}
public function get_total_spent( &$customer ) {
return 0;
}
...
I was able to fix this issue by modifying includes/model/class-customer.php
file to something like this.
...
'last_order_id' => function() {
$last_order = apply_filters(
'woocommerce_customer_get_last_order',
get_user_meta( $customer->get_id(), '_last_order', true ),
$customer
);
if ( '' === $last_order ) {
global $wpdb;
$meta_key = ! empty( $this->data->get_billing_email() ) ? '_billing_email' : '_customer_user';
$meta_value = ! empty( $this->data->get_billing_email() )
? $this->data->get_billing_email()
: $this->data->get_id();
$last_order = $wpdb->get_var(
"SELECT posts.ID
FROM $wpdb->posts AS posts
LEFT JOIN {$wpdb->postmeta} AS meta on posts.ID = meta.post_id
WHERE meta.meta_key = '".$meta_key."'
AND meta.meta_value = '" . $meta_value . "'
AND posts.post_type = 'shop_order'
AND posts.post_status IN ( '" . implode( "','", array_map( 'esc_sql', array_keys( wc_get_order_statuses() ) ) ) . "' )
ORDER BY posts.ID DESC"
);
update_user_meta( $customer->get_id(), '_last_order', $last_order );
}
if ( ! $last_order ) {
return null;
}
return absint( $last_order );
},
...
I used some code from here class-wc-customer-data-store.php.
I'm not sure if this is a related issue but also using order
query after checkout with the same order ID returns null
for guest customer.
I experience the same issue. When trying to load the data for a guest account, even if the customer object returns the proper e-mail, I cannot get the order from the order query, it always returns null.
I experience the same issue.
I used woocommerce-session correctly.
@kidunot89 we can see that this issue is marked as resolved.
But This query
query { customer { orders { ... } } }
only works correctly in the Graphql IDE from the backend admin page.
@wcoppens @sidyes Have you tried setting the guest user's email to the session using the
updateCustomer
mutation. This will give the guest user access to the order data.
@kidunot89 But how can I use this mutation without user.accessToken?
mutation UPDATE_CUSTOMER_MUTATION($input: UpdateCustomerInput!) {
updateCustomer(input: $input) {
clientMutationId
customer {
email
billing {
country
state
postcode
email
}
shipping {
country
state
postcode
email
}
calculatedShipping
hasCalculatedShipping
}
}
}```
Hey.
I had the same problem, and after looking inside the code (class-order.php
), we can see that the visibility of the order
fields depend on the user being either the owner of the order, or the guest customer being the current user (and thus the order's owner). See owner_matches_current_user()
.
This is checked by matching the email
field in the billing
address with the customer's email
. If neither of those fields are set or if they don't match, you won't be able to get values other than null
for most of the order
object.
You can set the email addresses with the updateCustomer
mutation. You don't need an access token for that operation, just a session token set in the request's cookies, which you should be using to identify a guest customer anyway.
Hope this helps!