> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cocartapi.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Convert Cart to Order

> Learn how to convert a cart session into an order

In this tutorial, we'll walk through the process of converting a shopping cart into an order using the WooCommerce REST API. This is particularly useful when you need to programmatically create orders from cart sessions.

<Info>
  CoCart will provide it's own checkout API in the future that will stream line the process. In the mean time, this is the best method.
</Info>

<Tip>
  You will need WooCommerce API credentials (consumer key and secret) for this.
</Tip>

## Step 1: Retrieve the Cart Data

First, we'll fetch the current cart data using the CoCart API:

<Tip>
  In the following request examples, you would replace `<cart_key>`, `<username>` and `<password>` before sending the request.
</Tip>

<AccordionGroup>
  <Accordion title="Guest Customer">
    <CodeGroup>
      ```bash cURL theme={"system"}
      curl -X GET \
        https://your-store.com/wp-json/cocart/v2/cart?cart_key=<cart_key> \
        -H 'Accept: application/json' \
        -H 'Content-Type: application/json' \
        -H 'User-Agent: CoCart API/v2' // Not a requirement.
      ```

      ```php PHP theme={"system"}
      $curl = curl_init();

      curl_setopt_array( $curl, array(
        CURLOPT_URL => "https://your-store.com/wp-json/cocart/v2/cart?cart_key=<cart_key>",
        CURLOPT_CUSTOMREQUEST => "GET",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTPHEADER => array(
          'Accept: application/json',
          'Content-Type: application/json;charset=utf-8'
          'User-Agent: CoCart API/v2', // Not a requirement.
        )
      ) );

      $cart = curl_exec($curl);
      curl_close($curl);
      ```

      ```javascript JavaScript theme={"system"}
      const getCart = async () => {
        const response = await fetch('https://your-store.com/wp-json/cocart/v2/cart?cart_key=<cart_key>', {
          method: 'GET',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'User-Agent': 'CoCart API/v2' // Not a requirement.
          }
        });
        
        return await response.json();
      };
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Registered Customer Authenticated">
    <CodeGroup>
      ```bash cURL theme={"system"}
      curl -X GET \
        https://your-store.com/wp-json/cocart/v2/cart \
        -H 'Accept: application/json' \
        -H 'Content-Type: application/json' \
        -H 'Authorization: Basic base64_encode(<username>:<password>)'
        -H 'User-Agent: CoCart API/v2' // Not a requirement.
      ```

      ```php PHP theme={"system"}
      $curl = curl_init();

      curl_setopt_array( $curl, array(
        CURLOPT_URL => "https://your-store.com/wp-json/cocart/v2/cart",
        CURLOPT_CUSTOMREQUEST => "GET",
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTPHEADER => array(
          'Accept: application/json',
          'Content-Type: application/json;charset=utf-8'
          'Authorization: Basic ' . base64_encode(<username> . ':' . <password>)
          'User-Agent: CoCart API/v2', // Not a requirement.
        )
      ) );

      $cart = curl_exec($curl);
      curl_close($curl);
      ```

      ```javascript JavaScript theme={"system"}
      const auth = btoa('<username>:<password>');
      const getCart = async () => {
        const response = await fetch('https://your-store.com/wp-json/cocart/v2/cart', {
          method: 'GET',
          headers: {
            'Accept': 'application/json',
            'Content-Type': 'application/json',
            'Authorization': `Basic ${auth}`
            'User-Agent': 'CoCart API/v2' // Not a requirement.
          }
        });
        
        return await response.json();
      };
      ```
    </CodeGroup>
  </Accordion>
</AccordionGroup>

## Step 2: Prepare Order Data

Next, we'll prepare the order data using the cart information. We'll need to:

1. Decode the cart JSON
2. Set up billing and shipping information
3. Configure payment details

<CodeGroup>
  ```bash cURL theme={"system"}
  # First decode and store the cart response from Step 1
  CART_DATA=$(cat cart-response.json)

  # Prepare the order data structure
  ORDER_DATA=$(jq -n \
    --arg payment_method "bacs" \
    --arg payment_title "Direct Bank Transfer" \
    --argjson paid true \
    --argjson cart "$CART_DATA" \
  '{
    payment_method: $payment_method,
    payment_method_title: $payment_title,
    set_paid: $paid,
    billing: {
      first_name: $cart.customer.billing_address.billing_first_name,
      last_name: $cart.customer.billing_address.billing_last_name,
      address_1: $cart.customer.billing_address.billing_address_1,
      address_2: $cart.customer.billing_address.billing_address_2,
      city: $cart.customer.billing_address.billing_city,
      state: $cart.customer.billing_address.billing_state,
      postcode: $cart.customer.billing_address.billing_postcode,
      country: $cart.customer.billing_address.billing_country,
      email: $cart.customer.billing_address.billing_email,
      phone: $cart.customer.billing_address.billing_phone
    },
    shipping: {
      first_name: $cart.customer.shipping_address.shipping_first_name,
      last_name: $cart.customer.shipping_address.shipping_last_name,
      address_1: $cart.customer.shipping_address.shipping_address_1,
      address_2: $cart.customer.shipping_address.shipping_address_2,
      city: $cart.customer.shipping_address.shipping_city,
      state: $cart.customer.shipping_address.shipping_state,
      postcode: $cart.customer.shipping_address.shipping_postcode,
      country: $cart.customer.shipping_address.shipping_country
    }
  }')
  ```

  ```javascript JavaScript theme={"system"}
  const cart = await getCart();

  const orderData = {
      payment_method: 'bacs',
      payment_method_title: 'Direct Bank Transfer',
      set_paid: true,
      billing: {
          first_name: cart.customer.billing_address.billing_first_name,
          last_name: cart.customer.billing_address.billing_last_name,
          address_1: cart.customer.billing_address.billing_address_1,
          address_2: cart.customer.billing_address.billing_address_2,
          city: cart.customer.billing_address.billing_city,
          state: cart.customer.billing_address.billing_state,
          postcode: cart.customer.billing_address.billing_postcode,
          country: cart.customer.billing_address.billing_country,
          email: cart.customer.billing_address.billing_email,
          phone: cart.customer.billing_address.billing_phone
      },
      shipping: {
          first_name: cart.customer.shipping_address.shipping_first_name,
          last_name: cart.customer.shipping_address.shipping_last_name,
          address_1: cart.customer.shipping_address.shipping_address_1,
          address_2: cart.customer.shipping_address.shipping_address_2,
          city: cart.customer.shipping_address.shipping_city,
          state: cart.customer.shipping_address.shipping_state,
          postcode: cart.customer.shipping_address.shipping_postcode,
          country: cart.customer.shipping_address.shipping_country
      },
      line_items: [],
      shipping_lines: []
  };
  ```

  ```php PHP theme={"system"}
  // Decode cart data
  $cart = json_decode($cart);

  // Prepare order data
  $order_data = array(
      'payment_method' => 'bacs',
      'payment_method_title' => 'Direct Bank Transfer',
      'set_paid' => true,
      'billing' => array(
          'first_name' => $cart->customer->billing_address->billing_first_name,
          'last_name' => $cart->customer->billing_address->billing_last_name,
          'address_1' => $cart->customer->billing_address->billing_address_1,
          'address_2' => $cart->customer->billing_address->billing_address_2,
          'city' => $cart->customer->billing_address->billing_city,
          'state' => $cart->customer->billing_address->billing_state,
          'postcode' => $cart->customer->billing_address->billing_postcode,
          'country' => $cart->customer->billing_address->billing_country,
          'email' => $cart->customer->billing_address->billing_email,
          'phone' => $cart->customer->billing_address->billing_phone
      ),
      'shipping' => array(
          'first_name' => $cart->customer->shipping_address->shipping_first_name,
          'last_name' => $cart->customer->shipping_address->shipping_last_name,
          'address_1' => $cart->customer->shipping_address->shipping_address_1,
          'address_2' => $cart->customer->shipping_address->shipping_address_2,
          'city' => $cart->customer->shipping_address->shipping_city,
          'state' => $cart->customer->shipping_address->shipping_state,
          'postcode' => $cart->customer->shipping_address->shipping_postcode,
          'country' => $cart->customer->shipping_address->shipping_country
      ),
      'line_items' => array(),
      'shipping_lines' => array()
  );
  ```
</CodeGroup>

## Step 3: Add Shipping Method

If shipping is selected in the cart, we'll add it to the order:

<CodeGroup>
  ```bash cURL theme={"system"}
  # Add shipping lines if shipping method exists
  if [[ $(echo "$CART_DATA" | jq -r '.shipping.packages.default.chosen_method') != "null" ]]; then
    CHOSEN_METHOD=$(echo "$CART_DATA" | jq -r '.shipping.packages.default.chosen_method')
    ORDER_DATA=$(echo "$ORDER_DATA" | jq \
      --arg method_id "$(echo "$CART_DATA" | jq -r ".shipping.packages.default.rates.$CHOSEN_METHOD.method_id")" \
      --arg title "$(echo "$CART_DATA" | jq -r ".shipping.packages.default.rates.$CHOSEN_METHOD.label")" \
      --arg cost "$(echo "$CART_DATA" | jq -r ".shipping.packages.default.rates.$CHOSEN_METHOD.cost")" \
      '. + {shipping_lines: [{method_id: $method_id, method_title: $title, total: $cost}]}')
  fi
  ```

  ```javascript JavaScript theme={"system"}
  if (cart.shipping?.packages?.default?.chosen_method) {
      const chosenMethod = cart.shipping.packages.default.rates[cart.shipping.packages.default.chosen_method];
      orderData.shipping_lines.push({
          method_id: chosenMethod.method_id,
          method_title: chosenMethod.label,
          total: chosenMethod.cost
      });
  }
  ```

  ```php PHP theme={"system"}
  if (isset($cart->shipping->packages->default->chosen_method)) {
      $chosen_method = $cart->shipping->packages->default->rates->{$cart->shipping->packages->default->chosen_method};
      $order_data['shipping_lines'][] = array(
          'method_id' => $chosen_method->method_id,
          'method_title' => $chosen_method->label,
          'total' => $chosen_method->cost
      );
  }
  ```
</CodeGroup>

## Step 4: Process Line Items

We'll convert cart items into order line items:

<CodeGroup>
  ```php PHP theme={"system"}
  foreach ($cart->items as $item) {
      $line_item = array(
          'product_id' => $item->id,
          'quantity' => $item->quantity->value,
          'name' => $item->name,
          'total' => $item->totals->total
      );

      if (!empty($item->meta->product_type) && $item->meta->product_type === 'variation') {
          $line_item['variation_id'] = $item->id;
          $line_item['product_id'] = $item->parent_id;
      }

      $order_data['line_items'][] = $line_item;
  }
  ```

  ```javascript JavaScript theme={"system"}
  orderData.line_items = cart.items.map(item => {
      const lineItem = {
          product_id: item.id,
          quantity: item.quantity.value,
          name: item.name,
          total: item.totals.total
      };

      if (item.meta?.product_type === 'variation') {
          lineItem.variation_id = item.id;
          lineItem.product_id = item.parent_id;
      }

      return lineItem;
  });
  ```

  ```bash cURL theme={"system"}
  # Process line items
  ORDER_DATA=$(echo "$ORDER_DATA" | jq \
    --argjson cart "$CART_DATA" \
    '. + {line_items: ($cart.items | map({
      product_id: .id,
      quantity: .quantity.value,
      name: .name,
      total: .totals.total,
      variation_id: (if .meta.product_type == "variation" then .id else null end),
      product_id: (if .meta.product_type == "variation" then .parent_id else .id end)
    }))}')
  ```
</CodeGroup>

## Step 5: Create the Order

Finally, we'll send the prepared data to the WooCommerce API to create the order:

<CodeGroup>
  ```bash cURL theme={"system"}
  ```

  ```javascript JavaScript theme={"system"}
  const createOrder = async (orderData) => {
      const consumerKey = 'your_consumer_key';
      const consumerSecret = 'your_consumer_secret';
      const domain = 'https://example-store.com';
      
      try {
          const response = await fetch(`${domain}/wp-json/wc/v3/orders`, {
              method: 'POST',
              headers: {
                  'Accept': 'application/json',
                  'Content-Type': 'application/json',
                  'Authorization': `Basic ${btoa(`${consumerKey}:${consumerSecret}`)}`
              },
              body: JSON.stringify(orderData)
          });

          if (!response.ok) {
              throw new Error(`HTTP error! status: ${response.status}`);
          }

          const order = await response.json();
          console.log(`Order created successfully. Order ID: ${order.id}`);
          return order;
      } catch (error) {
          console.error('Error creating order:', error);
          throw error;
      }
  };

  // Usage
  try {
      const order = await createOrder(orderData);
      // Handle successful order creation
  } catch (error) {
      // Handle error
  }
  ```

  ```php PHP theme={"system"}
  $consumer_key = 'your_consumer_key';
  $consumer_secret = 'your_consumer_secret';
  $domain = 'https://example-store.com';

  $response = wp_remote_post($domain . "/wp-json/wc/v3/orders", array(
      'headers' => array(
          'Accept' => 'application/json',
          'Content-Type' => 'application/json',
          'Authorization' => 'Basic ' . base64_encode($consumer_key . ':' . $consumer_secret)
      ),
      'body' => json_encode($order_data),
      'timeout' => 30
  ));

  if (is_wp_error($response)) {
      echo "Error: " . $response->get_error_message();
  } else {
      $order = json_decode(wp_remote_retrieve_body($response));
      echo "Order created successfully. Order ID: " . $order->id;
  }
  ```
</CodeGroup>

## Conclusion

You've now successfully converted a CoCart cart into a WooCommerce order! The response will contain the newly created order details. Remember to:

* Replace `example-store.com` with your actual domain
* Insert your WooCommerce API credentials
* Handle any potential errors in the response
* Consider adding error checking and validation

For more information about the available order parameters, consult the [WooCommerce REST API documentation](https://woocommerce.github.io/woocommerce-rest-api-docs/#orders).
