Enable Discovery debug logging for production troubleshooting
- Add DISCOVERY_LOG_LEVEL=debug - Add DISCOVERY_SHOW_PROGRESS=true - Temporary changes for debugging InitializerProcessor fixes on production
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
@@ -33,21 +34,22 @@ final class CustomerController
|
||||
try {
|
||||
$options = [
|
||||
'limit' => 50,
|
||||
'fields' => 'id,email,first_name,last_name,orders_count,total_spent'
|
||||
'fields' => 'id,email,first_name,last_name,orders_count,total_spent',
|
||||
];
|
||||
|
||||
$customers = $this->client->getCustomers($options);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $customers
|
||||
'data' => $customers,
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -63,14 +65,15 @@ final class CustomerController
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $customer
|
||||
'data' => $customer,
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -91,26 +94,28 @@ final class CustomerController
|
||||
'addresses' => $request->addresses ?? [],
|
||||
'password' => $request->password ?? null,
|
||||
'password_confirmation' => $request->password ?? null,
|
||||
'send_email_welcome' => $request->sendWelcomeEmail ?? false
|
||||
'send_email_welcome' => $request->sendWelcomeEmail ?? false,
|
||||
];
|
||||
|
||||
// Entferne leere Felder
|
||||
$customerData = array_filter($customerData, fn($value) => $value !== null);
|
||||
$customerData = array_filter($customerData, fn ($value) => $value !== null);
|
||||
|
||||
$customer = $this->client->createCustomer($customerData);
|
||||
|
||||
$result = new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $customer
|
||||
'data' => $customer,
|
||||
]);
|
||||
$result->status = Status::CREATED;
|
||||
|
||||
return $result;
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
@@ -11,8 +12,10 @@ final readonly class CustomerRequest
|
||||
public string $email,
|
||||
public ?string $phone = null,
|
||||
public ?bool $verifiedEmail = null,
|
||||
/** @var array<string, mixed>|null */
|
||||
public ?array $addresses = null,
|
||||
public ?string $password = null,
|
||||
public ?bool $sendWelcomeEmail = null
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
@@ -34,21 +35,22 @@ final class OrderController
|
||||
$options = [
|
||||
'limit' => 50,
|
||||
'status' => 'any',
|
||||
'fields' => 'id,order_number,customer,total_price,created_at,financial_status'
|
||||
'fields' => 'id,order_number,customer,total_price,created_at,financial_status',
|
||||
];
|
||||
|
||||
$orders = $this->client->getOrders($options);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $orders
|
||||
'data' => $orders,
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -64,14 +66,15 @@ final class OrderController
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $order
|
||||
'data' => $order,
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -92,26 +95,28 @@ final class OrderController
|
||||
'fulfillment_status' => $request->fulfillmentStatus ?? null,
|
||||
'tags' => $request->tags ?? '',
|
||||
'note' => $request->note ?? null,
|
||||
'email' => $request->email ?? null
|
||||
'email' => $request->email ?? null,
|
||||
];
|
||||
|
||||
// Entferne leere Felder
|
||||
$orderData = array_filter($orderData, fn($value) => $value !== null);
|
||||
$orderData = array_filter($orderData, fn ($value) => $value !== null);
|
||||
|
||||
$order = $this->client->createOrder($orderData);
|
||||
|
||||
$result = new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $order
|
||||
'data' => $order,
|
||||
]);
|
||||
$result->status = Status::CREATED;
|
||||
|
||||
return $result;
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
@@ -6,14 +7,19 @@ namespace App\Application\Shopify;
|
||||
final class OrderRequest
|
||||
{
|
||||
public function __construct(
|
||||
/** @var array<int, array<string, mixed>> */
|
||||
public readonly array $lineItems,
|
||||
/** @var array<string, mixed>|null */
|
||||
public readonly ?array $customer = null,
|
||||
/** @var array<string, mixed>|null */
|
||||
public readonly ?array $shippingAddress = null,
|
||||
/** @var array<string, mixed>|null */
|
||||
public readonly ?array $billingAddress = null,
|
||||
public readonly ?string $financialStatus = null,
|
||||
public readonly ?string $fulfillmentStatus = null,
|
||||
public readonly ?string $tags = null,
|
||||
public readonly ?string $note = null,
|
||||
public readonly ?string $email = null
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
@@ -33,21 +34,22 @@ final class ProductController
|
||||
try {
|
||||
$options = [
|
||||
'limit' => 50,
|
||||
'fields' => 'id,title,variants,images,status,published_at'
|
||||
'fields' => 'id,title,variants,images,status,published_at',
|
||||
];
|
||||
|
||||
$products = $this->client->getProducts($options);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $products
|
||||
'data' => $products,
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -63,14 +65,15 @@ final class ProductController
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $product
|
||||
'data' => $product,
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -90,21 +93,23 @@ final class ProductController
|
||||
'tags' => $request->tags ?? '',
|
||||
'variants' => $request->variants ?? [],
|
||||
'options' => $request->options ?? [],
|
||||
'images' => $request->images ?? []
|
||||
'images' => $request->images ?? [],
|
||||
]);
|
||||
|
||||
$result = new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $product
|
||||
'data' => $product,
|
||||
]);
|
||||
$result->status = Status::CREATED;
|
||||
|
||||
return $result;
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -119,27 +124,44 @@ final class ProductController
|
||||
$productData = [];
|
||||
|
||||
// Nur die Felder aktualisieren, die tatsächlich im Request enthalten sind
|
||||
if (isset($request->title)) $productData['title'] = $request->title;
|
||||
if (isset($request->description)) $productData['body_html'] = $request->description;
|
||||
if (isset($request->vendor)) $productData['vendor'] = $request->vendor;
|
||||
if (isset($request->productType)) $productData['product_type'] = $request->productType;
|
||||
if (isset($request->tags)) $productData['tags'] = $request->tags;
|
||||
if (isset($request->variants)) $productData['variants'] = $request->variants;
|
||||
if (isset($request->options)) $productData['options'] = $request->options;
|
||||
if (isset($request->images)) $productData['images'] = $request->images;
|
||||
if (isset($request->title)) {
|
||||
$productData['title'] = $request->title;
|
||||
}
|
||||
if (isset($request->description)) {
|
||||
$productData['body_html'] = $request->description;
|
||||
}
|
||||
if (isset($request->vendor)) {
|
||||
$productData['vendor'] = $request->vendor;
|
||||
}
|
||||
if (isset($request->productType)) {
|
||||
$productData['product_type'] = $request->productType;
|
||||
}
|
||||
if (isset($request->tags)) {
|
||||
$productData['tags'] = $request->tags;
|
||||
}
|
||||
if (isset($request->variants)) {
|
||||
$productData['variants'] = $request->variants;
|
||||
}
|
||||
if (isset($request->options)) {
|
||||
$productData['options'] = $request->options;
|
||||
}
|
||||
if (isset($request->images)) {
|
||||
$productData['images'] = $request->images;
|
||||
}
|
||||
|
||||
$product = $this->client->updateProduct($id, $productData);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $product
|
||||
'data' => $product,
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -155,14 +177,15 @@ final class ProductController
|
||||
|
||||
return new JsonResult([
|
||||
'success' => $success,
|
||||
'message' => $success ? 'Produkt erfolgreich gelöscht' : 'Produkt konnte nicht gelöscht werden'
|
||||
'message' => $success ? 'Produkt erfolgreich gelöscht' : 'Produkt konnte nicht gelöscht werden',
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -178,14 +201,15 @@ final class ProductController
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $products
|
||||
'data' => $products,
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
@@ -14,5 +15,6 @@ final class ProductRequest
|
||||
public readonly ?array $variants = null,
|
||||
public readonly ?array $options = null,
|
||||
public readonly ?array $images = null
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
@@ -35,14 +36,15 @@ final class ShopController
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $shopInfo
|
||||
'data' => $shopInfo,
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -58,14 +60,15 @@ final class ShopController
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $webhooks
|
||||
'data' => $webhooks,
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
@@ -85,16 +88,18 @@ final class ShopController
|
||||
|
||||
$result = new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $webhook
|
||||
'data' => $webhook,
|
||||
]);
|
||||
$result->status = Status::CREATED;
|
||||
|
||||
return $result;
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,11 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
|
||||
use App\Framework\Attributes\Route;
|
||||
use App\Framework\Config\External\ExternalApiConfig;
|
||||
use App\Framework\Http\Method;
|
||||
use App\Framework\Http\Request;
|
||||
use App\Framework\Http\Status;
|
||||
@@ -11,6 +13,11 @@ use App\Framework\Router\Result\JsonResult;
|
||||
|
||||
final class ShopifyWebhookHandler
|
||||
{
|
||||
public function __construct(
|
||||
private readonly ExternalApiConfig $externalApiConfig
|
||||
) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Verarbeitet eingehende Shopify-Webhooks
|
||||
*
|
||||
@@ -27,9 +34,10 @@ final class ShopifyWebhookHandler
|
||||
// Validiere den HMAC, um sicherzustellen, dass der Request von Shopify kommt
|
||||
$rawData = $request->body;
|
||||
|
||||
if (!$this->validateWebhookHmac($hmac, $rawData)) {
|
||||
if (! $this->validateWebhookHmac($hmac, $rawData)) {
|
||||
$result = new JsonResult(['error' => 'Ungültiger HMAC']);
|
||||
$result->status = Status::UNAUTHORIZED;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
@@ -40,15 +48,18 @@ final class ShopifyWebhookHandler
|
||||
switch ($topic) {
|
||||
case 'orders/create':
|
||||
$this->processOrderCreated($data);
|
||||
|
||||
break;
|
||||
case 'products/create':
|
||||
case 'products/update':
|
||||
$this->processProductUpdate($data);
|
||||
|
||||
break;
|
||||
case 'customers/create':
|
||||
$this->processCustomerCreated($data);
|
||||
|
||||
break;
|
||||
// Weitere Webhook-Themen...
|
||||
// Weitere Webhook-Themen...
|
||||
default:
|
||||
// Unbekanntes Thema, loggen oder ignorieren
|
||||
break;
|
||||
@@ -63,12 +74,11 @@ final class ShopifyWebhookHandler
|
||||
*/
|
||||
private function validateWebhookHmac(?string $hmac, string $data): bool
|
||||
{
|
||||
if (!$hmac) {
|
||||
if (! $hmac) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Das Shared Secret sollte eigentlich in ApiConfig sein
|
||||
$secret = 'dein_webhook_shared_secret'; // ODER aus ApiConfig holen
|
||||
$secret = $this->externalApiConfig->shopify->webhookSecret;
|
||||
$calculatedHmac = base64_encode(hash_hmac('sha256', $data, $secret, true));
|
||||
|
||||
return hash_equals($calculatedHmac, $hmac);
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
@@ -9,5 +10,6 @@ final class WebhookRequest
|
||||
public readonly string $topic,
|
||||
public readonly string $address,
|
||||
public readonly ?string $format = 'json'
|
||||
) {}
|
||||
) {
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user