Des modules ajoutés et mise en page du CSS

This commit is contained in:
2021-01-20 12:37:48 +01:00
parent ae363c7447
commit 9ae46f8c88
409 changed files with 35050 additions and 6579 deletions

View File

@@ -0,0 +1,414 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace PayPal\Service\Base;
use Monolog\Logger;
use PayPal\Api\Amount;
use PayPal\Api\FuturePayment;
use PayPal\Api\Payer;
use PayPal\Api\PayerInfo;
use PayPal\Api\ShippingAddress;
use PayPal\Api\Transaction;
use PayPal\Auth\OAuthTokenCredential;
use PayPal\Event\PayPalEvents;
use PayPal\Event\PayPalOrderEvent;
use PayPal\Model\PaypalCart;
use PayPal\Model\PaypalCartQuery;
use PayPal\Model\PaypalOrder;
use PayPal\Model\PaypalPlanifiedPayment;
use PayPal\PayPal;
use PayPal\Rest\ApiContext;
use PayPal\Service\PayPalLoggerService;
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use Symfony\Component\Routing\RouterInterface;
use Thelia\Core\Event\Cart\CartRestoreEvent;
use Thelia\Core\Event\TheliaEvents;
use Thelia\Core\HttpFoundation\Session\Session;
use Thelia\Core\Translation\Translator;
use Thelia\Model\Cart;
use Thelia\Model\Country;
use Thelia\Model\Currency;
use Thelia\Model\Order;
use Thelia\Model\OrderAddressQuery;
class PayPalBaseService
{
/** @var EventDispatcherInterface */
protected $dispatcher;
/** @var RequestStack */
protected $requestStack;
/** @var RouterInterface */
protected $router;
/** @var OAuthTokenCredential */
protected $authTokenCredential;
/**
* PayPalBaseService constructor.
* @param EventDispatcherInterface $dispatcher
* @param RequestStack $requestStack
* @param RouterInterface $router
*/
public function __construct(EventDispatcherInterface $dispatcher, RequestStack $requestStack, RouterInterface $router)
{
$this->dispatcher = $dispatcher;
$this->requestStack = $requestStack;
$this->router = $router;
$this->authTokenCredential = new OAuthTokenCredential(self::getLogin(), self::getPassword());
}
/**
* @param Order $order
* @param string|null $creditCardId
* @param PaypalPlanifiedPayment $planifiedPayment
* @return PayPalOrderEvent
*/
public function generatePayPalOrder(Order $order, $creditCardId = null, PaypalPlanifiedPayment $planifiedPayment = null)
{
$payPalOrder = new PaypalOrder();
$payPalOrder
->setId($order->getId())
->setAmount($order->getTotalAmount())
;
if (null !== $creditCardId) {
$payPalOrder->setCreditCardId($creditCardId);
}
if (null !== $planifiedPayment) {
/** @var \Thelia\Model\Lang $lang */
$lang = $this->requestStack->getCurrentRequest()->getSession()->get('thelia.current.lang');
$planifiedPayment->getTranslation($lang->getLocale());
$payPalOrder
->setPlanifiedTitle($planifiedPayment->getTitle())
->setPlanifiedDescription($planifiedPayment->getDescription())
->setPlanifiedFrequency($planifiedPayment->getFrequency())
->setPlanifiedFrequencyInterval($planifiedPayment->getFrequencyInterval())
->setPlanifiedCycle($planifiedPayment->getCycle())
->setPlanifiedMinAmount($planifiedPayment->getMinAmount())
->setPlanifiedMaxAmount($planifiedPayment->getMaxAmount())
;
}
$payPalOrderEvent = new PayPalOrderEvent($payPalOrder);
$this->dispatcher->dispatch(PayPalEvents::PAYPAL_ORDER_CREATE, $payPalOrderEvent);
return $payPalOrderEvent;
}
/**
* @param PaypalOrder $payPalOrder
* @param $state
* @param string|null $paymentId
* @param string|null $agreementId
* @return PayPalOrderEvent
*/
public function updatePayPalOrder(PaypalOrder $payPalOrder, $state, $paymentId = null, $agreementId = null)
{
$payPalOrder->setState($state);
if (null !== $paymentId) {
$payPalOrder->setPaymentId($paymentId);
}
if (null !== $agreementId) {
$payPalOrder->setAgreementId($agreementId);
}
$payPalOrderEvent = new PayPalOrderEvent($payPalOrder);
$this->dispatcher->dispatch(PayPalEvents::PAYPAL_ORDER_UPDATE, $payPalOrderEvent);
return $payPalOrderEvent;
}
/**
* @return PaypalCart
*/
public function getCurrentPayPalCart()
{
/** @var Session $session */
$session = $this->requestStack->getCurrentRequest()->getSession();
$cart = $session->getSessionCart($this->dispatcher);
if (null === $cart) {
$cartEvent = new CartRestoreEvent();
$this->dispatcher->dispatch(TheliaEvents::CART_RESTORE_CURRENT, $cartEvent);
$cart = $cartEvent->getCart();
}
if (null === $payPalCart = PaypalCartQuery::create()->findOneById($cart->getId())) {
$payPalCart = new PaypalCart();
$payPalCart->setId($cart->getId());
}
return $payPalCart;
}
/**
* @param string $method
* @param array $fundingInstruments
* @param PayerInfo $payerInfo
* @return Payer
*/
public static function generatePayer($method = PayPal::PAYPAL_METHOD_PAYPAL, $fundingInstruments = [], PayerInfo $payerInfo = null)
{
$payer = new Payer();
$payer->setPaymentMethod($method);
// Never set empty instruments when communicating with PayPal
if (count($fundingInstruments) > 0) {
$payer->setFundingInstruments($fundingInstruments);
}
if (null !== $payerInfo) {
$payer->setPayerInfo($payerInfo);
}
return $payer;
}
public static function generatePayerInfo($data = [])
{
$payerInfo = new PayerInfo($data);
return $payerInfo;
}
public static function generateShippingAddress(Order $order)
{
if (null !== $orderAddress = OrderAddressQuery::create()->findOneById($order->getDeliveryOrderAddressId())) {
$shippingAddress = new ShippingAddress();
if (null !== $state = $orderAddress->getState()) {
$payPalState = $state->getIsocode();
} else {
$payPalState = 'CA';
}
$shippingAddress
->setLine1($orderAddress->getAddress1())
->setCity($orderAddress->getCity())
->setPostalCode($orderAddress->getZipcode())
->setCountryCode($orderAddress->getCountry()->getIsoalpha2())
->setState($payPalState)
;
if (null !== $orderAddress->getAddress2()) {
if (null !== $orderAddress->getAddress3()) {
$shippingAddress->setLine2($orderAddress->getAddress2() . ' ' . $orderAddress->getAddress3());
} else {
$shippingAddress->setLine2($orderAddress->getAddress2());
}
} elseif (null !== $orderAddress->getAddress3()) {
$shippingAddress->setLine2($orderAddress->getAddress3());
}
if (null !== $orderAddress->getStateId()) {
//$shippingAddress->setState($orderAddress->getState()->getIsocode());
}
return $shippingAddress;
} else {
$message = Translator::getInstance()->trans(
'Order address no found to generate PayPal shipping address',
[],
PayPal::DOMAIN_NAME
);
PayPalLoggerService::log(
$message,
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::ERROR
);
throw new \Exception($message);
}
}
/**
* @param Order $order
* @param Currency $currency
* @return Amount
*/
public function generateAmount(Order $order, Currency $currency)
{
// Specify the payment amount.
$amount = new Amount();
$amount->setCurrency($currency->getCode());
$amount->setTotal($order->getTotalAmount());
return $amount;
}
/**
* @param Cart $cart
* @param Currency $currency
* @return Amount
*/
public function generateAmountFromCart(Cart $cart, Currency $currency)
{
// Specify the payment amount.
$amount = new Amount();
$amount->setCurrency($currency->getCode());
$amount->setTotal($cart->getTaxedAmount(Country::getDefaultCountry()));
return $amount;
}
/**
* @param Amount $amount
* @param string $description
* @return Transaction
*/
public function generateTransaction(Amount $amount, $description = '')
{
// ###Transaction
// A transaction defines the contract of a
// payment - what is the payment for and who
// is fulfilling it. Transaction is created with
// a `Payee` and `Amount` types
$transaction = new Transaction();
$transaction->setAmount($amount);
$transaction->setDescription($description);
return $transaction;
}
public function getAccessToken()
{
$config = self::getApiContext()->getConfig();
$accessToken = $this->authTokenCredential->getAccessToken($config);
return $accessToken;
}
public function getRefreshToken()
{
$refreshToken = FuturePayment::getRefreshToken($this->getAccessToken(), self::getApiContext());
return $refreshToken;
}
/**
* SDK Configuration
*
*@return ApiContext
*/
public static function getApiContext()
{
$apiContext = new ApiContext();
// Alternatively pass in the configuration via a hashmap.
// The hashmap can contain any key that is allowed in
// sdk_config.ini
$apiContext->setConfig([
'acct1.ClientId' => self::getLogin(),
'acct1.ClientSecret' => self::getPassword(),
'http.ConnectionTimeOut' => 30,
'http.Retry' => 1,
'mode' => self::getMode(),
'log.LogEnabled' => true,
'log.FileName' => '../log/PayPal.log',
'log.LogLevel' => 'INFO',
'cache.enabled' => true,
'cache.FileName' => '../cache/prod/PayPal.cache',
'http.headers.PayPal-Partner-Attribution-Id' => 'Thelia_Cart',
]);
return $apiContext;
}
/**
* @return string
*/
public static function getLogin()
{
if (PayPal::getConfigValue('sandbox') == 1) {
$login = PayPal::getConfigValue('sandbox_login');
} else {
$login = PayPal::getConfigValue('login');
}
return $login;
}
/**
* @return string
*/
public static function getPassword()
{
if (PayPal::getConfigValue('sandbox') == 1) {
$password = PayPal::getConfigValue('sandbox_password');
} else {
$password = PayPal::getConfigValue('password');
}
return $password;
}
/**
* @return string
*/
public static function getMerchantId()
{
if (PayPal::getConfigValue('sandbox') == 1) {
$login = PayPal::getConfigValue('sandbox_merchant_id');
} else {
$login = PayPal::getConfigValue('merchant_id');
}
return $login;
}
/**
* @return string
*/
public static function getMode()
{
if (PayPal::getConfigValue('sandbox') == 1) {
$mode = 'sandbox';
} else {
$mode = 'live';
}
return $mode;
}
public static function isSandboxMode()
{
if (self::getMode() === 'live') {
return false;
} else {
return true;
}
}
}

