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_createWixOrderwhich delegates tocreateOrderFunctioninbackend/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_confirmOrderPaymentwhich delegates tohandleConfirmOrderPaymentinbackend/orderHttpHandlers.js).
- This function records the payment using
orderTransactions.addPayments()andorderTransactions.updatePaymentStatus()withTransactionStatus.APPROVED. - This correctly updates the order’s
paymentStatustoPAIDand the overall orderstatustoAPPROVED.
- Desired Fulfillment State After Payment: We want the
Order.fulfillmentStatusto remainNOT_FULFILLEDat 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
statusbecomesAPPROVEDandpaymentStatusbecomesPAID, the summaryOrder.fulfillmentStatusautomatically 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
fulfillmentStatusupon order payment or approval. - Attempting to Set Initial
Order.status:
- We tried explicitly setting
status: orders.OrderStatus.INITIALIZEDorstatus: "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 showINITIALIZEDwhen no status is provided, which is fine).
- Attempting to Directly Update
Order.fulfillmentStatusAfter Payment:
- In
handleConfirmOrderPayment, after the order becamePAIDandFULFILLED, 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 fielderror, indicatingOrder.fulfillmentStatuscannot 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 becamePAIDandFULFILLED, 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_FULFILLEDorder), 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 forAPPROVEDorders.
- Attempting to Proactively Create a “Pending” Fulfillment After Payment Confirmation (
orderHttpHandlers.js):
- After
addPaymentsandupdatePaymentStatus(order becomesPAID,APPROVED, and automaticallyFULFILLEDby 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
Orderobject usingelevate(orders.getOrder)(orderId), its summaryOrder.fulfillmentStatusstill showsFULFILLED.
Additional Information:
- We are using the V3 eCommerce APIs (
wix-ecom-backend). - The products are configured as physical items.
- Our
orderCreator.jsnow successfully creates orders that initially log asstatus: INITIALIZED,paymentStatus: NOT_PAID,fulfillmentStatus: NOT_FULFILLED. The issue arises after payment confirmation. - We need the
fulfillmentStatusto accurately reflectNOT_FULFILLEDin 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 theorderFulfillmentsAPI 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_FULFILLEDstatus). - Your current
backend/orderHttpHandlers.js(specifically thehandleConfirmOrderPaymentfunction showing the payment confirmation and the attempt to create a “Pending” fulfillment). - Example Velo logs showing the sequence:
- Log from
orderCreator.jsafterorders.createOrder()(showing initialNOT_FULFILLED). - Logs from
orderHttpHandlers.jsafter payment showingOrder.fulfillmentStatusbecomingFULFILLED. - Logs showing the successful creation of the “Pending”
Fulfillmentrecord. - Logs showing the re-fetched
Order.fulfillmentStatusstill beingFULFILLED.
- Log from
Thank you in advance for your help!