Okay, here’s an expanded version of the post for the Velo community or Wix Support, structured to fit the common “ask a question” template you provided. This version incorporates all the details we’ve uncovered.
Question:
How can we ensure that an Order.fulfillmentStatus
for physical goods remains NOT_FULFILLED
after payment confirmation when using the Velo eCommerce Orders API, instead of it automatically changing to FULFILLED
?
Product:
Wix Velo (Backend code using wix-ecom-backend
and wix-auth
modules, specifically the orders
, orderTransactions
, and orderFulfillments
APIs). This backend is being called from a Flutter mobile application.
What are you trying to achieve:
We are implementing a custom checkout flow for physical products (sculptures). Our desired order lifecycle is:
- Initial Order Creation: When a user finalizes their cart in our Flutter app, we call a Velo HTTP function (
post_createWixOrder
which delegates tocreateOrderFunction
inbackend/orderCreator.js
) to create an order usingorders.createOrder()
.
- Expected Initial State:
status: INITIALIZED
,paymentStatus: NOT_PAID
,fulfillmentStatus: NOT_FULFILLED
. - Actual Initial State (SUCCESS): We have successfully achieved this. Our logs (from
orderCreator.js
) confirm this state afterorders.createOrder()
completes.
- Payment Processing: The user pays via Stripe. After successful payment, our Flutter app calls another Velo HTTP function (
post_confirmOrderPayment
which delegates tohandleConfirmOrderPayment
inbackend/orderHttpHandlers.js
).
- This function records the payment using
orderTransactions.addPayments()
andorderTransactions.updatePaymentStatus()
withTransactionStatus.APPROVED
. - This correctly updates the order’s
paymentStatus
toPAID
and the overall orderstatus
toAPPROVED
.
- Desired Fulfillment State After Payment: We want the
Order.fulfillmentStatus
to remainNOT_FULFILLED
at this point, as the physical items have not yet been prepared or shipped. - Actual Fulfillment State After Payment (The Problem): Immediately after the payment is confirmed and the order
status
becomesAPPROVED
andpaymentStatus
becomesPAID
, the summaryOrder.fulfillmentStatus
automatically changes toFULFILLED
. This happens even before any explicit fulfillment actions are taken by us for shipping.
What have you already tried:
- Verifying Wix Dashboard Settings: We have confirmed that in our Wix Store settings, there are no options enabled to “automatically mark orders as fulfilled when paid.”
- Checking Wix Automations: We have confirmed there are no active Wix Automations that would change the
fulfillmentStatus
upon order payment or approval. - Attempting to Set Initial
Order.status
:
- We tried explicitly setting
status: orders.OrderStatus.INITIALIZED
orstatus: "INITIALIZED"
in the payload fororders.createOrder()
. - Result: This caused a “Bad Request” error from the API. It seems
orders.createOrder()
enforces a default status (likelyAPPROVED
, though our initial logs showINITIALIZED
when no status is provided, which is fine).
- Attempting to Directly Update
Order.fulfillmentStatus
After Payment:
- In
handleConfirmOrderPayment
, after the order becamePAID
andFULFILLED
, we tried callingelevate(orders.updateOrder)(orderId, { fulfillmentStatus: orders.FulfillmentStatus.NOT_FULFILLED }, { fieldMask: ["fulfillmentStatus"] })
. - Result: This failed with an
INVALID_ARGUMENT: "options.fieldMask" Field mask points to read-only field
error, indicatingOrder.fulfillmentStatus
cannot be directly written to this way.
- Attempting to Delete Auto-Created Fulfillments (Strategy 1):
- Our hypothesis was that Wix might be auto-creating a fulfillment record.
- In
handleConfirmOrderPayment
, after the order becamePAID
andFULFILLED
, we calledelevate(orderFulfillments.listFulfillmentsForSingleOrder)(orderId)
. - Result: This returned an empty
fulfillments: []
array. Thus, there were no explicit fulfillment records to delete to try and revert the summary status.
- Attempting to Proactively Create a “Pending” Fulfillment During Initial Order Creation (
orderCreator.js
):
- After
orders.createOrder()
(which resulted in anINITIALIZED
,NOT_PAID
,NOT_FULFILLED
order), we immediately tried to callelevate(orderFulfillments.createFulfillment)(orderId, placeholderFulfillmentPayload)
. - Result: This failed with
INVALID_ARGUMENT: Order [...] - is not approved so cannot be fulfilled
. This confirms fulfillments can only be created forAPPROVED
orders.
- Attempting to Proactively Create a “Pending” Fulfillment After Payment Confirmation (
orderHttpHandlers.js
):
- After
addPayments
andupdatePaymentStatus
(order becomesPAID
,APPROVED
, and automaticallyFULFILLED
by Wix). - We then successfully call
elevate(orderFulfillments.createFulfillment)(orderId, { lineItems: [...], status: "Pending" })
. A new fulfillment record withstatus: "Pending"
is successfully created and associated with the order. - Problem Persists: Despite this “Pending” fulfillment record existing, when we immediately re-fetch the main
Order
object usingelevate(orders.getOrder)(orderId)
, its summaryOrder.fulfillmentStatus
still showsFULFILLED
.
Additional Information:
- We are using the V3 eCommerce APIs (
wix-ecom-backend
). - The products are configured as physical items.
- Our
orderCreator.js
now successfully creates orders that initially log asstatus: INITIALIZED
,paymentStatus: NOT_PAID
,fulfillmentStatus: NOT_FULFILLED
. The issue arises after payment confirmation. - We need the
fulfillmentStatus
to accurately reflectNOT_FULFILLED
in the Wix dashboard and for our app’s order history page until we manually initiate and complete the shipping process (at which point we would use theorderFulfillments
API to create/update a fulfillment with tracking details and a “Fulfilled” status).
Our Core Question for the Velo Community/Wix Support:
Given that: a. The order starts as NOT_FULFILLED
. b. Wix automatically changes the summary Order.fulfillmentStatus
to FULFILLED
once the order is PAID
and APPROVED
. c. We cannot directly update this summary Order.fulfillmentStatus
back to NOT_FULFILLED
using orders.updateOrder()
. d. Creating an explicit “Pending” Fulfillment
record after payment (which succeeds) does not revert the summary Order.fulfillmentStatus
from FULFILLED
.
What is the correct Velo API procedure to ensure an order for physical goods remains NOT_FULFILLED
(or reflects PARTIALLY_FULFILLED
due to a “Pending” fulfillment record) in its summary Order.fulfillmentStatus
after payment, until we explicitly mark it as shipped by creating/completing a fulfillment with tracking information?
Is there a specific property on the Order
object during creation (via orders.createOrder
), or an option during payment confirmation (via orderTransactions
API), or a specific way to structure the initial “Pending” Fulfillment
object that will prevent the main Order.fulfillmentStatus
from defaulting to FULFILLED
prematurely?
Thank you for any guidance!
Code Snippets (You can attach or link to your Velo files if the forum supports it, or paste key functions):
- Your current
backend/orderCreator.js
(the version that successfully creates an order with initialNOT_FULFILLED
status). - Your current
backend/orderHttpHandlers.js
(specifically thehandleConfirmOrderPayment
function showing the payment confirmation and the attempt to create a “Pending” fulfillment). - Example Velo logs showing the sequence:
- Log from
orderCreator.js
afterorders.createOrder()
(showing initialNOT_FULFILLED
). - Logs from
orderHttpHandlers.js
after payment showingOrder.fulfillmentStatus
becomingFULFILLED
. - Logs showing the successful creation of the “Pending”
Fulfillment
record. - Logs showing the re-fetched
Order.fulfillmentStatus
still beingFULFILLED
.
- Log from
Thank you in advance for your help!