Currently, a payment method doesn't store any configuration that relates to the payment type. The payment method entity only stores common properties such as controller class, module, labels, and so on.

This means that modules implementing a payment type need to implement their own storage. In the modules I've seen so far, this configuration gets dumped in the core variable system, which is quick but inelegant and poor for overall site performance. There's also a lot of boilerplate code that needs to be added: hook_ENTITY_TYPE_ACTION() needs to be added for insert/update/delete, as can be seen in this project's own basic payment method: http://cgit.drupalcode.org/payment/tree/modules/paymentmethodbasic/payme...

I think this could be improved by adding a 'config' column to the payment method entity table, and having payment_form_payment_method_submit() serialize form values into it. This would mean a duplication of stored data for existing payment method modules, but those be updated in future.

Comments

joachim created an issue. See original summary.

Xano’s picture

Category: Feature request » Support request
Priority: Major » Normal
Status: Active » Fixed

This can all be stored in Payment::$context_data.

Also, payment types are an 8.x-2.x concept. They're called payment contexts in 7.x-1.x.

joachim’s picture

Category: Support request » Feature request
Status: Fixed » Active

I'm not sure we're talking about the same thing here. I mean payment methods, not payments. The storage I'm talking about is configuration for a method.

For example, paymentmethodbasic has to implement its own table and have a load of code to handle storage, of which this is just a sample:

/**
 * Implements hook_ENTITY_TYPE_ACTION().
 */
function paymentmethodbasic_payment_method_insert(PaymentMethod $payment_method) {
  if ($payment_method->controller->name == 'PaymentMethodBasicController') {
    $payment_method->controller_data += $payment_method->controller->controller_data_defaults;
    $query = db_insert('paymentmethodbasic');
    $values = array_merge($payment_method->controller_data, array(
      'pmid' => $payment_method->pmid,
    ));
    $query->fields($values);
    $query->execute();
  }
}

/**
 * Implements hook_ENTITY_TYPE_ACTION().
 */
function paymentmethodbasic_payment_method_update(PaymentMethod $payment_method) {
  if ($payment_method->controller->name == 'PaymentMethodBasicController') {
    $query = db_update('paymentmethodbasic');
    $values = array_merge($payment_method->controller_data, array(
      'pmid' => $payment_method->pmid,
    ));
    $query->fields($values);
    $query->condition('pmid', $payment_method->pmid);
    $query->execute();
  }
}

/**
 * Implements hook_ENTITY_TYPE_ACTION().
 */
function paymentmethodbasic_payment_method_delete($entity) {
  if ($entity->controller->name == 'PaymentMethodBasicController') {
    db_delete('paymentmethodbasic')
      ->condition('pmid', $entity->pmid)
      ->execute();
  }
}

It's basically having to pick data out of the payment_method entity on save, handle storage, and then stick it into the payment_method entity on load.

torotil’s picture

Status: Active » Fixed

This is implemented with #2824638: Persist $method->controller_data. Payment method specific data can now be stored in $payment->controller_data.

Status: Fixed » Closed (fixed)

Automatically closed - issue fixed for 2 weeks with no activity.