web-dev-qa-db-ja.com

チェックアウト中に請求先住所を要求しないでください

デフォルトでは、Commerce 2はすべての注文のクレジットカード情報+住所情報(名前、住所、および会社名)を要求します。ユーザーにクレジットカード情報を入力してもらいたいが、名前、住所、または会社名を収集したくない。 ストライプは名前/アドレス情報を必要としません なので、私もそれを要求したくありません。

私の支払いゲートウェイとして Commerce Stripe を使用していますが、これは Commerce PaypalManualなどのすべての支払いゲートウェイに適用されます(クレジットカードなし)支払いゲートウェイ。

では、チェックアウトページから住所フォームを安全に削除するにはどうすればよいですか?

私は最初に直接コマースをハックしようとしましたが(悪い習慣、それがどのように機能するかを確認しようとしただけです)、モジュールを壊しました。

周りを見回してみると、請求情報がCommerceコードに深く関連しているように見えました。それを分離する方法はありますか?すべての店舗(デジタル製品などを販売する店舗)が顧客の住所を必要とするわけではありません。

チェックアウトの「支払い情報」画面で、「国」から「郵便番号」までのすべてのフィールドを削除します。

commerce checkout screen

3
Patrick Kenny

実際、 drupal.orgのこのスレッドによると 、請求フォームを非表示にしてCommerce Stripeが引き続き機能するという事実は異常です。通常、これによりCommerceがクラッシュします。

現時点では、Commerce 2には請求先住所が必要です。

Drupal.orgに 実験パッチ および Commerceが請求先住所を必要とする理由の説明 があります。

0
Patrick Kenny

確かにそれを行うのはかなり難しいです。これを行う1つの方法は、ダミーの請求先住所を設定し、住所フォームを非表示にすることです。

次のことを行う必要があります。

  1. カスタムモジュールで、CommerceCheckoutPaneプラグインを追加します。プラグインクラスは\ Drupal\commerce_payment\Plugin\Commerce\CheckoutPane\PaymentInformationを拡張する必要があります。
  2. そこにあるbuildPaneForm()メソッドをオーバーライドします。

    • #after_buildコールバックを設定します。このコールバックでは、各住所フィールドを必須にしないでください。 #after_buildコールバックが必要なのは、それ以外の場合は住所フィールドが使用できないためです。
    • Commerce_profile_select要素で、#element_validateコールバックを設定します。このコールバックで、アドレス値を設定します。 #element_validateが必要なのは、一般的なフォーム検証コールバックが検証プロセスで呼び出されずにアドレスを設定できないためです。これは、住所要素に制約があり、#element_validateの後、一般的なフォームが検証される前に、住所がこの制約に対して検証されるためです。一般的なフォーム検証コールバックで住所を設定しようとすると、制約のために住所フィールドに必要なエラーが発生します。

      #element_validateコールバックは#after_buildコールバックでも設定できます。これは、以下のコード例で行いました。

  3. アドレスフォームを非表示にするには、アドレスフォームの#accessFALSEに設定する必要があります。以前のアドレスフォームはまだ利用できないため、これは#after_buildコールバックでも発生する必要があります。
  4. チェックアウトフロー設定で、デフォルトの支払い情報ペインを無効にします(まだ有効になっていない場合は、カスタム支払い情報ペインを有効にします)。
  5. 「確認」ステップでダミーの請求先住所を非表示にするには、テンプレートcommerce-payment-method--credit-card.html.twig(および/またはcommerce-payment-method.html.twigを使用している場合は、クレジットカード支払い方法)をテーマに追加し、_{{ payment_method.billing_profile }}行を削除します。

コード例(ファイル名:mymodule/src/Plugin/Commerce/CheckoutPane/PaymentInformation.php):

namespace Drupal\custom_commerce\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) {
    // Set dummy address.
    $address = [
      'given_name' => 'A',
      'family_name' => 'A',
      'address_line1' => 'Dummy street',
      'postal_code' => '1234 AB',
      'locality' => 'Dummy city',
      'country_code' => 'NL',
    ];
    $form_state->setValue($element['address']['widget'][0]['address']['#parents'], $address);
  }

}
4
MegaChriz

TL:DR;

admin/config/people/profiles/types/manage/customer/form-displayに移動し、非表示にするフォーム要素を無効にします(設定はサイト全体に適用されます)

説明

これは簡単にできるはずですが、私自身はこれをテストしていないことを前もって言っておきます。

住所として表示されているのは「請求プロファイル」です(注文と支払い方法の両方に請求プロファイルIIRCがあります。DCは請求プロファイル自体を作成していません(Drupal 7とは異なります)しかし、代わりにプロファイルモジュールを使用しています。

DCが「請求プロファイル」または「請求情報」をレンダリングするとき、それは使用するプロファイルタイプ(顧客)に対して行われたグローバル設定に従います。つまり、すべての要素を無効にするなど、フォームの表示方法を設定できます。これはadmin/config/people/profiles/types/manage/customer/form-displayで行うことができます。これは、DC自体に触れずにさらに情報を収集したい場合は、プロファイルにフィールドを追加できることも意味します。

免責事項-私はこれを自分でテストしていませんが、商取引をかなり台無しにしたので、これが機能することを確信しています。

3
googletorp