everything semi working before sample implementation
This commit is contained in:
@@ -164,36 +164,58 @@ class CustomOrderController extends Controller
|
||||
*/
|
||||
public function depositPayment(Request $request)
|
||||
{
|
||||
Log::info('Deposit payment initiated', [
|
||||
'request_data' => $request->all(),
|
||||
'user_id' => auth()->id(),
|
||||
]);
|
||||
$validated = $request->validate([
|
||||
'custom_order_id' => 'required|exists:custom_orders,id',
|
||||
]);
|
||||
Log::info('Deposit payment validation passed', $validated);
|
||||
|
||||
$customOrder = CustomOrder::findOrFail($validated['custom_order_id']);
|
||||
|
||||
// Check authorization
|
||||
if ($customOrder->user_id !== auth()->id()) {
|
||||
Log::warning('Unauthorized deposit payment attempt', [
|
||||
'custom_order_id' => $customOrder->id,
|
||||
'user_id' => auth()->id(),
|
||||
]);
|
||||
abort(403);
|
||||
}
|
||||
|
||||
// Check if already paid
|
||||
if ($customOrder->deposit_status === 'paid') {
|
||||
Log::info('Deposit already paid for custom order', [
|
||||
'custom_order_id' => $customOrder->id,
|
||||
]);
|
||||
return redirect()->route('custom-orders.show', $customOrder)
|
||||
->with('info', 'Deposit already paid for this order.');
|
||||
}
|
||||
|
||||
// Initiate Yoco payment for deposit
|
||||
Log::info('Initiating Yoco payment for custom order deposit', [
|
||||
'custom_order_id' => $customOrder->id,
|
||||
'deposit_amount' => $customOrder->deposit_amount,
|
||||
]);
|
||||
$yocoResponse = $this->initiateYocoPayment(
|
||||
amount: (int)($customOrder->deposit_amount * 100), // Convert to cents
|
||||
orderId: $customOrder->uuid,
|
||||
customOrder: $customOrder,
|
||||
orderType: 'custom_deposit',
|
||||
description: "Deposit for Custom {$customOrder->type} Order #{$customOrder->order_number}"
|
||||
description: "Deposit for Order #{$customOrder->order_number}"
|
||||
);
|
||||
|
||||
if (!$yocoResponse) {
|
||||
Log::error('Failed to initiate Yoco payment for custom order deposit', [
|
||||
'custom_order_id' => $customOrder->id,
|
||||
]);
|
||||
return redirect()->route('custom-orders.show', $customOrder)
|
||||
->with('error', 'Failed to initiate payment. Please try again.');
|
||||
}
|
||||
|
||||
Log::info('Yoco payment initiated successfully for custom order deposit', [
|
||||
'custom_order_id' => $customOrder->id,
|
||||
'checkout_url' => $yocoResponse['checkout_url'],
|
||||
]);
|
||||
return redirect($yocoResponse['checkout_url']);
|
||||
}
|
||||
|
||||
@@ -207,11 +229,11 @@ class CustomOrderController extends Controller
|
||||
abort(403);
|
||||
}
|
||||
|
||||
// Update order status
|
||||
$customOrder->update([
|
||||
'deposit_status' => 'paid',
|
||||
'status' => 'submitted',
|
||||
]);
|
||||
// // Update order status
|
||||
// $customOrder->update([
|
||||
// 'deposit_status' => 'paid',
|
||||
// 'status' => 'submitted',
|
||||
// ]);
|
||||
|
||||
return view('custom-orders.deposit-success', [
|
||||
'customOrder' => $customOrder,
|
||||
@@ -250,67 +272,143 @@ class CustomOrderController extends Controller
|
||||
/**
|
||||
* Initiate Yoco payment
|
||||
*/
|
||||
private function initiateYocoPayment($amount, $orderId, $orderType, $description)
|
||||
private function initiateYocoPayment($amount, $customOrder, $orderType, $description)
|
||||
{
|
||||
$yocoSecret = config('services.yoco.secret_key');
|
||||
|
||||
Log::info('Initiating Yoco payment', [
|
||||
'order_id' => $customOrder->uuid,
|
||||
'order_type' => $orderType,
|
||||
'amount' => $amount,
|
||||
'description' => $description,
|
||||
]);
|
||||
|
||||
if (!$yocoSecret) {
|
||||
if (!$customOrder) {
|
||||
Log::error('Custom order not found for Yoco payment', [
|
||||
'order_id' => $customOrder->uuid ?? 'unknown',
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
Log::info('Custom order found for Yoco payment', [
|
||||
'order_id' => $customOrder->uuid,
|
||||
'custom_order_data' => $customOrder->toArray(),
|
||||
]);
|
||||
// Get configuration
|
||||
$secretKey = config('services.yoco.secret_key');
|
||||
$mode = config('services.yoco.mode');
|
||||
|
||||
Log::info('Yoco configuration', [
|
||||
'mode' => $mode,
|
||||
'secret_key_set' => !empty($secretKey) && $secretKey !== 'sk_test_your_key_here',
|
||||
]);
|
||||
|
||||
// Check if API key is configured
|
||||
if (empty($secretKey) || $secretKey === 'sk_test_your_key_here') {
|
||||
Log::error('Yoco secret key not configured');
|
||||
return null;
|
||||
}
|
||||
|
||||
$payload = [
|
||||
|
||||
$baseUrl = $mode === 'live'
|
||||
? 'https://payments.yoco.com/api/checkouts'
|
||||
: 'https://payments.yoco.com/api/checkouts';
|
||||
|
||||
$checkoutData = [
|
||||
'amount' => $amount,
|
||||
'currency' => 'ZAR',
|
||||
'successUrl' => route('yoco-custom-deposit-success', ['customOrder' => $orderId]),
|
||||
'failureUrl' => route('custom-orders.show', ['customOrder' => $orderId]),
|
||||
'cancelUrl' => route('custom-orders.show', ['customOrder' => $orderId]),
|
||||
'successUrl' => route('yoco-custom-deposit-success', ['customOrder' => $customOrder->uuid]),
|
||||
'cancelUrl' => route('custom-orders.show', ['customOrder' => $customOrder->uuid]),
|
||||
'failureUrl' => route('custom-orders.show', ['customOrder' => $customOrder->uuid]),
|
||||
'metadata' => [
|
||||
'order_uuid' => $orderId,
|
||||
'order_uuid' => $customOrder->uuid,
|
||||
'order_type' => $orderType,
|
||||
],
|
||||
'description' => $description,
|
||||
'site' => 'additional_design',
|
||||
'description' => $description
|
||||
]
|
||||
];
|
||||
|
||||
Log::info('Yoco checkout data prepared', [
|
||||
'order_id' => $customOrder->uuid,
|
||||
'checkout_data' => $checkoutData,
|
||||
]);
|
||||
|
||||
// Make API request to Yoco
|
||||
|
||||
try {
|
||||
Log::info('Initiating Yoco payment', [
|
||||
'amount' => $amount,
|
||||
'orderId' => $orderId,
|
||||
'description' => $description
|
||||
]);
|
||||
|
||||
$response = Http::withHeaders([
|
||||
'Authorization' => 'Bearer ' . $yocoSecret,
|
||||
'Authorization' => 'Bearer ' . $secretKey,
|
||||
'Content-Type' => 'application/json',
|
||||
])->post('https://payments.yoco.com/api/checkouts', $payload);
|
||||
|
||||
Log::info('Yoco API response', [
|
||||
'status' => $response->status(),
|
||||
'body' => $response->body()
|
||||
]);
|
||||
|
||||
])->post($baseUrl, $checkoutData);
|
||||
|
||||
if ($response->successful()) {
|
||||
$data = $response->json();
|
||||
Log::info('Yoco payment success', [
|
||||
'checkout_url' => $data['redirectUrl'] ?? 'N/A',
|
||||
'checkout_id' => $data['id'] ?? 'N/A'
|
||||
$checkout = $response->json();
|
||||
|
||||
$checkoutId = $checkout['id'] ?? null;
|
||||
$redirectUrl = $checkout['redirectUrl'] ?? null;
|
||||
|
||||
Log::info('Yoco checkout created for custom order', [
|
||||
'order_uuid' => $customOrder->uuid,
|
||||
'checkout_id' => $checkoutId,
|
||||
'redirect_url' => $redirectUrl,
|
||||
]);
|
||||
|
||||
if (!$checkoutId || !$redirectUrl) {
|
||||
Log::error('Invalid Yoco checkout response: missing id or redirectUrl', [
|
||||
'order_uuid' => $customOrder->uuid,
|
||||
'response' => $checkout,
|
||||
]);
|
||||
throw new \Exception('Invalid Yoco checkout response: missing id or redirectUrl');
|
||||
}
|
||||
|
||||
// Persist checkout info to database
|
||||
try {
|
||||
$customOrder->update([
|
||||
'yoco_checkout_id' => $checkoutId,
|
||||
'yoco_redirect_url' => $redirectUrl,
|
||||
'yoco_checkout_response' => json_encode($checkout),
|
||||
]);
|
||||
|
||||
// Reload the model to verify update
|
||||
$customOrder->refresh();
|
||||
|
||||
if ($customOrder->yoco_checkout_id) {
|
||||
Log::info('Yoco checkout info saved successfully for custom order', [
|
||||
'order_uuid' => $customOrder->uuid,
|
||||
'yoco_checkout_id' => $customOrder->yoco_checkout_id,
|
||||
]);
|
||||
} else {
|
||||
Log::warning('Yoco checkout ID not saved after update for custom order', [
|
||||
'order_uuid' => $customOrder->uuid,
|
||||
'order_data' => $customOrder->toArray(),
|
||||
]);
|
||||
}
|
||||
} catch (\Exception $dbException) {
|
||||
Log::error('Database error while saving Yoco checkout info for custom order', [
|
||||
'order_uuid' => $customOrder->uuid,
|
||||
'error_message' => $dbException->getMessage(),
|
||||
'error_code' => $dbException->getCode(),
|
||||
'checkout_id' => $checkoutId,
|
||||
'redirect_url' => $redirectUrl,
|
||||
]);
|
||||
throw $dbException;
|
||||
}
|
||||
|
||||
return [
|
||||
'checkout_url' => $data['redirectUrl'],
|
||||
'checkout_id' => $data['id'],
|
||||
'checkout_url' => $redirectUrl,
|
||||
'checkout_id' => $checkoutId,
|
||||
];
|
||||
} else {
|
||||
Log::error('Yoco payment API error', [
|
||||
Log::error('Yoco API Error for custom order', [
|
||||
'order_uuid' => $customOrder->uuid,
|
||||
'status' => $response->status(),
|
||||
'body' => $response->body()
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
} catch (\Exception $e) {
|
||||
Log::error('Yoco payment exception: ' . $e->getMessage(), [
|
||||
'trace' => $e->getTraceAsString()
|
||||
Log::error('Yoco Payment Exception for custom order', [
|
||||
'order_uuid' => $customOrder->uuid,
|
||||
'message' => $e->getMessage()
|
||||
]);
|
||||
return null;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
namespace App\Http\Controllers;
|
||||
|
||||
use App\Models\CustomOrder;
|
||||
use App\Models\Order;
|
||||
use App\Models\OrderItem;
|
||||
use App\Models\Product;
|
||||
@@ -267,6 +268,7 @@ class OrderController extends Controller
|
||||
'metadata' => [
|
||||
'order_uuid' => $order->uuid,
|
||||
'order_number' => $order->order_number,
|
||||
'order_type' => 'standard',
|
||||
'site' => 'additional_design',
|
||||
],
|
||||
];
|
||||
@@ -477,6 +479,7 @@ class OrderController extends Controller
|
||||
|
||||
$metadata = $payload['metadata'] ?? [];
|
||||
$orderUuid = $metadata['order_uuid'] ?? null;
|
||||
$orderType = $metadata['order_type'] ?? null;
|
||||
$site = $metadata['site'] ?? null;
|
||||
$paymentId = $payload['id'] ?? null;
|
||||
$status = $payload['status'] ?? null;
|
||||
@@ -484,6 +487,7 @@ class OrderController extends Controller
|
||||
\Log::info('Yoco Webhook: Payload extracted', [
|
||||
'type' => $type,
|
||||
'site' => $site,
|
||||
'order_type' => $orderType,
|
||||
'order_uuid' => $orderUuid,
|
||||
'payment_id' => $paymentId,
|
||||
'status' => $status,
|
||||
@@ -506,49 +510,107 @@ class OrderController extends Controller
|
||||
return response()->json(['error' => 'Invalid payload'], 400);
|
||||
}
|
||||
|
||||
// 7. Update Payment State
|
||||
$order = Order::where('uuid', $orderUuid)->first();
|
||||
// 7. Update Payment State where orderType is 'standard'
|
||||
if ($orderType === 'standard') {
|
||||
|
||||
if (!$order) {
|
||||
\Log::warning('Yoco Webhook: Order not found', ['order_uuid' => $orderUuid]);
|
||||
return response()->json(['error' => 'Order not found'], 404);
|
||||
}
|
||||
|
||||
if ($status === 'succeeded') {
|
||||
\Log::info('Yoco Webhook: Processing successful payment', [
|
||||
'order_uuid' => $orderUuid,
|
||||
'payment_id' => $paymentId,
|
||||
]);
|
||||
$order = Order::where('uuid', $orderUuid)->first();
|
||||
|
||||
if ($order->payment_status !== 'paid') {
|
||||
$order->update([
|
||||
'payment_status' => 'paid',
|
||||
'status' => 'processing',
|
||||
'yoco_checkout_response' => json_encode($payload),
|
||||
if (!$order) {
|
||||
\Log::warning('Yoco Webhook: Order not found', ['order_uuid' => $orderUuid]);
|
||||
return response()->json(['error' => 'Order not found'], 404);
|
||||
}
|
||||
|
||||
if ($status === 'succeeded') {
|
||||
\Log::info('Yoco Webhook: Processing successful payment', [
|
||||
'order_uuid' => $orderUuid,
|
||||
'payment_id' => $paymentId,
|
||||
]);
|
||||
|
||||
// Reduce stock
|
||||
foreach ($order->items as $item) {
|
||||
$product = $item->product;
|
||||
$product->stock -= $item->quantity;
|
||||
$product->save();
|
||||
if ($order->payment_status !== 'paid') {
|
||||
$order->update([
|
||||
'payment_status' => 'paid',
|
||||
'status' => 'processing',
|
||||
'yoco_checkout_response' => json_encode($payload),
|
||||
]);
|
||||
|
||||
// Reduce stock
|
||||
foreach ($order->items as $item) {
|
||||
$product = $item->product;
|
||||
$product->stock -= $item->quantity;
|
||||
$product->save();
|
||||
}
|
||||
|
||||
\Log::info('Yoco Webhook: Order updated for successful payment', [
|
||||
'order_uuid' => $orderUuid,
|
||||
'order_id' => $order->id,
|
||||
]);
|
||||
}
|
||||
|
||||
\Log::info('Yoco Webhook: Order updated for successful payment', [
|
||||
} elseif ($status === 'failed' || $status === 'cancelled') {
|
||||
\Log::info('Yoco Webhook: Processing failed/cancelled payment', [
|
||||
'order_uuid' => $orderUuid,
|
||||
'order_id' => $order->id,
|
||||
'payment_id' => $paymentId,
|
||||
'status' => $status,
|
||||
]);
|
||||
|
||||
$order->update([
|
||||
'payment_status' => 'failed',
|
||||
]);
|
||||
}
|
||||
} elseif ($status === 'failed' || $status === 'cancelled') {
|
||||
\Log::info('Yoco Webhook: Processing failed/cancelled payment', [
|
||||
'order_uuid' => $orderUuid,
|
||||
'payment_id' => $paymentId,
|
||||
'status' => $status,
|
||||
]);
|
||||
} elseif ($orderType === 'custom_deposit' || $orderType === 'custom_balance') {
|
||||
|
||||
$order->update([
|
||||
'payment_status' => 'failed',
|
||||
]);
|
||||
$order = CustomOrder::where('uuid', $orderUuid)->first();
|
||||
|
||||
if (!$order) {
|
||||
\Log::warning('Yoco Webhook: Order not found', ['order_uuid' => $orderUuid]);
|
||||
return response()->json(['error' => 'Order not found'], 404);
|
||||
}
|
||||
|
||||
if ($status === 'succeeded') {
|
||||
\Log::info('Yoco Webhook: Processing successful payment', [
|
||||
'order_uuid' => $orderUuid,
|
||||
'payment_id' => $paymentId,
|
||||
'order_type' => $orderType,
|
||||
]);
|
||||
|
||||
if ($orderType === 'custom_deposit' && $order->deposit_status !== 'paid') {
|
||||
$order->update([
|
||||
'deposit_status' => 'paid',
|
||||
'status' => 'submitted',
|
||||
'yoco_checkout_response' => json_encode($payload),
|
||||
]);
|
||||
|
||||
\Log::info('Yoco Webhook: Order updated for successful deposit payment', [
|
||||
'order_uuid' => $orderUuid,
|
||||
'order_id' => $order->id,
|
||||
'order_type' => $orderType,
|
||||
]);
|
||||
|
||||
} elseif ($orderType === 'custom_balance' && $order->balance_status !== 'paid') {
|
||||
$order->update([
|
||||
'balance_status' => 'paid',
|
||||
'status' => 'in production',
|
||||
'yoco_checkout_response' => json_encode($payload),
|
||||
]);
|
||||
|
||||
\Log::info('Yoco Webhook: Order updated for successful balance payment', [
|
||||
'order_uuid' => $orderUuid,
|
||||
'order_id' => $order->id,
|
||||
'order_type' => $orderType,
|
||||
]);
|
||||
}
|
||||
} elseif ($status === 'failed' || $status === 'cancelled') {
|
||||
\Log::info('Yoco Webhook: Processing failed/cancelled payment', [
|
||||
'order_uuid' => $orderUuid,
|
||||
'payment_id' => $paymentId,
|
||||
'status' => $status,
|
||||
]);
|
||||
|
||||
if ($orderType === 'custom_deposit') {
|
||||
$order->update(['deposit_status' => 'failed']);
|
||||
} elseif ($orderType === 'custom_balance') {
|
||||
$order->update(['balance_status' => 'failed']);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
\Log::info('Yoco Webhook: Processed successfully', [
|
||||
|
||||
Reference in New Issue
Block a user