How are prices "applied" in minting?

Hi! I'm trying to understand how is the pricing logic implemented in smart contracts, specifically ones that mint NFTs. I have two code examples:

:1234: Code to reproduce

  1. Dizzy Dragon smart contract
    /*
    * Mint Dizzy Dragon NFTs, woo!
    */
    function adoptDragons(uint256 numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to adopt dragons");
        require(numberOfTokens <= MAX_MINTS_PER_TXN, "You can only adopt 15 dragons at a time");
        require(totalSupply() + numberOfTokens <= maxTokenSupply, "Purchase would exceed max available dragons");
        require(mintPrice * numberOfTokens <= msg.value, "Ether value sent is not correct");

        for(uint256 i = 0; i < numberOfTokens; i++) {
            uint256 mintIndex = _tokenIdCounter.current() + 1;
            if (mintIndex <= maxTokenSupply) {
                _safeMint(msg.sender, mintIndex);
                _tokenIdCounter.increment();
            }
        }

        // If we haven't set the starting index, set the starting index block.
        if (startingIndexBlock == 0) {
            startingIndexBlock = block.number;
        }
    }

So there's a require for the msg.value, but why is there no further visible ethereum transfer? There's obviously a mintPrice. Is it somehow handled by exchange platforms like OpenSea?

  1. Same goes for Bored Ape Yacht Club:
    /**
    * Mints Bored Apes
    */
    function mintApe(uint numberOfTokens) public payable {
        require(saleIsActive, "Sale must be active to mint Ape");
        require(numberOfTokens <= maxApePurchase, "Can only mint 20 tokens at a time");
        require(totalSupply().add(numberOfTokens) <= MAX_APES, "Purchase would exceed max supply of Apes");
        require(apePrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        
        for(uint i = 0; i < numberOfTokens; i++) {
            uint mintIndex = totalSupply();
            if (totalSupply() < MAX_APES) {
                _safeMint(msg.sender, mintIndex);
            }
        }

        // If we haven't set the starting index and this is either 1) the last saleable token or 2) the first token to be sold after
        // the end of pre-sale, set the starting index block
        if (startingIndexBlock == 0 && (totalSupply() == MAX_APES || block.timestamp >= REVEAL_TIMESTAMP)) {
            startingIndexBlock = block.number;
        } 
    }

There's even a "Ether value sent is not correct" error message in both examples.
I know that unused gas is returned to the sender, so basically I'm trying to figure out where is that process happening.

Thanks in advance.

The function is "payable" which means you can call it and send ETH with the call itself. The function then checks if the price to be paid is larger than or equal msg.value (=the amount of ETH that was sent with the transaction). If require fails, it will send the ETH and all unused gas back.

So to answer your question, the ETH transfer already happened when the function was called. Its like I can send you a mail by letter telling you what to do vs. I can send you a letter telling you what to do and add a 10 dollar note to the envelope as payment. What happens here corresponds to the second option.