chore: complete update
This commit is contained in:
117
src/Application/Shopify/CustomerController.php
Normal file
117
src/Application/Shopify/CustomerController.php
Normal file
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
|
||||
use App\Framework\Api\ApiException;
|
||||
use App\Framework\Attributes\Route;
|
||||
use App\Framework\Http\Method;
|
||||
use App\Framework\Http\Status;
|
||||
use App\Framework\Router\Result\JsonResult;
|
||||
use App\Infrastructure\Api\ShopifyClient;
|
||||
use Archive\Config\ApiConfig;
|
||||
|
||||
final class CustomerController
|
||||
{
|
||||
private ShopifyClient $client;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->client = new ShopifyClient(
|
||||
ApiConfig::SHOPIFY_SHOP_DOMAIN->value,
|
||||
ApiConfig::SHOPIFY_ACCESS_TOKEN->value,
|
||||
ApiConfig::SHOPIFY_API_VERSION->value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Kunden ab
|
||||
*/
|
||||
#[Route(path: '/api/shopify/customers', method: Method::GET)]
|
||||
public function listCustomers(): JsonResult
|
||||
{
|
||||
try {
|
||||
$options = [
|
||||
'limit' => 50,
|
||||
'fields' => 'id,email,first_name,last_name,orders_count,total_spent'
|
||||
];
|
||||
|
||||
$customers = $this->client->getCustomers($options);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $customers
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft einen einzelnen Kunden ab
|
||||
*/
|
||||
#[Route(path: '/api/shopify/customers/{id}', method: Method::GET)]
|
||||
public function getCustomer(int $id): JsonResult
|
||||
{
|
||||
try {
|
||||
$customer = $this->client->getCustomer($id);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $customer
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen neuen Kunden
|
||||
*/
|
||||
#[Route(path: '/api/shopify/customers', method: Method::POST)]
|
||||
public function createCustomer(CustomerRequest $request): JsonResult
|
||||
{
|
||||
try {
|
||||
$customerData = [
|
||||
'first_name' => $request->firstName,
|
||||
'last_name' => $request->lastName,
|
||||
'email' => $request->email,
|
||||
'phone' => $request->phone ?? null,
|
||||
'verified_email' => $request->verifiedEmail ?? true,
|
||||
'addresses' => $request->addresses ?? [],
|
||||
'password' => $request->password ?? null,
|
||||
'password_confirmation' => $request->password ?? null,
|
||||
'send_email_welcome' => $request->sendWelcomeEmail ?? false
|
||||
];
|
||||
|
||||
// Entferne leere Felder
|
||||
$customerData = array_filter($customerData, fn($value) => $value !== null);
|
||||
|
||||
$customer = $this->client->createCustomer($customerData);
|
||||
|
||||
$result = new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $customer
|
||||
]);
|
||||
$result->status = Status::CREATED;
|
||||
return $result;
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/Application/Shopify/CustomerRequest.php
Normal file
18
src/Application/Shopify/CustomerRequest.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
|
||||
final readonly class CustomerRequest
|
||||
{
|
||||
public function __construct(
|
||||
public string $firstName,
|
||||
public string $lastName,
|
||||
public string $email,
|
||||
public ?string $phone = null,
|
||||
public ?bool $verifiedEmail = null,
|
||||
public ?array $addresses = null,
|
||||
public ?string $password = null,
|
||||
public ?bool $sendWelcomeEmail = null
|
||||
) {}
|
||||
}
|
||||
118
src/Application/Shopify/OrderController.php
Normal file
118
src/Application/Shopify/OrderController.php
Normal file
@@ -0,0 +1,118 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
|
||||
use App\Framework\Api\ApiException;
|
||||
use App\Framework\Attributes\Route;
|
||||
use App\Framework\Http\Method;
|
||||
use App\Framework\Http\Status;
|
||||
use App\Framework\Router\Result\JsonResult;
|
||||
use App\Infrastructure\Api\ShopifyClient;
|
||||
use Archive\Config\ApiConfig;
|
||||
|
||||
final class OrderController
|
||||
{
|
||||
private ShopifyClient $client;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->client = new ShopifyClient(
|
||||
ApiConfig::SHOPIFY_SHOP_DOMAIN->value,
|
||||
ApiConfig::SHOPIFY_ACCESS_TOKEN->value,
|
||||
ApiConfig::SHOPIFY_API_VERSION->value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Bestellungen ab
|
||||
*/
|
||||
#[Route(path: '/api/shopify/orders', method: Method::GET)]
|
||||
public function listOrders(): JsonResult
|
||||
{
|
||||
try {
|
||||
$options = [
|
||||
'limit' => 50,
|
||||
'status' => 'any',
|
||||
'fields' => 'id,order_number,customer,total_price,created_at,financial_status'
|
||||
];
|
||||
|
||||
$orders = $this->client->getOrders($options);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $orders
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft eine einzelne Bestellung ab
|
||||
*/
|
||||
#[Route(path: '/api/shopify/orders/{id}', method: Method::GET)]
|
||||
public function getOrder(int $id): JsonResult
|
||||
{
|
||||
try {
|
||||
$order = $this->client->getOrder($id);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $order
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt eine neue Bestellung
|
||||
*/
|
||||
#[Route(path: '/api/shopify/orders', method: Method::POST)]
|
||||
public function createOrder(OrderRequest $request): JsonResult
|
||||
{
|
||||
try {
|
||||
$orderData = [
|
||||
'line_items' => $request->lineItems,
|
||||
'customer' => $request->customer ?? null,
|
||||
'shipping_address' => $request->shippingAddress ?? null,
|
||||
'billing_address' => $request->billingAddress ?? null,
|
||||
'financial_status' => $request->financialStatus ?? 'pending',
|
||||
'fulfillment_status' => $request->fulfillmentStatus ?? null,
|
||||
'tags' => $request->tags ?? '',
|
||||
'note' => $request->note ?? null,
|
||||
'email' => $request->email ?? null
|
||||
];
|
||||
|
||||
// Entferne leere Felder
|
||||
$orderData = array_filter($orderData, fn($value) => $value !== null);
|
||||
|
||||
$order = $this->client->createOrder($orderData);
|
||||
|
||||
$result = new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $order
|
||||
]);
|
||||
$result->status = Status::CREATED;
|
||||
return $result;
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
19
src/Application/Shopify/OrderRequest.php
Normal file
19
src/Application/Shopify/OrderRequest.php
Normal file
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
|
||||
final class OrderRequest
|
||||
{
|
||||
public function __construct(
|
||||
public readonly array $lineItems,
|
||||
public readonly ?array $customer = null,
|
||||
public readonly ?array $shippingAddress = 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
|
||||
) {}
|
||||
}
|
||||
192
src/Application/Shopify/ProductController.php
Normal file
192
src/Application/Shopify/ProductController.php
Normal file
@@ -0,0 +1,192 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
|
||||
use App\Framework\Api\ApiException;
|
||||
use App\Framework\Attributes\Route;
|
||||
use App\Framework\Http\Method;
|
||||
use App\Framework\Http\Status;
|
||||
use App\Framework\Router\Result\JsonResult;
|
||||
use App\Infrastructure\Api\ShopifyClient;
|
||||
use Archive\Config\ApiConfig;
|
||||
|
||||
final class ProductController
|
||||
{
|
||||
private ShopifyClient $client;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->client = new ShopifyClient(
|
||||
ApiConfig::SHOPIFY_SHOP_DOMAIN->value,
|
||||
ApiConfig::SHOPIFY_ACCESS_TOKEN->value,
|
||||
ApiConfig::SHOPIFY_API_VERSION->value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Produkte aus dem Shopify-Shop ab
|
||||
*/
|
||||
#[Route(path: '/api/shopify/products', method: Method::GET)]
|
||||
public function listProducts(): JsonResult
|
||||
{
|
||||
try {
|
||||
$options = [
|
||||
'limit' => 50,
|
||||
'fields' => 'id,title,variants,images,status,published_at'
|
||||
];
|
||||
|
||||
$products = $this->client->getProducts($options);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $products
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft ein einzelnes Produkt anhand seiner ID ab
|
||||
*/
|
||||
#[Route(path: '/api/shopify/products/{id}', method: Method::GET)]
|
||||
public function getProduct(int $id): JsonResult
|
||||
{
|
||||
try {
|
||||
$product = $this->client->getProduct($id);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $product
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt ein neues Produkt
|
||||
*/
|
||||
#[Route(path: '/api/shopify/products', method: Method::POST)]
|
||||
public function createProduct(ProductRequest $request): JsonResult
|
||||
{
|
||||
try {
|
||||
$product = $this->client->createProduct([
|
||||
'title' => $request->title,
|
||||
'body_html' => $request->description ?? '',
|
||||
'vendor' => $request->vendor ?? 'Custom Shop',
|
||||
'product_type' => $request->productType ?? '',
|
||||
'tags' => $request->tags ?? '',
|
||||
'variants' => $request->variants ?? [],
|
||||
'options' => $request->options ?? [],
|
||||
'images' => $request->images ?? []
|
||||
]);
|
||||
|
||||
$result = new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $product
|
||||
]);
|
||||
$result->status = Status::CREATED;
|
||||
return $result;
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Aktualisiert ein bestehendes Produkt
|
||||
*/
|
||||
#[Route(path: '/api/shopify/products/{id}', method: Method::PUT)]
|
||||
public function updateProduct(int $id, ProductRequest $request): JsonResult
|
||||
{
|
||||
try {
|
||||
$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;
|
||||
|
||||
$product = $this->client->updateProduct($id, $productData);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $product
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht ein Produkt
|
||||
*/
|
||||
#[Route(path: '/api/shopify/products/{id}', method: Method::DELETE)]
|
||||
public function deleteProduct(int $id): JsonResult
|
||||
{
|
||||
try {
|
||||
$success = $this->client->deleteProduct($id);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => $success,
|
||||
'message' => $success ? 'Produkt erfolgreich gelöscht' : 'Produkt konnte nicht gelöscht werden'
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht nach Produkten
|
||||
*/
|
||||
#[Route(path: '/api/shopify/products/search', method: Method::GET)]
|
||||
public function searchProducts(string $query): JsonResult
|
||||
{
|
||||
try {
|
||||
$products = $this->client->searchProducts($query);
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $products
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/Application/Shopify/ProductRequest.php
Normal file
18
src/Application/Shopify/ProductRequest.php
Normal file
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
|
||||
final class ProductRequest
|
||||
{
|
||||
public function __construct(
|
||||
public readonly string $title,
|
||||
public readonly ?string $description = null,
|
||||
public readonly ?string $vendor = null,
|
||||
public readonly ?string $productType = null,
|
||||
public readonly ?string $tags = null,
|
||||
public readonly ?array $variants = null,
|
||||
public readonly ?array $options = null,
|
||||
public readonly ?array $images = null
|
||||
) {}
|
||||
}
|
||||
101
src/Application/Shopify/ShopController.php
Normal file
101
src/Application/Shopify/ShopController.php
Normal file
@@ -0,0 +1,101 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
|
||||
use App\Framework\Api\ApiException;
|
||||
use App\Framework\Attributes\Route;
|
||||
use App\Framework\Http\Method;
|
||||
use App\Framework\Http\Status;
|
||||
use App\Framework\Router\Result\JsonResult;
|
||||
use App\Infrastructure\Api\ShopifyClient;
|
||||
use Archive\Config\ApiConfig;
|
||||
|
||||
final class ShopController
|
||||
{
|
||||
private ShopifyClient $client;
|
||||
|
||||
public function __construct()
|
||||
{
|
||||
$this->client = new ShopifyClient(
|
||||
ApiConfig::SHOPIFY_SHOP_DOMAIN->value,
|
||||
ApiConfig::SHOPIFY_ACCESS_TOKEN->value,
|
||||
ApiConfig::SHOPIFY_API_VERSION->value
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft Informationen über den Shop ab
|
||||
*/
|
||||
#[Route(path: '/api/shopify/shop', method: Method::GET)]
|
||||
public function getShopInfo(): JsonResult
|
||||
{
|
||||
try {
|
||||
$shopInfo = $this->client->getShopInfo();
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $shopInfo
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft die Webhooks des Shops ab
|
||||
*/
|
||||
#[Route(path: '/api/shopify/webhooks', method: Method::GET)]
|
||||
public function getWebhooks(): JsonResult
|
||||
{
|
||||
try {
|
||||
$webhooks = $this->client->getWebhooks();
|
||||
|
||||
return new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $webhooks
|
||||
]);
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Erstellt einen neuen Webhook
|
||||
*/
|
||||
#[Route(path: '/api/shopify/webhooks', method: Method::POST)]
|
||||
public function createWebhook(WebhookRequest $request): JsonResult
|
||||
{
|
||||
try {
|
||||
$webhook = $this->client->createWebhook(
|
||||
$request->topic,
|
||||
$request->address,
|
||||
$request->format ?? 'json'
|
||||
);
|
||||
|
||||
$result = new JsonResult([
|
||||
'success' => true,
|
||||
'data' => $webhook
|
||||
]);
|
||||
$result->status = Status::CREATED;
|
||||
return $result;
|
||||
} catch (ApiException $e) {
|
||||
$result = new JsonResult([
|
||||
'success' => false,
|
||||
'error' => $e->getMessage()
|
||||
]);
|
||||
$result->status = Status::from($e->getCode() ?: 500);
|
||||
return $result;
|
||||
}
|
||||
}
|
||||
}
|
||||
103
src/Application/Shopify/ShopifyWebhookHandler.php
Normal file
103
src/Application/Shopify/ShopifyWebhookHandler.php
Normal file
@@ -0,0 +1,103 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
|
||||
use App\Framework\Attributes\Route;
|
||||
use App\Framework\Http\Method;
|
||||
use App\Framework\Http\Request;
|
||||
use App\Framework\Http\Status;
|
||||
use App\Framework\Router\Result\JsonResult;
|
||||
|
||||
final class ShopifyWebhookHandler
|
||||
{
|
||||
/**
|
||||
* Verarbeitet eingehende Shopify-Webhooks
|
||||
*
|
||||
* Hinweis: Shopify überprüft die Authentizität von Webhooks mit dem X-Shopify-Hmac-Sha256 Header
|
||||
*/
|
||||
#[Route(path: '/webhook/shopify', method: Method::POST)]
|
||||
public function handleWebhook(Request $request): JsonResult
|
||||
{
|
||||
// Webhook-Thema aus dem Header lesen
|
||||
$topic = $request->headers->get('X-Shopify-Topic')[0] ?? null;
|
||||
$shopDomain = $request->headers->get('X-Shopify-Shop-Domain')[0] ?? null;
|
||||
$hmac = $request->headers->get('X-Shopify-Hmac-Sha256')[0] ?? null;
|
||||
|
||||
// Validiere den HMAC, um sicherzustellen, dass der Request von Shopify kommt
|
||||
$rawData = $request->body;
|
||||
|
||||
if (!$this->validateWebhookHmac($hmac, $rawData)) {
|
||||
$result = new JsonResult(['error' => 'Ungültiger HMAC']);
|
||||
$result->status = Status::UNAUTHORIZED;
|
||||
return $result;
|
||||
}
|
||||
|
||||
// Daten verarbeiten
|
||||
$data = json_decode($rawData, true);
|
||||
|
||||
// Je nach Topic unterschiedlich verarbeiten
|
||||
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...
|
||||
default:
|
||||
// Unbekanntes Thema, loggen oder ignorieren
|
||||
break;
|
||||
}
|
||||
|
||||
// Shopify erwartet eine erfolgreiche Antwort (2xx)
|
||||
return new JsonResult(['success' => true]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validiert den HMAC-Header
|
||||
*/
|
||||
private function validateWebhookHmac(?string $hmac, string $data): bool
|
||||
{
|
||||
if (!$hmac) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Das Shared Secret sollte eigentlich in ApiConfig sein
|
||||
$secret = 'dein_webhook_shared_secret'; // ODER aus ApiConfig holen
|
||||
$calculatedHmac = base64_encode(hash_hmac('sha256', $data, $secret, true));
|
||||
|
||||
return hash_equals($calculatedHmac, $hmac);
|
||||
}
|
||||
|
||||
/**
|
||||
* Verarbeitet eine neu erstellte Bestellung
|
||||
*/
|
||||
private function processOrderCreated(array $orderData): void
|
||||
{
|
||||
// Hier die Logik für neue Bestellungen implementieren
|
||||
// z.B. in eigenes System übertragen, E-Mails versenden, etc.
|
||||
}
|
||||
|
||||
/**
|
||||
* Verarbeitet Produkt-Updates
|
||||
*/
|
||||
private function processProductUpdate(array $productData): void
|
||||
{
|
||||
// Hier die Logik für Produkt-Updates implementieren
|
||||
// z.B. Lagerbestand in eigenem System aktualisieren
|
||||
}
|
||||
|
||||
/**
|
||||
* Verarbeitet einen neu erstellten Kunden
|
||||
*/
|
||||
private function processCustomerCreated(array $customerData): void
|
||||
{
|
||||
// Hier die Logik für neue Kunden implementieren
|
||||
// z.B. in CRM-System übertragen, Newsletter-Anmeldung
|
||||
}
|
||||
}
|
||||
13
src/Application/Shopify/WebhookRequest.php
Normal file
13
src/Application/Shopify/WebhookRequest.php
Normal file
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace App\Application\Shopify;
|
||||
|
||||
final class WebhookRequest
|
||||
{
|
||||
public function __construct(
|
||||
public readonly string $topic,
|
||||
public readonly string $address,
|
||||
public readonly ?string $format = 'json'
|
||||
) {}
|
||||
}
|
||||
Reference in New Issue
Block a user