commerce_paypal.module in Commerce PayPal 8
Same filename and directory in other branches
Implements PayPal payment services for use with Drupal Commerce.
File
commerce_paypal.moduleView source
<?php
/**
* @file
* Implements PayPal payment services for use with Drupal Commerce.
*/
use Drupal\commerce_checkout\Entity\CheckoutFlowInterface;
use Drupal\commerce_payment\Entity\PaymentGateway;
use Drupal\commerce_paypal\Plugin\Commerce\PaymentGateway\CheckoutInterface;
use Drupal\commerce_price\Calculator;
use Drupal\Core\Access\AccessResult;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
/**
* Implements hook_theme().
*/
function commerce_paypal_theme() {
$theme = [
'commerce_paypal_checkout_custom_card_fields' => [
'variables' => [],
],
];
return $theme;
}
/**
* Implements hook_form_BASE_FORM_ID_alter().
*/
function commerce_paypal_form_views_form_commerce_cart_form_default_alter(&$form, FormStateInterface $form_state, $form_id) {
/** @var \Drupal\views\ViewExecutable $view */
$view = reset($form_state
->getBuildInfo()['args']);
// Only add the smart payment buttons if the cart form view has order items.
if (empty($view->result)) {
return;
}
$entity_type_manager = \Drupal::entityTypeManager();
$order_id = $view->args[0];
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $entity_type_manager
->getStorage('commerce_order')
->load($order_id);
// Skip injecting the smart payment buttons if the order total is zero or
// negative.
if (!$order
->getTotalPrice() || !$order
->getTotalPrice()
->isPositive()) {
return;
}
/** @var \Drupal\commerce_payment\PaymentGatewayStorageInterface $payment_gateway_storage */
$payment_gateway_storage = $entity_type_manager
->getStorage('commerce_payment_gateway');
// Load the payment gateways. This fires an event for filtering the
// available gateways, and then evaluates conditions on all remaining ones.
$payment_gateways = $payment_gateway_storage
->loadMultipleForOrder($order);
// Can't proceed without any payment gateways.
if (empty($payment_gateways)) {
return;
}
foreach ($payment_gateways as $payment_gateway) {
$payment_gateway_plugin = $payment_gateway
->getPlugin();
if (!$payment_gateway_plugin instanceof CheckoutInterface) {
continue;
}
$config = $payment_gateway_plugin
->getConfiguration();
// We only inject the Smart payment buttons on the cart page if the
// configured payment solution is "smart_payment_buttons" and if the
// "enable_on_cart" setting is TRUE.
if ($payment_gateway_plugin
->getPaymentSolution() !== 'smart_payment_buttons' || !$config['enable_on_cart']) {
continue;
}
/** @var \Drupal\commerce_paypal\SmartPaymentButtonsBuilderInterface $builder */
$builder = \Drupal::service('commerce_paypal.smart_payment_buttons_builder');
$form['paypal_smart_payment_buttons'] = $builder
->build($order, $payment_gateway, FALSE);
break;
}
}
/**
* Implements hook_form_BASE_FORM_ID_alter() for commerce_checkout_flow.
*/
function commerce_paypal_form_commerce_checkout_flow_alter(&$form, FormStateInterface $form_state) {
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = \Drupal::routeMatch()
->getParameter('commerce_order');
// Loop over the payment methods to remove potentially duplicate PayPal
// options (See http://www.drupal.org/project/commerce_paypal/issues/3154770).
if (isset($form['payment_information']['payment_method'], $form['payment_information']['#payment_options'])) {
/** @var \Drupal\commerce_payment\PaymentOption $payment_option */
$paypal_checkout_options_count = 0;
foreach ($form['payment_information']['#payment_options'] as $key => $payment_option) {
/** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $payment_gateway */
$payment_gateway = PaymentGateway::load($payment_option
->getPaymentGatewayId());
$plugin = $payment_gateway
->getPlugin();
if ($plugin instanceof CheckoutInterface && $plugin
->getPaymentSolution() === 'smart_payment_buttons') {
$paypal_checkout_options_count++;
// This will ensure we only keep the first paypal checkout option found.
if ($paypal_checkout_options_count > 1 && isset($form['payment_information']['payment_method']['#options'][$key])) {
unset($form['payment_information']['payment_method']['#options'][$key]);
}
}
}
}
// Inject the Smart payment buttons on the review page.
if ($form['#step_id'] !== 'review') {
return;
}
if ($order
->get('payment_gateway')
->isEmpty() || !$order
->get('payment_gateway')->entity || $order
->get('checkout_flow')->target_id === 'paypal_checkout') {
return;
}
// Skip injecting the smart payment buttons if the order total is zero or
// negative.
if (!$order
->getTotalPrice() || !$order
->getTotalPrice()
->isPositive()) {
return;
}
/** @var \Drupal\commerce_payment\Entity\PaymentGatewayInterface $payment_gateway */
$payment_gateway = $order
->get('payment_gateway')->entity;
$payment_gateway_plugin = $payment_gateway
->getPlugin();
if (!$payment_gateway_plugin instanceof CheckoutInterface || $payment_gateway_plugin
->getPaymentSolution() !== 'smart_payment_buttons') {
return;
}
/** @var \Drupal\commerce_paypal\SmartPaymentButtonsBuilderInterface $builder */
$builder = \Drupal::service('commerce_paypal.smart_payment_buttons_builder');
$form['paypal_smart_payment_buttons'] = $builder
->build($order, $payment_gateway, TRUE);
$form['actions']['#access'] = FALSE;
// Put back the "go back" link.
if (isset($form['actions']['next']['#suffix'])) {
$form['paypal_smart_payment_buttons']['#suffix'] = $form['actions']['next']['#suffix'];
}
}
/**
* Implements hook_ENTITY_TYPE_access().
*
* Forbids the "paypal_checkout" checkout flow from being deletable.
*/
function commerce_paypal_commerce_checkout_flow_access(CheckoutFlowInterface $checkout_flow, $operation, AccountInterface $account) {
if ($checkout_flow
->id() === 'paypal_checkout' && $operation === 'delete') {
return AccessResult::forbidden();
}
return AccessResult::neutral();
}
/**
* Implements hook_library_info_build().
*/
function commerce_paypal_library_info_build() {
// Only build the PayPal Credit messaging JS if a PayPal Client ID was set on
// the PayPal Credit messaging settings form.
$client_id = \Drupal::config('commerce_paypal.credit_messaging_settings')
->get('client_id');
if (!$client_id) {
return [];
}
$url = sprintf('https://www.paypal.com/sdk/js?client-id=%s&components=messages', $client_id);
$libraries['credit_messaging'] = [
'header' => TRUE,
'js' => [
$url => [
'type' => 'external',
'attributes' => [
'data-partner-attribution-id' => 'CommerceGuys_Cart_SPB',
],
],
],
];
return $libraries;
}
/**
* Implements hook_form_BASE_FORM_ID_alter().
*/
function commerce_paypal_form_commerce_order_item_add_to_cart_form_alter(&$form, FormStateInterface $form_state, $form_id) {
// Check to see if PayPal Credit messaging is enabled on Add to Cart forms.
$enable_messaging = \Drupal::config('commerce_paypal.credit_messaging_settings')
->get('add_to_cart');
/** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
$order_item = $form_state
->getFormObject()
->getEntity();
if (!$enable_messaging || !$order_item
->getUnitPrice()) {
return;
}
// Add Credit Messaging JS to the form.
// @todo ensure messaging reapplies after an Ajax refresh.
$form['#attached']['library'][] = 'commerce_paypal/credit_messaging';
$form['paypal_credit_messaging_product'] = [
'#type' => 'html_tag',
'#tag' => 'div',
'#attributes' => [
'data-pp-message' => '',
'data-pp-placement' => 'product',
'data-pp-amount' => Calculator::trim($order_item
->getUnitPrice()
->getNumber()),
],
'#weight' => 1,
];
}
/**
* Implements hook_js_alter().
*/
function commerce_paypal_js_alter(&$javascript, \Drupal\Core\Asset\AttachedAssetsInterface $assets) {
$client_id = \Drupal::config('commerce_paypal.credit_messaging_settings')
->get('client_id');
if (!$client_id) {
return;
}
$paypal_checkout_js = drupal_get_path('module', 'commerce_paypal') . '/js/paypal-checkout.js';
// The paypal-checkout JS file isn't present, no need to do anything.
if (!isset($javascript[$paypal_checkout_js])) {
return;
}
// Remove the extra JS SDK added for credit messaging library if present.
foreach ($javascript as $key => $js) {
if (strpos($key, 'https://www.paypal.com/sdk/js') === 0) {
unset($javascript[$key]);
break;
}
}
}
Functions
Name | Description |
---|---|
commerce_paypal_commerce_checkout_flow_access | Implements hook_ENTITY_TYPE_access(). |
commerce_paypal_form_commerce_checkout_flow_alter | Implements hook_form_BASE_FORM_ID_alter() for commerce_checkout_flow. |
commerce_paypal_form_commerce_order_item_add_to_cart_form_alter | Implements hook_form_BASE_FORM_ID_alter(). |
commerce_paypal_form_views_form_commerce_cart_form_default_alter | Implements hook_form_BASE_FORM_ID_alter(). |
commerce_paypal_js_alter | Implements hook_js_alter(). |
commerce_paypal_library_info_build | Implements hook_library_info_build(). |
commerce_paypal_theme | Implements hook_theme(). |