At first I was thinking about simply letting them see a Google Drive link but that would have to stay the same so the customers could just send the link to one another, even though the people should have to use the smart contract to get it.
You can solve this with https://ipfs.io (a distributed file store) and an Ethereum DApp. Given that you mention that you want to require people to use a smart contract to get access to the file, I think you'll want to encrypt the file before storing on IPFS. Because the IPFS is distributed, anyone could get the file if they know it exists but only someone with access to the private key could read it.
When the conditions of the smart contract have been met, you can release the key. Because an Ethereum smart contract can't do the actual decryption, your web3 app would need to do this part.
For example, in the web3 app after the file is stored on the IPFS:
addNewFile: function() {
// encrypt the file
var encryptedFile = CryptoJS.AES.encrypt(fileData, passPhrase);
// store on the IPFS
ipfs.files.write( ... => {
// make sure it worked
...
// (fileName is an IPFS-generated hash uniquely identifying the (encrypted) file
// write it to the contract
deployedFileContract.AddFileEntry(fileLocation, fileName, passPhrase, function(error) {
// respond to error condition
});
});
};
retrieveEncyptedFile: function() {
...
deployedFileContract.RetrieveFileEntry.call(_pointer-to-file_, function(error, result) {
// fetch an encrypted file as a readable stream from IPFS
// decrypt it and probably do something funky with mime types to make sure it gets saved
var decryptedFile = CryptoJS.AES.decrypt(encryptedFileStream, passPhrase). ...
});
...
};
All up you would need your Solidity smart contract and a web3 app. You might run the IPFS js-client https://github.com/ipfs/js-ipfs in the browser, or access it via Nodejs or Go.