Можно ли собирать информацию о кредитной карте и адресную информацию на отдельных страницах в Commerce 2?


Я хочу, чтобы мой процесс оформления заказа выглядел так:

  1. Пользователи вводят данные своей кредитной карты и нажимают "Далее."

  2. Пользователи вводят информацию о своем адресе (профиль клиента), затем нажимают "Далее."

В рабочем процессе торговли по умолчанию пользователи вводят данные своей кредитной карты и адрес на той же странице.

Я хочу разделить информацию о кредитной карте и адресную информацию на разные страницы.

Как я могу это сделать безопасно?

Зачем это делать?

Потому что, если пользователь допускает ошибку при вводе своего адреса и проверка не выполняется, он также сбрасывает информацию о кредитной карте. Я хочу, чтобы пользователь вводил информацию о кредитной карте и адресе отдельно, чтобы в случае сбоя проверки им нужно было только повторно ввести ту или иную информацию.

 1
Author: Patrick Kenny, 2017-11-25

1 answers

Создание плагина потока оформления заказа может решить вашу проблему. Создайте плагин в своем пользовательском модуле, как показано в примере ниже:

namespace Drupal\my_checkout_flow\Plugin\Commerce\CheckoutFlow;

use Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowWithPanesBase;
use Drupal\Core\Form\FormStateInterface;

/**
 * @CommerceCheckoutFlow(
 *  id = "custom_checkout_flow",
 *  label = @Translation("Custom checkout flow"),
 * )
 */
class CustomCheckoutFlow extends CheckoutFlowWithPanesBase {

  /**
   * {@inheritdoc}
   */
  public function getSteps() {
    return [
      'login' => [
        'label' => $this->t('Login'),
        'previous_label' => $this->t('Return to login'),
        'has_order_summary' => FALSE,
      ],
      'card_info' => [
        'label' => $this->t('Card information'),
        'previous_label' => $this->t('Return to Card information'),
        'next_label' => $this->t('Continue to Card information'),
        'has_order_summary' => FALSE,
      ],
      'address_information' => [
        'label' => $this->t('Address information'),
        'previous_label' => $this->t('Return to Address information'),
        'next_label' => $this->t('Continue to Address information'),
        'has_order_summary' => FALSE,
      ],
      'review' => [
        'label' => $this->t('Review'),
        'has_order_summary' => TRUE,
      ],
    ] + parent::getSteps();
  }

}

После создания плагина вам необходимо изменить настройки процесса оформления заказа для вашего типа заказа.

Для получения дополнительной информации посетите: https://docs.drupalcommerce.org/commerce2/developer-guide/checkout/create-custom-checkout-flow


Обновление

Пользовательский поток проверки

<?php

namespace Drupal\my_checkout_flow\Plugin\Commerce\CheckoutFlow;

use Drupal\commerce_checkout\Plugin\Commerce\CheckoutFlow\CheckoutFlowWithPanesBase;

/**
 * @CommerceCheckoutFlow(
 *  id = "custom_checkout_flow",
 *  label = @Translation("Custom checkout flow"),
 * )
 */
class CustomCheckoutFlow extends CheckoutFlowWithPanesBase {

  /**
   * {@inheritdoc}
   */
  public function getSteps() {
    return [
      'login' => [
        'label' => $this->t('Login'),
        'previous_label' => $this->t('Go back'),
        'has_sidebar' => FALSE,
      ],
      'card_information' => [
        'label' => $this->t('Card information'),
        'previous_label' => $this->t('Go back'),
        'has_sidebar' => TRUE,
      ],
      'order_information' => [
        'label' => $this->t('Order information'),
        'has_sidebar' => TRUE,
        'next_label' => $this->t('Continue to Order information'),
        'previous_label' => $this->t('Go back'),
      ],
      'review' => [
        'label' => $this->t('Review'),
        'next_label' => $this->t('Continue to review'),
        'previous_label' => $this->t('Go back'),
        'has_sidebar' => TRUE,
      ],
    ] + parent::getSteps();
  }

}

Затем создайте контрольные области, как показано ниже:

Информация о выставлении счетов

<?php

