When watching for events from web3, this is the format of the result you get when one is called:
{ address: '0x9c0ac1e0f0a8e0b01c7b652d5fbe094ddff48b81',
blockNumber: 704227,
transactionHash: '0x5887ba4e15d51e1cfddf626ecf416a0002085a1e0929fffe1f90ad69d5040081',
transactionIndex: 0,
blockHash: '0x5f485133ec662f556d88affccc18a358375de160178c6cf7cc0cec678d833a2a',
logIndex: 0,
removed: false,
event: 'ExampleEvent',
args:
{ argOne: BigNumber { s: 1, e: 0, c: [Array] },
argTwo: '0x374623456fa2' } }
So you can just get the TX from result.transactionHash
Event in contract:
event ExampleEvent(uint argOne, bytes32 argTwo)
Web3 code:
import exampleContractObject from 'path/to/ExampleContract.json'
ExampleContract = web3.eth.contract(exampleContractObject.abi);
contractInstance = ExampleContract.at('0x9c0ac1e0f0a8e0b01c7b652d5fbe094ddff48b81');
exampleEvent = contractInstance.ExampleEvent();
exampleEvent.watch((err, result) => {
// Do something
}
EDIT:
The Transfer event from ERC20 tokens would look like this:
{ address: '<contract_address>',
blockNumber: <block_number>,
transactionHash: '<transaction_hash>',
transactionIndex: <tx_index_in_block,
blockHash: '<block_hash>',
logIndex: <log_index>,
removed: <> ,
event: 'Transfer',
args:
{ _from: <address>,
_two: <address> ,
_value: <uint256>} }
For ETH, you can check the amount the smart contract received without having to call any smart contract method, using any block explorer.
Programmatically, using an Ethereum node, you can call the eth.getBalance(<your address>)
method to find the ETH balance of any address (including smart contracts).
For ERC20 tokens, you have to call the balanceOf(<your smart contract address>)
method of the token's smart contract address.
As a proof, have a look at EtherDelta's smart contract on etherscan.io and see that the contract has ETH balance.
In order to receive payments reliably, it's best for you to generate 1 address/customer, so that your customers are able to send you funds from any wallet they might use.
Best Answer
If you want to receive ethers as payment. This is obviously the case like you will receive funds in different accounts and then transfer these ethers to your main account. You will definitely need gas for such transaction. But it depends on your requirements.
For transferring ethers the gas used by the transaction is 21,000. If you set gas price to 21GWei, the transaction will cost you 0.000441 Ether ($0.13, quoted from etherscan.io). So you have to spend $13 for every 100 users. This is not a big amount you should be worried about but again it depends on requirements of the product. I don't see this as a major concern.
The major issue arises when you start accepting erc-20 tokens as payment, in that case when you wish to transfer tokens from each user's address to your main account, each user account must have ethers (to pay for transaction fee), but users have only transferred tokens. This is the thing you should be worried about. One possible way is you ask users for tokens as well as few ethers (for transaction fee).
The other possible solution could be having a pool of fixed addresses and providing users with repeated addresses. In that case, you have to either ask the user for transaction hash or account from which they are willing to pay to identify user's payment. This solution has privacy concerns like anyone can track the funds that you are possessing from block explorers.
The reason behind this is the basic difference between bitcoin and ethereum architecture. Bitcoin was made to use as currency but ethereum has much more to offer. That is why this implementation is quite easy in bitcoin but not in case of ethereum. I am not sure, whether there any merchant API's available for integrating erc-20 tokens as the payment method.
PS: The question asks for the best way. If somebody has the better solution, I'll love to hear that. Please edit the answer if this needs updation/modification.