# How YimMenuV2’s Transaction System Creates and Processes GTA Online Purchases

> Explore how YimMenuV2's transaction system mimics GTA Online purchases using Lua bindings and a placeholder basket structure. Discover the process and current limitations.

- Repository: [YimMenu/YimMenuV2](https://github.com/YimMenu/YimMenuV2)
- Tags: internals
- Published: 2026-07-17

---

**YimMenuV2 implements a placeholder transaction subsystem that mimics GTA Online’s internal "basket" structure through the `BasketTransaction` struct, exposing Lua bindings to build purchase data while awaiting reverse‑engineering of the native processing API.**

The YimMenuV2 mod menu provides a scripting layer for GTA Online that simulates in-game commerce through a custom transaction system. According to the source code in [`src/game/scripting/libraries/Transactions.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/scripting/libraries/Transactions.cpp), this implementation mirrors Rockstar’s internal **Basket** objects to create a temporary bridge for purchase workflows. The system currently supports constructing transaction containers and populating them with up to 70 items, preparing for future integration with the game’s native Transaction Manager.

## Understanding the BasketTransaction Data Structure

The foundation of the transaction system is the **`BasketTransaction`** structure defined at line 13 of [`Transactions.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/Transactions.cpp). This placeholder explicitly models the game’s internal commerce container, organizing purchase metadata and item arrays into a fixed‑size memory layout suitable for eventual native handoff.

### Core Fields and Memory Layout

The structure contains category and action identifiers alongside a fixed‑capacity item array:

```cpp
struct BasketTransaction {
    uint32_t m_Category; // e.g., "property", "car", "weapon"
    uint32_t m_Action;   // e.g., "buy", "sell"
    uint32_t m_NumItems;
    struct Item {
        char name[32];
        int price;
        int quantity;
    } m_Items[70];
};

```

As noted in the source comments, `m_Category` distinguishes purchase types such as property or vehicles, while `m_Action` specifies buy or sell operations. The **`m_Items`** array reserves contiguous storage for 70 entries, each tracking a 32‑character name, price integer, and quantity integer.

### Item Limits and Constraints

The system enforces a hard limit of **70 items per transaction**. The `AddItem` function explicitly checks `if (transaction.m_NumItems >= 70)` before insertion, raising a Lua error when the basket reaches capacity. This constraint aligns with Rockstar’s internal basket limitations observed during reverse engineering.

## Creating Transactions via the Lua Bridge

YimMenuV2 exposes the transaction system to Lua scripts through a dedicated bridge implemented in `RegisterTransactions`. This registration binds C++ helper functions to the global **`transactions`** table, allowing scripts to instantiate and manipulate `BasketTransaction` objects at runtime.

### Allocation and Initialization

The **`CreateTransaction`** function allocates a new `BasketTransaction` object via the `CreateObject` template and initializes its counters to zero:

```cpp
static int CreateTransaction(sol::state_view state) {
    auto transaction = CreateObject<BasketTransaction>(state);
    transaction->m_Category = 0;
    transaction->m_Action = 0;
    transaction->m_NumItems = 0;
    return 1; // return the transaction userdata
}

```

This function returns the allocated object as Lua userdata, enabling scripts to reference the same memory block for subsequent item additions and configuration changes.

### Template Helpers for Object Management

Two utility templates manage the type‑safe conversion between Lua userdata and C++ pointers. The **`GetObject`** template retrieves a pointer from the Lua stack, while **`CreateObject`** allocates a new instance and pushes it to the stack:

```cpp
template<class T>
static T* GetObject(sol::state_view state, int index) {
    return reinterpret_cast<T*>(sol::stack::reference(state, index).get_userdata());
}

template<class T>
static T* CreateObject(sol::state_view state) {
    T* obj = new T();
    sol::stack::push(state, obj);
    return obj;
}

```

These helpers ensure that Lua scripts handle `BasketTransaction` instances as opaque userdata objects while the C++ backend maintains type safety.

## Adding Items and Configuring Purchase Parameters

Once created, transactions require category selection, action definition, and item population. The system exposes discrete functions for each configuration step, allowing granular control over the basket contents before processing.

### Setting Categories and Actions

The **`SetCategory`** and **`SetAction`** functions modify the transaction’s metadata fields by extracting unsigned 32‑bit integers from the Lua stack:

```cpp
static int SetCategory(sol::state_view state) {
    auto& transaction = GetObject<BasketTransaction>(state, 1);
    transaction.m_Category = sol::stack::reference(state, 2).get<uint32_t>();
    return 0;
}

static int SetAction(sol::state_view state) {
    auto& transaction = GetObject<BasketTransaction>(state, 1);
    transaction.m_Action = sol::stack::reference(state, 2).get<uint32_t>();
    return 0;
}

```

Scripts invoke these functions to classify the transaction type—such as assigning category `1` for vehicles or action `0` for purchases—before adding specific items.

### Populating the Item Array

The **`AddItem`** function appends entries to the `m_Items` array using parameters passed from Lua:

```cpp
static int AddItem(sol::state_view state) {
    auto& transaction = GetObject<BasketTransaction>(state, 1);
    if (transaction.m_NumItems >= 70) {
        sol::error err("Transaction item limit reached");
        state.raise_error(err);
        return 0;
    }
    auto& item = transaction.m_Items[transaction.m_NumItems];
    const char* name = sol::stack::reference(state, 2).get<std::string>().c_str();
    int price = sol::stack::reference(state, 3).get<int>();
    int quantity = sol::stack::reference(state, 4).get<int>();
    strncpy(item.name, name, sizeof(item.name) - 1);
    item.price = price;
    item.quantity = quantity;
    transaction.m_NumItems++;
    return 0;
}

```

This implementation validates capacity, copies the item name into the fixed 32‑byte buffer, and increments the `m_NumItems` counter. Scripts can call this function repeatedly to build complex shopping carts containing multiple vehicles, weapons, or properties.

## Native Integration and Future Processing

While the current implementation constructs complete transaction objects, it does not yet invoke GTA Online’s native purchase processing. The codebase contains a placeholder for the **Transaction Manager** pointer that will eventually handle native communication.

### The TransactionMgr Pointer

In [`src/game/pointers/Pointers.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/pointers/Pointers.cpp), the system scans for a pattern associated with Rockstar’s internal Transaction Manager:

```cpp
constexpr auto transactionMgrPtrn = Pattern<"48 8B 05 ? ? ? ? 80 78 39 00 74 2D">("TransactionMgr");
scanner.Add(transactionMgrPtrn, [this](PointerCalculator ptr) {
    transactionMgr = ptr.GetAddress();
});

```

The **`transactionMgr`** member stores the resolved address, which future updates will use to invoke the game’s native basket processing functions. Currently, this pointer remains unused while the development team reverse engineers the correct native calling conventions.

### Current Limitations and TODOs

The source code explicitly marks the transaction system as temporary. Comments in [`Transactions.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/Transactions.cpp) state: *"TODO: Transaction system will be replaced by 'R*' API when it is ready"* and *"These are placeholders and *not* guaranteed to work on *any* game version."* The **`CanUseTransactions`** function currently returns `true` unconditionally, serving as a stub for future capability detection:

```cpp
static int CanUseTransactions(sol::state_view state) {
    sol::stack::push(state, true);
    return 1;
}

```

## Summary

- **YimMenuV2** defines a `BasketTransaction` struct in [`src/game/scripting/libraries/Transactions.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/scripting/libraries/Transactions.cpp) that mirrors GTA Online’s internal basket structure, supporting 70 items with name, price, and quantity fields.
- The **Lua bridge** exposes `CreateTransaction`, `SetCategory`, `SetAction`, and `AddItem` functions, allowing scripts to build purchase containers programmatically.
- Template helpers **`GetObject`** and **`CreateObject`** manage type‑safe conversion between Lua userdata and C++ transaction objects.
- The **TransactionMgr** pointer in [`src/game/pointers/Pointers.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/pointers/Pointers.cpp) prepares for native integration, though actual purchase processing awaits reverse engineering of Rockstar’s commerce API.
- The Recovery submenu in [`src/game/frontend/submenus/Recovery/Transactions.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/frontend/submenus/Recovery/Transactions.cpp) demonstrates ImGui‑based transaction building that invokes the Lua bindings internally.

## Frequently Asked Questions

### What is the maximum number of items per transaction in YimMenuV2?

The `BasketTransaction` structure supports exactly **70 items**, defined by the `m_Items[70]` array declaration at line 21 of [`Transactions.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/Transactions.cpp). The `AddItem` function enforces this limit by checking `if (transaction.m_NumItems >= 70)` and raising a Lua error if exceeded.

### How does YimMenuV2 currently process GTA Online purchases?

Currently, the system **does not process real purchases**. It constructs placeholder data structures and exposes them to Lua, but the `transactionMgr` pointer scanned in [`Pointers.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/Pointers.cpp) remains unimplemented. The TODO comments indicate this will be replaced by the official "R*" API once reverse engineered.

### Where is the transaction system defined in the YimMenuV2 codebase?

The core logic resides in **[`src/game/scripting/libraries/Transactions.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/scripting/libraries/Transactions.cpp)**, containing the struct definition and Lua bindings. UI integration appears in **[`src/game/frontend/submenus/Recovery/Transactions.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/frontend/submenus/Recovery/Transactions.cpp)**, while native pointer scanning occurs in **[`src/game/pointers/Pointers.cpp`](https://github.com/YimMenu/YimMenuV2/blob/main/src/game/pointers/Pointers.cpp)**.

### Can users create transactions through the UI or only via Lua scripts?

Both methods are supported. The system primarily exposes **Lua bindings** through `RegisterTransactions`, but the Recovery submenu demonstrates an **ImGui interface** that constructs transactions by calling `state["transactions"]["create_transaction"]` and related functions when the user clicks the "Add Item" button.