first commit
This commit is contained in:
@@ -0,0 +1,193 @@
|
||||
<?php
|
||||
|
||||
namespace KupShop\PayPalCheckoutBundle\Controller;
|
||||
|
||||
use KupShop\KupShopBundle\Context\CountryContext;
|
||||
use KupShop\KupShopBundle\Context\CurrencyContext;
|
||||
use KupShop\KupShopBundle\Util\Logging\SentryLogger;
|
||||
use PayPalCheckoutSdk\Core\PayPalHttpClient;
|
||||
use PayPalCheckoutSdk\Core\ProductionEnvironment;
|
||||
use PayPalCheckoutSdk\Core\SandboxEnvironment;
|
||||
use PayPalCheckoutSdk\Orders\OrdersCaptureRequest;
|
||||
use PayPalCheckoutSdk\Orders\OrdersCreateRequest;
|
||||
use PayPalCheckoutSdk\Orders\OrdersGetRequest;
|
||||
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
|
||||
use Symfony\Component\HttpFoundation\JsonResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpFoundation\Response;
|
||||
use Symfony\Component\Routing\Annotation\Route;
|
||||
|
||||
/**
|
||||
* !!!
|
||||
* composer require paypal/paypal-checkout-sdk.
|
||||
*/
|
||||
class PayPalCheckoutController extends AbstractController
|
||||
{
|
||||
/** @var CurrencyContext */
|
||||
protected $currencyContext;
|
||||
|
||||
/** @var CountryContext */
|
||||
protected $countryContext;
|
||||
|
||||
/** @var SentryLogger */
|
||||
protected $logger;
|
||||
|
||||
/** @var \PayPalCheckout */
|
||||
protected $payPalCheckout;
|
||||
|
||||
public function __construct(
|
||||
CurrencyContext $currencyContext,
|
||||
CountryContext $countryContext,
|
||||
SentryLogger $logger,
|
||||
) {
|
||||
$this->currencyContext = $currencyContext;
|
||||
$this->countryContext = $countryContext;
|
||||
$this->logger = $logger;
|
||||
\Payment::includeClass('PayPalCheckout');
|
||||
$this->payPalCheckout = new \PayPalCheckout();
|
||||
$this->payPalCheckout->loadConfig();
|
||||
}
|
||||
|
||||
protected function createClient(): PayPalHttpClient
|
||||
{
|
||||
$config = $this->payPalCheckout->config;
|
||||
if (($config['mode'] ?? 'sandbox') === 'sandbox') {
|
||||
$environment = new SandboxEnvironment($config['clientID'], $config['secret']);
|
||||
} else {
|
||||
$environment = new ProductionEnvironment($config['clientID'], $config['secret']);
|
||||
}
|
||||
|
||||
return new PayPalHttpClient($environment);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/paypal-checkout/create-paypal-order/")
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function createPayPalOrder(Request $request, \Cart $cart)
|
||||
{
|
||||
$cart->load();
|
||||
$deliveryTypeID = $this->payPalCheckout->config['delivery_type_id'];
|
||||
|
||||
$cart->setTransport($deliveryTypeID);
|
||||
// set street, email and country so cart does not break in case paypal fails
|
||||
$cart->updateAddresses(
|
||||
['street' => 'street', 'email' => 'email@email.com'],
|
||||
['country' => $this->countryContext->getActiveId()]
|
||||
);
|
||||
$step = 'delivery';
|
||||
$cart->findNextStep($step);
|
||||
$cart->actualStep = $step;
|
||||
$cart->save();
|
||||
$cart->createFromDB(); // TODO: accept also hidden delivery type
|
||||
|
||||
try {
|
||||
$inStoreError = $cart->checkCartItems();
|
||||
} catch (\Exception $e) {
|
||||
$inStoreError = $e->getMessage();
|
||||
}
|
||||
if (!empty($inStoreError)) {
|
||||
$response = ['error' => $inStoreError];
|
||||
|
||||
return new JsonResponse($response);
|
||||
}
|
||||
|
||||
$price = number_format($cart->totalPricePay->asFloat(), 2, '.', '');
|
||||
$data = [
|
||||
'intent' => 'CAPTURE',
|
||||
'purchase_units' => [
|
||||
[
|
||||
'amount' => [
|
||||
'currency_code' => $this->currencyContext->getActiveId(),
|
||||
'value' => $price,
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
|
||||
$request = new OrdersCreateRequest();
|
||||
$request->prefer('return=representation');
|
||||
$request->body = $data;
|
||||
$response = $this->createClient()->execute($request);
|
||||
|
||||
return new JsonResponse($response);
|
||||
}
|
||||
|
||||
/**
|
||||
* @Route("/paypal-checkout/capture-paypal-order/{paypalOrderID}/")
|
||||
*
|
||||
* @return Response
|
||||
*/
|
||||
public function capturePayPalOrder(string $paypalOrderID, Request $request, \Cart $cart)
|
||||
{
|
||||
$client = $this->createClient();
|
||||
$cart->load();
|
||||
$cart->createFromDB();
|
||||
|
||||
$orderGetResponse = $client->execute(new OrdersGetRequest($paypalOrderID));
|
||||
if (($orderGetResponse->result->status ?? false) === 'APPROVED') {
|
||||
$address = $orderGetResponse->result->purchase_units[0]->shipping->address;
|
||||
$tmpLine1 = explode(' ', $address->address_line_1);
|
||||
$house = count($tmpLine1) > 1 ? array_pop($tmpLine1) : '';
|
||||
$street = implode(' ', $tmpLine1);
|
||||
$invoice = [
|
||||
'email' => $orderGetResponse->result->payer->email_address,
|
||||
'gender' => 'male',
|
||||
'name' => $orderGetResponse->result->payer->name->given_name,
|
||||
'surname' => $orderGetResponse->result->payer->name->surname,
|
||||
'phone' => $orderGetResponse->result->payer->phone->phone_number ?? '',
|
||||
'zip' => $address->postal_code,
|
||||
'city' => $address->admin_area_2,
|
||||
'street' => $street,
|
||||
'house' => $house,
|
||||
'country' => $address->country_code,
|
||||
];
|
||||
$invoice['phone'] = empty($invoice['phone']) ? '123456789' : $invoice['phone'];
|
||||
$delivery = $invoice;
|
||||
$delivery['street'] = $address->address_line_1;
|
||||
unset($delivery['email'], $delivery['gender']);
|
||||
$cart->updateAddresses($invoice, $delivery);
|
||||
|
||||
$order = $cart->submitOrder();
|
||||
|
||||
if (!$order instanceof \Order) {
|
||||
$this->logger->captureMessage('PayPal Checkout: Failed to create kupshop order for PayPal order '.$paypalOrderID.': submitOrder() result '.json_encode($order));
|
||||
addUserMessage('Failed to create order', 'danger');
|
||||
redirection(createScriptURL(['s' => 'cart']));
|
||||
}
|
||||
|
||||
// create kupshop order payment
|
||||
$price = \Decimal::create($orderGetResponse->result->purchase_units[0]->amount->value);
|
||||
$this->payPalCheckout->setOrder($order);
|
||||
$this->payPalCheckout->createPayment($orderGetResponse->result->id, $price, [
|
||||
'PayPalCheckoutController' => true,
|
||||
'result' => $orderGetResponse,
|
||||
]);
|
||||
|
||||
// capture paypal order
|
||||
$captureResponse = $client->execute(new OrdersCaptureRequest($paypalOrderID));
|
||||
if (($captureResponse->result->status ?? false) === 'COMPLETED') {
|
||||
// capture succeeded
|
||||
if (!$this->payPalCheckout->setStatus(\Payment::STATUS_FINISHED, $orderGetResponse->result->id)) {
|
||||
$this->logger->captureMessage('setStatus failed!');
|
||||
throw new \Exception('Set status failed');
|
||||
}
|
||||
// redirect to order detail
|
||||
$this->payPalCheckout->success(translate('paymentSuccess', 'payment'));
|
||||
}
|
||||
|
||||
// payment storno
|
||||
if (!$this->payPalCheckout->setStatus(\Payment::STATUS_STORNO, $orderGetResponse->result->id)) {
|
||||
$this->logger->captureMessage('setStatus failed!');
|
||||
throw new \Exception('Set status failed');
|
||||
}
|
||||
// redirect to order detail
|
||||
$this->payPalCheckout->error(translate('payment_storno', 'payment'));
|
||||
}
|
||||
|
||||
$this->logger->captureMessage('PayPal Checkout: PayPal order '.$paypalOrderID.' not APPROVED!');
|
||||
addUserMessage('Failed to create order', 'danger');
|
||||
redirection(createScriptURL(['s' => 'cart']));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user