Unable to fetch Saved Credit Cards


CustomerContext.Current.CurrentContact.ContactCreditCards should return saved credit cards but it doesn't return any list or say length is always 0, even after saving one credit card entry through code.
Also the Saved payment tab is not there in latest versions for Customer Contact, so is this functionality removed intentionally or in process?

To Reproduce
Run this code and at first run there can be empty list of credit cards but after saving one it should show saved credit cards list.

var epiServerContext = CustomerContext.Current.CurrentContact;
            var epiServerCreditCards1 = CustomerContext.Current?.GetContactCreditCards(epiServerContext);
            var epiServerCreditCards2 = epiServerContext?.ContactCreditCards;
            var creditCard = new CreditCard
                LastFourDigits = Convert.ToString("1111"),
                ExpirationMonth = Convert.ToInt32(12),
                ExpirationYear = Convert.ToInt32(2023),
                CardType = 1,
Edited, Sep 14, 2022 10:26

Checking the foundation code that credit card creation is different that what you've got, instead it's

var creditCard = Mediachase.Commerce.Customers.CreditCard.CreateInstance();
creditCard.ContactId = PrimaryKeyId.Parse(_customerService.GetCurrentContactViewModel().ContactId.ToString());

Can you try this and see if you still get the issue as foundation is using GetContactCreditCards(currentContact) as you are

Sep 14, 2022 12:34
Sandeep Singh Shekhawat - Sep 15, 2022 12:00
Thanks for response Scott, I tried the exact code below:-
////////////////////////// Code Starts ////////////////////////////
var creditCard = Mediachase.Commerce.Customers.CreditCard.CreateInstance();
creditCard.ContactId = PrimaryKeyId.Parse(_customerService.GetCurrentContactViewModel().ContactId.ToString());
creditCard.LastFourDigits = "1234";
creditCard.ExpirationMonth = 12;
creditCard.ExpirationYear = 2023;
creditCard.CardType = 1;
var cards = CustomerContext.Current?.GetContactCreditCards(CustomerContext.Current.CurrentContact);
////////////////////////// XXXX ////////////////////////////

and the cards variable was empty, and I run that code in foundation. Is there any thing that I missed or that's a bug?

Apologies Scott, I don't mean to hijack your response. Just going to add my 2 cents.

CreditCard class has actually been marked as obsolete. The reason is that it's not actually PCI compliant because its storing credit card information as plain text in the database. So I expect they will remove this soon. I can't remember what the time frame is from marking a class obsolete to it being removed from the codebase, maybe Scott can help shed some light on that. I would not recommend using this part of commerce and implement your own credit card persistence and have it conform to pci compliance standards.

In answer to your original question, it looks like when the credit card gets loaded from the database, it casts it to Mediachase.Commerce.Customers.CreditCard immediately but because the cast fails...you end up getting an empty list. This is all happening inside the GetContactCreditCards method.

Sep 14, 2022 19:55
Sandeep Singh Shekhawat - Sep 15, 2022 12:06
Thanks for response Surjit, Can you elaborate more on implementing own credit card persistence. Did you mean to create own tables confirming to pci compliance standards?

Just want to add one more thing that add credit card works, in database I can see that row in cls_CreditCard table.
Surjit Bharath - Sep 15, 2022 22:35
There's a list of objectives you need to implement in order for your client to achieve PCI DSS. As Quan mentions in his post, most payment gateway providers will have some sort of integration that allows them to take card payment in your checkout journey without your client's server ever having to touch the credit card information. This means the payment gateway provider take on that responsibility and not your client. 90% of my commerce clients in the past 8 years have done it this way.

Credit card type is now marked as absolete - as Surjit said. Storing card numbers is not PCI compliant, which is why it is not recommended anymore. (in most cases, you should be using an external payment provider and they will handle the card information for you, that's usually easier, safer and more future proof.

If you just want to to store information like the last 4 numbers of the card, you can add extra field to your order and store it there. (as a customer I think that feature is quite helpful because I know which card I used for that order).

If you absolutely need to store card information, you can try this, again, not recommended:

                var creditcard = CreditCard.CreateInstance();
                creditcard.CardType = (int)CreditCard.eCreditCardType.Visa;
#pragma warning restore CS0618 // Type or member is obsolete
                creditcard.CreditCardNumber = "421698997636466";
                creditcard.LastFourDigits = "6466";

Sep 15, 2022 13:47
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.