View File

@@ -0,0 +1,940 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace PayPal\Service;
use Monolog\Logger;
use PayPal\Api\Agreement;
use PayPal\Api\AgreementStateDescriptor;
use PayPal\Api\ChargeModel;
use PayPal\Api\CreditCard;
use PayPal\Api\CreditCardToken;
use PayPal\Api\Currency;
use PayPal\Api\FundingInstrument;
use PayPal\Api\MerchantPreferences;
use PayPal\Api\Patch;
use PayPal\Api\PatchRequest;
use PayPal\Api\Payer;
use PayPal\Api\PaymentDefinition;
use PayPal\Api\Plan;
use PayPal\Common\PayPalModel;
use PayPal\Event\PayPalEvents;
use PayPal\Event\PayPalOrderEvent;
use PayPal\Event\PayPalPlanEvent;
use PayPal\Exception\PayPalConnectionException;
use PayPal\Model\PaypalOrder;
use PayPal\Model\PaypalOrderQuery;
use PayPal\Model\PaypalPlan;
use PayPal\Model\PaypalPlanifiedPayment;
use PayPal\Model\PaypalPlanQuery;
use PayPal\PayPal;
use PayPal\Service\Base\PayPalBaseService;
use Symfony\Component\Routing\Router;
use Thelia\Core\Translation\Translator;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\Order;
use Thelia\Model\OrderProduct;
use Thelia\Model\OrderProductQuery;
use Thelia\Model\OrderProductTax;
use Thelia\Model\OrderProductTaxQuery;
use Thelia\Tools\URL;
class PayPalAgreementService extends PayPalBaseService
{
const PLAN_TYPE_FIXED = 'FIXED';
const PLAN_TYPE_INFINITE = 'INFINITE';
const PAYMENT_TYPE_REGULAR = 'REGULAR';
const PAYMENT_TYPE_TRIAL = 'TRIAL';
const CHARGE_TYPE_SHIPPING = 'SHIPPING';
const CHARGE_TYPE_TAX = 'TAX';
const PAYMENT_FREQUENCY_DAY = 'DAY';
const PAYMENT_FREQUENCY_WEEK = 'WEEK';
const PAYMENT_FREQUENCY_MONTH = 'MONTH';
const PAYMENT_FREQUENCY_YEAR = 'YEAR';
const FAIL_AMOUNT_ACTION_CONTINUE = 'CONTINUE';
const FAIL_AMOUNT_ACTION_CANCEL = 'CANCEL';
const MAX_API_LENGHT = 128;
/**
* @param Order $order
* @param PaypalPlanifiedPayment $planifiedPayment
* @param null $description
* @return Agreement
* @throws PayPalConnectionException
* @throws \Exception
*/
public function makeAgreement(Order $order, PaypalPlanifiedPayment $planifiedPayment, $description = null)
{
//Sadly, this description can NOT be null
if (null === $description) {
$description = 'Thelia order ' . $order->getId();
}
$payPalOrderEvent = $this->generatePayPalOrder($order, null, $planifiedPayment);
$merchantPreferences = $this->createMerchantPreferences($order);
$chargeModel = $this->createChargeModel($order);
$totalAmount = $order->getTotalAmount();
$cycleAmount = round($totalAmount / $planifiedPayment->getCycle(), 2);
$paymentDefinition = $this->createPaymentDefinition(
$order,
'payment definition for order ' . $order->getId(),
[$chargeModel],
$cycleAmount,
self::PAYMENT_TYPE_REGULAR,
$planifiedPayment->getFrequency(),
$planifiedPayment->getFrequencyInterval(),
$planifiedPayment->getCycle()
);
$plan = $this->generateBillingPlan($order, 'plan for order ' . $order->getId(), $merchantPreferences, [$paymentDefinition]);
$plan = $this->createBillingPlan($order, $plan);
$plan = $this->activateBillingPlan($order, $plan);
$newPlan = new Plan();
$newPlan->setId($plan->getId());
// There is no Billing agreement possible with credit card
$agreement = $this->createBillingAgreementWithPayPal($order, $newPlan, 'agreement ' . $order->getId(), $description);
//We must update concerned order_product price... order discount... order postage... PayPal will create one invoice each cycle
$this->updateTheliaOrderForCycle($order, $planifiedPayment->getCycle(), $cycleAmount);
$this->updatePayPalOrder($payPalOrderEvent->getPayPalOrder(), $agreement->getState(), null, $agreement->getId());
return $agreement;
}
public function updateTheliaOrderForCycle(Order $order, $cycle, $cycleAmount)
{
//Be sure that there is no rounding price lost with this method
$moneyLeft = $cycleAmount;
$newPostage = round($order->getPostage() / $cycle, 2);
$newPostageTax = round($order->getPostageTax() / $cycle, 2);
$newDiscount = round($order->getDiscount() / $cycle, 2);
$moneyLeft -= ($newPostage + $newPostageTax + $newDiscount);
$orderProducts = OrderProductQuery::create()->filterByOrderId($order->getId())->find();
/** @var \Thelia\Model\OrderProduct $orderProduct */
foreach ($orderProducts as $orderProduct) {
$newPrice = round($orderProduct->getPrice() / $cycle, 2);
$newPromoPrice = round($orderProduct->getPrice() / $cycle, 2);
if ($orderProduct->getWasInPromo()) {
$moneyLeft -= $newPromoPrice;
} else {
$moneyLeft -= $newPrice;
}
$orderProduct
->setPrice($newPrice)
->setPromoPrice($newPromoPrice)
->save()
;
$taxes = OrderProductTaxQuery::create()->filterByOrderProductId($orderProduct->getId())->find();
/** @var \Thelia\Model\OrderProductTax $tax */
foreach ($taxes as $tax) {
$newAmount = round($tax->getAmount() / $cycle, 2);
$newPromoAmount = round($tax->getPromoAmount() / $cycle, 2);
if ($orderProduct->getWasInPromo()) {
$moneyLeft -= $newPromoAmount;
} else {
$moneyLeft -= $newAmount;
}
$tax
->setAmount($newAmount)
->setPromoAmount($newPromoAmount)
->save()
;
}
}
//Normally, $moneyLeft == 0 here. But in case of rouding price, adjust the rounding in the postage column
$newPostage += $moneyLeft;
$order
->setPostage($newPostage)
->setPostageTax($newPostageTax)
->setDiscount($newDiscount)
->save()
;
return $order;
}
/**
* @param $billingPlanId
* @return Plan
*/
public function getBillingPlan($billingPlanId)
{
$plan = Plan::get($billingPlanId, self::getApiContext());
return $plan;
}
/**
* @param Order $order
* @param Plan $plan
* @return Plan
*/
public function activateBillingPlan(Order $order, Plan $plan)
{
$patch = new Patch();
$value = new PayPalModel('{
"state":"ACTIVE"
}');
$patch
->setOp('replace')
->setPath('/')
->setValue($value)
;
$patchRequest = new PatchRequest();
$patchRequest->addPatch($patch);
$plan->update($patchRequest, self::getApiContext());
$plan = $this->getBillingPlan($plan->getId());
if (null === $payPalPlan = PaypalPlanQuery::create()
->filterByPaypalOrderId($order->getId())
->filterByPlanId($plan->getId())
->findOne()) {
$payPalPlan = new PaypalPlan();
$payPalPlan
->setPaypalOrderId($order->getId())
->setPlanId($plan->getId())
;
}
$payPalPlan->setState($plan->getState());
$payPalPlanEvent = new PayPalPlanEvent($payPalPlan);
$this->dispatcher->dispatch(PayPalEvents::PAYPAL_PLAN_UPDATE, $payPalPlanEvent);
return $plan;
}
/**
* @param $token
* @param null $orderId
* @return Agreement
* @throws PayPalConnectionException
* @throws \Exception
*/
public function activateBillingAgreementByToken($token, $orderId = null)
{
$agreement = new Agreement();
try {
$agreement->execute($token, self::getApiContext());
return $this->getBillingAgreement($agreement->getId());
} catch (PayPalConnectionException $e) {
$message = sprintf('url : %s. data : %s. message : %s', $e->getUrl(), $e->getData(), $e->getMessage());
PayPalLoggerService::log(
$message,
[
'customer_id' => $orderId
],
Logger::CRITICAL
);
throw $e;
} catch (\Exception $e) {
PayPalLoggerService::log(
$e->getMessage(),
[
'customer_id' => $orderId
],
Logger::CRITICAL
);
throw $e;
}
}
/**
* @param Order $order
* @param $name
* @param $merchantPreferences
* @param array $paymentDefinitions
* @param string $description
* @param string $type
* @return Plan
* @throws \Exception
*/
public function generateBillingPlan(Order $order, $name, $merchantPreferences, $paymentDefinitions = [], $description = '', $type = self::PLAN_TYPE_FIXED)
{
if (!in_array($type, self::getAllowedPlanType())) {
$message = Translator::getInstance()->trans(
'Invalid type send to generate billing plan',
[],
PayPal::DOMAIN_NAME
);
PayPalLoggerService::log(
$message,
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::ERROR
);
throw new \Exception($message);
}
if (!is_array($paymentDefinitions) || count($paymentDefinitions) <= 0) {
$message = Translator::getInstance()->trans(
'Invalid number of payment definition send to generate billing plan',
[],
PayPal::DOMAIN_NAME
);
PayPalLoggerService::log(
$message,
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::ERROR
);
throw new \Exception($message);
}
$plan = new Plan();
$plan
->setName(substr($name, 0, self::MAX_API_LENGHT))
->setDescription(substr($description, 0, self::MAX_API_LENGHT))
->setType($type)
->setPaymentDefinitions($paymentDefinitions)
->setMerchantPreferences($merchantPreferences)
;
return $plan;
}
/**
* @param Plan $plan
* @return bool
*/
public function deleteBillingPlan(Plan $plan)
{
$isDeleted = $plan->delete(self::getApiContext());
return $isDeleted;
}
/**
* @param int $pageSize
* @return \PayPal\Api\PlanList
*/
public function listBillingPlans($pageSize = 2)
{
$planList = Plan::all(['page_size' => $pageSize], self::getApiContext());
return $planList;
}
/**
* @param Order $order
* @param Plan $plan
* @return Plan
* @throws PayPalConnectionException
* @throws \Exception
*/
public function createBillingPlan(Order $order, Plan $plan)
{
try {
$plan = $plan->create(self::getApiContext());
if (null === $payPalPlan = PaypalPlanQuery::create()
->filterByPaypalOrderId($order->getId())
->filterByPlanId($plan->getId())
->findOne()) {
$payPalPlan = new PaypalPlan();
$payPalPlan
->setPaypalOrderId($order->getId())
->setPlanId($plan->getId())
;
}
$payPalPlan->setState($plan->getState());
$payPalPlanEvent = new PayPalPlanEvent($payPalPlan);
$this->dispatcher->dispatch(PayPalEvents::PAYPAL_PLAN_CREATE, $payPalPlanEvent);
return $plan;
} catch (PayPalConnectionException $e) {
$message = sprintf('url : %s. data : %s. message : %s', $e->getUrl(), $e->getData(), $e->getMessage());
PayPalLoggerService::log(
$message,
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::CRITICAL
);
throw $e;
} catch (\Exception $e) {
PayPalLoggerService::log(
$e->getMessage(),
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::CRITICAL
);
throw $e;
}
}
/**
* @param Order $order
* @param Plan $plan
* @param $creditCardId
* @param $name
* @param $description
* @return Agreement
*/
public function createBillingAgreementWithCreditCard(Order $order, Plan $plan, $creditCardId, $name, $description)
{
$creditCardToken = new CreditCardToken();
$creditCardToken->setCreditCardId($creditCardId);
$fundingInstrument = new FundingInstrument();
//$fundingInstrument->setCreditCardToken($creditCardToken);
$card = new CreditCard();
$card
->setType('visa')
->setNumber('4491759698858890')
->setExpireMonth('12')
->setExpireYear('2017')
->setCvv2('128')
;
$fundingInstrument->setCreditCard($card);
$payer = self::generatePayer(
PayPal::PAYPAL_METHOD_CREDIT_CARD,
[$fundingInstrument],
self::generatePayerInfo(['email' => $order->getCustomer()->getEmail()])
);
$agreement = $this->generateAgreement($order, $plan, $payer, $name, $description);
$agreement = $agreement->create(self::getApiContext());
return $agreement;
}
/**
* @param Order $order
* @param Plan $plan
* @param $name
* @param $description
* @return Agreement
*/
public function createBillingAgreementWithPayPal(Order $order, Plan $plan, $name, $description)
{
$payer = self::generatePayer(PayPal::PAYPAL_METHOD_PAYPAL);
$agreement = $this->generateAgreement($order, $plan, $payer, $name, $description);
$agreement = $agreement->create(self::getApiContext());
return $agreement;
}
/**
* @param $agreementId
* @return Agreement
*/
public function getBillingAgreement($agreementId)
{
$agreement = Agreement::get($agreementId, self::getApiContext());
return $agreement;
}
/**
* @param $agreementId
* @param array $params
* @return \PayPal\Api\AgreementTransactions
*/
public function getBillingAgreementTransactions($agreementId, $params = [])
{
if (is_array($params) || count($params) == 0) {
$params = [
'start_date' => date('Y-m-d', strtotime('-15 years')),
'end_date' => date('Y-m-d', strtotime('+5 days'))
];
}
$agreementTransactions = Agreement::searchTransactions($agreementId, $params, self::getApiContext());
return $agreementTransactions;
}
/**
* @param Agreement $agreement
* @param string $note
* @return Agreement
*/
public function suspendBillingAgreement(Agreement $agreement, $note = 'Suspending the agreement')
{
//Create an Agreement State Descriptor, explaining the reason to suspend.
$agreementStateDescriptor = new AgreementStateDescriptor();
$agreementStateDescriptor->setNote($note);
$agreement->suspend($agreementStateDescriptor, self::getApiContext());
$agreement = $this->getBillingAgreement($agreement->getId());
return $agreement;
}
/**
* @param Agreement $agreement
* @param string $note
* @return Agreement
*/
public function reActivateBillingAgreement(Agreement $agreement, $note = 'Reactivating the agreement')
{
//Create an Agreement State Descriptor, explaining the reason to re activate.
$agreementStateDescriptor = new AgreementStateDescriptor();
$agreementStateDescriptor->setNote($note);
$agreement->reActivate($agreementStateDescriptor, self::getApiContext());
$agreement = $this->getBillingAgreement($agreement->getId());
return $agreement;
}
/**
* @param Order $order
* @param $name
* @param array $chargeModels
* @param null $cycleAmount
* @param string $type
* @param string $frequency
* @param int $frequencyInterval
* @param int $cycles
* @return PaymentDefinition
* @throws \Exception
*/
public function createPaymentDefinition(Order $order, $name, $chargeModels = [], $cycleAmount = null, $type = self::PAYMENT_TYPE_REGULAR, $frequency = self::PAYMENT_FREQUENCY_DAY, $frequencyInterval = 1, $cycles = 1)
{
if (!in_array($type, self::getAllowedPaymentType())) {
$message = Translator::getInstance()->trans(
'Invalid payment type send to create payment definition',
[],
PayPal::DOMAIN_NAME
);
PayPalLoggerService::log(
$message,
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::ERROR
);
throw new \Exception($message);
}
if (!in_array($frequency, self::getAllowedPaymentFrequency())) {
$message = Translator::getInstance()->trans(
'Invalid payment frequency send to create payment definition',
[],
PayPal::DOMAIN_NAME
);
PayPalLoggerService::log(
$message,
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::ERROR
);
throw new \Exception($message);
}
if (!is_array($chargeModels) || count($chargeModels) <= 0) {
$message = Translator::getInstance()->trans(
'Invalid number of charge models send to create payment definition',
[],
PayPal::DOMAIN_NAME
);
PayPalLoggerService::log(
$message,
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::ERROR
);
throw new \Exception($message);
}
$paymentDefinition = new PaymentDefinition();
if (null === $cycleAmount) {
$totalAmount = $order->getTotalAmount();
$cycleAmount = round($totalAmount / $cycles, 2);
}
$paymentDefinition
->setName(substr($name, 0, self::MAX_API_LENGHT))
->setType($type)
->setFrequency($frequency)
->setFrequencyInterval($frequencyInterval)
->setCycles($cycles)
->setAmount(new Currency(['value' => $cycleAmount, 'currency' => self::getOrderCurrencyCode($order)]))
->setChargeModels($chargeModels)
;
return $paymentDefinition;
}
/**
* @param Order $order
* @param int $chargeAmount
* @param string $type
* @return ChargeModel
* @throws \Exception
*/
public function createChargeModel(Order $order, $chargeAmount = 0, $type = self::CHARGE_TYPE_SHIPPING)
{
if (!in_array($type, self::getAllowedChargeType())) {
$message = Translator::getInstance()->trans(
'Invalid charge type send to create charge model',
[],
PayPal::DOMAIN_NAME
);
PayPalLoggerService::log(
$message,
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::ERROR
);
throw new \Exception($message);
}
$chargeModel = new ChargeModel();
$chargeModel
->setType($type)
->setAmount(new Currency(['value' => $chargeAmount, 'currency' => self::getOrderCurrencyCode($order)]))
;
return $chargeModel;
}
/**
* @param Order $order
* @param bool $autoBillAmount
* @param string $failAction
* @param int $maxFailAttempts
* @param int $feeAmount
* @return MerchantPreferences
* @throws \Exception
*/
public function createMerchantPreferences(Order $order, $autoBillAmount = false, $failAction = self::FAIL_AMOUNT_ACTION_CONTINUE, $maxFailAttempts = 0, $feeAmount = 0)
{
if (!in_array($failAction, self::getAllowedFailedAction())) {
$message = Translator::getInstance()->trans(
'Invalid fail action send to create merchant preference',
[],
PayPal::DOMAIN_NAME
);
PayPalLoggerService::log(
$message,
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::ERROR
);
throw new \Exception($message);
}
$merchantPreferences = new MerchantPreferences();
$urlOk = URL::getInstance()->absoluteUrl(
$this->router->generate(
"paypal.agreement.ok",
[
'orderId' => $order->getId()
],
Router::ABSOLUTE_URL
)
);
$urlKo = URL::getInstance()->absoluteUrl(
$this->router->generate(
"paypal.agreement.ko",
[
'orderId' => $order->getId()
],
Router::ABSOLUTE_URL
)
);
if ($autoBillAmount) {
$autoBillAmountStr = 'YES';
} else {
$autoBillAmountStr = 'NO';
}
$merchantPreferences
->setReturnUrl($urlOk)
->setCancelUrl($urlKo)
->setAutoBillAmount($autoBillAmountStr)
->setInitialFailAmountAction($failAction)
->setMaxFailAttempts($maxFailAttempts)
->setSetupFee(new Currency(['value' => $feeAmount, 'currency' => self::getOrderCurrencyCode($order)]))
;
return $merchantPreferences;
}
/**
* @param Order $order
* @return Order
* @throws \Exception
* @throws \Propel\Runtime\Exception\PropelException
*/
public function duplicateOrder(Order $order)
{
$today = new \Datetime;
$newOrder = new Order();
$newOrder
->setCustomerId($order->getCustomerId())
->setInvoiceOrderAddressId($order->getInvoiceOrderAddressId())
->setDeliveryOrderAddressId($order->getDeliveryOrderAddressId())
->setInvoiceDate($today->format('Y-m-d H:i:s'))
->setCurrencyId($order->getCurrencyId())
->setCurrencyRate($order->getCurrencyRate())
->setDeliveryRef($order->getDeliveryRef())
->setInvoiceRef($order->getInvoiceRef())
->setDiscount($order->getDiscount())
->setPostage($order->getPostage())
->setPostageTax($order->getPostageTax())
->setPostageTaxRuleTitle($order->getPostageTaxRuleTitle())
->setPaymentModuleId($order->getPaymentModuleId())
->setDeliveryModuleId($order->getDeliveryModuleId())
->setStatusId($order->getStatusId())
->setLangId($order->getLangId())
->setCartId($order->getCartId())
->save()
;
$orderProducts = OrderProductQuery::create()->filterByOrderId($order->getId())->find();
/** @var \Thelia\Model\OrderProduct $orderProduct */
foreach ($orderProducts as $orderProduct) {
$newOrderProduct = new OrderProduct();
$newOrderProduct
->setOrderId($newOrder->getId())
->setProductRef($orderProduct->getProductRef())
->setProductSaleElementsRef($orderProduct->getProductSaleElementsRef())
->setProductSaleElementsId($orderProduct->getProductSaleElementsId())
->setTitle($orderProduct->getTitle())
->setChapo($orderProduct->getChapo())
->setDescription($orderProduct->getDescription())
->setPostscriptum($orderProduct->getPostscriptum())
->setQuantity($orderProduct->getQuantity())
->setPrice($orderProduct->getPrice())
->setPromoPrice($orderProduct->getPromoPrice())
->setWasNew($orderProduct->getWasNew())
->setWasInPromo($orderProduct->getWasInPromo())
->setWeight($orderProduct->getWeight())
->setEanCode($orderProduct->getEanCode())
->setTaxRuleTitle($orderProduct->getTaxRuleTitle())
->setTaxRuleDescription($orderProduct->getTaxRuleDescription())
->setParent($orderProduct->getParent())
->setVirtual($orderProduct->getVirtual())
->setVirtualDocument($orderProduct->getVirtualDocument())
->save()
;
$orderProductTaxes = OrderProductTaxQuery::create()->filterByOrderProductId($orderProduct->getId())->find();
/** @var \Thelia\Model\OrderProductTax $orderProductTax */
foreach ($orderProductTaxes as $orderProductTax) {
$newOrderProductTax = new OrderProductTax();
$newOrderProductTax
->setOrderProductId($newOrderProduct->getId())
->setTitle($orderProductTax->getTitle())
->setDescription($orderProductTax->getDescription())
->setAmount($orderProductTax->getAmount())
->setPromoAmount($orderProductTax->getPromoAmount())
->save()
;
}
}
if (null !== $payPalOrder = PaypalOrderQuery::create()->findOneById($order->getId())) {
$newPayPalOrder = new PaypalOrder();
$newPayPalOrder
->setId($newOrder->getId())
->setPaymentId($payPalOrder->getPaymentId())
->setAgreementId($payPalOrder->getAgreementId())
->setCreditCardId($payPalOrder->getCreditCardId())
->setState($payPalOrder->getState())
->setAmount($payPalOrder->getAmount())
->setDescription($payPalOrder->getDescription())
->setPayerId($payPalOrder->getPayerId())
->setToken($payPalOrder->getToken())
;
$newPayPalOrderEvent = new PayPalOrderEvent($newPayPalOrder);
$this->dispatcher->dispatch(PayPalEvents::PAYPAL_ORDER_CREATE, $newPayPalOrderEvent);
$payPalPlans = PaypalPlanQuery::create()->filterByPaypalOrderId($payPalOrder->getId());
/** @var \PayPal\Model\PaypalPlan $payPalPlan */
foreach ($payPalPlans as $payPalPlan) {
$newPayPalPlan = new PaypalPlan();
$newPayPalPlan
->setPaypalOrderId($newPayPalOrderEvent->getPayPalOrder()->getId())
->setPlanId($payPalPlan->getPlanId())
->setState($payPalPlan->getState())
;
$newPayPalPlanEvent = new PayPalPlanEvent($newPayPalPlan);
$this->dispatcher->dispatch(PayPalEvents::PAYPAL_PLAN_CREATE, $newPayPalPlanEvent);
}
}
return $newOrder;
}
/**
* @param Order $order
* @param Plan $plan
* @param Payer $payer
* @param $name
* @param string $description
* @return Agreement
* @throws \Exception
*/
public function generateAgreement(Order $order, Plan $plan, Payer $payer, $name, $description = '')
{
$agreement = new Agreement();
$agreement
->setName($name)
->setDescription($description)
->setStartDate((new \Datetime)->format('Y-m-d\TG:i:s\Z'))
->setPlan($plan)
;
//Add Payer to Agreement
$agreement
->setPayer($payer)
->setShippingAddress(self::generateShippingAddress($order))
;
return $agreement;
}
/**
* @param Order $order
* @return string
*/
public static function getOrderCurrencyCode(Order $order)
{
if (null === $currency = CurrencyQuery::create()->findOneById($order->getCurrencyId())) {
$currency = \Thelia\Model\Currency::getDefaultCurrency();
}
return $currency->getCode();
}
/**
* @return array
*/
public static function getAllowedPlanType()
{
return [
self::PLAN_TYPE_FIXED,
self::PLAN_TYPE_INFINITE
];
}
/**
* @return array
*/
public static function getAllowedPaymentType()
{
return [
self::PAYMENT_TYPE_REGULAR,
self::PAYMENT_TYPE_TRIAL
];
}
/**
* @return array
*/
public static function getAllowedChargeType()
{
return [
self::CHARGE_TYPE_SHIPPING,
self::CHARGE_TYPE_TAX
];
}
/**
* @return array
*/
public static function getAllowedPaymentFrequency()
{
return [
self::PAYMENT_FREQUENCY_DAY => self::PAYMENT_FREQUENCY_DAY,
self::PAYMENT_FREQUENCY_WEEK => self::PAYMENT_FREQUENCY_WEEK,
self::PAYMENT_FREQUENCY_MONTH => self::PAYMENT_FREQUENCY_MONTH,
self::PAYMENT_FREQUENCY_YEAR => self::PAYMENT_FREQUENCY_YEAR
];
}
/**
* @return array
*/
public static function getAllowedFailedAction()
{
return [
self::FAIL_AMOUNT_ACTION_CANCEL,
self::FAIL_AMOUNT_ACTION_CONTINUE
];
}
}

