> For the complete documentation index, see [llms.txt](https://paytr.gitbook.io/product-docs/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://paytr.gitbook.io/product-docs/developers/developer-docs/function-payinvoiceerc20.md).

# Function payInvoiceERC20

The `payInvoiceERC20` function enables everyone to make an early payment and start earning. The due date of the payment needs to be passed as an argument.

See \`[payInvoiceERC20Escrow](/product-docs/developers/developer-docs/function-payinvoiceerc20escrow.md)\` if you want to make an escrow payment without due date. The payment can be released at a later date.

```solidity
function payInvoiceERC20(
        address _payee,
        address _feeAddress,
        uint40 _dueDate,
        uint256 _amount,
        uint256 _feeAmount,
        bytes calldata _paymentReference,
        uint8 _shouldPayoutViaRequestNetwork
        ) external nonReentrant whenNotPaused {

            PaymentERC20 storage paymentERC20 = paymentMapping[_paymentReference];
            uint256 totalAmount = _amount + _feeAmount;

            if(_amount == 0) revert ZeroAmount();
            if(_payee == address(0)) revert ZeroPayeeAddress();
            if(_feeAddress == address(0)) revert ZeroFeeAddress();
            if(paymentERC20.amount != 0) revert PaymentReferenceInUse();
            if(totalAmount < minTotalAmountParameter) revert InvalidTotalAmount();
            if(_dueDate < uint40(block.timestamp + minDueDateParameter) || _dueDate > uint40(block.timestamp + maxDueDateParameter)) revert DueDateNotAllowed();

            IERC20(baseAsset).safeTransferFrom(msg.sender, address(this), totalAmount);
            
            uint256 cUsdcbalanceBeforeSupply = getContractCometBalance();
            IComet(cometAddress).supply(baseAsset, totalAmount);
            uint256 cUsdcbalanceAfterSupply = getContractCometBalance();
            uint256 cUsdcAmountToWrap = cUsdcbalanceAfterSupply - cUsdcbalanceBeforeSupply;         

            uint256 wrappedShares = IWrapper(wrapperAddress).deposit(cUsdcAmountToWrap, address(this));

            paymentMapping[_paymentReference] = PaymentERC20({
                amount: _amount,
                feeAmount: _feeAmount,
                wrapperSharesReceived: wrappedShares,
                dueDate: _dueDate,
                payer: msg.sender,
                payee: _payee,
                feeAddress: _feeAddress,
                shouldPayoutViaRequestNetwork: _shouldPayoutViaRequestNetwork
        });  

        emit PaymentERC20Event(baseAsset, _payee, _feeAddress, _amount, _dueDate, _feeAmount, _paymentReference);         
    }
```

<table><thead><tr><th>Parameter</th><th width="504.3333333333333">Description</th></tr></thead><tbody><tr><td><code>_payee</code></td><td>The receiver of the principal amount.</td></tr><tr><td><code>_feeAddress</code></td><td>In case you want to charge an extra fee, this is the receiving address of the fee.</td></tr><tr><td><code>_dueDate</code></td><td>The due date of the payment in <a href="https://www.epochconverter.com/">epoch</a> time. </td></tr><tr><td><code>_amount</code></td><td>The fee amount in wei. Make sure to double-check the number of decimals of the baseAsset.</td></tr><tr><td><code>_feeAmount</code></td><td>The fee amount in wei. Make sure to double-check the number of decimals of the baseAsset.</td></tr><tr><td><code>_paymentReference</code></td><td>Reference of the related payment. Make sure to add salt to and hash the _paymentReference to increase privacy and prevent double references.</td></tr><tr><td><code>_shouldPayOutViaRequestNetwork</code></td><td>This is a uint8 parameter. Pass a value != 0 if you want the payout of the invoice routed through Request Network's ERC20FeeProxy contract.</td></tr></tbody></table>

The `_amount` and `_feeAmount` total are transferred to Compound Finance's Comet contract, to earn yield.\
The payment details are stored in the `paymentMapping.`

Parameter `_shouldPayOutViaRequestNetwork` is a uint8 to save on gas fees (compared to a bool). You can pass a value of 0 if you don't want the payment to be routed through Request Network.

### **Interact with the** payInvoiceERC20 functio&#x6E;**:**

{% tabs %}
{% tab title="ethers.js" %}

```javascript
const paytrContract = new ethers.Contract(paytrContractAddress, PaytrABI, signer);

await paytrContract.payInvoiceERC20(
      payeeAddress,
      feeAddress,
      dueDate, //in epoch time
      amount,
      feeAmount,
      paymentReference, //bytes
      shouldPayOutViaRequestNetwork
      );

//example:      
await paytrContract.payInvoiceERC20(
      "0x67B94473D81D0cd00849D563C94d0432Ac988B49",
      "0xbF7Dc06Bd27BA2C4013cE02380a85aa7fe860f0A",
      1732779003,
      100_000_000, //100 USDC
      5_000_000, //5 USDC fee
      "0x494e56332d32343034",
      0 //the payment will not be routed through Request Network
      );


```

{% endtab %}

{% tab title="solidity" %}

```solidity
interface IPaytr{
    function payInvoiceERC20(
        address _payee,
        address _feeAddress,
        uint40 _dueDate,
        uint256 _amount,
        uint256 _feeAmount,
        bytes calldata _paymentReference,
        uint8 _shouldPayoutViaRequestNetwork
    ) external;
}

IPaytr(deployedPaytrAddress).payInvoiceERC20(
    address _payee,
    address _feeAddress,
    uint40 _dueDate,
    uint256 _amount,
    uint256 _feeAmount,
    bytes calldata _paymentReference,
    uint8 _shouldPayoutViaRequestNetwork
    );
    
//example
IPaytr(deployedPaytrAddress).payInvoiceERC20(
    0x67B94473D81D0cd00849D563C94d0432Ac988B49,
    0xbF7Dc06Bd27BA2C4013cE02380a85aa7fe860f0A,
    1732779003,
    100_000_000, //100 USDC
    5_000_000, //5 USDC fee
    "0x494e56332d32343034",
    0 //the payment will not be routed through Request Network
    );
    
    
```

{% endtab %}
{% endtabs %}
