From e4e008167a6463dfdd956767469b22cccb0addb4 Mon Sep 17 00:00:00 2001 From: Konstantinos Arvanitakis Date: Tue, 15 Sep 2026 21:22:45 +0300 Subject: [PATCH] Fix: Correct Display of last 4 digits of credit card --- src/Order/Services/TransactionRecorder.php | 2 ++ src/Payment/Drivers/StripePaymentDriver.php | 36 +++++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/src/Order/Services/TransactionRecorder.php b/src/Order/Services/TransactionRecorder.php index fc13e29..423959a 100644 --- a/src/Order/Services/TransactionRecorder.php +++ b/src/Order/Services/TransactionRecorder.php @@ -49,6 +49,8 @@ class TransactionRecorder 'reference' => $result->reference, 'status' => $result->status->name, 'notes' => $result->failureReason, + 'card_type' => $result->meta['card_type'] ?? null, + 'last_four' => $result->meta['last_four'] ?? null, 'meta' => $result->meta, ]); } diff --git a/src/Payment/Drivers/StripePaymentDriver.php b/src/Payment/Drivers/StripePaymentDriver.php index f3eadc9..65342cf 100644 --- a/src/Payment/Drivers/StripePaymentDriver.php +++ b/src/Payment/Drivers/StripePaymentDriver.php @@ -170,6 +170,7 @@ class StripePaymentDriver implements reference: $paymentIntent->id, amount: $amount, raw: $paymentIntent->toArray(), + meta: $this->cardMetaFromIntent($paymentIntent), ); $paymentIntent->status === PaymentIntent::STATUS_SUCCEEDED @@ -340,6 +341,7 @@ class StripePaymentDriver implements amount: $amount, failureReason: $paymentIntent->last_payment_error->message ?? null, raw: $paymentIntent->toArray(), + meta: $status === PaymentResultStatus::Pending ? [] : $this->cardMetaFromIntent($paymentIntent), continuation: $continuation, ); @@ -362,6 +364,40 @@ class StripePaymentDriver implements return $result; } + /** + * card_type/last_four for Modules\Core\Order\Services\ + * TransactionRecorder to map onto Transaction (see PaymentResult:: + * $meta's own docblock) — same fields, same source + * (payment_method_details on the underlying Charge) as lunarphp/ + * stripe's own StoreCharges, just reached via latest_charge instead of + * an order-level charge list, since this driver has no Order/Cart to + * enumerate charges from. + * + * @return array{card_type?: string, last_four?: string} + */ + private function cardMetaFromIntent(PaymentIntent $paymentIntent): array + { + $chargeId = $paymentIntent->latest_charge; + + if (blank($chargeId)) { + return []; + } + + $charge = Stripe::getCharge(is_string($chargeId) ? $chargeId : $chargeId->id); + + $paymentType = collect($charge->payment_method_details)->keys()->first(); + $details = collect($charge->payment_method_details)->first(); + + if (blank($details)) { + return []; + } + + return array_filter([ + 'card_type' => $details['brand'] ?? $paymentType, + 'last_four' => $details['last4'] ?? null, + ], fn ($value) => filled($value)); + } + private function declined(string $type, Price $amount, ApiErrorException $e, array $context, bool $authorizing): PaymentResult { $result = $this->failure($amount, $e);