diff --git a/packages/Webkul/Admin/src/Resources/lang/en/app.php b/packages/Webkul/Admin/src/Resources/lang/en/app.php index ed01931e0..01809f232 100755 --- a/packages/Webkul/Admin/src/Resources/lang/en/app.php +++ b/packages/Webkul/Admin/src/Resources/lang/en/app.php @@ -1369,7 +1369,11 @@ return [ 'custom-javascript' => 'Custom Javascript', 'paypal-smart-button' => 'PayPal', 'client-id' => 'Client Id', - 'client-id-info' => 'Use "sb" for testing.' + 'client-id-info' => 'Use "sb" for testing.', + 'client-secret' => 'Client Secret', + 'client-secret-info' => 'Add your secret key here', + 'accepted-currencies' => 'Accepted currencies', + 'accepted-currencies-info' => 'Add currency code comma seperated e.g. USD,INR,...' ] ] ]; diff --git a/packages/Webkul/Paypal/src/Config/system.php b/packages/Webkul/Paypal/src/Config/system.php index 5c0a36b02..3b16e91fd 100755 --- a/packages/Webkul/Paypal/src/Config/system.php +++ b/packages/Webkul/Paypal/src/Config/system.php @@ -86,6 +86,20 @@ return [ 'type' => 'depends', 'depend' => 'active:1', 'validation' => 'required_if:active,1', + ], [ + 'name' => 'client_secret', + 'title' => 'admin::app.admin.system.client-secret', + 'info' => 'admin::app.admin.system.client-secret-info', + 'type' => 'depends', + 'depend' => 'active:1', + 'validation' => 'required_if:active,1', + ], [ + 'name' => 'accepted_currencies', + 'title' => 'admin::app.admin.system.accepted-currencies', + 'info' => 'admin::app.admin.system.accepted-currencies', + 'type' => 'depends', + 'depend' => 'active:1', + 'validation' => 'required_if:active,1', ], [ 'name' => 'active', 'title' => 'admin::app.admin.system.status', @@ -93,7 +107,13 @@ return [ 'validation' => 'required', 'channel_based' => false, 'locale_based' => true - ], [ + ], [ + 'name' => 'sandbox', + 'title' => 'admin::app.admin.system.sandbox', + 'type' => 'boolean', + 'channel_based' => false, + 'locale_based' => true, + ], [ 'name' => 'sort', 'title' => 'admin::app.admin.system.sort_order', 'type' => 'select', diff --git a/packages/Webkul/Paypal/src/Http/Controllers/SmartButtonController.php b/packages/Webkul/Paypal/src/Http/Controllers/SmartButtonController.php index ea02745af..f0d0fba21 100755 --- a/packages/Webkul/Paypal/src/Http/Controllers/SmartButtonController.php +++ b/packages/Webkul/Paypal/src/Http/Controllers/SmartButtonController.php @@ -3,11 +3,20 @@ namespace Webkul\Paypal\Http\Controllers; use Webkul\Checkout\Facades\Cart; +use Webkul\Paypal\Payment\SmartButton; use Webkul\Sales\Repositories\OrderRepository; use Webkul\Sales\Repositories\InvoiceRepository; +use PayPalCheckoutSdk\Orders\OrdersCreateRequest; class SmartButtonController extends Controller { + /** + * SmartButton object + * + * @var \Webkul\Paypal\Payment\SmartButton + */ + protected $smartButtonClient; + /** * OrderRepository object * @@ -30,6 +39,7 @@ class SmartButtonController extends Controller * @return void */ public function __construct( + SmartButton $smartButtonClient, OrderRepository $orderRepository, InvoiceRepository $invoiceRepository ) @@ -37,14 +47,67 @@ class SmartButtonController extends Controller $this->orderRepository = $orderRepository; $this->invoiceRepository = $invoiceRepository; + + $this->smartButtonClient = $smartButtonClient->client(); } /** - * Success payment + * Success payment. * * @return \Illuminate\Http\JsonResponse */ - public function details() + public function details(OrdersCreateRequest $request) + { + $request->prefer('return=representation'); + $request->body = $this->buildRequestBody(); + $response = $this->smartButtonClient->execute($request); + return response()->json($response); + } + + /** + * Save order. + * + * @return \Illuminate\Http\Response + */ + public function saveOrder() + { + if (Cart::hasError()) { + return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403); + } + + try { + Cart::collectTotals(); + + $this->validateOrder(); + + $order = $this->orderRepository->create(Cart::prepareDataForOrder()); + + $this->orderRepository->update(['status' => 'processing'], $order->id); + + if ($order->canInvoice()) { + $this->invoiceRepository->create($this->prepareInvoiceData($order)); + } + + Cart::deActivateCart(); + + session()->flash('order', $order); + + return response()->json([ + 'success' => true, + ]); + } catch (\Exception $e) { + session()->flash('error', trans('shop::app.common.error')); + + throw $e; + } + } + + /** + * Build request body. + * + * @return array + */ + protected function buildRequestBody() { $cart = Cart::getCart(); @@ -143,12 +206,12 @@ class SmartButtonController extends Controller } /** - * Return cart items + * Return cart items. * * @param string $cart * @return array */ - public function getLineItems($cart) + protected function getLineItems($cart) { $lineItems = []; @@ -169,12 +232,12 @@ class SmartButtonController extends Controller } /** - * Return convert multiple address lines into 2 address lines + * Return convert multiple address lines into 2 address lines. * * @param string $address * @return array */ - public function getAddressLines($address) + protected function getAddressLines($address) { $address = explode(PHP_EOL, $address, 2); @@ -190,47 +253,7 @@ class SmartButtonController extends Controller } /** - * Save order - * - * @return \Illuminate\Http\Response - */ - public function saveOrder() - { - if (Cart::hasError()) { - return response()->json(['redirect_url' => route('shop.checkout.cart.index')], 403); - } - - try { - Cart::collectTotals(); - - $this->validateOrder(); - - $cart = Cart::getCart(); - - $order = $this->orderRepository->create(Cart::prepareDataForOrder()); - - $this->orderRepository->update(['status' => 'processing'], $order->id); - - if ($order->canInvoice()) { - $invoice = $this->invoiceRepository->create($this->prepareInvoiceData($order)); - } - - Cart::deActivateCart(); - - session()->flash('order', $order); - - return response()->json([ - 'success' => true, - ]); - } catch (\Exception $e) { - session()->flash('error', trans('shop::app.common.error')); - - throw $e; - } - } - - /** - * Prepares order's invoice data for creation + * Prepares order's invoice data for creation. * * @param \Webkul\Sales\Models\Order $order * @return array @@ -247,14 +270,20 @@ class SmartButtonController extends Controller } /** - * Validate order before creation + * Validate order before creation. * * @return void|\Exception */ - public function validateOrder() + protected function validateOrder() { $cart = Cart::getCart(); + $minimumOrderAmount = (int) core()->getConfigData('sales.orderSettings.minimum-order.minimum_order_amount') ?? 0; + + if (! $cart->checkMinimumOrder()) { + throw new \Exception(trans('shop::app.checkout.cart.minimum-order-message', ['amount' => core()->currency($minimumOrderAmount)])); + } + if ($cart->haveStockableItems() && ! $cart->shipping_address) { throw new \Exception(trans('Please check shipping address.')); } diff --git a/packages/Webkul/Paypal/src/Payment/SmartButton.php b/packages/Webkul/Paypal/src/Payment/SmartButton.php index 48ca893bc..16b1575b9 100644 --- a/packages/Webkul/Paypal/src/Payment/SmartButton.php +++ b/packages/Webkul/Paypal/src/Payment/SmartButton.php @@ -2,15 +2,41 @@ namespace Webkul\Paypal\Payment; +use PayPalCheckoutSdk\Core\PayPalHttpClient; +use PayPalCheckoutSdk\Core\SandboxEnvironment; +use PayPalCheckoutSdk\Core\ProductionEnvironment; + class SmartButton extends Paypal { /** - * Payment method code + * Client ID. + * + * @var string + */ + protected $clientId; + + /** + * Client secret. + * + * @var string + */ + protected $clientSecret; + + /** + * Payment method code. * * @var string */ protected $code = 'paypal_smart_button'; + /** + * Constructor. + */ + public function __construct() + { + $this->initialize(); + } + /** * Return paypal redirect url * @@ -19,4 +45,39 @@ class SmartButton extends Paypal public function getRedirectUrl() { } + + /** + * Returns PayPal HTTP client instance with environment that has access + * credentials context. Use this instance to invoke PayPal APIs, provided the + * credentials have access. + */ + public function client() + { + return new PayPalHttpClient($this->environment()); + } + + /** + * Set up and return PayPal PHP SDK environment with PayPal access credentials. + * This sample uses SandboxEnvironment. In production, use LiveEnvironment. + */ + protected function environment() + { + $isSandbox = core()->getConfigData('sales.paymentmethods.paypal_smart_button.sandbox') ?: false; + + if ($isSandbox) { + return new SandboxEnvironment($this->clientId, $this->clientSecret); + } + + return new ProductionEnvironment($this->clientId, $this->clientSecret); + } + + /** + * Initialize properties. + */ + protected function initialize() + { + $this->clientId = core()->getConfigData('sales.paymentmethods.paypal_smart_button.client_id') ?: ''; + + $this->clientSecret = core()->getConfigData('sales.paymentmethods.paypal_smart_button.client_secret') ?: ''; + } } \ No newline at end of file diff --git a/packages/Webkul/Paypal/src/Paypal.php b/packages/Webkul/Paypal/src/Paypal.php deleted file mode 100644 index 366de4a57..000000000 --- a/packages/Webkul/Paypal/src/Paypal.php +++ /dev/null @@ -1,30 +0,0 @@ -route()->getName() == 'shop.checkout.onepage.index' && core()->getConfigData('sales.paymentmethods.paypal_smart_button.active')) - +@if (request()->route()->getName() == 'shop.checkout.onepage.index') - + @php + $clientId = core()->getConfigData('sales.paymentmethods.paypal_smart_button.client_id'); + $acceptedCurrency = core()->getConfigData('sales.paymentmethods.paypal_smart_button.accepted_currencies'); + @endphp - - return; - } + - if (typeof paypal == 'undefined') { - window.flashMessages = [{'type': 'alert-error', 'message': "SDK Validation error: 'client-id not recognized for either production or sandbox: {{core()->getConfigData('sales.paymentmethods.paypal_smart_button.client_id')}}'" }]; + + + @endif \ No newline at end of file