Можно ли собирать информацию о кредитной карте и адресную информацию на отдельных страницах в Commerce 2?
Я хочу, чтобы мой процесс оформления заказа выглядел так:
Пользователи вводят данные своей кредитной карты и нажимают "Далее."
Пользователи вводят информацию о своем адресе (профиль клиента), затем нажимают "Далее."
В рабочем процессе торговли по умолчанию пользователи вводят данные своей кредитной карты и адрес на той же странице.
Я хочу разделить информацию о кредитной карте и адресную информацию на разные страницы.
Как я могу это сделать безопасно?
Зачем это делать?
Потому что, если пользователь допускает ошибку при вводе своего адреса и проверка не выполняется, он также сбрасывает информацию о кредитной карте. Я хочу, чтобы пользователь вводил информацию о кредитной карте и адресе отдельно, чтобы в случае сбоя проверки им нужно было только повторно ввести ту или иную информацию.
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';
}
}
После этого установите панели оформления заказа для вашего пользовательского потока оформления заказа, как показано на рисунке ниже:
Найти полный код в https://github.com/patilvishalvs/my_checkout_flow