# Create Order Widget

## Overview

This create order widget is the simplest way to initialise the customer checkout flow from your checkout site and will take all order information on the frontend javascript to begin the customer checkout flow. If you wish to initiate an order from your backend system then the [api-driven-create-order-widget](https://docs.optty.com/widget/api-driven-create-order-widget "mention") widget may be more suited to your use case.

## Step 1 - Widget Setup & Initialisation

<details>

<summary>Overview of <a data-mention href="widget-setup-and-integration">widget-setup-and-integration</a></summary>

### **1.1 Initiate Widget**

```javascript
<script>
  (function (w, d, s, o, f, js, fjs) {
    w['JS-Widget'] = o;
    w[o] = w[o] || function () { (w[o].q = w[o].q || []).push(arguments) };
    js = d.createElement(s), fjs = d.getElementsByTagName(s)[0];
    js.id = o; js.src = f; js.async = 1; fjs.parentNode.insertBefore(js, fjs);
  }(window, document, 'script', 'mw', 'https://widgets.qa.optty.com/widget-loader.js'));
</script>
```

### **1.2 Load configuration**

```javascript
<script>
    // … widget initiation script …
    mw('init', {
        token: {{CUSTOMER_WIDGET_TOKEN}},
        currency: "string",
        initialAmount: number
        mode: “live”
    });
</script>
```

### **1.3 Setup Optty Easy Checkout Widget**

```javascript
<script>
    mw('optty-easy-checkout-widget', {
        initialAmount: number,
    })
</script>
```

</details>

## **Step 2 - Payment Provider Selection**

There must be an implementation in your checkout to handle a customer selecting a payment method option. The easiest way to implement this is to use the [easy-checkout-widget](https://docs.optty.com/widget/easy-checkout-widget "mention"), otherwise if you wish to have complete control of the display of the payment method selection the [options](https://docs.optty.com/direct-api-orders/order-flow/options "mention") end point may be more preferable.

## Step 3 - Payload Field

Call the widget with required payload structure. For more details about the fields please view [direct-api-orders](https://docs.optty.com/direct-api-orders "mention") as this is where the fields are passed to after the widget is called. The two fields on the payload field that are handled different are the `dynamicCallbackUrl` and `paymentStatusFetchEnabled` which are outlined below.

**Parameters**

When using the `optty-create-order-widget`, note the following about `dynamicCallbackUrl`:

* For In-Context implementation: `dynamicCallbackUrl` is **required**
* For standard implementation: `dynamicCallbackUrl` is optional&#x20;

When provided, `dynamicCallbackUrl` should be a valid HTTPS URL that can receive requests for webhook notifications about order status changes.&#x20;

The  `paymentStatusFetchEnabled` determines whether to retrieve the payment status after the payment  is completed. If set to `true`, a payment object is included in the `onFinalized` callback response.

### Step 3.2 - Callback Functions

**onFinalize:** This callback function is called when the consumer finishes the checkout flow with the payment method.&#x20;

**onError:** This callback function is called when their was an error faced creating an order with the selected payment provider (bnplProvider), the best practise for handling this would be to remove that option from the checkout and get the customer to checkout with another provider. We also request any errors faced here to be sent to <support@optty.com> as we will follow up to get the technical issue with the provider directly on your behalf.

**onCancel:** This callback is only used when the in-context flow is used, and is when the customer cancels the checkout flow through either closing the popup table, or clicking the Optty cancel button on the IFrame, this IS NOT the only flow where a cancel occurs, if the customer cancels with the providers cancel functionality this will be passed as a CANCELED status in the onFinalize callback, but both should be handled the same way.

```javascript
<script>
    mw('optty-create-order-widget', {
        payload: {
          "locale": "en_US",
          "customerToken": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjdXN0b21lcklkZW50aWZpZXIiOiJmM2I1OGEzMzE4ZmI3OTk2NmQ4Yzc3Njc5OTg0MzBhNjFmODNhYzY2ODU0NGFlODMwZTkwNDE4YjkwNzQ4YWYyNWQ2Mjg1YTIxMzIzZDJkNmNkNTcyNGQwM2RkMTk2OWU3NjZlODU4ZGIwZjNjYjM1NjJlNTk1N2FhMGRhZTZjMiIsIm1lcmNoYW50SWQiOiI0NGFkMzIxMS0yYTgzLTRiNWUtYTJlNy03ZmZlNjhlZTkyMWMiLCJpYXQiOjE2NDc4NzAwNjQsImV4cCI6MTY0ODQ3NDg2NH0.oQmfzTDvaEywgtaV5dhSeY_6pZ95og9rswE5LuktEnc",
          "orderReference": {{YOUR_UNIQUE_REFERENCE}},
          "bnplProvider": {{SELECTED_BNPL_PROVIDER}},
          "orderAmount": 50,
          "taxAmount": 0,
          "shippingAmount": 0,
          "discountAmount": 0,
          "orderItems": [
            {
              "name": "Striped Silk Tie",
              "quantity": 1,
              "sku": "793775370033M",
              "unitPrice": 50,
              "totalAmount": 50
            }
          ],
          "purchaseCountry": "AU",
          "purchaseCurrency": "AUD",
          "customer": {
            "firstName": "Ben",
            "lastName": "Tester",
            "email": "tester1@optty.com",
            "phoneNumber": "+6591234567"
          },
          "autoCapture": true,
          "billingAddress": {
            "firstName": "RTS",
            "lastName": "VDP",
            "email": "ben.tester@gmail.com",
            "phoneNumber": "+6591234567",
            "streetAddress": "201 S. Division St.",
            "streetAddress2": "Ann Arbor",
            "city": "PUNE",
            "country": "US",
            "state": "New york",
            "region": "skdsk",
            "postalCode": "48104-2201"
          },
          "shippingMethod": "digital",
          "shippingAddress": {
            "firstName": "Kaufen",
            "lastName": "Darf",
            "email": "ben.tester@gmail.com",
            "phoneNumber": "+6591234567",
            "streetAddress": "Herrengraben 31",
            "streetAddress2": "",
            "city": "Herrengraben",
            "country": "US",
            "state": "New york",
            "region": "Herrengraben",
            "postalCode": "48104-2201"
          },
          "dynamicRedirectUrl": "https://webhook.site/f133ab94-8687-4b94-a570-e008d999f362",
          "dynamicCallbackUrl": "https://webhook.site/f133ab94-8687-4b94-a570-e008d999f362",
          "cancellationTimeout": 8660,
          "paymentStatusFetchEnabled": true
        },
      onError: function(err) {
         // Handle error 
        console.error({ err });
      },
      onCancel: function(cancel) {
        // Handle cancel
        console.log({ cancel });
      },
      onFinalize: function(data) {
         // Handle completion
        console.log('Payment completed:', data);
      }
    });
</script>
```

## **Step 4 - Checkout Display Configuration**

The checkout widget offers two display options: External Link and In-Context. The In-Context method minimizes customer friction by avoiding redirection, allowing them to complete the checkout directly on the site. Conversely, the External Link method redirects the customer to the payment method's page to finalize the checkout.

For the In-Context display, the widget can appear as either a Pop-Up or an IFrame. The choice between these two depends on the payment provider's security settings; if their checkout page disallows iframing on another site, the Pop-Up method will be used for that provider.

<figure><img src="https://3947039319-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfCUCEi1845pQGMcbjae6%2Fuploads%2FtoUsb9pycWaOMlkKvP84%2Fimage.png?alt=media&#x26;token=fc09181d-5b76-4854-b729-ee1246fa886a" alt=""><figcaption></figcaption></figure>

### Pop Up

<figure><img src="https://3947039319-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfCUCEi1845pQGMcbjae6%2Fuploads%2Flk9f0w9mHsG80DnuWExj%2Fimage.png?alt=media&#x26;token=350eab3f-e9ef-44ac-9337-9d600e87b8c5" alt=""><figcaption></figcaption></figure>

### IFrame

<figure><img src="https://3947039319-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FfCUCEi1845pQGMcbjae6%2Fuploads%2FRloB6Op0s3UVqGvwoqIe%2Fimage.png?alt=media&#x26;token=e8a1a44c-b342-440e-b91a-a6d77d6a43dc" alt=""><figcaption></figcaption></figure>

## **React Code Example**

To test this we recommend forking this example and entering your widget token from the UPP found under 'view profile' when hovering your user on the top right. Along with a currency which has a payment method enabled on the UPP.

{% embed url="<https://codesandbox.io/p/sandbox/optty-create-order-widget-966688>" %}

{% embed url="<https://codesandbox.io/p/sandbox/optty-create-order-widget-forked-qg4g6y>" %}
