From e685eedda86bd8c553d9f89019f6d254b6df3a66 Mon Sep 17 00:00:00 2001
From: Elaman Imashov <1479020+elaman@users.noreply.github.com>
Date: Mon, 27 Apr 2026 08:51:29 -0400
Subject: [PATCH] Initial commit.

---
 commerce_webform_order.module                 |   6 +
 src/Plugin/WebformElement/PaypalSmartButtons.php     | 166 ++++++++++++++++++
 templates/webform-element-commerce-paypal-smart-buttons.html.twig |  15 ++
 3 files changed, 187 insertions(+)
 create mode 100644 src/Plugin/WebformElement/PaypalSmartButtons.php
 create mode 100644 templates/webform-element-commerce-paypal-smart-buttons.html.twig

diff --git a/commerce_webform_order.module b/commerce_webform_order.module
index fedebb6..b2c3e1a 100644
--- a/commerce_webform_order.module
+++ b/commerce_webform_order.module
@@ -39,6 +39,12 @@ function commerce_webform_order_commerce_checkout_pane_info_alter(&$definitions)
  */
 function commerce_webform_order_theme() {
   return [
+    'webform_element_commerce_paypal_smart_buttons' => [
+      'variables' => [
+        'gateway_id' => '',
+        'smart_buttons' => '',
+      ],
+    ],
     'webform_element_commerce_stripe_express_checkout' => [
       'variables' => [
         'gateway_id' => '',
diff --git a/src/Plugin/WebformElement/PaypalSmartButtons.php b/src/Plugin/WebformElement/PaypalSmartButtons.php
new file mode 100644
index 0000000..742fcd0
--- /dev/null
+++ b/src/Plugin/WebformElement/PaypalSmartButtons.php
@@ -0,0 +1,166 @@
+<?php
+
+namespace Drupal\commerce_webform_order\Plugin\WebformElement;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\webform\Plugin\WebformElementBase;
+use Drupal\webform\WebformSubmissionInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+
+/**
+ * Provides an embedding of "PayPal Smart Buttons" experience.
+ *
+ * @WebformElement(
+ *   id = "commerce_webform_order_paypal_smart_buttons",
+ *   label = @Translation("PayPal Smart Buttons"),
+ *   description = @Translation("Renders a commerce PayPal Smart Buttons element."),
+ *   category = @Translation("Commerce"),
+ * )
+ */
+class PayPalSmartButtons extends WebformElementBase {
+
+  /**
+   * The entity type manager.
+   *
+   * @var \Drupal\Core\Entity\EntityTypeManagerInterface
+   */
+  protected $entityTypeManager;
+
+  /**
+   * The cart provider.
+   *
+   * @var \Drupal\commerce_cart\CartProviderInterface
+   */
+  protected $cartProvider;
+
+  /**
+   * The express checkout buttons builder.
+   *
+   * @var \Drupal\commerce_paypal\SmartPaymentButtonsBuilderInterface
+   */
+  protected $buttonsBuilder;
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    $instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
+    $instance->entityTypeManager = $container->get('entity_type.manager');
+    $instance->cartProvider = $container->get('commerce_cart.cart_provider');
+    $instance->buttonsBuilder = $container->get('commerce_paypal.smart_payment_buttons_builder');
+
+    return $instance;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  protected function defineDefaultProperties() {
+    $properties = [
+        'gateway_id' => '',
+      ] + parent::defineDefaultProperties();
+
+    unset(
+      $properties['required'],
+      $properties['required_error'],
+      $properties['unique'],
+      $properties['unique_user'],
+      $properties['unique_entity'],
+      $properties['unique_error'],
+    );
+
+    return $properties;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function form(array $form, FormStateInterface $form_state) {
+    $form = parent::form($form, $form_state);
+    $form['gateway_id'] = [
+      '#type' => 'textfield',
+      '#title' => $this->t('Payment Gateway Identifier'),
+      '#description' => $this->t('Enter a specific Gateway ID to render that provider. If left blank, the first
+        supported gateway (PayPal Smart Buttons) will be used by default.'),
+      '#default_value' => '100%',
+    ];
+
+    return $form;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function prepare(array &$element, ?WebformSubmissionInterface $webform_submission = NULL) {
+    parent::prepare($element, $webform_submission);
+
+    $element['#theme'] = 'webform_element_commerce_paypal_smart_buttons';
+
+    if (empty($element['#gateway_id'])) {
+      $element['#gateway_id'] = $this->getDefaultProperty('gateway_id');
+    }
+
+    // Empty by default.
+    $element['#smart_buttons'] = '';
+
+    // Get the list of the carts.
+    $carts = array_values($this->cartProvider->getCarts());
+    if (empty($carts)) {
+      return;
+    }
+
+    $gateway_id = $element['#gateway_id'];
+
+    /** @var \Drupal\commerce_payment\PaymentGatewayStorageInterface $payment_gateway_storage */
+    $payment_gateway_storage = $this->entityTypeManager->getStorage('commerce_payment_gateway');
+
+    if (!empty($gateway_id)) {
+      $payment_gateways = $payment_gateway_storage->loadByProperties([
+        'id' => $gateway_id,
+        'status' => 1,
+        'plugin' => 'paypal_checkout',
+        'configuration.payment_solution' => 'smart_payment_buttons',
+        'configuration.enable_on_cart' => true,
+      ]);
+    }
+
+    // Get all published gateways.
+    if (empty($payment_gateways)) {
+      $payment_gateways = $payment_gateway_storage->loadByProperties([
+        'status' => 1,
+        'plugin' => 'paypal_checkout',
+        'configuration.payment_solution' => 'smart_payment_buttons',
+        'configuration.enable_on_cart' => true,
+      ]);
+    }
+    // Can't proceed without any payment gateways.
+    if (empty($payment_gateways)) {
+      return;
+    }
+
+    // Add the rendered element.
+    $element['#smart_buttons'] = $this->buttonsBuilder->build($carts[0], array_values($payment_gateways)[0], true);
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isInput(array $element) {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function isContainer(array $element) {
+    return FALSE;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public function hasValue(array $element, WebformSubmissionInterface $webform_submission, array $options = []) {
+    return FALSE;
+  }
+
+}
diff --git a/templates/webform-element-commerce-paypal-smart-buttons.html.twig b/templates/webform-element-commerce-paypal-smart-buttons.html.twig
new file mode 100644
index 0000000..31affe9
--- /dev/null
+++ b/templates/webform-element-commerce-paypal-smart-buttons.html.twig
@@ -0,0 +1,15 @@
+{#
+/**
+ * @file
+ * Default theme implementation for a webform paypal smart buttons element.
+ *
+ * Available variables:
+ * - gateway_id: Commerce gateway id.
+ * - smart_buttons: The rendred buttons html-code.
+ *
+ * @ingroup themeable
+ */
+#}
+{% if smart_buttons %}
+  {{ smart_buttons }}
+{% endif %}
-- 
GitLab