Don't think there's an existing hook for it. I guess you could try to add it or request it. Regardless, wouldn't it be more elegant to use the Blizzlike currency system? I guess that might require a client-side patch for new entries in CurrencyType.dbc and maybe CurrencyCategory.dbc, unless you want to reuse an existing currency. You could maybe recycle item ID 37711: [Currency Token Test Token 1], it defaults to the "Miscellaneous" currency category and you could change the name and tooltip of the item server-side. That way, items in the vendor page would also have the right cost displayed. I don't know if that fits your design goal, though.
There already exist items that you can only buy if you meet rep requirements (things like item 30623: [Reservoir Key]). I tried adding such an item to an NPC unrelated to the reputation and it still checked my rep when buying, so I assume any item with a reputation requirement (on the item itself) will have that reputation as a purchasing requirement.In other words, try just putting a rep requirement on items and it wont let you buy them unless you meet the requirement.
But, it looks like its not really possible.
// Run all event handlers. If any of them return false then...if (!sEluna->OnBuyFromVendor(this, vendorguid, vendorslot, item, count, bag, slot)) { // ...abort the purchase! return false;}
If I'm not mistaken, you'd want to trigger the event from TrinityCore's Player::BuyItemFromVendorSlot. Instead of using SendBuyError, you could just use Eluna's Player:SendNotification method to show the player the red error text (or add a Player:SendBuyError method to Eluna if you really want to, but from what I understand its only purpose is to show the error message).
Please always prefer to use specialized packets: They are localized. Keeping semantics help for good user experience. There have been a lot of english-only errors in emulators for various things (summoning pets, buying stuff, …) in the past which could just be avoided by sending the correct packet.
enum LocaleConstant{ LOCALE_enUS = 0, LOCALE_koKR = 1, LOCALE_frFR = 2, LOCALE_deDE = 3, LOCALE_zhCN = 4, LOCALE_zhTW = 5, LOCALE_esES = 6, LOCALE_esMX = 7, LOCALE_ruRU = 8, TOTAL_LOCALES};