View File

@@ -0,0 +1,164 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace PayPal\Service;
use Monolog\Logger;
use PayPal\Api\OpenIdSession;
use PayPal\Api\OpenIdTokeninfo;
use PayPal\Api\OpenIdUserinfo;
use PayPal\Model\PaypalCustomer;
use PayPal\Model\PaypalCustomerQuery;
use PayPal\Service\Base\PayPalBaseService;
use Thelia\Core\Security\SecurityContext;
/**
* Class PayPalCustomerService
* @package PayPal\Service
*/
class PayPalCustomerService
{
/** @var SecurityContext */
protected $securityContext;
/**
* PayPalService constructor.
* @param SecurityContext $securityContext
*/
public function __construct(SecurityContext $securityContext)
{
$this->securityContext = $securityContext;
}
/**
* @param $authorizationCode
* @return OpenIdUserinfo
* @throws \Exception
*/
public function getUserInfoWithAuthorizationCode($authorizationCode)
{
try {
$accessToken = OpenIdTokeninfo::createFromAuthorizationCode(
['code' => $authorizationCode],
null,
null,
PayPalBaseService::getApiContext()
);
return $this->getUserInfo($accessToken->getAccessToken());
} catch (\Exception $ex) {
PayPalLoggerService::log($ex->getMessage(), [], Logger::ERROR);
throw $ex;
}
}
/**
* @param $accessToken
* @return OpenIdUserinfo
*/
public function getUserInfo($accessToken)
{
$params = array('access_token' => $accessToken);
$userInfo = OpenIdUserinfo::getUserinfo($params, PayPalBaseService::getApiContext());
return $userInfo;
}
/**
* @return PaypalCustomer
*/
public function getCurrentPayPalCustomer()
{
$payPalCustomer = new PaypalCustomer();
if (null !== $customer = $this->securityContext->getCustomerUser()) {
$payPalCustomer = PaypalCustomerQuery::create()->findOneById($customer->getId());
}
return $payPalCustomer;
}
/**
* @param $refreshToken
* @return OpenIdTokeninfo
* @throws \Exception
*/
public function generateAccessTokenFromRefreshToken($refreshToken)
{
try {
$tokenInfo = new OpenIdTokeninfo();
$tokenInfo = $tokenInfo->createFromRefreshToken(['refresh_token' => $refreshToken], PayPalBaseService::getApiContext());
return $tokenInfo;
} catch (\Exception $ex) {
PayPalLoggerService::log($ex->getMessage(), [], Logger::ERROR);
throw $ex;
}
}
/**
* @param $refreshToken
* @return OpenIdUserinfo
* @throws \Exception
*/
public function getUserInfoWithRefreshToken($refreshToken)
{
try {
$tokenInfo = $this->generateAccessTokenFromRefreshToken($refreshToken);
return $this->getUserInfo($tokenInfo->getAccessToken());
} catch (\Exception $ex) {
PayPalLoggerService::log($ex->getMessage(), [], Logger::ERROR);
throw $ex;
}
}
/**
* @return string
*/
public function getUrlToRefreshToken()
{
//Get Authorization URL returns the redirect URL that could be used to get user's consent
$redirectUrl = OpenIdSession::getAuthorizationUrl(
'http://25b3ee89.ngrok.io/',
[
'openid',
'profile',
'address',
'email',
'phone',
'https://uri.paypal.com/services/paypalattributes',
'https://uri.paypal.com/services/expresscheckout',
'https://uri.paypal.com/services/invoicing'
],
null,
null,
null,
PayPalBaseService::getApiContext()
);
return $redirectUrl;
}
}

