I order notes, BF checkout currency

This commit is contained in:
Fabian @ Blax Software 2026-01-25 10:40:17 +01:00
parent 1a8f111110
commit 440be3a36f
4 changed files with 71 additions and 14 deletions

View File

@ -163,10 +163,11 @@ class StripeWebhookController
// recordPayment(int $amount, ?string $reference, ?string $method, ?string $provider)
$order->recordPayment($amountPaid, $session->payment_intent, 'stripe', 'stripe');
// Add a detailed note
// Add a detailed note (customer-visible)
$order->addNote(
"Payment of " . Order::formatMoney($amountPaid, $currency) . " received via Stripe checkout (Session: {$session->id})",
OrderNote::TYPE_PAYMENT
"Payment of " . Order::formatMoney($amountPaid, $currency) . " received",
OrderNote::TYPE_PAYMENT,
true
);
// Mark order as processing if payment is successful
@ -202,10 +203,11 @@ class StripeWebhookController
$order = $cart->order;
if ($order && $order->status->canTransitionTo(OrderStatus::FAILED)) {
$order->update(['status' => OrderStatus::FAILED]);
// addNote(string $content, string $type, bool $isCustomerNote, ?string $authorType, ?string $authorId)
// Internal note - payment failure details should not be shown to customer
$order->addNote(
"Payment failed via Stripe checkout (Session: {$session->id})",
OrderNote::TYPE_PAYMENT
OrderNote::TYPE_PAYMENT,
false
);
}
}
@ -231,9 +233,11 @@ class StripeWebhookController
// Add note to order if it exists
$order = $cart->order;
if ($order) {
// Internal note - session expiry is a technical detail
$order->addNote(
"Stripe checkout session expired (Session: {$session->id})",
OrderNote::TYPE_SYSTEM
OrderNote::TYPE_SYSTEM,
false
);
}
}

View File

@ -2058,6 +2058,7 @@ class Cart extends Model
// Prepare session parameters
$sessionParams = [
'payment_method_types' => ['card'],
'currency' => strtoupper($this->currency),
'line_items' => $lineItems,
'mode' => 'payment',
'success_url' => $success_url,

View File

@ -147,10 +147,11 @@ class Order extends Model
$difference = $newPaid - $oldPaid;
if ($difference > 0) {
$currency = $order->currency ?? config('shop.currency', 'USD');
$order->addNote(
"Payment received: " . static::formatMoney($difference, $order->currency),
"Payment received: " . static::formatMoney($difference, $currency),
'payment',
false
true
);
// Mark as paid if fully paid
@ -441,10 +442,12 @@ class Order extends Model
$this->amount_refunded = ($this->amount_refunded ?? 0) + $amount;
$this->save();
$currency = $this->currency ?? config('shop.currency', 'USD');
$this->addNote(
"Refund processed: " . static::formatMoney($amount, $this->currency) .
"Refund processed: " . static::formatMoney($amount, $currency) .
($reason ? " - Reason: {$reason}" : ''),
'refund'
'refund',
true
);
// If fully refunded, update status
@ -566,6 +569,56 @@ class Order extends Model
]);
}
/**
* Scope to get final/finished orders (completed, cancelled, refunded, failed, delivered).
* Uses OrderStatus::isFinal() to determine which statuses are final.
*/
public function scopeFinal($query)
{
$finalStatuses = array_map(
fn(OrderStatus $status) => $status->value,
array_filter(OrderStatus::cases(), fn(OrderStatus $status) => $status->isFinal())
);
return $query->whereIn('status', $finalStatuses);
}
/**
* Alias for scopeFinal - get finished orders.
*/
public function scopeFinished($query)
{
return $this->scopeFinal($query);
}
/**
* Scope to get orders requiring payment (pending status).
* Uses OrderStatus::requiresPayment() to determine which statuses require payment.
*/
public function scopeRequiresPayment($query)
{
$requiresPaymentStatuses = array_map(
fn(OrderStatus $status) => $status->value,
array_filter(OrderStatus::cases(), fn(OrderStatus $status) => $status->requiresPayment())
);
return $query->whereIn('status', $requiresPaymentStatuses);
}
/**
* Scope to get orders with a paid status (processing, shipped, delivered, etc.).
* Uses OrderStatus::isPaid() - this is different from scopePaid() which checks amounts.
*/
public function scopeStatusPaid($query)
{
$paidStatuses = array_map(
fn(OrderStatus $status) => $status->value,
array_filter(OrderStatus::cases(), fn(OrderStatus $status) => $status->isPaid())
);
return $query->whereIn('status', $paidStatuses);
}
/**
* Scope to get completed orders.
*/
@ -575,7 +628,7 @@ class Order extends Model
}
/**
* Scope to get paid orders.
* Scope to get paid orders (by amount).
*/
public function scopePaid($query)
{
@ -583,7 +636,7 @@ class Order extends Model
}
/**
* Scope to get unpaid orders.
* Scope to get unpaid orders (by amount).
*/
public function scopeUnpaid($query)
{
@ -857,7 +910,7 @@ class Order extends Model
'status' => OrderStatus::PENDING,
]);
$order->addNote('Order created from cart checkout', 'system', false);
$order->addNote('Order created from cart checkout', 'system', true);
return $order;
}

View File

@ -685,7 +685,6 @@ class StripeWebhookOrderTest extends TestCase
$paymentNote = $order->notes()->where('type', OrderNote::TYPE_PAYMENT)->first();
$this->assertNotNull($paymentNote, 'Payment note should be created');
$this->assertStringContainsString('50', $paymentNote->content);
$this->assertStringContainsString('Stripe checkout', $paymentNote->content);
}
#[Test]