When the payment phase is completed, the user is guaranteed to receive the items ordered or an automatic refund for any unfulfilled items. Upon payment completion you’ll want to display an animation in the UI indicating that the delivery is in-progress. Then poll the GET order API to check on delivery status and update your application UI when delivery status is updated.

You can use client-side or server-side API keys to implement headless checkout. Check the code samples for the type of API key you’re using in your application.

We recommend a polling interval of about 1000ms and never below 500ms.
const getOrderDeliveryStatus = async () => {
    const apiUrl = "https://staging.crossmint.com/api/2022-06-09";
    try {
        const res = await fetch(`${apiUrl}/orders/${order.orderId}`, {
            method: "GET",
            headers: {
                "Content-Type": "application/json",
                "x-api-key": process.env.NEXT_PUBLIC_CROSSMINT_API_KEY,
                authorization: clientSecret, // saved from response of create order call
            },
        });

        const refreshedOrder = await res.json();

        setOrder(refreshedOrder);

        return refreshedOrder.lineItems[0].delivery.status;
    } catch (e) {
        console.error(e);
        throw new Error("Failed to fetch order");
    }
};

const pollDeliveryStatus = async () => {
    const intervalId = setInterval(async () => {
        try {
            const status = await getOrderDeliveryStatus();
            console.log("delivery status: ", status);
            if (status === "completed") {
                clearInterval(intervalId);
            }
        } catch (e) {
            clearInterval(intervalId);
            console.error("Error polling delivery status: ", e);
        }
    }, 2500);

    // Set a timeout to stop polling after 60 seconds
    setTimeout(() => {
        clearInterval(intervalId);
        console.log("Taking longer than expected...");
    }, 60000);
};

Error Handling

Once the payment has been confirmed, delivery is likely to complete successfully. Before accepting the payment Crossmint simulates the expected transaction, which means that most delivery issues will be prevented before payment is even accepted. Given a successful payment the delivery process will be retried until it completes successfully or determines that delivery is impossible.

The most common cause for a delivery failure is that the item is no longer available. In the case of primary sales this could mean that the collection is sold out. For secondary sales the reason could be that someone else bought the item first.

Your application should be aware of the potential for delivery to fail and provide information to the buyer on what to expect. In the case of multiple items purchased and partial delivery failure you’ll need to indicate which items were successfully delivered and which items failed.

Be sure to let your buyer know that in the case of a failed delivery they will be refunded automatically. If they have any questions or issues they can reach out to Crossmint support directly for assistance.

A receipt will be sent to the buyer as long as their email was included in the order. There are two ways to pass this information. If the recipient is set to an email address, it will be used to send the receipt. In the case that the recipient is set to a walletAddress you can include an optional receiptEmail property within the payment object.