View File

@@ -0,0 +1,133 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace PayPal\Service;
use Monolog\Logger;
use MySQLHandler\MySQLHandler;
use PayPal\Model\Map\PaypalLogTableMap;
use PayPal\Model\PaypalLogQuery;
use PayPal\PayPal;
use Propel\Runtime\Propel;
use Thelia\Install\Database;
/**
* Class PayPalLoggerService
* @package PayPal\Service
*/
class PayPalLoggerService
{
/**
* @param $message
* @param array $params
* @param int $level
*/
public static function log($message, $params = [], $level = Logger::DEBUG)
{
$staticParams = self::getStaticParams();
$logger = new Logger(PayPal::getModuleCode());
//Create MysqlHandler
$database = new Database(Propel::getConnection());
$mySQLHandler = new MySQLHandler(
$database->getConnection(),
PaypalLogTableMap::TABLE_NAME,
array_keys($staticParams),
$level
);
$logger->pushHandler($mySQLHandler);
//Now you can use the logger, and further attach additional information
switch ($level) {
case Logger::DEBUG:
$logger->addDebug($message, array_merge($staticParams, $params));
break;
case Logger::INFO:
$logger->addInfo($message, array_merge($staticParams, $params));
break;
case Logger::NOTICE:
$logger->addNotice($message, array_merge($staticParams, $params));
break;
case Logger::WARNING:
$logger->addWarning($message, array_merge($staticParams, $params));
break;
case Logger::ERROR:
$logger->addError($message, array_merge($staticParams, $params));
break;
case Logger::CRITICAL:
$logger->addCritical($message, array_merge($staticParams, $params));
break;
case Logger::ALERT:
$logger->addAlert($message, array_merge($staticParams, $params));
break;
case Logger::EMERGENCY:
$logger->addEmergency($message, array_merge($staticParams, $params));
break;
default:
$logger->addDebug($message, array_merge($staticParams, $params));
break;
}
}
/**
* @return array
* @throws \Propel\Runtime\Exception\PropelException
*/
public static function getStaticParams()
{
$psr3Fields = ['channel', 'level', 'message', 'time'];
$payPalLogFields = PaypalLogTableMap::getFieldNames(PaypalLogTableMap::TYPE_FIELDNAME);
$readableDate = new \Datetime();
$staticParams = [];
foreach ($payPalLogFields as $fieldName) {
// Do not interpret psr3 fields
if (in_array($fieldName, $psr3Fields)) {
continue;
}
if (in_array($fieldName, ['created_at', 'updated_at'])) {
$staticParams[$fieldName] = $readableDate->format('Y-m-d H:i:s');
} elseif (in_array($fieldName, ['id'])) {
$lastId = PaypalLogQuery::create()->count();
$staticParams[$fieldName] = $lastId + 1;
} else {
$staticParams[$fieldName] = null;
}
}
return $staticParams;
}
}