namespace Drupal\my_checkout_flow\Plugin\Commerce\CheckoutPane;

use \Drupal\commerce_checkout\Plugin\Commerce\CheckoutPane\BillingInformation;

/**
 * Provides the billing information pane.
 *
 * @CommerceCheckoutPane(
 *   id = "custom_billing_information",
 *   label = @Translation("Billing information"),
 *   default_step = "order_information",
 *   wrapper_element = "fieldset",
 * )
 */
class CustomBillingInformation extends BillingInformation {

}

Информация об оплате

<?php
namespace Drupal\my_checkout_flow\Plugin\Commerce\CheckoutPane;

use Drupal\commerce_payment\Plugin\Commerce\CheckoutPane\PaymentInformation as PaymentInformationBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;

/**
 * Provides the payment information pane.
 *
 * @CommerceCheckoutPane(
 *   id = "custom_commerce_payment_information",
 *   label = @Translation("Custom Payment information"),
 *   display_label = @Translation("Payment information"),
 *   default_step = "order_information",
 *   wrapper_element = "fieldset",
 * )
 */
class PaymentInformation extends PaymentInformationBase {

  /**
   * {@inheritdoc}
   */
  public function buildPaneForm(array $pane_form, FormStateInterface $form_state, array &$complete_form) {
    $pane_form = parent::buildPaneForm($pane_form, $form_state, $complete_form);

    // Add an after build callback in order to make modifications on the address form.
    $pane_form['#after_build'][] = [$this, 'paneFormAfterBuild'];

    return $pane_form;
  }

  /**
   * After build callback for the pane form.
   */
  public function paneFormAfterBuild(array $pane_form, FormStateInterface $form_state) {
    // Get billing form element. Where it is located depends on the payment method that is chosen.
    if (isset($pane_form['add_payment_method']['billing_information'])) {
      $billing_form = &$pane_form['add_payment_method']['billing_information'];
    }
    elseif (isset($pane_form['billing_information'])) {
      $billing_form = &$pane_form['billing_information'];
    }
    else {
      // No billing information found.
      return $pane_form;
    }

    // Get the address form element.
    $address_form = &$billing_form['address']['widget']['0']['address'];

    // Add element validation callback to autofill the address.
    $billing_form['#element_validate'] = array_merge(
      [[$this, 'profileSelectValidate']],
      \Drupal::service('element_info')->getInfoProperty('commerce_profile_select', '#element_validate', [])
    );

    // Set all address fields to non-required.
    foreach (Element::children($address_form) as $key) {
      $address_form[$key]['#required'] = FALSE;
    }

    // Hide the address form.
    $address_form['#access'] = FALSE;

    return $pane_form;
  }

  /**
   * Element validation callback for the profile select element.
   */
  public function profileSelectValidate(array &$element, FormStateInterface $form_state) {
    $billing_profile = $this->order->getBillingProfile()->get('address')->getValue();
    $form_state->setValue($element['address']['widget'][0]['address']['#parents'], $billing_profile[0]);
  }

}

Процесс оплаты

<?php

namespace Drupal\my_checkout_flow\Plugin\Commerce\CheckoutPane;

use Drupal\commerce_payment\Plugin\Commerce\CheckoutPane\PaymentProcess as BasePaymentProcess;

/**
 * Provides the payment process pane.
 *
 * @CommerceCheckoutPane(
 *   id = "custom_payment_process",
 *   label = @Translation("Custom Payment process"),
 *   default_step = "payment",
 *   wrapper_element = "container",
 * )
 */
class PaymentProcess extends BasePaymentProcess {

  /**
   * {@inheritdoc}
   */
  public function isVisible() {
    // This pane can't be used without the PaymentInformation pane.
    $payment_info_pane = $this->checkoutFlow->getPane('custom_commerce_payment_information');
    return $payment_info_pane->isVisible() && $payment_info_pane->getStepId() != '_disabled';
  }

}

После этого установите панели оформления заказа для вашего пользовательского потока оформления заказа, как показано на рисунке ниже:

enter image description here

Найти полный код в https://github.com/patilvishalvs/my_checkout_flow

 4
Author: Vishal Patil, 2017-11-30 13:18:02