Credit Card Numbers are still an issue
- Dominant language
- C#
- Stars
- 10.9k
- Forks
- 3.8k
- Avg merge
- 1d 11h
- Merged PRs (30d)
- 4
Description
Hi friends - wanted to revisit #110 once again as this latest rev has a few issues still.
First: the card number is [masked in the OrdersApi](https://github.com/dotnet/eShop/blob/b81ad9557090cc37233b9d1a0a729db7b44b6f14/src/Ordering.API/Apis/OrdersApi.cs#L140) which is great, but [just a few lines above it](https://github.com/dotnet/eShop/blob/b81ad9557090cc37233b9d1a0a729db7b44b6f14/src/Ordering.API/Apis/OrdersApi.cs#L134) will log a credit card number to the logs in the clear if there's request id problem.
## PCI Compliance and Privacy Issues
The [payment method](https://github.com/dotnet/eShop/blob/b81ad9557090cc37233b9d1a0a729db7b44b6f14/src/Ordering.Domain/AggregatesModel/BuyerAggregate/PaymentMethod.cs#L5) still stores all the things you're not supposed to store in server memory or otherwise. This is also (from what I can see) stored in the database, which is a PCI issue as well.
Given the credit card number is masked, storing any payment information doesn't make sense. The CVV is unusable as is everything else. From what I remember RE our privacy training, this kind of thing should be handled a bit more delicately :) (thinking about identifiable information here).
I know this is a "reference" application and is probably "for entertainment purposes only" :D but I think it would be nice to show people how credit card information should be handled so they don't find themselves in a super bad breach situation down the road.
In terms of a PR, I tried this once before and it's a very, very heavy lift to pull this out. I asked Sonnet 4.6 what it would take to "fix" this by plugging in Stripe (which is the simplest thing I could think of) and here's the response:
```
1. Frontend — src/WebApp
- Add Stripe.js / Stripe Elements to the Blazor app (via JS interop)
- Checkout.razor needs a card input component that tokenizes on the client
- BasketState.cs:100-104 — remove the hardcoded card fields entirely; instead get back a paymentMethodId from Stripe Elements before
calling CreateOrder
2. API contract — CreateOrderRequest / CreateOrderCommand
- Drop CardNumber, CardHolderName, CardExpiration, CardSecurityNumber, CardTypeId
- Add StripePaymentMethodId (a pm_xxx token)
3. Order domain — src/Ordering.Domain
- Order.cs constructor takes card fields today — strip those out, add StripePaymentMethodId
- PaymentMethod.cs — replace _cardNumber, _securityNumber, etc. with _stripePaymentMethodId and _stripeCustomerId
- New DB migration to update the PaymentMethod table schema
4. PaymentProcessor — src/PaymentProcessor
- This is the biggest change. Replace the config-flag simulation in OrderStatusChangedToStockConfirmedIntegrationEventHandler.cs with
a real Stripe call:
- Create/retrieve a Stripe Customer
- Create and confirm a PaymentIntent using the stored paymentMethodId
- Publish success/failure event based on the actual Stripe result
- Add Stripe.net NuGet package, configure API key via secrets/env
5. Logging fix
- OrdersApi.cs:134 — fix the warning log that would dump the raw request (moot once card fields are gone, but fix anyway)
6. Secrets management
- Stripe secret key needs to go in dotnet user-secrets / env vars for the PaymentProcessor project
- Stripe publishable key needs to reach the Blazor frontend
---
Rough order of work
1. Stripe account + keys
2. PaymentMethod domain model + migration
3. Order/command chain (remove card fields, add paymentMethodId)
4. Checkout UI (Stripe Elements via JS interop)
5. PaymentProcessor → real Stripe API call
6. End-to-end test with Stripe test cards
The Blazor/JS interop piece for Stripe Elements is probably the trickiest part since there's no native Stripe Blazor library — you'd
write a small JS shim and call it from Razor. Everything else is fairly mechanical plumbing.
```
This isn't something I think I would want to do in a PR without working with the team directly.
Contributor guide
Assessment
This issue has not been assessed yet.