When a method is payable, it's possible to send ether to the contract while calling it, and the function can check the amount sent through msg.value.
How can I make a function receive something other than ether, such as an ERC20 token?
An ERC20 token is just another contract. The ERC20 standard gives you two functions that work together to help pay a contract: approve() and transferFrom().
If the token contract is called "token" and the contract you're trying to pay is called "store", the process looks like this:
token.approve(store, amount); This gives store permission to transfer amount of the user's tokens.store.buy();, which calls token.transferFrom() to perform the actual transfer.The buy() function might look like this:
function buy() external { require(token.transferFrom(msg.sender, this, amount)); // having now received <amount> tokens from the sender, deliver whatever was // purchased, etc. } buy() function needs a parameter uint256 amount. address(this) instead of this?