Skip to content
Snippets Groups Projects
Commit 54cba127 authored by Anas Mawlawi's avatar Anas Mawlawi Committed by Anas Mawlawi
Browse files

Issue #3364230 by Anas_maw: Support latest copy and pay API

parent 2bd90d51
No related branches found
No related tags found
No related merge requests found
name: Commerce Hyperpay
type: module
description: 'Provides Commerce integration for Hyperpay Payments.'
description: "Provides Commerce integration for Hyperpay Payments."
package: Commerce (contrib)
core: 8.x
core_version_requirement: ^8.8 || ^9
dependencies:
- commerce:commerce_payment
commerce_payment.commerce_payment_gateway.plugin.hyperpay_gateway_checkout:
type: commerce_payment_gateway_configuration
mapping:
user_id:
test_mode_type:
type: string
label: 'User ID'
password:
label: "Test Mode Type"
allowed_cards:
type: sequence
label: "Allowed Cards"
sequence:
type: string
auth_bearer:
type: string
label: 'Password'
label: "Authorization Bearer"
entity_id:
type: string
label: 'Entity ID'
label: "Entity ID"
reuse_payment_method:
type: boolean
label: "Allow reusing payment method"
entity_id_recurring:
type: string
label: "Entity ID (Recurring)"
widget_style:
type: string
label: "Widget Style"
var wpwlOptions;
(function ($, Drupal, drupalSettings) {
'use strict';
"use strict";
Drupal.behaviors.initHyperpayPayment = {
attach: function (context) {
var $form = $(context).find('.paymentWidgets');
var $form = $(context).find(".paymentWidgets");
if ($form.length > 0) {
$form.once('hyperpay-payment-form').each(function () {
var hyperpay_settings = drupalSettings.commerce_hyperpay;
$form.once("hyperpay-payment-form").each(function () {
var hyperpay_settings = drupalSettings.commerce_hyperpay_pg;
wpwlOptions = {
locale: hyperpay_settings.langcode
locale: hyperpay_settings.langcode,
style: hyperpay_settings.style,
};
var hyperpay = document.createElement('script');
hyperpay.type = 'text/javascript';
hyperpay.src = hyperpay_settings.hyperpay_url;
var s = document.getElementsByTagName('script')[0];
var hyperpay = document.createElement("script");
hyperpay.type = "text/javascript";
hyperpay.src = hyperpay_settings.hyperpay_url;
var s = document.getElementsByTagName("script")[0];
s.parentNode.insertBefore(hyperpay, s);
});
}
}
},
};
})(jQuery, Drupal, drupalSettings);
......@@ -3,10 +3,11 @@
namespace Drupal\commerce_hyperpay\Plugin\Commerce\PaymentGateway;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\OffsitePaymentGatewayInterface;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsRefundsInterface;
/**
* Provides the interface for the HyperPay payment gateway.
*/
interface HyperPayInterface extends OffsitePaymentGatewayInterface {
interface HyperPayInterface extends OffsitePaymentGatewayInterface, SupportsRefundsInterface {
}
......@@ -4,7 +4,7 @@ namespace Drupal\commerce_hyperpay\PluginForm;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_payment\PluginForm\PaymentOffsiteForm as BasePaymentOffsiteForm;
use Drupal\commerce_price\NumberFormatterFactoryInterface;
use CommerceGuys\Intl\Formatter\CurrencyFormatterInterface;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
......@@ -17,31 +17,31 @@ use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides the Hyperpay plugin form.
*/
class HyperpayForm extends BasePaymentOffsiteForm implements ContainerInjectionInterface {
class HyperPayCopyAndPayForm extends BasePaymentOffsiteForm implements ContainerInjectionInterface {
use StringTranslationTrait;
/**
* The currency storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $currencyStorage;
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* The number formatter.
*
* @var \CommerceGuys\Intl\Formatter\NumberFormatterInterface
* @var \CommerceGuys\Intl\Formatter\CurrencyFormatterInterface
*/
protected $numberFormatter;
protected $currencyFormatter;
/**
* Constructs a new HyperpayForm object.
*
......@@ -49,18 +49,17 @@ class HyperpayForm extends BasePaymentOffsiteForm implements ContainerInjectionI
* The entity type manager.
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
* @param \Drupal\commerce_price\NumberFormatterFactoryInterface $number_formatter_factory
* @param \CommerceGuys\Intl\Formatter\CurrencyFormatterInterface $currency_formatter
* The number formatter factory.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
*/
public function __construct(EntityTypeManagerInterface $entity_type_manager, LanguageManagerInterface $language_manager, NumberFormatterFactoryInterface $number_formatter_factory) {
public function __construct(EntityTypeManagerInterface $entity_type_manager, LanguageManagerInterface $language_manager, CurrencyFormatterInterface $currency_formatter) {
$this->currencyStorage = $entity_type_manager->getStorage('commerce_currency');
$this->languageManager = $language_manager;
$this->numberFormatter = $number_formatter_factory->createInstance();
$this->numberFormatter->setMaximumFractionDigits(2);
$this->currencyFormatter = $currency_formatter;
}
/**
* {@inheritdoc}
*/
......@@ -68,26 +67,26 @@ class HyperpayForm extends BasePaymentOffsiteForm implements ContainerInjectionI
return new static(
$container->get('entity_type.manager'),
$container->get('language_manager'),
$container->get('commerce_price.number_formatter_factory')
$container->get('commerce_price.currency_formatter')
);
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
/** @var \Drupal\commerce_payment\Entity\PaymentInterface $payment */
$payment = $this->entity;
$order = $payment->getOrder();
/** @var \Drupal\commerce_hyperpay\Plugin\Commerce\PaymentGateway\HyperPayInterface $hyperpay_gateway */
$hyperpay_gateway = $payment->getPaymentGateway()->getPlugin();
$payment_amount = $hyperpay_gateway->getPayableAmount($order);
$payment->setAmount($payment_amount);
$request_params = [
'currency' => $payment_amount->getCurrencyCode(),
'amount' => $payment_amount->getNumber(),
......@@ -96,60 +95,61 @@ class HyperpayForm extends BasePaymentOffsiteForm implements ContainerInjectionI
'customer.email' => $order->getEmail(),
'customer.ip' => $order->getIpAddress(),
];
$customer = $order->getCustomer();
if ($customer && $customer->isAuthenticated()) {
$request_params['customer.merchantCustomerId'] = $customer->id();
}
$billing_profile = $order->getBillingProfile();
/** @var \Drupal\address\AddressInterface|null $billing_address */
$billing_address = $billing_profile
&& $billing_profile->hasField('address')
&& !$billing_profile->get('address')->isEmpty() ?
$billing_profile->address->first() : NULL;
if ($billing_address) {
$request_params['customer.givenName'] = $billing_address->getGivenName();
$request_params['customer.surname'] = $billing_address->getFamilyName();
if ($company = $billing_address->getOrganization()) {
$request_params['customer.companyName'] = $company;
}
$request_params['billing.street1'] = $billing_address->getAddressLine1();
$request_params['billing.street2'] = $billing_address->getAddressLine2();
$request_params['billing.city'] = $billing_address->getLocality();
$request_params['billing.state'] = $billing_address->getAdministrativeArea();
$request_params['billing.postcode'] = $billing_address->getPostalCode();
$request_params['billing.country'] = $billing_address->getCountryCode();
}
$shipping_profile = $this->getShippingProfile($order);
/** @var \Drupal\address\AddressInterface|null $shipping_address */
$shipping_address = $shipping_profile
&& $shipping_profile->hasField('address')
&& !$shipping_profile->get('address')->isEmpty() ?
$shipping_profile->address->first() : NULL;
if ($shipping_address) {
$request_params['shipping.customer.email'] = $order->getEmail();
$request_params['shipping.customer.ip'] = $order->getIpAddress();
$request_params['shipping.customer.givenName'] = $shipping_address->getGivenName();
$request_params['shipping.customer.surname'] = $shipping_address->getFamilyName();
if ($company = $shipping_address->getOrganization()) {
$request_params['shipping.customer.companyName'] = $company;
}
$request_params['shipping.street1'] = $shipping_address->getAddressLine1();
$request_params['shipping.street2'] = $shipping_address->getAddressLine2();
$request_params['shipping.city'] = $shipping_address->getLocality();
$request_params['shipping.postcode'] = $shipping_address->getPostalCode();
$request_params['shipping.country'] = $shipping_address->getCountryCode();
}
$request_params['merchantTransactionId'] = $order->id();
$checkout_id = $hyperpay_gateway->prepareCheckout($request_params);
// Set the checkout ID as (temporary) remote ID. On actual payment, we will
// receive the real payment ID and we will use that as our remote ID then.
$payment->setRemoteId($checkout_id);
......@@ -157,22 +157,33 @@ class HyperpayForm extends BasePaymentOffsiteForm implements ContainerInjectionI
$authorize_transition = $payment->getState()->getWorkflow()->getTransition('authorize');
$payment->getState()->applyTransition($authorize_transition);
$payment->save();
$script_url = sprintf("%s/v1/paymentWidgets.js?checkoutId=%s", $hyperpay_gateway->getApiUrl(), $checkout_id);
$js_settings = [
'hyperpay_url' => $script_url,
'langcode' => $this->languageManager->getCurrentLanguage()->getId(),
'style' => $hyperpay_gateway->getConfiguration()['widget_style'],
];
$form['#attached']['drupalSettings']['commerce_hyperpay'] = $js_settings;
$form['#attached']['library'][] = 'commerce_hyperpay/init';
/** @var \Drupal\commerce_price\Entity\CurrencyInterface $currency */
$currency = $this->currencyStorage->load($payment_amount->getCurrencyCode());
$amount_formatted = $this->t('Amount to be paid: @amount', ['@amount' => $this->numberFormatter->formatCurrency($payment_amount->getNumber(), $currency)]);
$amount_formatted = $this->t('Amount to be paid: @amount', [
'@amount' => $this->currencyFormatter->format($payment_amount->getNumber(), $payment_amount->getCurrencyCode(), ['maximum_fraction_digits' => 2]),
]);
$allowed_cards_array = $hyperpay_gateway->getConfiguration()['allowed_cards'];
$allowed_cards = '';
foreach ($allowed_cards_array as $key => $value) {
if ($value) {
empty($allowed_cards) ? $allowed_cards .= $value : $allowed_cards .= ' ' . $value;
}
}
$form['cards'] = [
'#type' => 'hidden',
'#value' => 'VISA MASTER MASTERDEBIT MAESTRO DISCOVER AMEX',
'#value' => $allowed_cards,
// Plugin forms are embedded using #process, so it's too late to attach
// another #process to $form itself, it must be on a sub-element.
'#process' => [
......@@ -182,12 +193,11 @@ class HyperpayForm extends BasePaymentOffsiteForm implements ContainerInjectionI
'#cancel_url' => $form['#cancel_url'],
'#amount' => $amount_formatted,
];
// No need to call buildRedirectForm(), as we embed an iframe.
return $form;
}
/**
* Prepares the complete form in order to work with Hyperpay.
*
......@@ -208,18 +218,18 @@ class HyperpayForm extends BasePaymentOffsiteForm implements ContainerInjectionI
$complete_form['#action'] = $element['#action'];
$complete_form['#attributes']['class'][] = 'paymentWidgets';
$complete_form['#attributes']['data-brands'] = $element['#value'];
if (!empty($element['#amount'])) {
$complete_form['#prefix'] = $element['#amount'];
}
// As the Hyperpay fully replaces the HTML form, we need to place the
// cancel link outside the form as suffix.
$complete_form['#suffix'] = Link::fromTextAndUrl(t('Cancel'), Url::fromUri($element['#cancel_url']))->toString();
return $element;
}
/**
* Gets the shipping profile, if exists.
*
......@@ -244,7 +254,8 @@ class HyperpayForm extends BasePaymentOffsiteForm implements ContainerInjectionI
return $shipment->getShippingProfile();
}
}
return NULL;
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment