# 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](https://paytr.gitbook.io/product-docs/developers/developer-docs/function-payinvoiceerc20escrow)\` 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 %}


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://paytr.gitbook.io/product-docs/developers/developer-docs/function-payinvoiceerc20.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
