diff --git a/payment/lib/Drupal/payment/Element/PaymentLineItem.php b/payment/lib/Drupal/payment/Element/PaymentLineItem.php
index b7560b0..1dea6be 100644
--- a/payment/lib/Drupal/payment/Element/PaymentLineItem.php
+++ b/payment/lib/Drupal/payment/Element/PaymentLineItem.php
@@ -18,11 +18,16 @@ use Drupal\payment\Plugin\payment\line_item\PaymentLineItemInterface;
 class PaymentLineItem {
 
   /**
+   * An unlimited cardinality.
+   */
+  const CARDINALITY_UNLIMITED = -1;
+
+  /**
    * Implements form #process callback.
    */
   public static function process(array $element, array &$form_state, array $form) {
     // Validate the element configuration.
-    if (count($element['#default_value']) > $element['#cardinality']) {
+    if ($element['#cardinality'] > self::CARDINALITY_UNLIMITED && count($element['#default_value']) > $element['#cardinality']) {
       throw new \InvalidArgumentException('The number of default line items can not be higher than the cardinality.');
     }
     foreach ($element['#default_value'] as $line_item) {
@@ -39,6 +44,7 @@ class PaymentLineItem {
       '#empty' => t('There are no line items yet.'),
       '#header' => array(t('Line item'), t('Weight'), t('Operations')),
       '#tabledrag' => array(array('order', 'self', 'payment-line-item-weight')),
+      '#tree' => TRUE,
       '#type' => 'table',
     );
 
@@ -77,7 +83,7 @@ class PaymentLineItem {
 
     // "Add more line items" button.
     $element['add_more'] = array(
-      '#access' => $element['#cardinality'] == 0 || count($line_items) < $element['#cardinality'],
+      '#access' => $element['#cardinality'] == self::CARDINALITY_UNLIMITED || count($line_items) < $element['#cardinality'],
       '#attributes' => array(
         'class' => array('payment-add-more'),
       ),
@@ -115,23 +121,25 @@ class PaymentLineItem {
     // Reorder line items based on their weight elements.
     $line_items = array();
     $values = NestedArray::getValue($form_state['values'], $element['#parents']);
-    foreach ($values['line_items'] as $name => $line_item_values) {
-      $line_items[$name] = $line_item_values['weight'];
-    }
-    asort($line_items);
-    foreach (static::getLineItems($element, $form_state) as $line_item) {
-      $line_items[$line_item->getName()] = $line_item;
+    if ($values['line_items']) {
+      foreach ($values['line_items'] as $name => $line_item_values) {
+        $line_items[$name] = $line_item_values['weight'];
+      }
+      asort($line_items);
+      foreach (static::getLineItems($element, $form_state) as $line_item) {
+        $line_items[$line_item->getName()] = $line_item;
+      }
+      static::setLineItems($element, $form_state, array_values($line_items));
     }
-    static::setLineItems($element, $form_state, array_values($line_items));
   }
 
   /**
    * Implements form #submit callback.
    */
   public static function addMoreSubmit(array &$form, array &$form_state) {
-    $parents = array_slice($form_state['triggering_element']['#parents'], 0, -2);
+    $parents = array_slice($form_state['triggering_element']['#array_parents'], 0, -2);
     $root_element = NestedArray::getValue($form, $parents);
-    $values = NestedArray::getValue($form_state['values'], $parents);
+    $values = NestedArray::getValue($form_state['values'], array_slice($form_state['triggering_element']['#parents'], 0, -2));
     $line_item = \Drupal::service('plugin.manager.payment.line_item')
       ->createInstance($values['add_more']['type'])
       ->setName(static::createLineItemName($root_element, $form_state, $values['add_more']['type']));
@@ -145,7 +153,7 @@ class PaymentLineItem {
    * Implements form AJAX callback.
    */
   public static function addMoreAjaxSubmit(array &$form, array &$form_state) {
-    $parents = array_slice($form_state['triggering_element']['#parents'], 0, -2);
+    $parents = array_slice($form_state['triggering_element']['#array_parents'], 0, -2);
     $root_element = NestedArray::getValue($form, $parents);
 
     return array_intersect_key($root_element, array_flip(element_children($root_element)));
@@ -155,10 +163,10 @@ class PaymentLineItem {
    * Implements form #submit callback.
    */
   public static function deleteSubmit(array &$form, array &$form_state) {
-    $root_element_parents  = array_slice($form_state['triggering_element']['#parents'], 0, -3);
+    $root_element_parents  = array_slice($form_state['triggering_element']['#array_parents'], 0, -3);
     $root_element = NestedArray::getValue($form, $root_element_parents);
     $line_items = array_values(static::getLineItems($root_element, $form_state));
-    $parents = $form_state['triggering_element']['#parents'];
+    $parents = $form_state['triggering_element']['#array_parents'];
     $line_item_name = $parents[count($parents) - 2];
     foreach ($line_items as $i => $line_item) {
       if ($line_item->getName() == $line_item_name) {
@@ -173,9 +181,9 @@ class PaymentLineItem {
    * Implements form AJAX callback.
    */
   public static function deleteAjaxSubmit(array &$form, array &$form_state) {
-    $root_element_parents  = array_slice($form_state['triggering_element']['#parents'], 0, -3);
+    $root_element_parents  = array_slice($form_state['triggering_element']['#array_parents'], 0, -3);
     $root_element = NestedArray::getValue($form, $root_element_parents);
-    $parents = $form_state['triggering_element']['#parents'];
+    $parents = $form_state['triggering_element']['#array_parents'];
     $line_item_name = $parents[count($parents) - 2];
     $response = new AjaxResponse();
     $response->addCommand(new RemoveCommand('#' . $root_element['#id'] . ' .payment-line-item-name-' . $line_item_name));
diff --git a/payment/payment.module b/payment/payment.module
index e7444c9..523081f 100644
--- a/payment/payment.module
+++ b/payment/payment.module
@@ -5,6 +5,7 @@
  * Hook implementations and shared functions.
  */
 
+use Drupal\payment\Element\PaymentLineItem;
 use Drupal\payment\Entity\PaymentInterface;
 use Drupal\payment\Plugin\payment\line_item\Basic;
 
@@ -269,9 +270,10 @@ function payment_element_info() {
     '#attached' => array(
       'css' => array(drupal_get_path('module', 'payment') . '/css/payment.css'),
     ),
-    // The number of values this element allows, which must be at least as much
-    // as the number of line items in the default value. Enter 0 for unlimited.
-    '#cardinality' => 0,
+    // The number of values this element allows, which must be at least as many
+    // as the number of line items in the default value. For unlimited values,
+    // use \Drupal\payment\Element\PaymentLineItem::CARDINALITY_UNLIMITED.
+    '#cardinality' => PaymentLineItem::CARDINALITY_UNLIMITED,
     // An array of
     // \Drupal\payment\Plugin\payment\line_item\PaymentLineItemInterface
     // objects.
diff --git a/payment_form/lib/Drupal/payment_form/Plugin/field/field_type/PaymentForm.php b/payment_form/lib/Drupal/payment_form/Plugin/field/field_type/PaymentForm.php
new file mode 100644
index 0000000..4774613
--- /dev/null
+++ b/payment_form/lib/Drupal/payment_form/Plugin/field/field_type/PaymentForm.php
@@ -0,0 +1,102 @@
+<?php
+
+/**
+ * Contains Drupal\payment_form\Plugin\field\field_type\PaymentForm.
+ */
+
+namespace Drupal\payment_form\Plugin\field\field_type;
+
+use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Entity\Annotation\FieldType;
+use Drupal\field\FieldInterface;
+use Drupal\field\Plugin\Type\FieldType\ConfigFieldItemBase;
+
+/**
+ * Defines a payment form field.
+ *
+ * @FieldType(
+ *   default_widget = "payment_form",
+ *   default_formatter = "payment_form",
+ *   id = "payment_form",
+ *   instance_settings = {
+ *     "currency_code" = null
+ *   },
+ *   label = @Translation("Payment form")
+ * )
+ */
+class PaymentForm extends ConfigFieldItemBase {
+
+  /**
+   * Definitions of the contained properties.
+   *
+   * @see static::getPropertyDefinitions()
+   *
+   * @var array
+   */
+  static $propertyDefinitions;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function schema(FieldInterface $field) {
+    $schema = array(
+      'columns' => array(
+        'amount' => array(
+          'type' => 'float',
+          'size' => 'big',
+          'not null' => TRUE,
+        ),
+        'currency_code' => array(
+          'type' => 'varchar',
+          'length' => 3,
+          'not null' => TRUE,
+        ),
+        'name' => array(
+          'type' => 'varchar',
+          'length' => '255',
+          'not null' => TRUE,
+        ),
+        'quantity' => array(
+          'type' => 'int',
+          'not null' => TRUE,
+        ),
+        // Line items are plugin instances, and there may be more data than the
+        // four required pieces that we know of and can store separately.
+        'line_item' => array(
+          'type' => 'blob',
+          'not null' => TRUE,
+          'serialize' => TRUE,
+        ),
+      ),
+    );
+
+    return $schema;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function getPropertyDefinitions() {
+    if (!isset(static::$propertyDefinitions)) {
+      static::$propertyDefinitions = parent::getPropertyDefinitions();
+      // @todo Convert this to an entity reference once config entities are
+      //   supported. Also rename the property to "currency".
+      static::$propertyDefinitions['currency_code'] = array(
+        'type' => 'string',
+        'label' => t('Currency'),
+        'required' => TRUE,
+      );
+      static::$propertyDefinitions['line_items'] = array(
+        'label' => t('Line items'),
+        'list' => TRUE,
+        'required' => TRUE,
+        'settings' => array(
+          'default_value' => array(),
+        ),
+        'type' => 'any',
+      );
+    }
+
+    return static::$propertyDefinitions;
+  }
+}
diff --git a/payment_form/lib/Drupal/payment_form/Plugin/field/formatter/PaymentForm.php b/payment_form/lib/Drupal/payment_form/Plugin/field/formatter/PaymentForm.php
new file mode 100644
index 0000000..16f718f
--- /dev/null
+++ b/payment_form/lib/Drupal/payment_form/Plugin/field/formatter/PaymentForm.php
@@ -0,0 +1,44 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\payment_form\Plugin\field\formatter\PaymentForm.
+ */
+
+namespace Drupal\payment_form\Plugin\field\formatter;
+
+use Drupal\field\Annotation\FieldFormatter;
+use Drupal\Core\Annotation\Translation;
+use Drupal\field\Plugin\Type\Formatter\FormatterBase;
+use Drupal\Core\Entity\EntityInterface;
+use Drupal\Core\Entity\Field\FieldInterface;
+
+/**
+ * A payment form formatter.
+ *
+ * @FieldFormatter(
+ *   id = "payment_form",
+ *   label = @Translation("Payment form"),
+ *   field_types = {
+ *     "payment_form",
+ *   }
+ * )
+ */
+class PaymentForm extends FormatterBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function viewElements(EntityInterface $entity, $langcode, FieldInterface $items) {
+    $context_manager = \Drupal::service('plugin.manager.payment.context');
+    // @todo Set the entity reference.
+    $context = $context_manager->createInstance('payment_form');
+    $payment = entity_create('payment', array(
+      'context' => $context,
+    ))->setCurrencyCode($this->fieldDefinition->getFieldSetting('currency_code'))
+      ->setLineItems($this->fieldDefinition->getFieldSetting('line_items'));
+
+    return \Drupal::service('plugin.manager.entity')->getFormController('payment', 'payment_form_field')->setEntity($payment);
+  }
+
+}
diff --git a/payment_form/lib/Drupal/payment_form/Plugin/field/widget/PaymentForm.php b/payment_form/lib/Drupal/payment_form/Plugin/field/widget/PaymentForm.php
new file mode 100644
index 0000000..fa493ce
--- /dev/null
+++ b/payment_form/lib/Drupal/payment_form/Plugin/field/widget/PaymentForm.php
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\payment_form\Plugin\field\widget\PaymentForm.
+ */
+
+namespace Drupal\payment_form\Plugin\field\widget;
+
+use Drupal\Core\Annotation\Translation;
+use Drupal\Core\Entity\Field\FieldInterface;
+use Drupal\currency\Entity\Currency;
+use Drupal\field\Annotation\FieldWidget;
+use Drupal\field\Plugin\Type\Widget\WidgetBase;
+
+/**
+ * A payment configuration widget.
+ *
+ * @FieldWidget(
+ *   field_types = {
+ *     "payment_form"
+ *   },
+ *   id = "payment_form",
+ *   label = @Translation("Payment configuration"),
+ *   multiple_values = "true"
+ * )
+ */
+class PaymentForm extends WidgetBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function settingsSummary() {
+    $count = count($this->getSetting('line_items'));
+    $summary = array(format_plural($count, t('!count line item.'), t('!count line items'), array(
+      '!count' => $count,
+    )));
+
+    return $summary;
+  }
+
+  /**
+   * Implements Drupal\field\Plugin\Type\Widget\WidgetInterface::formElement().
+   */
+  public function formElement(FieldInterface $items, $delta, array $element, $langcode, array &$form, array &$form_state) {
+    $element['currency_code'] = array(
+      '#type' => 'select',
+      '#title' => t('Payment currency'),
+      '#options' => Currency::options(),
+      '#default_value' => $this->getSetting('currency_code'),
+      '#required' => TRUE,
+    );
+    $line_items = array();
+    foreach ($items as $item) {
+      $line_items[] = $item->line_item;
+    }
+    $line_items = array_filter($line_items);
+    $element['line_items'] = array(
+      '#cardinality' => $this->fieldDefinition->getFieldCardinality(),
+      '#default_value' => $line_items,
+      '#type' => 'payment_line_items',
+    );
+
+    return $element;
+  }
+
+}
diff --git a/payment_form/lib/Drupal/payment_form/Plugin/payment/type/PaymentForm.php b/payment_form/lib/Drupal/payment_form/Plugin/payment/type/PaymentForm.php
new file mode 100644
index 0000000..86e1b9b
--- /dev/null
+++ b/payment_form/lib/Drupal/payment_form/Plugin/payment/type/PaymentForm.php
@@ -0,0 +1,64 @@
+<?php
+
+/**
+ * Contains \Drupal\payment_form\Plugin\payment\type\PaymentForm.
+ */
+
+namespace Drupal\payment_form\Plugin\payment\type;
+
+
+use Drupal\Core\Annotation\Translation;
+use Drupal\payment\Annotations\PaymentType;
+use Drupal\payment\Plugin\payment\type\Base;
+use Symfony\Component\HttpFoundation\RedirectResponse;
+
+/**
+ * The payment form field payment type.
+ *
+ * @PaymentType(
+ *   derivative = "Drupal\payment_form\Plugin\payment\type\PaymentFormDerivative",
+ *   id = "payment_form",
+ *   label = @Translation("Payment form field")
+ * )
+ */
+class PaymentForm extends Base {
+
+  /**
+   * {@inheritdoc}
+   */
+  public function resumeContext() {
+    parent::resumeContext();
+    $payment = $this->getPayment();
+    if ($payment->access('view')) {
+      $uri = $payment->uri();
+      $view = ' ' . l(t('View payment'), $uri['path'], $uri['options']) . '.';
+    }
+    if ($payment->getStatus()->isOrHasAncestor('payment_pending')) {
+      drupal_set_message(t('Your payment is still being processed.') . $view);
+    }
+    elseif ($payment->getStatus()->isOrHasAncestor('payment_success')) {
+      drupal_set_message(t('Your payment was successfully completed.') . $view);
+    }
+    elseif ($payment->getStatus()->isOrHasAncestor('payment_failed')) {
+      drupal_set_message(t('Your payment failed.') . $view);
+    }
+
+    // @todo Add an entity reference field to the payment and use that.
+    $entity = entity_load($payment->context_data['entity_type'], $payment->context_data['entity_id']);
+    if ($uri = entity_uri($payment->context_data['entity_type'], $entity)) {
+      return new RedirectResponse(url($uri['path'], $uri['options']));
+    }
+    return new RedirectResponse(url('<front>'));
+
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function paymentDescription($language_code = NULL) {
+    // @todo Add an entity reference field to the payment and use that, or
+    //   perhaps add a configurable description to the entity, or use the entity
+    //   label, or–like 7.x-1.x–use the field instance label.
+    return t('Unavailable');
+  }
+}
diff --git a/payment_form/lib/Drupal/payment_form/Plugin/payment/type/PaymentFormDerivative.php b/payment_form/lib/Drupal/payment_form/Plugin/payment/type/PaymentFormDerivative.php
new file mode 100644
index 0000000..a8bdd8a
--- /dev/null
+++ b/payment_form/lib/Drupal/payment_form/Plugin/payment/type/PaymentFormDerivative.php
@@ -0,0 +1,107 @@
+<?php
+
+/**
+ * @file
+ * Definition of Drupal\payment_form\Plugin\payment\type\PaymentFormDerivative.
+ */
+
+namespace Drupal\payment_form\Plugin\payment\type;
+
+use Drupal\Core\Plugin\Discovery\ContainerDerivativeInterface;
+use Drupal\Core\Entity\EntityManager;
+use Drupal\Core\Entity\Query\QueryFactory;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides a payment type plugin definition for every entity type.
+ */
+class PaymentFormDerivative implements ContainerDerivativeInterface {
+
+  /**
+   * List of derivative definitions.
+   *
+   * @var array
+   */
+  protected $derivatives;
+
+  /**
+   * The entity manager.
+   *
+   * @var \Drupal\Core\Entity\EntityManager
+   */
+  protected $entityManager;
+
+  /**
+   * The entity query factory.
+   *
+   * @var \Drupal\Core\Entity\Query\QueryFactory
+   */
+  protected $queryFactory;
+
+  /**
+   * Constructs an EntityDerivative object.
+   *
+   * @param \Drupal\Core\Entity\EntityManager $entity_manager
+   *   The entity manager.
+   */
+  public function __construct(EntityManager $entity_manager, QueryFactory $query_factory) {
+    $this->entityManager = $entity_manager;
+    $this->queryFactory = $query_factory;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, $base_plugin_id) {
+    return new static($container->get('plugin.manager.entity'), $container->get('entity.query'));
+  }
+
+  /**
+   * Implements DerivativeInterface::getDerivativeDefinition().
+   */
+  public function getDerivativeDefinition($derivative_id, array $base_plugin_definition) {
+    if (!isset($this->derivatives)) {
+      $this->getDerivativeDefinitions($base_plugin_definition);
+    }
+    if (isset($this->derivatives[$derivative_id])) {
+      return $this->derivatives[$derivative_id];
+    }
+  }
+
+  /**
+   * Implements DerivativeInterface::getDerivativeDefinitions().
+   */
+  public function getDerivativeDefinitions(array $base_plugin_definition) {
+    // Every entity type that has a payment_form field instance attached to it,
+    // is a derivative.
+    if (!isset($this->derivatives)) {
+      $this->derivatives = array();
+      // Get all payment_form fields.
+      $field_names = $this->queryFactory->get('field_entity')
+        ->condition('type', 'payment_form')
+        ->execute();
+      // Get the instances for the fields.
+      $instance_ids = $this->queryFactory->get('field_instance')
+        ->condition('field_name', $field_names)
+        ->execute();
+      $instances = $this->entityManager->getStorageController('field_instance')->loadMultiple($instance_ids);
+      // Get the entity types.
+      $entity_types = array();
+      foreach ($instances as $instance) {
+        $entity_types[] = $instance->entity_type;
+      }
+      // Declare every entity type as a derivative.
+      foreach (array_unique($entity_types) as $entity_type) {
+        $entity_info = $this->entityManager->getDefinition($entity_type);
+        $this->derivatives[$entity_type] = array(
+          'id' => $base_plugin_definition['id'] . ':' . $entity_type,
+          'label' => t('!plugin_label (!entity_type_label)', array(
+            '!plugin_label' => $base_plugin_definition['label'],
+            '!entity_type_label' => $entity_info['label'],
+          )),
+        ) + $base_plugin_definition;
+      }
+    }
+    return $this->derivatives;
+  }
+}
diff --git a/payment_form/lib/Drupal/payment_form/Tests/Plugin/field/field_type/PaymentFormWebTest.php b/payment_form/lib/Drupal/payment_form/Tests/Plugin/field/field_type/PaymentFormWebTest.php
new file mode 100644
index 0000000..ebe880a
--- /dev/null
+++ b/payment_form/lib/Drupal/payment_form/Tests/Plugin/field/field_type/PaymentFormWebTest.php
@@ -0,0 +1,76 @@
+<?php
+
+/**
+ * @file
+ * Contains class \Drupal\payment_form\Tests\Plugin\field\field_type\PaymentFormWebTest.
+ */
+
+namespace Drupal\payment_form\Tests\Plugin\field\field_type;
+
+use Drupal\payment\Generate;
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests \Drupal\payment_form\Plugin\field\field_type\PaymentForm.
+ */
+class PaymentFormWebTest extends WebTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = array('field_ui', 'payment', 'payment_form');
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'description' => '',
+      'name' => '\Drupal\payment_form\Plugin\field\field_type\PaymentForm web test',
+      'group' => 'Payment Form Field',
+    );
+  }
+
+  /**
+   * Tests the field.
+   */
+  protected function testField() {
+    $this->assertTrue(FALSE);
+
+    $entity_type = 'user';
+    $bundle = 'user';
+
+    // Create the field and field instance.
+    $field_name = strtolower($this->randomName());
+    entity_create('field_entity', array(
+      'cardinality' => FIELD_CARDINALITY_UNLIMITED,
+      'entity_type' => $entity_type,
+      'name' => $field_name,
+      'type' => 'payment_form',
+    ))->save();
+
+    entity_create('field_instance', array(
+      'bundle' => $entity_type,
+      'entity_type' => $entity_type,
+      'field_name' => $field_name,
+      'settings' => array(
+        'handler' => 'default',
+        'handler_settings' => array(
+          'currency_code' => 'EUR',
+          // @todo.
+          'line_items' => array(),
+        ),
+      ),
+    ))->save();
+
+    // Set a field value on an entity.
+    $user = entity_create($entity_type, array());
+    $field_value = $this->randomName();
+    $user->{$field_name}[0]->currency_code = $field_value;
+    $this->assertIdentical($user->{$field_name}[0]->currency_code, $field_value);
+    debug($user->{$field_name}[0]->getPropertyDefinitions());
+    debug($user->{$field_name}[0]->currency_code);
+    $user->{$field_name}[0]->line_items = Generate::createPaymentLineItems();
+    debug($user->{$field_name}[0]->line_items);
+  }
+}
diff --git a/payment_form/lib/Drupal/payment_form/Tests/Plugin/field/formatter/PaymentFormWebTest.php b/payment_form/lib/Drupal/payment_form/Tests/Plugin/field/formatter/PaymentFormWebTest.php
new file mode 100644
index 0000000..53cf3a0
--- /dev/null
+++ b/payment_form/lib/Drupal/payment_form/Tests/Plugin/field/formatter/PaymentFormWebTest.php
@@ -0,0 +1,55 @@
+<?php
+
+/**
+ * @file
+ * Contains class \Drupal\payment\Tests\Plugin\field\formatter\PaymentFormWebTest.
+ */
+
+namespace Drupal\payment_form\Tests\Plugin\field\formatter;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests \Drupal\payment\Plugin\field\formatter\PaymentForm.
+ */
+class PaymentFormWebTest extends WebTestBase {
+
+  /**
+   * The line item to test.
+   *
+   * @var \Drupal\payment\Plugin\payment\line_item\Basic
+   */
+  protected $lineItem;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = array('payment', 'payment_test');
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'description' => '',
+      'name' => '\Drupal\payment\Plugin\field\formatter\PaymentForm web test',
+      'group' => 'Payment Form Field',
+    );
+  }
+
+  /**
+   * {@inheritdoc
+   */
+  protected function setUp() {
+    parent::setUp();
+    $this->lineItem = $this->container->get('plugin.manager.payment.line_item')->createInstance('payment_basic');
+  }
+
+  /**
+   * Tests the formatter().
+   */
+  protected function testFormatter() {
+    // @todo Finish this test.
+    $this->assertTrue(FALSE);
+  }
+}
diff --git a/payment_form/lib/Drupal/payment_form/Tests/Plugin/field/widget/PaymentFormWebTest.php b/payment_form/lib/Drupal/payment_form/Tests/Plugin/field/widget/PaymentFormWebTest.php
new file mode 100644
index 0000000..103eb21
--- /dev/null
+++ b/payment_form/lib/Drupal/payment_form/Tests/Plugin/field/widget/PaymentFormWebTest.php
@@ -0,0 +1,70 @@
+<?php
+
+/**
+ * @file
+ * Contains class \Drupal\payment_form\Tests\Plugin\field\widget\PaymentFormWebTest.
+ */
+
+namespace Drupal\payment_form\Tests\Plugin\field\widget;
+
+use Drupal\simpletest\WebTestBase;
+
+/**
+ * Tests \Drupal\payment_form\Plugin\field\widget\PaymentForm.
+ */
+class PaymentFormWebTest extends WebTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  public static $modules = array('field_ui', 'payment', 'payment_form');
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function getInfo() {
+    return array(
+      'description' => '',
+      'name' => '\Drupal\payment_form\Plugin\field\widget\PaymentForm web test',
+      'group' => 'Payment Form Field',
+    );
+  }
+
+  /**
+   * Tests the widget.
+   */
+  protected function testWidget() {
+    $user = $this->drupalCreateUser(array('administer user fields'));
+    $this->drupalLogin($user);
+
+    // Test the widget when setting a default field value.
+    $field_name = strtolower($this->randomName());
+    debug($field_name);
+    $this->drupalPost('admin/config/people/accounts/fields', array(
+      'fields[_add_new_field][label]' => $this->randomString(),
+      'fields[_add_new_field][field_name]' => $field_name,
+      'fields[_add_new_field][type]' => 'payment_form',
+    ), t('Save'));
+    $this->drupalPost(NULL, array(), t('Save field settings'));
+    $this->drupalPost(NULL, array(), t('Add a line item'));
+    $this->drupalPost(NULL, array(
+      'default_value_input[field_' . $field_name . '][und][currency_code]' => 'EUR',
+      'default_value_input[field_' . $field_name . '][und][line_items][line_items][payment_basic][plugin_form][description]' => $this->randomString(),
+    ), t('Save settings'));
+    // Get all payment_form fields.
+    $field_names = $this->container->get('entity.query')->get('field_entity')
+      ->condition('type', 'payment_form')
+      ->execute();
+    $this->assertTrue(in_array('field_' . $field_name, $field_names));
+
+    // Test the widget when creating an entity.
+    $this->drupalGet('user/' . $user->id() . '/edit');
+    $this->drupalPost(NULL, array(), t('Add a line item'));
+    $this->drupalPost(NULL, array(
+      'field_' . $field_name . '[und][currency_code]' => 'EUR',
+      'field_' . $field_name . '[und][line_item][line_items][payment_basic][plugin_form][description]' => $this->randomString(),
+    ), t('Save'));
+    // @todo Storage fails. Revisit this and make sure it works.
+    $this->assertTrue(FALSE);
+  }
+}
diff --git a/paymentform/paymentform.info.yml b/payment_form/payment_form.info.yml
similarity index 88%
rename from paymentform/paymentform.info.yml
rename to payment_form/payment_form.info.yml
index 083bcb3..2554182 100644
--- a/paymentform/paymentform.info.yml
+++ b/payment_form/payment_form.info.yml
@@ -4,5 +4,6 @@ core: 8.x
 type: module
 package: Payment
 dependencies:
+  - entity_reference
   - field
   - payment
diff --git a/payment_form/payment_form.module b/payment_form/payment_form.module
new file mode 100644
index 0000000..c17ff7c
--- /dev/null
+++ b/payment_form/payment_form.module
@@ -0,0 +1,38 @@
+<?php
+
+/**
+ * @file
+ *   Hook implementations and general functions.
+ */
+
+use Drupal\field\FieldInterface;
+
+/**
+ * Implements hook_ENTITY_TYPE_create().
+ */
+function payment_form_field_entity_create(FieldInterface $field) {
+  if ($field->type == 'payment_form') {
+    payment_form_entity_reference_create($field);
+  }
+}
+
+/**
+ * Implements hook_ENTITY_TYPE_insert().
+ */
+function payment_form_field_entity_insert(FieldInterface $field) {
+  if ($field->type == 'payment_form') {
+    payment_form_entity_reference_create($field);
+  }
+}
+
+/**
+ * Creates a reverse entity reference field for payment_form fields.
+ *
+ * @param \Drupal\field\FieldInterface $field
+ */
+function payment_form_entity_reference_create(FieldInterface $field) {
+  $bundle = 'payment_form:' . $field->entity_type;
+  $field_name = 'payment_form_' . $field->entity_type;
+  // @todo Make sure the field is locked.
+//  entity_reference_create_instance('payment', $bundle, $field_name, t('Source entity'), $field->entity_type);
+}
diff --git a/payment_test/lib/Drupal/payment_test/PaymentLineItemElement.php b/payment_test/lib/Drupal/payment_test/PaymentLineItemElement.php
index 307ab96..2cb715a 100644
--- a/payment_test/lib/Drupal/payment_test/PaymentLineItemElement.php
+++ b/payment_test/lib/Drupal/payment_test/PaymentLineItemElement.php
@@ -33,7 +33,8 @@ class PaymentLineItemElement implements ContainerInjectionInterface, FormInterfa
    * {@inheritdoc}
    */
   public function buildForm(array $form, array &$form_state) {
-    $form['line_item'] = array(
+    // Nest the element to make sure that works.
+    $form['container']['line_item'] = array(
       '#cardinality' => 4,
       '#default_value' => Generate::createPaymentLineItems(),
       '#type' => 'payment_line_items',
@@ -56,6 +57,6 @@ class PaymentLineItemElement implements ContainerInjectionInterface, FormInterfa
    * {@inheritdoc}
    */
   public function submitForm(array &$form, array &$form_state) {
-    $value = \Drupal::state()->set('payment_test_line_item_form_element', PaymentLineItem::getLineItems($form['line_item'], $form_state));
+    $value = \Drupal::state()->set('payment_test_line_item_form_element', PaymentLineItem::getLineItems($form['container']['line_item'], $form_state));
   }
 }
diff --git a/paymentform/paymentform.install b/paymentform/paymentform.install
deleted file mode 100644
index 00c0bf8..0000000
--- a/paymentform/paymentform.install
+++ /dev/null
@@ -1,44 +0,0 @@
-<?php
-
-/**
- * @file
- * Installation and uninstallation functions.
- */
-
-/**
- * Implements hook_field_schema().
- */
-function paymentform_field_schema($field) {
-  if ($field['type'] == 'paymentform') {
-    $schema = array(
-      'columns' => array(
-        'amount' => array(
-          'type' => 'float',
-          'size' => 'big',
-          'not null' => TRUE,
-        ),
-        'description' => array(
-          'type' => 'varchar',
-          'length' => 255,
-          'default' => '',
-        ),
-        'name' => array(
-          'type' => 'varchar',
-          'length' => '255',
-          'not null' => TRUE,
-        ),
-        'quantity' => array(
-          'type' => 'int',
-          'not null' => TRUE,
-        ),
-        'tax_rate' => array(
-          'type' => 'float',
-          'size' => 'big',
-          'not null' => TRUE,
-        ),
-      ),
-    );
-  }
-
-  return $schema;
-}
\ No newline at end of file
diff --git a/paymentform/paymentform.module b/paymentform/paymentform.module
deleted file mode 100644
index b62b22d..0000000
--- a/paymentform/paymentform.module
+++ /dev/null
@@ -1,244 +0,0 @@
-<?php
-
-/**
- * @file
- *   Hook implementations and general functions.
- */
-
-/**
- * Implements hook_field_info().
- */
-function paymentform_field_info() {
-  $field['paymentform'] = array(
-    'label' => t('Payment form'),
-    'description' => t('Adds a payment form to the <em>view</em> page.'),
-    'instance_settings' => array(
-      'currency_code' => 'XXX',
-    ),
-    'default_widget' => 'paymentform_line_item',
-    'default_formatter' => 'paymentform',
-  );
-
-  return $field;
-}
-
-/**
- * Implements hook_field_widget_info().
- */
-function paymentform_field_widget_info() {
-  $widget['paymentform_line_item'] = array(
-    'label' => t('Payment line item configuration'),
-    'description' => t("Allows users to configure line items for the form's payment."),
-    'field types' => array('paymentform'),
-    'behaviors' => array(
-      'multiple values' => FIELD_BEHAVIOR_CUSTOM,
-      'default value' => FIELD_BEHAVIOR_NONE,
-    ),
-  );
-
-  return $widget;
-}
-
-/**
- * Implements hook_field_formatter_info().
- */
-function paymentform_field_formatter_info() {
-  $formatters['paymentform'] = array(
-    'label' => t('Payment form'),
-    'field types' => array('paymentform'),
-  );
-
-  return $formatters;
-}
-
-/**
- * Implements hook_field_instance_settings_form().
- */
-function paymentform_field_instance_settings_form($field, $instance) {
-  $form = array();
-
-  if ($instance['widget']['type'] == 'paymentform_line_item') {
-    $form['currency_code'] = array(
-      '#type' => 'select',
-      '#title' => t('Currency'),
-      '#options' => payment_currency_options(),
-      '#default_value' => $instance['settings']['currency_code'],
-      '#required' => TRUE,
-    );
-  }
-
-  return $form;
-}
-
-/**
- * Implements hook_field_widget_form().
- */
-function paymentform_field_widget_form(array &$form, array &$form_state, array $field, array $instance, $langcode, array $items, $delta, array $element) {
-  global $user;
-
-  $default_value = array();
-  foreach ($items as $line_item_data) {
-    $default_value[] = new PaymentLineItem($line_item_data);
-  }
-  if ($instance['widget']['type'] == 'paymentform_line_item') {
-    $element = array(
-      '#type' => 'value',
-      // Use a validation callback to convert the PaymentLineItem objects from
-      // the payment_line_item element to arrays usable by Field API.
-      '#element_validate' => array('paymentform_field_widget_form_validate'),
-    ) + $element;
-    $element['line_item'] = array(
-      '#type' => 'payment_line_item',
-      '#currency_code' => $instance['settings']['currency_code'],
-      '#cardinality' => (int) $field['cardinality'],
-      '#default_value' => $default_value,
-      '#required' => $element['#required'],
-    );
-  }
-
-  return $element;
-}
-
-/**
- * Implements hook_field_validate().
- */
-function paymentform_field_validate($entity_type, $entity, $field, $instance, $langcode, $items, &$errors) {
-  if ($field['type'] == 'paymentform') {
-    foreach ($items as $delta => $line_item_data) {
-      $base = array(
-        'delta' => $delta,
-      );
-
-      // Amount.
-      $base['property'] = 'amount';
-      if (!is_float($line_item_data['amount'])) {
-        $errors[$field['field_name']][$langcode][$delta][] = array(
-          'error' => 'paymentform_line_item_amount_no_float',
-          'message' => t('The amount is no floating point.'),
-        ) + $base;
-      }
-
-      // Quantity.
-      $base['property'] = 'quantity';
-      if (!is_int($line_item_data['quantity'])) {
-        $errors[$field['field_name']][$langcode][$delta][] = array(
-          'error' => 'paymentform_line_item_quantity_no_integer',
-          'message' => t('The quantity is no integer.'),
-        ) + $base;
-      }
-      elseif ($line_item_data['quantity'] < 0) {
-        $errors[$field['field_name']][$langcode][$delta][] = array(
-          'error' => 'paymentform_line_item_quantity_negative',
-          'message' => t('The quantity cannot be negative.'),
-        ) + $base;
-      }
-
-      // Tax rate.
-      $base['property'] = 'tax_rate';
-      if (!is_float($line_item_data['tax_rate'])) {
-        $errors[$field['field_name']][$langcode][$delta][] = array(
-          'error' => 'paymentform_line_item_tax_rate_no_float',
-          'message' => t('The tax rate is no floating point.'),
-        ) + $base;
-      }
-      elseif ($line_item_data['tax_rate'] < 0) {
-        $errors[$field['field_name']][$langcode][$delta][] = array(
-          'error' => 'paymentform_line_item_tax_rate_negative',
-          'message' => t('The tax rate cannot be negative.'),
-        ) + $base;
-      }
-
-      // Machine name.
-      $base['property'] = 'name';
-      if (empty($line_item_data['name'])) {
-        $errors[$field['field_name']][$langcode][$delta][] = array(
-          'error' => 'paymentform_line_item_name_empty',
-          'message' => t('The machine-readable name is empty.'),
-        ) + $base;
-      }
-    }
-  }
-}
-
-/**
- * Implements hook_field_widget_error().
- */
-function paymentform_field_widget_error($element, $error, $form, &$form_state) {
-  // This is a form-element specific error.
-  if (isset($error['delta']) && isset($error['property'])) {
-    form_error($element['line_item']['container_' . $error['delta']][$error['property']], $error['message']);
-  }
-  // This is a field-wide error.
-  else {
-    form_error($element['line_item'], $error['message']);
-  }
-}
-
-/**
- * Implements hook_field_is_empty().
- */
-function paymentform_field_is_empty($item, array $field) {
-  if ($field['type'] == 'paymentform') {
-    return empty($item);
-  }
-}
-
-/**
- * Implements hook_field_formatter_view().
- */
-function paymentform_field_formatter_view($entity_type, $entity, $field, $instance, $langcode, $items, $display) {
-  if ($display['type'] == 'paymentform') {
-    list($entity_id) = entity_extract_ids($entity_type, $entity);
-    $payment = new Payment(array(
-      'context_data' => array(
-        'entity_type' => $entity_type,
-        'entity_id' => $entity_id,
-      ),
-      'currency_code' => $instance['settings']['currency_code'],
-      'description' => $instance['label'],
-      'finish_callback' => 'paymentform_payment_finish',
-    ));
-    foreach ($items as $line_item_data) {
-      $payment->setLineItem(new PaymentLineItem($line_item_data));
-    }
-
-    return drupal_get_form('payment_form_standalone', $payment);
-  }
-}
-
-/**
- * Implements Payment::finish_callback.
- */
-function paymentform_payment_finish(Payment $payment) {
-  if (payment_access('view', $payment)) {
-    $view = ' ' . l(t('View payment'), 'payment/' . $payment->pid) . '.';
-  }
-  if (payment_status_is_or_has_ancestor($payment->getStatus()->status, PAYMENT_STATUS_PENDING)) {
-    drupal_set_message(t('Your payment is still being processed.') . $view);
-  }
-  elseif (payment_status_is_or_has_ancestor($payment->getStatus()->status, PAYMENT_STATUS_SUCCESS)) {
-    drupal_set_message(t('Your payment was successfully completed.') . $view);
-  }
-  elseif (payment_status_is_or_has_ancestor($payment->getStatus()->status, PAYMENT_STATUS_FAILED)) {
-    drupal_set_message(t('Your payment failed.') . $view);
-  }
-
-  $entity = entity_load_single($payment->context_data['entity_type'], $payment->context_data['entity_id']);
-  if ($uri = entity_uri($payment->context_data['entity_type'], $entity)) {
-    drupal_goto($uri['path'], $uri['options']);
-  }
-  drupal_goto('<front>');
-}
-
-
-
-/**
- * Implements form validate callback for a paymentform_line_item field widget.
- */
-function paymentform_field_widget_form_validate(array $element, array &$form_state) {
-  $line_items = array();
-  foreach ($form_state['values'][$element['#field_name']][$element['#language']]['line_item'] as $line_item) {
-    $line_items[] = (array) $line_item;
-  }
-  form_set_value($element, $line_items, $form_state);
-}
\ No newline at end of file
diff --git a/paymentform/tests/PaymentformWebTestCase.php b/paymentform/tests/PaymentformWebTestCase.php
deleted file mode 100644
index 6c6bb00..0000000
--- a/paymentform/tests/PaymentformWebTestCase.php
+++ /dev/null
@@ -1,63 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains class PaymentformWebTestCase.
- */
-
-/**
- * Contains functionality shared by Paymentform test cases.
- */
-class PaymentformWebTestCase extends PaymentWebTestCase {
-  /**
-   * Overrides parent::setUp().
-   */
-
-  /**
-   * Overrides parent::setUp().
-   */
-  function setUp(array $modules = array()) {
-    parent::setUp($modules + array('field', 'node', 'paymentform'));
-
-    $this->content_type = $this->drupalCreateContentType();
-    // Field configuration.
-    $this->field_paymentform = field_create_field(array(
-      'field_name' => 'field_paymentform',
-      'type' => 'paymentform',
-      'cardinality' => 2,
-    ));
-    $this->field_paymentform_instance = field_create_instance(array(
-      'field_name' => 'field_paymentform',
-      'entity_type' => 'node',
-      'bundle' => $this->content_type->type,
-      'widget' => array(
-        'type' => 'paymentform_line_item',
-      ),
-    ));
-    $this->PaymentLineItemData = array(
-      'amount' => 1.0,
-      'description' => 'foo',
-      'name' => 'bar',
-      'quantity' => 1,
-      'tax_rate' => 0.0,
-    );
-  }
-
-  /**
-   * Checks if a FieldValidationException contains a specified error code.
-   *
-   * @param FieldValidationException $e
-   * @param string $code
-   *
-   * @return boolean
-   */
-  function fieldValidationExceptionError(FieldValidationException $e, $code) {
-    $codes = array();
-    foreach ($e->errors['field_paymentform'][LANGUAGE_NONE][0] as $error) {
-      if ($error['error'] == $code) {
-        return TRUE;
-      }
-    }
-    return FALSE;
-  }
-}
diff --git a/paymentform/tests/paymentform_test/paymentform_test.info b/paymentform/tests/paymentform_test/paymentform_test.info
deleted file mode 100644
index 63f2aa9..0000000
--- a/paymentform/tests/paymentform_test/paymentform_test.info
+++ /dev/null
@@ -1,10 +0,0 @@
-;name = Payment Form Field tests
-;description = "Supports Payment Form's automated tests."
-;core = 7.x
-;dependencies[] = paymentform
-;package = Payment
-;hidden = TRUE
-;files[] = tests/PaymentformTestCallablesWebTestCase.test
-;files[] = tests/PaymentformTestFieldWebTestCase.test
-;files[] = tests/PaymentformTestFieldFormatterWebTestCase.test
-;files[] = tests/PaymentformTestLineItemFieldWidgetWebTestCase.test
diff --git a/paymentform/tests/paymentform_test/paymentform_test.module b/paymentform/tests/paymentform_test/paymentform_test.module
deleted file mode 100644
index e69de29..0000000
diff --git a/paymentform/tests/paymentform_test/tests/PaymentformTestFieldFormatterWebTestCase.php b/paymentform/tests/paymentform_test/tests/PaymentformTestFieldFormatterWebTestCase.php
deleted file mode 100644
index 9c9272d..0000000
--- a/paymentform/tests/paymentform_test/tests/PaymentformTestFieldFormatterWebTestCase.php
+++ /dev/null
@@ -1,41 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains class PaymentformTestFieldFormatterWebTestCase.
- */
-
-/**
- * Tests the paymentform field formatter.
- */
-class PaymentformTestFieldFormatterWebTestCase extends PaymentformWebTestCase {
-
-  static function getInfo() {
-    return array(
-      'name' => 'Payment form field formatter',
-      'group' => 'Payment Form Field',
-      'dependencies' => array('paymentform_test'),
-    );
-  }
-
-  /**
-   * Overrides parent::setUp().
-   */
-  function setUp(array $modules = array()) {
-    parent::setUp($modules + array('paymentform_test'));
-  }
-
-  /**
-   * Test the paymentform field formatter.
-   */
-  function testPaymentformFieldFormatter() {
-    $node = $this->drupalCreateNode(array(
-      'type' => $this->content_type->type,
-    ));
-    $node->field_paymentform[LANGUAGE_NONE][0] = $this->PaymentLineItemData;
-    node_save($node);
-    $this->drupalGet('node/' . $node->nid);
-    $elements = $this->xpath('//form[@id="payment-form-standalone"]');
-    $this->assertTrue(isset($elements[0]), 'The <em>Payment form</em> field formatter shows a payment form.');
-  }
-}
diff --git a/paymentform/tests/paymentform_test/tests/PaymentformTestFieldWebTestCase.php b/paymentform/tests/paymentform_test/tests/PaymentformTestFieldWebTestCase.php
deleted file mode 100644
index 9f59dfd..0000000
--- a/paymentform/tests/paymentform_test/tests/PaymentformTestFieldWebTestCase.php
+++ /dev/null
@@ -1,120 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains class PaymentformTestFieldWebTestCase.
- */
-
-/**
- * Tests the paymentform field.
- */
-class PaymentformTestFieldWebTestCase extends PaymentformWebTestCase {
-
-  static function getInfo() {
-    return array(
-      'name' => 'Payment form field',
-      'group' => 'Payment Form Field',
-    );
-  }
-
-  /**
-   * Test the paymentform field validation.
-   */
-  function testPaymentformFieldValidation() {
-    $node = $this->DrupalCreateNode(array(
-      'type' => $this->content_type->type,
-    ));
-    $line_item_data = array();
-    $node->field_paymentform[LANGUAGE_NONE][0] = &$line_item_data;
-
-    // Test that a non-float amount is invalid.
-    $line_item_data = array(
-      'amount' => 2,
-    ) + $this->PaymentLineItemData;
-    $message = "The <em>Payment form</em> field's validation throws an error if the amount is no float";
-    try {
-      field_attach_validate('node', $node);
-      $this->assertTrue(FALSE, $message);
-    }
-    catch (FieldValidationException $e) {
-      $this->assertTrue($this->fieldValidationExceptionError($e, 'paymentform_line_item_amount_no_float'), $message);
-    }
-
-    // Test the machine name, which cannot be empty.
-    $line_item_data = array(
-      'name' => '',
-    ) + $this->PaymentLineItemData;
-    $message = "The <em>Payment form</em> field's validation throws an error if the machine name is empty";
-    try {
-      field_attach_validate('node', $node);
-      $this->assertTrue(FALSE, $message);
-    }
-    catch (FieldValidationException $e) {
-      $this->assertTrue($this->fieldValidationExceptionError($e, 'paymentform_line_item_name_empty'), $message);
-    }
-
-    // Test that a non-integer quantity is invalid.
-    $line_item_data = array(
-      'quantity' => 1.0,
-    ) + $this->PaymentLineItemData;
-    $message = "The <em>Payment form</em> field's validation throws an error if the quantity amount is no integer";
-    try {
-      field_attach_validate('node', $node);
-      $this->assertTrue(FALSE, $message);
-    }
-    catch (FieldValidationException $e) {
-      $this->assertTrue($this->fieldValidationExceptionError($e, 'paymentform_line_item_quantity_no_integer'), $message);
-    }
-    // Test that a negative quantity is invalid.
-    $line_item_data = array(
-      'quantity' => -1,
-    ) + $this->PaymentLineItemData;
-    $message = "The <em>Payment form</em> field's validation throws an error if the quantity is negative";
-    try {
-      field_attach_validate('node', $node);
-      $this->assertTrue(FALSE, $message);
-    }
-    catch (FieldValidationException $e) {
-      $this->assertTrue($this->fieldValidationExceptionError($e, 'paymentform_line_item_quantity_negative'), $message);
-    }
-
-    // Test that a non-float tax rate is invalid.
-    $line_item_data = array(
-      'tax_rate' => 2,
-    ) + $this->PaymentLineItemData;
-    $message = "The <em>Payment form</em> field's validation throws an error if the tax rate is no float";
-    try {
-      field_attach_validate('node', $node);
-      $this->assertTrue(FALSE, $message);
-    }
-    catch (FieldValidationException $e) {
-      $this->assertTrue($this->fieldValidationExceptionError($e, 'paymentform_line_item_tax_rate_no_float'), $message);
-    }
-    // Test that a negative tax rate is invalid.
-    $line_item_data = array(
-      'tax_rate' => -1.0,
-    ) + $this->PaymentLineItemData;
-    $message = "The <em>Payment form</em> field's validation throws an error if the tax rate is negative";
-    try {
-      field_attach_validate('node', $node);
-      $this->assertTrue(FALSE, $message);
-    }
-    catch (FieldValidationException $e) {
-      $this->assertTrue($this->fieldValidationExceptionError($e, 'paymentform_line_item_tax_rate_negative'), $message);
-    }
-  }
-
-  /**
-   * Test the paymentform field storage.
-   */
-  function testPaymentformFieldStorage() {
-    $node = $this->drupalCreateNode(array(
-      'type' => $this->content_type->type,
-    ));
-    $node->field_paymentform[LANGUAGE_NONE][0] = $this->PaymentLineItemData;
-    node_save($node);
-    $node = node_load($node->nid, NULL, TRUE);
-    $diff = array_diff_assoc($node->field_paymentform[LANGUAGE_NONE][0], $this->PaymentLineItemData);
-    $this->assertTrue(is_array($diff) && empty($diff), 'Payment line item data is saved and loaded correctly.');
-  }
-}
diff --git a/paymentform/tests/paymentform_test/tests/PaymentformTestLineItemFieldWidgetWebTestCase.php b/paymentform/tests/paymentform_test/tests/PaymentformTestLineItemFieldWidgetWebTestCase.php
deleted file mode 100644
index 23e7163..0000000
--- a/paymentform/tests/paymentform_test/tests/PaymentformTestLineItemFieldWidgetWebTestCase.php
+++ /dev/null
@@ -1,40 +0,0 @@
-<?php
-
-/**
- * Contains class PaymentformTestLineItemFieldWidgetWebTestCase.
- */
-
-/**
- * Tests the paymentform_line_item field widget.
- */
-class PaymentformTestLineItemFieldWidgetWebTestCase extends PaymentformWebTestCase {
-
-  static function getInfo() {
-    return array(
-      'name' => 'Payment line item field widget',
-      'group' => 'Payment Form Field',
-      'dependencies' => array('node'),
-    );
-  }
-  /**
-   * Overrides parent::setUp().
-   */
-
-  /**
-   * Overrides parent::setUp().
-   */
-  function setUp(array $modules = array()) {
-    parent::setUp($modules + array('paymentform_test'));
-  }
-
-  /**
-   * Test the widget's presence.
-   */
-  function testPaymentformLineItemFieldWidgetInputElements() {
-    $web_user = $this->drupalCreateUser(array('create ' . $this->content_type->type . ' content'));
-    $this->drupalLogin($web_user);
-    $this->drupalGet('node/add/page');
-    $elements = $this->xpath('//div[@id="edit-field-paymentform-und-line-item-container-0"]');
-    $this->assertTrue(isset($elements[0]), 'The <em>Payment line item configuration</em> field widget shows the <em>payment_line_item</em> form element.');
-  }
-}
