user12: The type of handleError function is
:: (e -> Contract w s e' a)-> Contract w s e a -> Contract w s e' a

It takes two arguments

a function which takes error and returns a Contract monad (Contract w s e' a) without error
Contract Monad with error

and returns a Contract Monad without error (Contract w s e a). This is what I could understand. However when this is used in the following code
payContract = do
   pp <- endpoint @"pay"
   let tx = mustPayToPubKey (ppRecipient pp) $ lovelaceValueOf $ ppLovelace pp
   handleError (\err -> Contract.logInfo $ "caught error: " ++ unpack err) $ void $ submitTx tx
   payContract

In this function call submitTx Tx gives the Contract Monad with error and the lambda function \err -> Contract.logInfo $ "caught error: " ++ unpack err may be the first argument. What is happening to the returned Monad without error? and why void is used?

user1130: 
What is happening to the returned Monad?

All of this takes place within the do block. So, similar to the
<- endpoint @"pay"

the returned Monad is being abstracted away for you. The whole function is returning a Contract, so if it fails on either line, it will exit "early" and return the failed value. The reason it's not using the <- symbol is the answer to your second question:

why void is used?

We don't need the contained value.
void :: Functor f => f a -> f () 

So, void for Contract converts Contract w s e a to Contract w s e ().

You could also do this conversion by ignoring the output of a monad, as long as you still return the correct a for Contract, which in this case is ().
_ <- submit tx
return ()

is equivalent to
void $ submit tx

However, void is more explicit and fits better with the
handleError (\err -> Contract.logInfo $ "caught error: " ++ unpack err)

in your example.

user1110: Definitions:
submitTx :: forall w s e. (HasWriteTx s, AsContractError e) => TxConstraints Void Void -> Contract w s e Tx
void :: Functor f => f a -> f ()
handleError :: (e -> Contract w s e' a)-> Contract w s e a -> Contract w s e' a
Explaination:
submitTx tx is of type Contract w s e Tx, i.e. a Contract Monad with return type Tx.
void takes any Monad and maps it to a Monad with return type (). This is useful if you don't care for the returned value: void $ submitTx tx :: Contract w s e ()
handleError then takes the Monad and handles any errors with the specified error handler (e -> Contract w s e' a). However, it doesn't change the return type of the Contract Monad. In case there is no error on runtime the return value is just passed through.
payContract calls itself recursively on the last line of the do block in order to listen to the pay-endpoint indefinitely. Let's assume you'd leave out handleError and only use void $ submitTx tx your contract would crash on the first submission error.
If you wouldn't use void, your program would still be valid, but your compiler would output a warning, because you didn't use the return value of submitTx tx.

12: <p>The type of handleError function is</p>
<pre><code>:: (e -&gt; Contract w s e' a)-&gt; Contract w s e a -&gt; Contract w s e' a
</code></pre>
<p>It takes two arguments</p>
<ul>
<li>a function which takes error and returns a Contract monad <code>(Contract w s e' a)</code> without error</li>
<li>Contract Monad with error</li>
</ul>
<p>and returns a Contract Monad without error <code>(Contract w s e a)</code>. This is what I could understand. However when this is used in the following code</p>
<pre><code>payContract = do
   pp &lt;- endpoint @&quot;pay&quot;
   let tx = mustPayToPubKey (ppRecipient pp) $ lovelaceValueOf $ ppLovelace pp
   handleError (\err -&gt; Contract.logInfo $ &quot;caught error: &quot; ++ unpack err) $ void $ submitTx tx
   payContract
</code></pre>
<p>In this function call <code>submitTx Tx</code> gives the Contract Monad with error and the lambda function <code>\err -&gt; Contract.logInfo $ &quot;caught error: &quot; ++ unpack err</code> may be the first argument. What is happening to the returned Monad without error? and why void is used?</p>
 1130: <blockquote>
<p>What is happening to the returned Monad?</p>
</blockquote>
<p>All of this takes place within the <code>do</code> block. So, similar to the</p>
<pre><code>&lt;- endpoint @&quot;pay&quot;
</code></pre>
<p>the returned Monad is being abstracted away for you. The whole function is returning a <code>Contract</code>, so if it fails on either line, it will exit &quot;early&quot; and return the failed value. The reason it's not using the <code>&lt;-</code> symbol is the answer to your second question:</p>
<blockquote>
<p>why void is used?</p>
</blockquote>
<p>We don't need the contained value.</p>
<pre><code>void :: Functor f =&gt; f a -&gt; f () 
</code></pre>
<p>So, <code>void</code> for <code>Contract</code> converts <code>Contract w s e a</code> to <code>Contract w s e ()</code>.</p>
<hr />
<p>You could also do this conversion by ignoring the output of a monad, as long as you still return the correct <code>a</code> for <code>Contract</code>, which in this case is <code>()</code>.</p>
<pre><code>_ &lt;- submit tx
return ()
</code></pre>
<p>is equivalent to</p>
<pre><code>void $ submit tx
</code></pre>
<p>However, <code>void</code> is more explicit and fits better with the</p>
<pre><code>handleError (\err -&gt; Contract.logInfo $ &quot;caught error: &quot; ++ unpack err)
</code></pre>
<p>in your example.</p>
 1110: <p><strong>Definitions:</strong></p>
<p><code>submitTx :: forall w s e. (HasWriteTx s, AsContractError e) =&gt; TxConstraints Void Void -&gt; Contract w s e Tx</code></p>
<p><code>void :: Functor f =&gt; f a -&gt; f ()</code></p>
<p><code>handleError :: (e -&gt; Contract w s e' a)-&gt; Contract w s e a -&gt; Contract w s e' a</code></p>
<p><strong>Explaination:</strong></p>
<p><code>submitTx tx</code> is of type <code>Contract w s e Tx</code>, i.e. a Contract Monad with return type <code>Tx</code>.</p>
<p><code>void</code> takes any Monad and maps it to a Monad with return type <code>()</code>. This is useful if you don't care for the returned value: <code>void $ submitTx tx :: Contract w s e ()</code></p>
<p><code>handleError</code> then takes the Monad and handles any errors with the specified error handler (<code>e -&gt; Contract w s e' a</code>). However, it doesn't change the return type of the Contract Monad. In case there is no error on runtime the return value is just passed through.</p>
<p><code>payContract</code> calls itself recursively on the last line of the do block in order to listen to the <code>pay</code>-endpoint indefinitely. Let's assume you'd leave out <code>handleError</code> and only use <code>void $ submitTx tx</code> your contract would crash on the first submission error.</p>
<p>If you wouldn't use <code>void</code>, your program would still be valid, but your compiler would output a warning, because you didn't use the return value of <code>submitTx tx</code>.</p>
