> ## Documentation Index
> Fetch the complete documentation index at: https://docs.cryptoprocessing.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Configure underpayment handling

export function Available({to, except}) {
  const roles = <Tooltip tip="Roles determine what each user can see and do in the portal." cta="See role descriptions" href="/merchant-administration/add-a-user#determine-which-role-to-use">roles</Tooltip>;
  if (to) {
    return <><strong>Available to {roles}:</strong> {to.map(role => <>{" "}<Badge color="blue">{role}</Badge></>)}</>;
  } else {
    return <><strong>Available to all {roles} except</strong> {except.map(role => <>{" "}<Badge color="blue">{role}</Badge></>)}</>;
  }
}

export const Failed = () => <Badge stroke shape="rounded" color="red">Failed</Badge>;

export const Paid = () => <Badge stroke shape="rounded" color="green">Paid</Badge>;

<Available to={["Owner"]} />

Customers may sometimes send slightly less than they need to — for example, because they entered the amount incorrectly or didn't account for a fee deducted by their wallet or exchange.

In your merchant settings, you choose what CryptoProcessing does in such cases: [Accept underpayments](#accept-underpayments) or [Reject & refund automatically](#reject-&-refund-automatically). You can change the setting at any time. It takes effect immediately and applies to all current and future payment requests.

## Accept underpayments

If receiving the exact requested amount is not critical for your business, you can configure an **underpayment tolerance** to accept payments below the requested amount.

There are two common ways to use this feature:

* **Accept as fully paid.** Accept an underpaid payment request as successfully completed and consider the customer's payment obligation fulfilled, as long as the amount is within your configured tolerance.

* **Credit the actual paid amount.** If you use payment requests to top up customer balances, you can credit the amount the customer actually paid instead of the requested amount. You can find the received amount in the [currency\_received.amount](/api-reference/callbacks/payment-request-callbacks#body-currency-received) parameter of the payment request callback.

In both cases, CryptoProcessing credits your merchant balance with the actual received amount, not the originally requested amount. If [your customer pays the processing fee](/payment-requests/fees#passing-the-processing-fee-to-your-customer), the received amount will include this fee. Make sure to subtract it before crediting the customer's balance.

You can set the tolerance as a percentage of the total (e.g., allow underpayments up to 2%) or as the EUR amount (e.g., allow underpayments up to 10 EUR). You can also combine the two values so that the percentage caps at a certain limit (e.g., allow underpayments up to 2% but no more than 10 EUR).

<Tip>
  Here's how a combined rule of **2% / 10 EUR** applies to different payment requests:

  * **100 EUR** expected → **at least 98 EUR** required (underpayment up to 2%)
  * **1000 EUR** expected → **at least 990 EUR** required (underpayment capped at 10 EUR)
</Tip>

CryptoProcessing keeps waiting for the full expected amount until the payment request [times out](/payment-requests#lifespan-and-rate-lock). If the payment is not complete by then, the paid amount is checked against the tolerance. If it's within the tolerance, the payment request gets the <Paid /> status, and the actual paid amount is reported in the API callback (see the [Integration guide](/payment-requests/integration-guide#process-the-callback)). Otherwise, it gets the <Failed /> status, and CryptoProcessing initiates an automatic [refund](/payment-requests/refunds) for the received funds minus a refund fee.

To enable this behavior:

<Steps>
  <Step>
    Go to **Settings → Payment requests**.
  </Step>

  <Step>
    On the **Payment handling rules** tab, click **Manage**.
  </Step>

  <Step>
    Select **Accept underpayments**.
  </Step>

  <Step>
    Specify the **Underpayment tolerance**.

    You can enter the percentage, the maximum EUR amount, or both.
  </Step>

  <Step>
    Enter your 2FA code and click **Save changes**.
  </Step>
</Steps>

## Reject & refund automatically

This is the default behavior we set for all merchants. If there is not enough funds received when the payment request [times out](/payment-requests#lifespan-and-rate-lock), it gets the <Failed /> status. CryptoProcessing initiates an automatic [refund](/payment-requests/refunds) for the received funds minus a refund fee.

To enable this behavior:

<Steps>
  <Step>
    Go to **Settings → Payment requests**.
  </Step>

  <Step>
    On the **Payment handling rules** tab, click **Manage**.
  </Step>

  <Step>
    Select **Reject & refund automatically**.
  </Step>

  <Step>
    Enter your 2FA code and click **Save changes**.
  </Step>
</Steps>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.