Wp-graphql-woocommerce: How to get order and mark it as paid after redirecting back from PayPal?

Created on 28 Apr 2020  Â·  7Comments  Â·  Source: wp-graphql/wp-graphql-woocommerce

Describe the bug
I just implemented guest checkout, but I have two questions:

After using the checkout mutation with PayPal (built-in WooCommerce, no plugin), how can I mark the order as paid? When I pay with PayPal I got redirected back to http://localhost:3000/checkout/order-received/3748/?key=wc_order_7gZyMZEDDPW5j&utm_nooverride=1

The order query has orderId and orderKey arguments for lookup, but I cannot query the order by the key in frontend as a guest. And also updateOrder is not possible due to permission as a guest or normal logged-in customer.

Expected behavior
Order should be queryable and can be marked as paid from frontend, using the order ID and/or key stored in the session.

question

Most helpful comment

@ardiewen @kidunot89 It's also worth to note that the updateCustomer mutation can be called as a guest to collect the checkout data, so we won't need a local state for that🙂

But back to my question from above, how can I show oder details of the completed order as a guest using the orderKey? The order query does not find any order – except I'm logged in as an admin

All 7 comments

In my understanding, the checkout mutation is meant to support inline checkout sessions, including using external payment gateways, but not "managed" checkout solutions where the user has to leave your site then gets redirected back to a confirmation screen.

If you wish to use a managed checkout solution, you would have to initiate the checkout mutation after the user is redirected back to your site.

E.g. an effect that runs on your /checkout/order-received/?transactionId=XXXXXXXXX page that collects the transactionId query parameter then submits the actual checkout mutation with the following variables added: transactionId, isPaid.

The problem with this method is how do you store your other checkout data, such as billing / shipping information while the user leaves the site and comes back? This is generally collected before sending the user to the external payment gateway.

For checkouts that don't require the user to leave the site, but use an external payment gateway, e.g. Stripe, this is how it's done:

  1. Create a cart session by using the addToCart mutation
  2. Collect shipping/billing address, and shipping method from the user and store it in a local state checkout object
  3. Collect the payment card number and submit a payment intent or create charge API call to your payment gateway, receiving a transactionId in return.
  4. add the paymentMethod, transactionId, and isPaid parameters to your local state checkout object then call the checkout mutation. This "finalizes" the checkout and creates the order.

Any modifications to the order status / details after the checkout mutation has been called, will require Store Manager level access via the API, as you have noted.

Edit: You may wish to check out release v0.5.1 as well, since it appears to be bringing in support for payment gateways. Looks like only Stripe is supported for now, but native paypal may be coming.

@efoken @ardiewen It's also important to note that the transactionId can be any string value, and it's evaluation is typically up to payment gateway, and I don't know what gateways have any evaluation in place. However it is possible to add your own evaluation step using the graphql_checkout_prepaid_order_validation hook

@ardiewen @kidunot89 It's also worth to note that the updateCustomer mutation can be called as a guest to collect the checkout data, so we won't need a local state for that🙂

But back to my question from above, how can I show oder details of the completed order as a guest using the orderKey? The order query does not find any order – except I'm logged in as an admin

@efoken For my use case, I get a customer's orders in an authenticated state via the customer query.

I first use the viewer query to get a customer id, which then I feed into the following query:

 query GET_ORDERS_BY_CUSTOMER($id: ID!, $first: Int, $after: String) {
    customer(id: $id) {
      id
      customerId
      orders(first: $first, after: $after) {
        pageInfo {
          endCursor
          hasNextPage
        }
        nodes {
          ...OrderFields
        }
      }
      orderCount
      totalSpent
    }
  }

You may want to explore this to see if you can run the customer query in an unauthenticated state. I presume running the updateCustomer mutation can return a customer id as part of the results? This should be enough for the input variables to run the customer query.

@ardiewen Didn't work. The customer query alway returns new_customer as the id and when checking out, the customer object is saved to the database and the session is thrown away. So I'm not able to get that customer back while being unauthenticated.

@kidunot89 related to #275? For @efoken's use case, it's in the context of guest session instead of authenticated queries.

If I'm understanding correctly, users and customers in woocommerce are distinct. So if a user checks out as a guest, a customer entry is still created in the woocommerce database. Is that right?

If so, then the checkout mutation should still return a unique customerId?

@ardiewen @efoken Not quite, customer data isn't written to the wp_users table unless the user is authenticated through the createUser, registerUser, or registerCustomer mutations. When the user is unauthenticated, the customer data provided to mutations like updateCustomer and updateShippingMethod is written to the WooCommerce's custom customer session data table as a serialize string.

Was this page helpful?
0 / 5 - 0 ratings