Skip to main content

Fulfilling orders in Unity

In this tutorial step, you will learn how to fill orders in your game by using the Unity Orderbook package.

This allows players to purchase NFTs listed for sale in the marketplace.
Fulfilling orders in UnityFulfilling orders in Unity
💡Prerequisite step
Before continuing with this step, ensure you have completed the previous cancelling orders step of this tutorial series.

Overview

Now that players can create orders and view active listings, we can enable other players to fill the active NFT listings using the Unity Orderbook package.

In the sample game, we've added the buy button next to each listing in a stack, which will allow the player to buy the NFT for the price specified in the listing. Once the order is filled, the NFT will appear in the players inventory.

Fill Order

Fill an order

To fulfil an order, you need to send 1–2 transactions:

  1. An approval transaction (if required, as determined by the API).

  2. A fulfilment transaction to complete the order.

Below is an example of how to process an order fulfilment:

using System;
using System.Collections.Generic;
using Cysharp.Threading.Tasks;
using Immutable.Orderbook.Api;
using Immutable.Orderbook.Client;
using Immutable.Orderbook.Model;
using Immutable.Passport;
using Immutable.Passport.Model;
using Newtonsoft.Json;
using UnityEngine;

public class FulfilOrderUseCase
{
private static readonly Lazy<FulfilOrderUseCase> s_Instance = new(() => new FulfilOrderUseCase());

private readonly OrderbookApi m_OrderbookApi = new(new Configuration { BasePath = "https://api.immutable.com" });

private FulfilOrderUseCase() { }

public static FulfilOrderUseCase Instance => s_Instance.Value;

/// <summary>
/// Executes an order by fulfilling a listing and optionally confirming its status.
/// </summary>
/// <param name="listingId">The unique identifier of the listing to fulfil.</param>
/// <param name="fees">The taker fees</param>
public async UniTask ExecuteOrder(string listingId, List<FulfillOrderRequestTakerFeesInner> fees)
{
try
{
var request = new FulfillOrderRequest(
takerAddress: SaveManager.Instance.WalletAddress,
listingId: listingId,
takerFees: fees);

var createListingResponse = await m_OrderbookApi.FulfillOrderAsync(request);

if (createListingResponse.Actions.Count > 0)
{
foreach (var transaction in createListingResponse.Actions)
{
var transactionHash = await Passport.Instance.ZkEvmSendTransaction(new TransactionRequest
{
to = transaction.PopulatedTransactions.To,
data = transaction.PopulatedTransactions.Data,
value = "0"
});
Debug.Log($"Transaction hash: {transactionHash}");
}
}
}
catch (ApiException e)
{
Debug.LogError($"API Error: {e.Message} (Status: {e.ErrorCode})");
Debug.LogError(e.ErrorContent);
Debug.LogError(e.StackTrace);
throw;
}
}
}

After filling the order

The order fulfilment transaction is now being processed. Upon validating the required contract approvals and wallet balance requirements onchain, the order will asynchronously transition to the FILLED status.

We recommend taking an optimistic view and showing the order as FILLED as soon as it is submitted, then polling the order status to check for updates for the most seamless player experience.

💡Status polling
You can poll the Get Listing endpoint to check on status updates. In the near future we also plan on introducing push based (webhook) integration for order events.

You can see all the different order status types in the table in the order statuses documentation.

For more details on each step, you can read the Typescript documentation for filling orders since the Unity Orderbook closely follows this implementation.

You can also view a full example in the Unity sample game.

Conclusion

Great, now you can fill an order in the marketplace! That's everything you need to know to get started with the Immutable Orderbook in Unity. For further reading on related topics, check out the articles below.


Related content