diff --git a/payment/payment.classes.inc b/payment/payment.classes.inc
index b4a94c2..91bb0cd 100644
--- a/payment/payment.classes.inc
+++ b/payment/payment.classes.inc
@@ -755,13 +755,25 @@ class PaymentMethodController {
    * @throws PaymentValidationException
    */
   function validate(Payment $payment, PaymentMethod $payment_method, $strict) {
-    // Confirm the payment amount is higher than 0.
-    if ($payment->totalAmount(TRUE) <= 0) {
-      throw new PaymentValidationAmountBelowMinimumException(t('The amount should be higher than 0.'));
+    $currencies = $payment_method->controller->currencies;
+
+    // Confirm the payment amount is higher than the supported minimum.
+    $minimum = isset($currencies[$payment->currency_code]['minimum']) ? $currencies[$payment->currency_code]['minimum'] : PAYMENT_MINIMUM_AMOUNT;
+    if ($payment->totalAmount(TRUE) < $minimum) {
+      throw new PaymentValidationAmountBelowMinimumException(t('The amount should be higher than !minimum.', array(
+        '!minumum' => payment_amount_human_readable($minimum, $payment->currency_code),
+      )));
+    }
+
+    // Confirm the payment amount does not exceed the maximum.
+    if (isset($currencies[$payment->currency_code]['maximum']) && $payment->totalAmount(TRUE) > $currencies[$payment->currency_code]['maximum']) {
+      throw new PaymentValidationAmountExceedsMaximumException(t('The amount should be lower than !maximum.', array(
+        '!maximum' => payment_amount_human_readable($currencies[$payment->currency_code]['maximum'], $payment->currency_code),
+      )));
     }
 
     // Confirm the payment's currency is supported.
-    if (!empty($this->currencies) && !in_array($payment->currency_code, $this->currencies)) {
+    if (!empty($this->currencies) && !isset($this->currencies[$payment->currency_code])) {
       throw new PaymentValidationUnsupportedCurrencyException(t('The currency is not supported by this payment method.'));
     }
   }
@@ -1017,6 +1029,11 @@ class PaymentValidationException extends Exception {}
 class PaymentValidationAmountBelowMinimumException extends PaymentValidationException {}
 
 /**
+ * Exception thrown if a payment's total amount exceeds the supported maximum.
+ */
+class PaymentValidationAmountExceedsMaximumException extends PaymentValidationException {}
+
+/**
  * Exception thrown if a payment uses a currency that is unsupported by a
  * payment method.
  */
diff --git a/payment/payment.module b/payment/payment.module
index c638089..0611a72 100644
--- a/payment/payment.module
+++ b/payment/payment.module
@@ -46,6 +46,11 @@ define('PAYMENT_STATUS_FAILED', 'payment_status_failed');
 define('PAYMENT_LINE_ITEM_TOKEN_PREFIX', 'line_item-');
 
 /**
+ * The absolute minimum payment amount.
+ */
+define('PAYMENT_MINIMUM_AMOUNT', 0.001);
+
+/**
  * Implements hook_init().
  */
 function payment_init() {
diff --git a/payment/payment.rules.inc b/payment/payment.rules.inc
index e927827..12a8944 100644
--- a/payment/payment.rules.inc
+++ b/payment/payment.rules.inc
@@ -430,5 +430,5 @@ function payment_rules_condition_payment_uses_payment_method_type(Payment $payme
  * @return boolean
  */
 function payment_rules_condition_payment_method_controller_supports_currency(Payment $payment, $currency) {
-  return empty($payment->method->controller->currencies) ? TRUE : in_array($currency, $payment->method->controller->currencies);
+  return empty($payment->method->controller->currencies) ? TRUE : isset($payment->method->controller->currencies[$currency]);
 }
\ No newline at end of file
diff --git a/payment/tests/payment.test b/payment/tests/payment.test
index d4ef48f..0b65dbb 100644
--- a/payment/tests/payment.test
+++ b/payment/tests/payment.test
@@ -229,4 +229,87 @@ class PaymentStatusItemTest extends DrupalWebTestCase {
     $payment->setStatus($status_success);
     $this->assertTrue($payment->getStatus() === $status_success, 'Payment::setStatus() sets status items in the right order and Payment::getStatus() retrieves them.');
   }
+}
+
+/**
+ * Test payment validation.
+ */
+class PaymentValidationTest extends DrupalWebTestCase {
+
+  static function getInfo() {
+    return array(
+      'name' => 'Payment validation',
+      'group' => 'Payment',
+    );
+  }
+
+  /**
+   * Implements DrupalWebTestCase::setUp().
+   */
+  function setUp() {
+    parent::setUp('payment', 'paymentmethodbasic');
+  }
+
+  /**
+   * Test payment validation.
+   */
+  function testPaymentValidation() {
+    $payment_method = new PaymentMethod(array(
+      'controller' => payment_method_controller_load('PaymentMethodBasicController'),
+    ));
+    $payment = new Payment(array(
+      'currency_code' => 'EUR',
+      'method' => $payment_method,
+    ));
+
+    // Test that a payment with a total amount below PAYMENT_MINIMUM_AMOUNT
+    // invalidates.
+    $valid = TRUE;
+    try {
+      $payment->method->validate($payment);
+    }
+    // An exception was thrown during validation.
+    catch (PaymentValidationAmountBelowMinimumException $e) {
+      $valid = FALSE;
+    }
+    $this->assertFalse($valid, 'PaymentMethodController::validate() invalidates a payment of which the amount is below the default minimum of ' . PAYMENT_MINIMUM_AMOUNT . '.');
+
+    // Set custom minimum and maximum amounts.
+    $payment->method->controller->currencies['EUR'] = array(
+      'minimum' => 10,
+      'maximum' => 20,
+    );
+
+    // Test that a payment with a total amount below its controller's minimum
+    // invalidates.
+    $payment->setLineItem(new PaymentLineItem(array(
+      'name' => 'payment_test',
+      'amount' => 5,
+    )));
+    $valid = TRUE;
+    try {
+      $payment->method->validate($payment);
+    }
+    // An exception was thrown during validation.
+    catch (PaymentValidationAmountBelowMinimumException $e) {
+      $valid = FALSE;
+    }
+    $this->assertFalse($valid, "PaymentMethodController::validate() invalidates a payment of which the amount is below its controller's supported minimum.");
+
+    // Test that a payment with a total amount above its controller's maximum
+    // invalidates.
+    $payment->setLineItem(new PaymentLineItem(array(
+      'name' => 'payment_test2',
+      'amount' => 25,
+    )));
+    $valid = TRUE;
+    try {
+      $payment->method->validate($payment);
+    }
+    // An exception was thrown during validation.
+    catch (PaymentValidationAmountExceedsMaximumException $e) {
+      $valid = FALSE;
+    }
+    $this->assertFalse($valid, "PaymentMethodController::validate() invalidates a payment of which the amount exceeds its controller's supported maximum.");
+  }
 }
\ No newline at end of file