View File

@@ -0,0 +1,411 @@
<?php
/*************************************************************************************/
/* */
/* Thelia */
/* */
/* Copyright (c) OpenStudio */
/* email : info@thelia.net */
/* web : http://www.thelia.net */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the GNU General Public License as published by */
/* the Free Software Foundation; either version 3 of the License */
/* */
/* This program is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */
/* GNU General Public License for more details. */
/* */
/* You should have received a copy of the GNU General Public License */
/* along with this program. If not, see <http://www.gnu.org/licenses/>. */
/* */
/*************************************************************************************/
namespace PayPal\Service;
use Monolog\Logger;
use PayPal\Api\Amount;
use PayPal\Api\CreditCard;
use PayPal\Api\CreditCardToken;
use PayPal\Api\Details;
use PayPal\Api\FundingInstrument;
use PayPal\Api\FuturePayment;
use PayPal\Api\OpenIdTokeninfo;
use PayPal\Api\Payer;
use PayPal\Api\Payment;
use PayPal\Api\PaymentExecution;
use PayPal\Api\RedirectUrls;
use PayPal\Api\Transaction;
use PayPal\Exception\PayPalConnectionException;
use PayPal\PayPal;
use PayPal\Service\Base\PayPalBaseService;
use Thelia\Core\Translation\Translator;
use Thelia\Model\Cart;
use Thelia\Model\Currency;
use Thelia\Model\CurrencyQuery;
use Thelia\Model\Order;
use Thelia\Tools\URL;
/**
* Class PayPalPaymentService
* @package PayPal\Service
*/
class PayPalPaymentService extends PayPalBaseService
{
/**
* Create a payment using a previously obtained
* credit card id. The corresponding credit
* card is used as the funding instrument.
*
* @param Order $order
* @param bool $future
* @param string|null $creditCardId
* @param string|null $description
* @return Payment
*/
public function makePayment(Order $order, $creditCardId = null, $description = null, $future = false)
{
$payPalOrderEvent = $this->generatePayPalOrder($order);
if (null !== $creditCardId) {
$creditCardToken = new CreditCardToken();
$creditCardToken->setCreditCardId($creditCardId);
$fundingInstrument = new FundingInstrument();
$fundingInstrument->setCreditCardToken($creditCardToken);
$payer = self::generatePayer(PayPal::PAYPAL_METHOD_CREDIT_CARD, [$fundingInstrument]);
} else {
$payer = self::generatePayer();
}
// Specify the payment amount.
if (null === $currency = CurrencyQuery::create()->findOneById($order->getCurrencyId())) {
$currency = Currency::getDefaultCurrency();
}
$amount = $this->generateAmount($order, $currency);
$transaction = $this->generateTransaction($amount, $description);
$payment = $this->generatePayment($order, $payer, $transaction, $future);
$this->updatePayPalOrder($payPalOrderEvent->getPayPalOrder(), $payment->getState(), $payment->getId());
return $payment;
}
public function makePaymentFromCart(Cart $cart, $description = null, $future = false, $fromCartView = true)
{
$payer = self::generatePayer();
// Specify the payment amount.
if (null === $currency = CurrencyQuery::create()->findOneById($cart->getCurrencyId())) {
$currency = Currency::getDefaultCurrency();
}
$amount = $this->generateAmountFromCart($cart, $currency);
$transaction = $this->generateTransaction($amount, $description);
$payment = $this->generatePaymentFromCart($cart, $payer, $transaction, $future, $fromCartView);
//$this->updatePayPalOrder($payPalOrderEvent->getPayPalOrder(), $payment->getState(), $payment->getId());
return $payment;
}
/**
* Completes the payment once buyer approval has been
* obtained. Used only when the payment method is 'paypal'
*
* @param string $paymentId id of a previously created
* payment that has its payment method set to 'paypal'
* and has been approved by the buyer.
*
* @param string $payerId PayerId as returned by PayPal post
* buyer approval.
*
* @return Payment
*/
public function executePayment($paymentId, $payerId, Details $details = null)
{
$payment = $this->getPaymentDetails($paymentId);
$paymentExecution = new PaymentExecution();
$paymentExecution->setPayerId($payerId);
if (null !== $details) {
$amount = new Amount();
$totalDetails = (float)$details->getShipping() + (float)$details->getTax() + (float)$details->getSubtotal();
$amount
->setCurrency('EUR')
->setTotal($totalDetails)
->setDetails($details)
;
$transaction = new Transaction();
$transaction->setAmount($amount);
$paymentExecution->addTransaction($transaction);
}
$payment = $payment->execute($paymentExecution, self::getApiContext());
return $payment;
}
public function createDetails($shipping = 0, $shippingTax = 0, $subTotal = 0)
{
$details = new Details();
$details
->setShipping($shipping)
->setTax($shippingTax)
->setSubtotal($subTotal)
;
return $details;
}
/**
* Retrieves the payment information based on PaymentID from Paypal APIs
*
* @param $paymentId
*
* @return Payment
*/
public function getPaymentDetails($paymentId)
{
$payment = Payment::get($paymentId, self::getApiContext());
return $payment;
}
/**
* @param $authorizationCode
* @return OpenIdTokeninfo
* @throws PayPalConnectionException
*/
public function generateAccessToken($authorizationCode)
{
try {
// Obtain Authorization Code from Code, Client ID and Client Secret
$accessToken = OpenIdTokeninfo::createFromAuthorizationCode(
['code' => $authorizationCode],
null,
null,
self::getApiContext()
);
return $accessToken;
} catch (PayPalConnectionException $ex) {
PayPalLoggerService::log($ex->getMessage(), [], Logger::ERROR);
throw $ex;
}
}
/**
* @param $type
* @param $number
* @param $expireMonth
* @param $expireYear
* @param $cvv2
* @return string
* @throws \Exception
*/
public function getPayPalCreditCardId($type, $number, $expireMonth, $expireYear, $cvv2)
{
try {
$card = new CreditCard();
$card->setType($type);
$card->setNumber((int)$number);
$card->setExpireMonth((int)$expireMonth);
$card->setExpireYear((int)$expireYear);
$card->setCvv2($cvv2);
$card->create(self::getApiContext());
return $card->getId();
} catch (\Exception $e) {
PayPalLoggerService::log($e->getMessage(), [], Logger::ERROR);
throw new \Exception(Translator::getInstance()->trans('Credit card is invalid', [], PayPal::DOMAIN_NAME));
}
}
/**
* @param Order $order
* @param Payer $payer
* @param Transaction $transaction
* @param bool $future
* @return FuturePayment|Payment
* @throws PayPalConnectionException
* @throws \Exception
*/
public function generatePayment(Order $order, Payer $payer, Transaction $transaction, $future = false)
{
if ($future) {
$payment = new FuturePayment();
$payment->setIntent('authorize');
} else {
$payment = new Payment();
$payment->setIntent('sale');
}
$payment
->setRedirectUrls($this->getRedirectUrls($order))
->setPayer($payer)
->setTransactions([$transaction])
;
$clientMetadataId = '123123456';
try {
if ($future) {
//$authorizationCode = self::getAuthorizationCode();
$refreshToken = $this->getRefreshToken();
//$refreshToken = FuturePayment::getRefreshToken($this->getAuthorizationCode(), self::getApiContext());
$payment->updateAccessToken($refreshToken, self::getApiContext());
$payment->create(self::getApiContext(), $clientMetadataId);
} else {
$payment->create(self::getApiContext());
}
return $payment;
} catch (PayPalConnectionException $e) {
$message = sprintf('url : %s. data : %s. message : %s', $e->getUrl(), $e->getData(), $e->getMessage());
PayPalLoggerService::log(
$message,
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::CRITICAL
);
throw $e;
} catch (\Exception $e) {
PayPalLoggerService::log(
$e->getMessage(),
[
'customer_id' => $order->getCustomerId(),
'order_id' => $order->getId()
],
Logger::CRITICAL
);
throw $e;
}
}
/**
* @param Cart $cart
* @param Payer $payer
* @param Transaction $transaction
* @param bool $future
* @return FuturePayment|Payment
* @throws PayPalConnectionException
* @throws \Exception
*/
public function generatePaymentFromCart(Cart $cart, Payer $payer, Transaction $transaction, $future = false, $fromCartView = true)
{
if ($future) {
$payment = new FuturePayment();
$payment->setIntent('authorize');
} else {
$payment = new Payment();
$payment->setIntent('sale');
}
if ($fromCartView) {
$payment->setRedirectUrls($this->getRedirectCartUrls($cart));
} else {
$payment->setRedirectUrls($this->getRedirectInvoiceUrls($cart));
}
$payment
->setPayer($payer)
->setTransactions([$transaction])
;
$clientMetadataId = '123123456';
try {
if ($future) {
//$authorizationCode = self::getAuthorizationCode();
$refreshToken = $this->getRefreshToken();
//$refreshToken = FuturePayment::getRefreshToken($this->getAuthorizationCode(), self::getApiContext());
$payment->updateAccessToken($refreshToken, self::getApiContext());
$payment->create(self::getApiContext(), $clientMetadataId);
} else {
$payment->create(self::getApiContext());
}
return $payment;
} catch (PayPalConnectionException $e) {
$message = sprintf('url : %s. data : %s. message : %s', $e->getUrl(), $e->getData(), $e->getMessage());
PayPalLoggerService::log(
$message,
[],
Logger::CRITICAL
);
throw $e;
} catch (\Exception $e) {
PayPalLoggerService::log(
$e->getMessage(),
[],
Logger::CRITICAL
);
throw $e;
}
}
/**
* @param Order $order
* @return RedirectUrls
*/
public function getRedirectUrls(Order $order)
{
$redirectUrls = new RedirectUrls();
$urlOk = URL::getInstance()->absoluteUrl('/module/paypal/ok/' . $order->getId());
$urlCancel = URL::getInstance()->absoluteUrl('/module/paypal/cancel/' . $order->getId());
$redirectUrls->setReturnUrl($urlOk);
$redirectUrls->setCancelUrl($urlCancel);
return $redirectUrls;
}
/**
* @param Cart $cart
* @return RedirectUrls
*/
public function getRedirectCartUrls(Cart $cart)
{
$redirectUrls = new RedirectUrls();
$urlOk = URL::getInstance()->absoluteUrl('/module/paypal/express/checkout/ok/' . $cart->getId());
$urlCancel = URL::getInstance()->absoluteUrl('/module/paypal/express/checkout/ko/' . $cart->getId());
$redirectUrls->setReturnUrl($urlOk);
$redirectUrls->setCancelUrl($urlCancel);
return $redirectUrls;
}
/**
* @param Cart $cart
* @return RedirectUrls
*/
public function getRedirectInvoiceUrls(Cart $cart)
{
$redirectUrls = new RedirectUrls();
$urlOk = URL::getInstance()->absoluteUrl('/module/paypal/invoice/express/checkout/ok/' . $cart->getId());
$urlCancel = URL::getInstance()->absoluteUrl('/module/paypal/invoice/express/checkout/ko/' . $cart->getId());
$redirectUrls->setReturnUrl($urlOk);
$redirectUrls->setCancelUrl($urlCancel);
return $redirectUrls;
}
}