Skip to content
Snippets Groups Projects
Commit 94f4140e authored by Anas Mawlawi's avatar Anas Mawlawi
Browse files

Issue #3447301 by Anas_maw: 2.0.x release roadmap

parent b2aa812b
No related branches found
Tags 2.0.0
No related merge requests found
Showing
with 2826 additions and 608 deletions
# Commerce Paytabs
## CONTENTS OF THIS FILE
- Introduction
- Requirements
- Installation
- Configuration
- How it works
- Maintainers
## INTRODUCTION
**Commerce PayTabs** is [Drupal Commerce](https://drupal.org/project/commerce)
module that integrates the [paytabs.com](https://www.paytabs.com/) payement
gateway into your Drupal Commerce shop.
## REQUIREMENTS
This module requires the following:
- Submodules of Drupal Commerce package (https://drupal.org/project/commerce)
- Commerce core
- Commerce Payment (and its dependencies)
- Telephone
- paytabs.com account (test or live) (https://www.paytabs.com/)
## INSTALLATION
Open your terminal and download with composer.
composer require drupal/commerce_paytabs
OR
1. Download the module to your DRUPAL_ROOT/modules directory,
or where ever you install contrib modules on your site.
2. Go to Admin > Extend and enable the module.
## CONFIGURATION
- Create a new telephone field from /admin/config/people/profile-types/manage/customer/fields
to allow the user to enter thier phone number during checkout process.
- Create a new PayTabs Hosted page payment gateway.
Administration > Commerce > Configuration > Payment gateways > Add payment gateway
Paytabs hosted page specific settings available:
- Merchant Profile id
- Server Key
- Merchant region
- Pay Page Mode
- Integration Mode
- Customer profile telephone field, select the telephone field you created in the previous step
- Hide shipping address
- Order Status
- Allow reusing payment method
## HOW IT WORKS
- HostedPage
HostedPage payment has two options: Iframe embeded on the checkout page, or redirect to the payment page.
- 3DS support:
Handled by the HyperPay HostedPage.
- Checkout workflow:
It follows the Drupal Commerce Credit Card workflow.
The customer should enter his/her credit card data
or select one of the credit cards saved with Paytabs
from a previous order.
- Payment Terminal
The store owner can Void, Capture and Refund the PayTabs payments from the order page.
## MAINTAINERS
- Anas Mawlawi (Anas_maw) - <https://www.drupal.org/u/anas_maw>
- Yasser Samman (yasser-samman) - https://www.drupal.org/u/yasser-samman
This 2.0.x branch has been developed by:
- Coders Enterprise Web & Mobile Solutions: https://www.codersme.com/
Commerce PayTabs
Issues:
-------
Unfortunately, the cancel link on the pay page of PayTabs does not
cancel payments when redirected to Drupal commerce. It needs work.
Description
-----------
This module provides integration with the PayTabs payment gateway.
CONTENTS OF THIS FILE
---------------------
* Introduction
* Requirements
* Installation
* Configuration
INTRODUCTION
------------
This project integrates PayTabs online payments into
the Drupal Commerce payment and checkout systems.
REQUIREMENTS
------------
This module requires no external dependencies.
But make sure to enable the 'Telephone' core module.
INSTALLATION
------------
* You can install this module via Composer, or
* clone it from drupal.org Git repo, or
* Download the module from D.O and install it the usual way:
- Place it in the /modules or /modules/contrib directory
- Go to 'Extend' as an administrator, and
- Enable the module
CONFIGURATION
-------------
* Create new PayTabs payment gateway
Administration > Commerce > Configuration > Payment gateways > Add payment gateway
Provide the following settings:
- Merchant email.
- Secret key.
......@@ -2,6 +2,7 @@ name: Commerce Paytabs
type: module
description: 'Provides Paytabs payment integration for Drupal Commerce 2.x.'
package: Commerce
core: 8.x
core_version_requirement: ^9.5 || ^10
dependencies:
- commerce:commerce_payment
- drupal:telephone
<?php
hosted_page:
version: 1.3.0
js:
js/paytabs_hosted_page.js: {}
dependencies:
- core/jquery
- core/drupal
- core/once
- core/drupalSettings
langcode: en
status: true
dependencies:
config:
- field.storage.profile.telephone
- profile.type.customer
module:
- core
id: profile.customer.telephone
field_name: telephone
entity_type: profile
bundle: customer
label: Phone
description: 'International phone number format, example: +359888888888'
required: true
translatable: false
default_value: { }
default_value_callback: ''
settings: { }
field_type: telephone
langcode: en
status: true
dependencies:
enforced:
module:
- commerce_paytabs
module:
- core
- profile
id: profile.telephone
field_name: telephone
entity_type: profile
type: telephone
settings: { }
module: core
locked: true
cardinality: 1
translatable: true
indexes: { }
persist_with_no_fields: false
custom_storage: false
commerce_payment.commerce_payment_gateway.plugin.paytabs_offsite_redirect:
type: commerce_payment_gateway_configuration
mapping:
merchant_email:
profile_id:
type: string
label: 'Merchant email'
secret_key:
label: 'Profile id'
server_key:
type: string
label: 'Secret key'
label: 'Server key'
merchant_region:
type: string
label: 'region'
pay_page_mode:
type: string
label: 'Pay Page Mode'
iframe:
type: string
label: 'Iframe'
telephone_field:
type: string
label: 'Telephone field'
hide_shipping_address:
type: boolean
label: 'Hide shipping address'
complete_order_status:
type: string
label: 'complete order status'
reuse_payment_method:
type: boolean
label: "Allow reusing payment method"
(function ($, Drupal, drupalSettings) {
"use strict";
Drupal.behaviors.offsiteForm = {
attach: function (context) {
var ptLink = drupalSettings.commerce_paytabs.redirect_url;
var return_link = drupalSettings.commerce_paytabs.return_url;
var iframe = document.createElement("iframe");
iframe.width = "100%";
iframe.height = "900px";
iframe.id = "PaytabsIframe";
iframe.setAttribute("src", ptLink);
var $form = $(context).find(".checkout-pane");
if ($form.length > 0) {
$(once("#paymentWidgets", $form)).append(iframe);
}
},
};
})(jQuery, Drupal, drupalSettings);
This diff is collapsed.
This diff is collapsed.
......@@ -3,25 +3,13 @@
namespace Drupal\commerce_paytabs\Plugin\Commerce\PaymentGateway;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\OffsitePaymentGatewayInterface;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsAuthorizationsInterface;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsRefundsInterface;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\SupportsStoredPaymentMethodsInterface;
/**
* Provides the interface for the PayTabs payment gateway.
*/
interface PaytabsOffsiteRedirectInterface extends OffsitePaymentGatewayInterface, SupportsRefundsInterface {
/**
* Performs http request.
*
* @param string $api_uri
* The uri of the request.
* @param array $paytabs_data
* The order entity, or null.
*
* @return array
* Paytabs response data.
*
*/
public function doHttpRequest($api_uri, array $paytabs_data);
interface PaytabsInterface extends OffsitePaymentGatewayInterface, SupportsRefundsInterface, SupportsStoredPaymentMethodsInterface, SupportsAuthorizationsInterface {
}
<?php
namespace Drupal\commerce_paytabs\Plugin\Commerce\PaymentGateway;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_payment\Entity\PaymentInterface;
use Drupal\commerce_payment\Exception\PaymentGatewayException;
use Drupal\commerce_payment\PaymentMethodTypeManager;
use Drupal\commerce_payment\PaymentTypeManager;
use Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\OffsitePaymentGatewayBase;
use Drupal\commerce_price\Price;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use GuzzleHttp\ClientInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\Core\Url;
/**
* Provides the Off-site Redirect payment gateway.
*
* @CommercePaymentGateway(
* id = "paytabs_offsite_redirect",
* label = "Paytabs",
* display_label = "Paytabs",
* forms = {
* "offsite-payment" = "Drupal\commerce_paytabs\PluginForm\OffsiteRedirect\PaytabsOffsiteForm",
* },
* payment_method_types = {"credit_card"},
* credit_card_types = {
* "visa", "mastercard",
* },
* )
*/
class PaytabsOffsiteRedirect extends OffsitePaymentGatewayBase implements PaytabsOffsiteRedirectInterface {
/**
* The logger.
*
* @var \Drupal\Core\Logger\LoggerChannelInterface
*/
protected $logger;
/**
* The HTTP client.
*
* @var \GuzzleHttp\Client
*/
protected $httpClient;
/**
* The time.
*
* @var \Drupal\Component\Datetime\TimeInterface
*/
protected $time;
/**
* Module handler service.
*
* @var \Drupal\Core\Extension\ModuleHandlerInterface
*/
protected $moduleHandler;
/**
* Constructs a new PaytabsOffsiteRedirect object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\commerce_payment\PaymentTypeManager $payment_type_manager
* The payment type manager.
* @param \Drupal\commerce_payment\PaymentMethodTypeManager $payment_method_type_manager
* The payment method type manager.
* @param \Drupal\Component\Datetime\TimeInterface $time
* The time.
* @param \Drupal\Core\Logger\LoggerChannelFactoryInterface $logger_channel_factory
* The logger channel factory.
* @param \GuzzleHttp\ClientInterface $client
* The client.
* @param \Drupal\Core\Extension\ModuleHandlerInterface $module_handler
* The module handler.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager, PaymentTypeManager $payment_type_manager, PaymentMethodTypeManager $payment_method_type_manager, TimeInterface $time, LoggerChannelFactoryInterface $logger_channel_factory, ClientInterface $client, ModuleHandlerInterface $module_handler) {
parent::__construct($configuration, $plugin_id, $plugin_definition, $entity_type_manager, $payment_type_manager, $payment_method_type_manager, $time);
$this->logger = $logger_channel_factory->get('commerce_paytabs');
$this->httpClient = $client;
$this->moduleHandler = $module_handler;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager'),
$container->get('plugin.manager.commerce_payment_type'),
$container->get('plugin.manager.commerce_payment_method_type'),
$container->get('datetime.time'),
$container->get('logger.factory'),
$container->get('http_client'),
$container->get('module_handler')
);
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'merchant_email' => '',
'secret_key' => '',
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$form['merchant_email'] = [
'#type' => 'textfield',
'#title' => $this->t('Merchant email'),
'#required' => TRUE,
'#description' => $this->t('Your merchant email used to sign up with your PayTabs account.'),
'#attributes' => [
'placeholder' => \Drupal::config('system.site')->get('mail'),
],
'#default_value' => $this->configuration['merchant_email'],
];
$form['secret_key'] = [
'#type' => 'textfield',
'#required' => TRUE,
'#title' => $this->t('Secret Key'),
'#description' => $this->t('You can find the secret key on your PayTabs Merchant’s Dashboard - PayTabs Services - ecommerce Plugins and API.'),
'#default_value' => $this->configuration['secret_key'],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::validateConfigurationForm($form, $form_state);
if (!$form_state->getErrors() && $form_state->isSubmitted()) {
$values = $form_state->getValue($form['#parents']);
$this->configuration['merchant_email'] = $values['merchant_email'];
$this->configuration['secret_key'] = $values['secret_key'];
$api_uri = Url::fromUri('https://www.paytabs.com/apiv2/validate_secret_key')->toString();
$response = $this->doHttpRequest($api_uri, $values);
if (!$response->response_code == 4000) {
$form_state->setError($form, $this->t('Invalid API credentials.'));
}
}
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::submitConfigurationForm($form, $form_state);
if (!$form_state->getErrors()) {
$values = $form_state->getValue($form['#parents']);
$this->configuration['merchant_email'] = $values['merchant_email'];
$this->configuration['secret_key'] = $values['secret_key'];
}
}
/**
* {@inheritdoc}
*/
public function onReturn(OrderInterface $order, Request $request) {
// PayTabs returns payment_reference through a post request
$paytabs_data = [
'merchant_email' => $this->configuration['merchant_email'],
'secret_key' => $this->configuration['secret_key'],
'payment_reference' => $request->request->get('payment_reference'),
];
$api_uri = Url::fromUri('https://www.paytabs.com/apiv2/verify_payment')->toString();
try {
$resource = $this->doHttpRequest($api_uri, $paytabs_data);
if ($resource->response_code == 100) {
$payment_storage = $this->entityTypeManager->getStorage('commerce_payment');
$payment = $payment_storage->create([
'state' => 'completed',
'amount' => $order->getTotalPrice(),
'payment_gateway' => $this->entityId,
'order_id' => $order->id(),
'remote_id' => $resource->pt_invoice_id,
'remote_state' => $resource->result,
'authorized' => $this->time->getRequestTime(),
]);
$payment->save();
drupal_set_message($this->t('Your payment was successful with Order ID : @orderid', [
'@orderid' => $order->id(),
]));
}
if ($resource->response_code == 481 || $resource->response_code == 482) {
$payment_storage = $this->entityTypeManager->getStorage('commerce_payment');
$payment = $payment_storage->create([
'state' => 'authorization',
'amount' => $order->getTotalPrice(),
'payment_gateway' => $this->entityId,
'order_id' => $order->id(),
'remote_id' => $resource->pt_invoice_id,
'remote_state' => $resource->result,
'authorized' => $this->time->getRequestTime(),
]);
$payment->save();
$this->logger->alert('If this transaction is genuine, please contact PayTabs customer service to enquire about the feasibility of processing this transaction.');
}
} catch (PaymentGatewayException $e) {
$this->logger->error($e->getMessage());
}
}
/**
* {@inheritdoc}
*/
public function onCancel(OrderInterface $order, Request $request) {
// @TODO this function is not working - no ping is received from PayTabs
$status = $request->get('status');
drupal_set_message($this->t('Payment @status on @gateway but may resume the checkout process here when you are ready.', [
'@status' => $status,
'@gateway' => $this->getDisplayLabel(),
]), 'error');
}
/**
* {@inheritdoc}
*/
public function refundPayment(PaymentInterface $payment, Price $amount = NULL) {
// TODO: Implement refundPayment() method.
}
/**
* {@inheritdoc}
*/
public function doHttpRequest($api_uri, array $paytabs_data) {
$request = $this->httpClient->post($api_uri,
[
'form_params' => $paytabs_data,
])->getBody();
$result = json_decode($request);
return $result;
}
public function getShippingInfo(OrderInterface $order) {
if (!$this->moduleHandler->moduleExists('commerce_shipping')) {
return [];
}
else {
// Check if the order references shipments.
if ($order->hasField('shipments') && !$order->get('shipments')->isEmpty()) {
$shipping_profiles = [];
// Loop over the shipments to collect shipping profiles.
foreach ($order->get('shipments')->referencedEntities() as $shipment) {
if ($shipment->get('shipping_profile')->isEmpty()) {
continue;
}
$shipping_profile = $shipment->getShippingProfile();
$shipping_profiles[$shipping_profile->id()] = $shipping_profile;
}
if ($shipping_profiles && count($shipping_profiles) === 1) {
$shipping_profile = reset($shipping_profiles);
/** @var \Drupal\address\AddressInterface $address */
$address = $shipping_profile->address->first();
$shipping_info = [
'shipping_first_name' => $address->getGivenName(),
'shipping_last_name' => $address->getFamilyName(),
'address_shipping' => $address->getAddressLine1(),
'city_shipping' => $address->getLocality(),
'state_shipping' => $address->getAdministrativeArea(),
'postal_code_shipping' => $address->getPostalCode(),
'country_shipping' => \Drupal::service('address.country_repository')->get($address->getCountryCode())->getThreeLetterCode(),
];
}
return $shipping_info;
}
}
}
}
<?php
namespace Drupal\commerce_paytabs\Plugin\Commerce\PaymentMethodType;
use Drupal\commerce_payment\Plugin\Commerce\PaymentMethodType\CreditCard;
use Drupal\entity\BundleFieldDefinition;
/**
* Provides the paytabs credit card payment method type.
*
* @CommercePaymentMethodType(
* id = "paytabs_credit_card",
* label = @Translation("Credit card"),
* )
*/
class PaytabsCreditCard extends CreditCard {
/**
* {@inheritdoc}
*/
public function buildFieldDefinitions() {
$fields = parent::buildFieldDefinitions();
$fields['trans_ref'] = BundleFieldDefinition::create('string')
->setLabel($this->t('Transaction Reference'))
->setDescription($this->t('The initial payment transaction reference.'))
->setSetting('max_length', 255)
->setDisplayConfigurable('view', TRUE);
return $fields;
}
}
File deleted
<?php
namespace Drupal\commerce_paytabs\PluginForm\HostedPage;
use CommerceGuys\Addressing\Country\CountryRepositoryInterface;
use Drupal\commerce_payment\PluginForm\PaymentOffsiteForm as BasePaymentOffsiteForm;
use Drupal\commerce_paytabs\PaytabsApi;
use Drupal\commerce_paytabs\PaytabsEnum;
use Drupal\commerce_paytabs\PaytabsRequestHolder;
use Drupal\commerce_paytabs\PaytabsSDK;
use Drupal\Core\DependencyInjection\ContainerInjectionInterface;
use Drupal\Core\Extension\ModuleExtensionList;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Language\LanguageManagerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides the Paytabs hosted payment page.
*/
class PaymentPage extends BasePaymentOffsiteForm implements ContainerInjectionInterface {
/**
* The language manager.
*
* @var \Drupal\Core\Language\LanguageManagerInterface
*/
protected $languageManager;
/**
* The country repository.
*
* @var \CommerceGuys\Addressing\Country\CountryRepositoryInterface
*/
protected $countryRepository;
/**
* The module extension list.
*
* @var \Drupal\Core\Extension\ModuleExtensionList
*/
protected $moduleExtensionList;
/**
* The logger.
*
* @var \Drupal\Core\Logger\LoggerChannelInterface
*/
protected $logger;
/**
* The messenger.
*
* @var \Drupal\Core\Messenger\MessengerInterface
*/
protected $messenger;
/**
* The paytabs SDK.
*
* @var \Drupal\commerce_paytabs\PaytabsSDK
*/
protected $paytabsSdk;
/**
* Constructs a new HyperpayForm object.
*
* @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
* The language manager.
* @param \CommerceGuys\Addressing\Country\CountryRepositoryInterface $country_repository
* The country repository.
* @param \Drupal\Core\Extension\ModuleExtensionList $module_extension_list
* The module extension list.
* @param Drupal\Core\Logger\LoggerChannelInterface $logger_channel_factory
* The logger.
* @param Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
*/
public function __construct(LanguageManagerInterface $language_manager, CountryRepositoryInterface $country_repository, ModuleExtensionList $module_extension_list = NULL, LoggerChannelFactoryInterface $logger_channel_factory, MessengerInterface $messenger) {
$this->paytabs_sdk = new PaytabsSDK();
$this->languageManager = $language_manager;
$this->countryRepository = $country_repository;
$this->moduleExtensionList = $module_extension_list;
$this->logger = $logger_channel_factory->get('commerce_paytabs');
$this->messenger = $messenger;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('language_manager'),
$container->get('address.country_repository'),
$container->get('extension.list.module'),
$container->get('logger.factory'),
$container->get('messenger')
);
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form = parent::buildConfigurationForm($form, $form_state);
$payment = $this->entity;
$order = $payment->getOrder();
$payment_gateway_plugin = $payment->getPaymentGateway()->getPlugin();
$config = $payment_gateway_plugin->getConfiguration();
$payment_amount = $payment->getAmount();
$customer = $order->getCustomer();
$paytabs_core = new PaytabsRequestHolder();
$paytabs_api = PaytabsApi::getInstance($config['region'], $config['profile_id'], $config['server_key']);
$transaction_title = $this->t('Order Number: @order_number', ['@order_number' => $order->id()]);
$billing_profile = $order->getBillingProfile();
$billing_phone = $billing_profile->hasField($config['telephone_field']) ? $billing_profile->get($config['telephone_field'])->value : 00000000000;
$billing_info = $billing_profile->address->first();
$billing_country_code = $billing_info->getCountryCode();
$billing_country = $this->countryRepository->get($billing_country_code)->getThreeLetterCode();
$billing_full_name = $billing_info->getGivenName() . ' ' . $billing_info->getFamilyName();
$platform_version = $this->moduleExtensionList->getExtensionInfo('commerce')['version'] ?? 0;
$plugin_version = $this->moduleExtensionList->getExtensionInfo('commerce_paytabs')['version'] ?? 0;
$frammed = $config['iframe'] == 'true' ? TRUE : FALSE;
$hide_shipping = $config['hide_shipping_address'] == 'true' ? TRUE : FALSE;
$paytabs_core
->set01PaymentCode('all')
->set02Transaction($config['pay_page_mode'], 'ecom')
->set03Cart($order->id(), $payment_amount->getCurrencyCode(), floatval($payment_amount->getNumber()), $transaction_title)
->set04CustomerDetails($billing_full_name, $customer->getEmail(), $billing_phone, $billing_info->getAddressLine1(), $billing_info->getLocality(), $billing_info->getAdministrativeArea() ? str_replace(" Governorate", "", $billing_info->getAdministrativeArea()) : $billing_info->getLocality(), $billing_country, $billing_info->getPostalCode() ? $billing_info->getPostalCode() : '00000', $order->getIpAddress())
->set06HideShipping($hide_shipping)
->set07URLs($form['#return_url'], $payment_gateway_plugin->getNotifyUrl()->toString())
->set08Lang($this->languageManager->getCurrentLanguage()->getName())
->set09Framed($frammed, 'parent')
->set99PluginInfo('DrupalCommerce', $platform_version, $plugin_version);
$shipping_profile = $payment_gateway_plugin->getShippingProfile($order);
if ($shipping_profile) {
$shipping_phone = $shipping_profile->hasField($config['telephone_field']) ? $shipping_profile->get($config['telephone_field'])->value : 00000000000;
$shipping_info = $shipping_profile->address->first();
$shipping_full_name = $shipping_info->getGivenName() . ' ' . $shipping_info->getFamilyName();
$shipping_country_code = $shipping_info->getCountryCode();
$shipping_country = $this->countryRepository->get($shipping_country_code)->getThreeLetterCode();
$paytabs_core->set05ShippingDetails(FALSE, $shipping_full_name, $customer->getEmail(), $shipping_phone, $shipping_info->getAddressLine1(), $shipping_info->getLocality(), $shipping_info->getAdministrativeArea() ? str_replace(" Governorate", "", $shipping_info->getAdministrativeArea()) : $shipping_info->getLocality(), $shipping_country, $shipping_info->getPostalCode() ? $shipping_info->getPostalCode() : '00000', $order->getIpAddress());
}
if ($config['reuse_payment_method']) {
$paytabs_core->set11TokeniseInfo(TRUE, 2, PaytabsEnum::TOKEN_TYPE_REGISTERED);
}
$pp_params = $paytabs_core->pt_build();
$response = $paytabs_api->create_pay_page($pp_params);
if ($response->success) {
$redirect_url = $response->redirect_url;
$form['commerce_message']['#action'] = $redirect_url;
$redirect_method = 'post';
if ($frammed === TRUE) {
$form['#attributes']['id'][] = 'paymentWidgets';
$form['#attached']['drupalSettings']['commerce_paytabs']['redirect_url'] = $redirect_url;
$form['#attached']['drupalSettings']['commerce_paytabs']['return_url'] = $form['#return_url'];
$form['#attached']['library'][] = 'commerce_paytabs/hosted_page';
// No need to call buildRedirectForm(), as we embed an iframe.
return $form;
}
else {
return $this->buildRedirectForm($form, $form_state, $redirect_url, $pp_params, $redirect_method);
}
}
else {
$this->messenger->addStatus($this->t('Something went wrong, please try again later'));
$this->logger->error('failed to create payment page for order and response from paytabs is :' . $response->message);
}
}
}
File deleted
<?php
namespace Drupal\commerce_paytabs\PluginForm\OffsiteRedirect;
use Drupal\commerce_payment\Exception\PaymentGatewayException;
use Drupal\commerce_payment\PluginForm\PaymentOffsiteForm as BasePaymentOffsiteForm;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
class PaytabsOffsiteForm extends BasePaymentOffsiteForm {
/**
* {@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;
/** @var \Drupal\commerce_payment\Plugin\Commerce\PaymentGateway\OffsitePaymentGatewayInterface $payment_gateway_plugin */
$payment_gateway_plugin = $payment->getPaymentGateway()->getPlugin();
$config = $payment_gateway_plugin->getConfiguration();
/** @var \Drupal\commerce_price\Price $amount */
$payment_amount = $payment->getAmount();
/** @var \Drupal\profile\Entity\ProfileInterface $profile */
$profile = $payment->getOrder()->getBillingProfile();
/** @var \Drupal\user\Entity\User $user */
$user = $profile->getOwner();
$language = \Drupal::languageManager()->getCurrentLanguage()->getName();
/** @var \Drupal\address\Plugin\Field\FieldType\AddressItem $billing_info */
$billing_info = $profile->get('address')->first();
/** @var \Drupal\telephone\Plugin\Field\FieldType\TelephoneItem $phone */
$phone = $profile->get('telephone')->value;
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $payment->getOrder();
$products = $this->getItemsTitleName($order);
$product_titles = implode(' || ', $products);
$items_unit_price = $this->getOrderItemsUnitPrice($order);
$product_items_unit_price = implode(' || ', $items_unit_price);
$items_quantity = $this->getOrderItemsQuantity($order);
$product_items_quantity = implode(' || ', $items_quantity);
$site_url = Url::fromUri('internal:/', ['absolute' => TRUE])
->toString();
$site_ip = gethostbyname($site_url);
$order_number = $payment->getOrder()->id();
$transaction_title = t('Order Number: ') . $order_number;
$raw_amount = $payment_amount->getNumber();
$amount = number_format($raw_amount, 3);
$currency_code = $payment_amount->getCurrencyCode();
$order_country_code = $billing_info->getCountryCode();
$country = \Drupal::service('address.country_repository')->get($order_country_code)->getThreeLetterCode();
$discount = $this->getPromotionsTotal($order);
$other_charges = array_sum($this->getOtherCharges($order));
$shipping_info = $payment_gateway_plugin->getShippingInfo($order);
$shipping_first_name = $shipping_info['shipping_first_name'];
$shipping_last_name = $shipping_info['shipping_last_name'];
$address_shipping = $shipping_info['address_shipping'];
$city_shipping = $shipping_info['city_shipping'];
$state_shipping = $shipping_info['state_shipping'];
$postal_code_shipping = $shipping_info['postal_code_shipping'];
$country_shipping = $shipping_info['country_shipping'];
$paytabs_data = [
'merchant_email' => $config['merchant_email'],
'secret_key' => $config['secret_key'],
'site_url' => $site_url,
'return_url' => $form['#return_url'],
'title' => $transaction_title,
'cc_first_name' => $billing_info->getGivenName(),
'cc_last_name' => $billing_info->getFamilyName(),
'cc_phone_number' => '00'.'973', // @TODO get country area code
'phone_number' => $phone, // @TODO phone field validation
'email' => $user->getEmail(),
'products_per_title' => $product_titles,
'unit_price' => $product_items_unit_price,
'quantity' => $product_items_quantity,
'other_charges' => $other_charges,
'amount' => $amount,
'discount' => $discount,
'currency' => $currency_code,
'reference_no' => $order_number,
'ip_customer' => $order->getIpAddress(),
'ip_merchant' => $site_ip,
'billing_address' => $billing_info->getAddressLine1(),
'city' => $billing_info->getLocality(),
'state' => $billing_info->getAdministrativeArea() ? $billing_info->getAdministrativeArea() : $billing_info->getLocality(),
'postal_code' => $billing_info->getPostalCode() ? $billing_info->getPostalCode() : '00000',
'country' => $country,
'shipping_first_name' => $shipping_first_name ? $shipping_first_name : $billing_info->getGivenName(),
'shipping_last_name' => $shipping_last_name ? $shipping_last_name : $billing_info->getFamilyName(),
'address_shipping' => $address_shipping ? $address_shipping : $billing_info->getAddressLine1(),
'city_shipping' => $city_shipping ? $city_shipping : $billing_info->getLocality(),
'state_shipping' => ($state_shipping ? $state_shipping : $city_shipping) ? $billing_info->getAdministrativeArea() : $billing_info->getLocality(),
'postal_code_shipping' => $postal_code_shipping ? $postal_code_shipping : ($billing_info->getPostalCode() ? $billing_info->getPostalCode() : '00000'),
'country_shipping' => $country_shipping ? $country_shipping : $country,
'msg_lang' => $language,
'cms_with_version' => 'Drupal 8',
];
$api_uri = Url::fromUri('https://www.paytabs.com/apiv2/create_pay_page')->toString();
$response = $payment_gateway_plugin->doHttpRequest($api_uri, $paytabs_data);
if ($response->response_code == 4012) {
$payment_url = $response->payment_url;
}
else {
throw new PaymentGatewayException(sprintf('[Paytabs error #%s]: %s', $response->response_code, $response->result));
}
$redirect_url = $payment_url;
$form['commerce_message']['#action'] = $redirect_url;
$data = [
// 'return' => $form['#return_url'],
];
$redirect_method = 'post';
return $this->buildRedirectForm($form, $form_state, $redirect_url, $data, $redirect_method);
}
/**
* Gets the unit price for each order item.
* @param \Drupal\commerce_order\Entity\OrderInterface $order
*
* @return array
*/
protected function getOrderItemsUnitPrice(OrderInterface $order) {
$order_item_unit = [];
$order_items = $order->getItems();
foreach ($order_items as $order_item) {
if (!empty($order_item)) {
$order_item_unit[] = number_format($order_item->getUnitPrice()->getNumber(), 3);
}
}
return $order_item_unit;
}
/**
* Gets the quantity for each order item.
* @param \Drupal\commerce_order\Entity\OrderInterface $order
*
* @return array
*/
protected function getOrderItemsQuantity(OrderInterface $order) {
$order_item_quantity = [];
$order_items = $order->getItems();
foreach ($order_items as $order_item) {
if (!empty($order_item)) {
$order_item_quantity[] = number_format($order_item->getQuantity());
}
}
return $order_item_quantity;
}
/**
* Gets the title for each order item.
* @param \Drupal\commerce_order\Entity\OrderInterface $order
*
* @return array
*/
protected function getItemsTitleName(OrderInterface $order) {
$order_item_title = [];
$order_items = $order->getItems();
foreach ($order_items as $order_item) {
if (!empty($order_item)) {
$order_item_title[] = $order_item->getTitle();
}
}
return $order_item_title;
}
/**
* Get the discount out of the total adjustments
* @param \Drupal\commerce_order\Entity\OrderInterface $order
*
* @return string
*/
Protected function getPromotionsTotal(OrderInterface $order) {
foreach ($order->collectAdjustments() as $adjustment) {
$type = $adjustment->getType();
if ($type == 'Promotion') {
return $promotion = number_format($type->getAmount()->getNumber(), 3);
}
}
}
/**
* Get the all other charges (e.g. shipping charges, taxes, VAT, etc) minus discounts
* @param \Drupal\commerce_order\Entity\OrderInterface $order
*
* @return array
*/
Protected function getOtherCharges(OrderInterface $order) {
$other_charges = [];
foreach ($order->collectAdjustments() as $adjustment) {
if ($adjustment->isPositive()) {
$other_charges[] = number_format($adjustment->getAmount()->getNumber(), 3);
}
}
return $other_charges;
}
}
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