import { WorkflowData } from "@medusajs/framework/workflows-sdk";
/**
 * The data to complete a cart and place an order.
 */
export type CompleteCartWorkflowInput = {
    /**
     * The ID of the cart to complete.
     */
    id: string;
};
export type CompleteCartWorkflowOutput = {
    /**
     * The ID of the order that was created.
     */
    id: string;
};
export declare const completeCartWorkflowId = "complete-cart";
/**
 * This workflow completes a cart and places an order for the customer. It's executed by the
 * [Complete Cart Store API Route](https://docs.medusajs.com/api/store/carts/complete-cart).
 *
 * You can use this workflow within your own customizations or custom workflows, allowing you to wrap custom logic around completing a cart.
 * For example, in the [Subscriptions recipe](https://docs.medusajs.com/resources/recipes/subscriptions/examples/standard#create-workflow),
 * this workflow is used within another workflow that creates a subscription order.
 *
 * ## Payment Validation
 *
 * When completing a cart, this workflow validates the cart's payment sessions, but it doesn't validate payment amounts.
 *
 * The workflow requires the cart's payment collection to have at least one payment session in a processable status: `pending`,
 * `requires_more`, `authorized`, `captured`, or `pending_authorization` (used for asynchronous or deferred authorization, such as
 * bank transfers). If the payment collection hasn't been initiated, or no payment session is in a processable status, the workflow
 * throws an error.
 *
 * The workflow doesn't compare the authorized or captured amount against the cart's total. It neither requires the amount to equal
 * the cart's total nor enforces a minimum amount. The amount that's authorized or captured is the payment session's own amount, which
 * is set to the cart's total when the payment collection is created or refreshed. So, if the cart changes after its payment collection
 * is created without the payment collection being refreshed, the workflow authorizes or captures the payment session's existing amount
 * and records it in the order's transactions as-is.
 *
 * If the cart's total is zero and covered by credit lines, the workflow can complete the cart without a payment session.
 *
 * ### Don't Mutate the Cart in Hooks
 *
 * Don't use this workflow's hooks (such as the `validate` hook) to mutate the cart's line items, shipping methods, or totals.
 * The workflow retrieves the cart once at the beginning, before any hook runs, and builds the order from that snapshot. It doesn't
 * re-retrieve the cart or refresh the payment collection afterwards. So, a mutation made in a hook has two consequences that leave
 * the order and payment inconsistent with the change:
 *
 * - The created order is built from the initial cart snapshot, so the mutation isn't reflected in the order.
 * - As explained in the previous section, the authorized or captured amount is the payment session's own amount, which was set to the
 * cart's total when the payment collection was created or refreshed. So, the payment amount doesn't account for the mutation either.
 *
 * If you need to change the cart before completing it, do so in a separate step or workflow that runs before `completeCartWorkflow`,
 * and refresh the cart's payment collection so that the payment session's amount matches the new total.
 *
 * ## Payment Authorization and Failure Handling
 *
 * The workflow creates the order first, then authorizes the cart's payment session as its last operation. This ordering minimizes the
 * window in which an authorized or captured payment must be rolled back: only recording the order's transactions, running the
 * `orderCreated` hook, and creating links happen after the payment is authorized.
 *
 * If the workflow fails after the payment was authorized or captured, its compensation reverts the payment automatically, so a completion
 * failure doesn't leave an orphaned payment:
 *
 * - An authorized payment that wasn't captured is canceled.
 * - A captured payment is refunded, unless a later or concurrent completion attempt already placed an order for the same cart. In that
 * case, the refund is skipped so that the successful order keeps its payment.
 *
 * Because the payment is reverted before the workflow returns, a caller doesn't need to issue a refund itself when completion fails. When
 * this workflow is executed by the Complete Cart Store API Route, the route distinguishes the two outcomes with a `type` field in its
 * response: a value of `order` means the cart was completed and an order was placed, whereas `cart` means completion failed and the error
 * is set in the response's `error` field. So, a storefront verifies whether an order was created by checking that the response's `type` is
 * `order`, rather than assuming a payment was charged.
 *
 * ## Cart Completion Idempotency
 *
 * This workflow's logic is idempotent, meaning that if it is executed multiple times with the same input, it will not create duplicate orders. The
 * same order will be returned for subsequent executions with the same cart ID. This is necessary to avoid rolling back payments or causing
 * other side effects if the workflow is retried or fails due to transient errors.
 *
 * So, if you use this workflow within your own, make sure your workflow's steps are idempotent as well to avoid unintended side effects.
 * Your workflow must also acquire and release locks around this workflow to prevent concurrent executions for the same cart.
 *
 * The following sections cover some common scenarios and how to handle them.
 *
 * ### Creating Links and Linked Records
 *
 * In some cases, you might want to create custom links or linked records to the order. For example, you might want to create a link from the order to a
 * digital order.
 *
 * In such cases, ensure that your workflow's logic checks for existing links or records before creating new ones. You can query the
 * [entry point of the link](https://docs.medusajs.com/learn/fundamentals/module-links/custom-columns#method-2-using-entry-point)
 * to check for existing links before creating new ones.
 *
 * For example:
 *
 * ```ts
 * import {
 *   createWorkflow,
 *   when,
 *   WorkflowResponse
 * } from "@medusajs/framework/workflows-sdk"
 * import {
 *   useQueryGraphStep,
 *   completeCartWorkflow,
 *   acquireLockStep,
 *   releaseLockStep
 * } from "@medusajs/framework/workflows-sdk"
 * import digitalProductOrderOrderLink from "../../links/digital-product-order"
 *
 * type WorkflowInput = {
 *   cart_id: string
 * }
 *
 * const createDigitalProductOrderWorkflow = createWorkflow(
 *   "create-digital-product-order",
 *   (input: WorkflowInput) => {
 *     acquireLockStep({
 *       key: input.cart_id,
 *       timeout: 30,
 *       ttl: 120,
 *     });
 *     const { id } = completeCartWorkflow.runAsStep({
 *       input: {
 *         id: input.cart_id
 *       }
 *     })
 *
 *     const { data: existingLinks } = useQueryGraphStep({
 *       entity: digitalProductOrderOrderLink.entryPoint,
 *       fields: ["digital_product_order.id"],
 *       filters: { order_id: id },
 *     }).config({ name: "retrieve-existing-links" });
 *
 *
 *     const digital_product_order = when(
 *       "create-digital-product-order-condition",
 *       { existingLinks },
 *       (data) => {
 *         return (
 *           data.existingLinks.length === 0
 *         );
 *       }
 *     )
 *     .then(() => {
 *       // create digital product order logic...
 *     })
 *
 *     // other workflow logic...
 *
 *     releaseLockStep({
 *       key: input.cart_id,
 *     })
 *
 *     return new WorkflowResponse({
 *       // workflow output...
 *     })
 *   }
 * )
 * ```
 *
 * ### Custom Validation with Conflicts
 *
 * Some use cases require custom validation that may cause conflicts on subsequent executions of the workflow.
 * For example, if you're selling tickets to an event, you might want to validate that the tickets are available
 * on selected dates.
 *
 * In this scenario, if the workflow is retried after the first execution, the validation
 * will fail since the tickets would have already been reserved in the first execution. This makes the cart
 * completion non-idempotent.
 *
 * To handle these cases, you can create a step that throws an error if the validation fails. Then, in the compensation function,
 * you can cancel the order if the validation fails. For example:
 *
 * ```ts
 * import { createStep, StepResponse } from "@medusajs/framework/workflows-sdk"
 * import { MedusaError } from "@medusajs/framework/utils"
 * import { cancelOrderWorkflow } from "@medusajs/medusa/core-flows"
 *
 * type StepInput = {
 *   order_id: string
 *   // other input fields...
 * }
 *
 * export const customCartValidationStep = createStep(
 *   "custom-cart-validation",
 *   async (input, { container }) => {
 *     const isValid = true // replace with actual validation logic
 *
 *     if (!isValid) {
 *       throw new MedusaError(
 *         MedusaError.Types.INVALID_DATA,
 *         "Custom cart validation failed"
 *       )
 *     }
 *
 *     return new StepResponse(void 0, input.order_id)
 *   },
 *   async (order_id, { container, context }) => {
 *     if (!order_id) return
 *
 *     cancelOrderWorkflow(container).run({
 *       input: {
 *         id: order_id,
 *       },
 *       context,
 *       container
 *     })
 *   }
 * )
 * ```
 *
 * Then, in your custom workflow, only run the validation step if the order is being created for the first time. For example,
 * only run the validation if the link from the order to your custom data does not exist yet:
 *
 * ```ts
 * import {
 *   createWorkflow,
 *   when,
 *   WorkflowResponse
 * } from "@medusajs/framework/workflows-sdk"
 * import { useQueryGraphStep } from "@medusajs/framework/workflows-sdk"
 * import ticketOrderLink from "../../links/ticket-order"
 *
 * type WorkflowInput = {
 *   cart_id: string
 * }
 *
 * const createTicketOrderWorkflow = createWorkflow(
 *   "create-ticket-order",
 *   (input: WorkflowInput) => {
 *     acquireLockStep({
 *       key: input.cart_id,
 *       timeout: 30,
 *       ttl: 120,
 *     });
 *     const { id } = completeCartWorkflow.runAsStep({
 *       input: {
 *         id: input.cart_id
 *       }
 *     })
 *
 *     const { data: existingLinks } = useQueryGraphStep({
 *       entity: ticketOrderLink.entryPoint,
 *       fields: ["ticket.id"],
 *       filters: { order_id: id },
 *     }).config({ name: "retrieve-existing-links" });
 *
 *
 *     const ticket_order = when(
 *       "create-ticket-order-condition",
 *       { existingLinks },
 *       (data) => {
 *         return (
 *           data.existingLinks.length === 0
 *         );
 *       }
 *     )
 *     .then(() => {
 *       customCartValidationStep({ order_id: id })
 *       // create ticket order logic...
 *     })
 *
 *     // other workflow logic...
 *
 *     releaseLockStep({
 *       key: input.cart_id,
 *     })
 *
 *     return new WorkflowResponse({
 *       // workflow output...
 *     })
 *   }
 * )
 * ```
 *
 * The first time this workflow is executed for a cart, the validation step will run and validate the cart. If the validation fails,
 * the order will be canceled in the compensation function.
 *
 * If the validation is successful and the workflow is retried, the validation step will be skipped since the link from the order to the
 * ticket order already exists. This ensures that the workflow remains idempotent.
 *
 * @example
 * const { result } = await completeCartWorkflow(container)
 * .run({
 *   input: {
 *     id: "cart_123"
 *   }
 * })
 *
 * @summary
 *
 * Complete a cart and place an order.
 *
 * @property hooks.validate - This hook is executed before the order is created and the payment is authorized. You can consume this hook to perform any custom validation. If validation fails, you can throw an error to stop the workflow execution. Don't use this hook to mutate the cart's line items or totals, as explained in the Don't Mutate the Cart in Hooks section.
 */
export declare const completeCartWorkflow: import("@medusajs/framework/workflows-sdk").ReturnWorkflow<CompleteCartWorkflowInput, CompleteCartWorkflowOutput, [import("@medusajs/framework/workflows-sdk").Hook<"validate", {
    input: WorkflowData<CompleteCartWorkflowInput>;
    cart: any;
}, unknown>]>;
//# sourceMappingURL=complete-cart.d.ts.map