This document describes how to work with the recurring billing smart contract factory and a recurring billing smart contract.
- Smart Contracts Addresses
- Recurring Billing Smart Contract Factory
- Using Recurring Billing Smart Contract
Mainnet:
- 0xDCc90D21186e9c1B60439FdBf88f0f14ad3A7355: Recurring Billing Smart Contract Factory
- 0x9dF38BdF603b36B8FE8040De760dFbB84cCeFa6d: Recurring Billing Smart Contract (for DREAM token)
Testnet (Ropsten):
Please create an issue/pull request regarding deploying recurring billing smart contract factories for any other networks.
Recurring billing smart contract factory allows to create recurring billing smart contracts for any ERC20-compatible tokens. Thus, you can enable recurring billing for your own tokens.
To create new recurring billing smart contract for your token, execute newRecurringBillingContract function in recurring billing smart contract factory, providing a token address as an argument. You can make this transaction from any account: this account won't be provided with any special control over the new recurring billing smart contract.
Once mined, check the event logs of the transaction and find NewRecurringBillingContractCreated(address token, address recurringBillingContract) event. This event has an address of the new recurring billing smart contract for your token (example for DREAM token: 9df38bdf603b36b8fe8040de760dfbb84ccefa6d is the new recurring billing contract address). You don't need to create more than 1 recurring billing smart contract for your token. However, in case you really need this you can publish more transactions to newRecurringBillingContract function, each one will create a new recurring billing smart contract.
You can use Etherscan or similar resources to find out event logs of past transactions and check whether recurring billing smart contract was created for your token.
Etherscan does not inherit verified smart contract code for newly created smart contracts yet, so you have to verify smart contract code manually. In order to verify the code of your newly created recurring billing smart contract, go to verify smart contract code on Etherscan and:
- Copy-paste the code from the smart contract factory. To make things more clear, you can delete
contract RecurringBillingContractFactorydefinition from the code. - In the
Addressinput, put the address of your newly created recurring billing smart contract. - In the
Contract Nameinput, putTokenRecurringBilling. - Select
0.5.2as a compiler version. - Select
YesforOptimization Enabled. Ensure thatRunssays200. - In "Constructor Arguments ABI-encoded", put the newly created smart contract address as it appears in the
NewRecurringBillingContractCreatedevent log. E.g. for DREAM token we had to put0000000000000000000000009df38bdf603b36b8fe8040de760dfbb84ccefa6d(0x9df38bdf603b36b8fe8040de760dfbb84ccefa6d). - Press
Verify and Publish.
Once you've got the recurring billing smart contract address for your token, you can use it for your needs, it's permanent. Example: Recurring Billing for DREAM Token.
The recurring billing smart contract defines workflow between a merchant and a customer. Workflow:
- Merchant registers themselves in this smart contract using
registerNewMerchant.- Merchant specifies
beneficiaryaddress, which receives tokens. - Merchant specifies
merchantaddress, which is able to changemerchantandbeneficiaryaddresses. - Merchant specified an address that is authorized to call
chargerelated to this merchant.- Later, merchant can (de)authorize another addresses to call
chargeusingchangeMerchantChargingAccount.
- Later, merchant can (de)authorize another addresses to call
- As a result, merchant gets
merchantId, which is used to initialize recurring billing by customers. - Merchant account can change their
beneficiary,merchantand authorized charging addresses by calling:- Function
changeMerchantAccount, which changes account that can control this merchant (merchantId). - Function
changeMerchantBeneficiaryAddress, which changes merchant'sbeneficiary. - Function
changeMerchantChargingAccount, which (de)authorizes addresses to callchargeon behalf of this merchant.
- Function
- Merchant specifies
- According to an off-chain agreement with merchant, customer calls
allowRecurringBillingand:- Specifies
billingId, which is given off-chain by merchant (merchant will listen blockchain Event on this ID). - Specifies
merchantId, the merchant which will receive tokens. - Specifies
periodin seconds, during which only one charge can occur. - Specifies
value, amount in tokens which can be charged eachperiod.- If the customer doesn't have at least
valuetokens,allowRecurringBillingerrors. - If the customer haven't approved at least
valuetokens for a smart contract,allowRecurringBillingerrors.
- If the customer doesn't have at least
billingIdis then used by merchant to charge customer eachperiod.
- Specifies
- Merchant use authorized accounts (1.iii) to call the
chargefunction eachperiodto charge agreed amount from a customer.- It is impossible to call
chargeif the date of the last charge is less thanperiod. - Calling
chargecancels billing when called after 2periods from the last charge. - Thus, to successfully charge an account,
chargemust be strictly called within 1 and 2periods after the last charge. - Calling
chargeerrors if any of the following occur:- Customer canceled recurring billing with
cancelRecurringBilling. - Customer's balance is lower than the chargeable amount.
- Customer's allowance to the smart contract is less than the chargeable amount.
- Specified
billingIddoes not exists. - There's no
periodpassed since the last charge.
- Customer canceled recurring billing with
- Next charge date increments strictly by
periodeach charge, thus, there's no need to execchargestrictly on time.
- It is impossible to call
- Customer can cancel further billing by calling
cancelRecurringBillingand passingbillingId. - TokenRecurringBilling smart contract implements
receiveApprovalfunction for allowing/cancelling billing within one call from the token smart contract. Parameterdatais encoded as tightly-packed (uint256 metadata, uint256 billingId).metadatais encoded usingencodeBillingMetadata.- As for
receiveApproval,lastChargeAtinmetadatais used as an action identifier. lastChargeAt=0specifies that customer wants to allow new recurring billing.lastChargeAt=1specifies that customer wants to cancel existing recurring billing.- Make sure that passed
bytesparameter is exactly 64 bytes in length.
The common automated setup for the recurring billing smart contract can be arranged like this:
- (One-time action) Merchant (a business representative) register themselves in a smart contract, determining which address will receive tokens and which address will be authorized to charge customers on behalf of merchant account.
- (One-time action) Merchant develops back end for recurring charges from authorized charging account. In short, back end publishes charge Ethereum transaction from charging account each time it sees
BillingAllowedevent or when the time allows to do the next charge. Additionally, back end can listen forBillingChargedevent to strictly define the next charge date. - (One-time action) Merchant develops front end for end users, primarily allowing them to call
allowRecurringBillingfunction. Note that billing parameters should arrive and get validated on the back end. If billing parameters don't match with ones generated on a back end, merchant should not perform any charges. - (Recurring) Each time there is a charge possible, back end charges customers using
chargefunction.
More detailed description of how to work with these smart contracts is coming on the developer's Medium.