|
|
@@ -0,0 +1,115 @@
|
|
|
+<?php
|
|
|
+
|
|
|
+namespace Webkul\BagistoApi\State;
|
|
|
+
|
|
|
+use ApiPlatform\Metadata\Operation;
|
|
|
+use ApiPlatform\State\ProviderInterface;
|
|
|
+use Illuminate\Support\Facades\Auth;
|
|
|
+use Webkul\BagistoApi\Dto\PaymentMethodOutput;
|
|
|
+use Webkul\BagistoApi\Exception\AuthorizationException;
|
|
|
+use Webkul\BagistoApi\Exception\OperationFailedException;
|
|
|
+use Webkul\BagistoApi\Exception\ResourceNotFoundException;
|
|
|
+use Webkul\Payment\Facades\Payment;
|
|
|
+use Webkul\Sales\Models\Order;
|
|
|
+use Webkul\Sales\Repositories\OrderRepository;
|
|
|
+
|
|
|
+/**
|
|
|
+ * Provides available payment methods for repaying an existing order.
|
|
|
+ */
|
|
|
+class RepayOrderPaymentMethodsProvider implements ProviderInterface
|
|
|
+{
|
|
|
+ public function __construct(
|
|
|
+ protected OrderRepository $orderRepository,
|
|
|
+ ) {}
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Provide payment methods for replaying payment on an order.
|
|
|
+ */
|
|
|
+ public function provide(Operation $operation, array $uriVariables = [], array $context = []): object|array|null
|
|
|
+ {
|
|
|
+ $args = $context['args'] ?? [];
|
|
|
+ $orderId = $args['orderId'] ?? null;
|
|
|
+
|
|
|
+ if (! $orderId || ! is_numeric($orderId)) {
|
|
|
+ throw new ResourceNotFoundException(__('bagistoapi::app.graphql.customer-order.id-required'));
|
|
|
+ }
|
|
|
+
|
|
|
+ $customer = Auth::guard('sanctum')->user();
|
|
|
+
|
|
|
+ if (! $customer) {
|
|
|
+ throw new AuthorizationException(__('bagistoapi::app.graphql.logout.unauthenticated'));
|
|
|
+ }
|
|
|
+
|
|
|
+ $order = $this->orderRepository->find((int) $orderId);
|
|
|
+
|
|
|
+ if (! $order) {
|
|
|
+ throw new ResourceNotFoundException(__('bagistoapi::app.graphql.payment.order-not-found', ['id' => $orderId]));
|
|
|
+ }
|
|
|
+
|
|
|
+ if ((int) $order->customer_id !== (int) $customer->id) {
|
|
|
+ throw new OperationFailedException(__('bagistoapi::app.graphql.payment.replay-not-allowed'));
|
|
|
+ }
|
|
|
+
|
|
|
+ if (! in_array($order->status, [Order::STATUS_PENDING, Order::STATUS_PENDING_PAYMENT], true)) {
|
|
|
+ throw new OperationFailedException(__('bagistoapi::app.graphql.payment.not-pending', ['status' => $order->status]));
|
|
|
+ }
|
|
|
+
|
|
|
+ $methods = Payment::getSupportedPaymentMethods();
|
|
|
+
|
|
|
+ if ($methods && is_array($methods) && isset($methods['payment_methods'])) {
|
|
|
+ $methodsArray = $methods['payment_methods'];
|
|
|
+ } elseif ($methods && is_object($methods) && property_exists($methods, 'payment_methods')) {
|
|
|
+ $methodsArray = (array) $methods->payment_methods;
|
|
|
+ } else {
|
|
|
+ $methodsArray = [];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (! $methodsArray || ! is_array($methodsArray)) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ $outputs = [];
|
|
|
+ $currentMethod = (string) ($order->payment?->method ?? '');
|
|
|
+
|
|
|
+ foreach ($methodsArray as $key => $method) {
|
|
|
+ $methodData = is_object($method) ? (array) $method : $method;
|
|
|
+ $methodCode = (string) ($methodData['method'] ?? $key);
|
|
|
+ $isValid = $this->isValidPaymentMethod($methodCode,$order);
|
|
|
+ //TODO 逻辑判断支付是否符合要求
|
|
|
+ if (!$isValid) {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ $output = new PaymentMethodOutput;
|
|
|
+ $output->id = $methodCode;
|
|
|
+ $output->method = $methodData['method'] ?? null;
|
|
|
+ $output->title = $methodData['method_title'] ?? null;
|
|
|
+ $output->description = $methodData['description'] ?? null;
|
|
|
+ $output->icon = $methodData['image'] ?? null;
|
|
|
+ // $output->isAllowed = $isAllowed;
|
|
|
+ $output->additionalData = $methodData['additional_data'] ?? null;
|
|
|
+ $outputs[] = $output;
|
|
|
+ }
|
|
|
+
|
|
|
+ return $outputs;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Replay support parity with PaymentService::createGatewayOrderForOrder:
|
|
|
+ * - paypal_smart_button is natively supported
|
|
|
+ * - custom gateways must provide a handler class with createGatewayOrder()
|
|
|
+ */
|
|
|
+ private function isValidPaymentMethod(string $methodCode,Order $order): bool
|
|
|
+ {
|
|
|
+ if ($methodCode === 'paypal_smart_button') {
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+
|
|
|
+ $config = config('payment_methods.'.$methodCode);
|
|
|
+
|
|
|
+ if (! is_array($config) || empty($config['class'])) {
|
|
|
+ return false;
|
|
|
+ }
|
|
|
+ return true;
|
|
|
+ }
|
|
|
+}
|