cancel
Showing results for 
Search instead for 
Did you mean: 

Get Customer Profile unable to reffrence cardNumber

How do I cast the masked CC numbers from the responce?

 

I tried doing a foreach (var s in response.profile.paymentProfiles)

and then drilling into s.payment.item.cardNumber But that does not seem to be option.

PaceDev
Member
6 REPLIES 6

It's odd that the API shows the responce

creditCardContains credit card payment information for the customer profile. 
cardNumberThe customer’s credit card number.
All sensitive payment information in the output is masked.
13 to 16 digits.

 

But the responce has it as Item.

 

-        paymentProfiles    {AuthorizeNet.Api.Contracts.V1.customerPaymentProfileMaskedType[1]}    AuthorizeNet.Api.Contracts.V1.customerPaymentProfileMaskedType[]
-        [0]    {AuthorizeNet.Api.Contracts.V1.customerPaymentProfileMaskedType}    AuthorizeNet.Api.Contracts.V1.customerPaymentProfileMaskedType
+        billTo    {AuthorizeNet.Api.Contracts.V1.customerAddressType}    AuthorizeNet.Api.Contracts.V1.customerAddressType
        customerPaymentProfileId    "2501154857"    string
        customerProfileId    null    string
        customerType    individual    AuthorizeNet.Api.Contracts.V1.customerTypeEnum
        customerTypeSpecified    false    bool
        defaultPaymentProfile    false    bool
        defaultPaymentProfileSpecified    false    bool
        driversLicense    null    AuthorizeNet.Api.Contracts.V1.driversLicenseMaskedType
-        payment    {AuthorizeNet.Api.Contracts.V1.paymentMaskedType}    AuthorizeNet.Api.Contracts.V1.paymentMaskedType
-        Item    {AuthorizeNet.Api.Contracts.V1.creditCardMaskedType}    object {AuthorizeNet.Api.Contracts.V1.creditCardMaskedType}
        cardArt    null    AuthorizeNet.Api.Contracts.V1.cardArt
        cardNumber    "XXXX1111"    string
        cardType    "Visa"    string
        expirationDate    "XXXX"    string


and when you call:

 

string ppId = response.profile.paymentProfiles[0].customerPaymentProfileId;

string ccnum = response.profile.paymentProfiles[0].payment.Item.cardNumber;

 

 

Severity    Code    Description    Project    File    Line    Suppression State
Error    CS1061    'object' does not contain a definition for 'cardNumber' and no extension method 'cardNumber' accepting a first argument of type 'object' could be found

PaceDev
Member

Found a way around the problem but surely there has to be a better way.

 

 

Dictionary<string, string> CcLookup = new Dictionary<string, string>();
        string MaskedCcNumber = string.Empty;

        foreach (customerPaymentProfileMaskedType item in response.profile.paymentProfiles)
        {
            MaskedCcNumber = string.Empty;
            string j = GetXMLFromObject(item.payment.Item);
            XmlDocument doc = new XmlDocument();
            doc.LoadXml(j);

            XmlNodeList CardNumberTags = doc.GetElementsByTagName("cardNumber");
            if (CardNumberTags.Count <= 0)
            {
                
            }
            else
            {
                MaskedCcNumber = CardNumberTags[0].InnerText;
            }
            CcLookup.Add(item.customerPaymentProfileId, MaskedCcNumber);
        }

        if (response != null && response.messages.resultCode == messageTypeEnum.Ok)
        {

        }
        else if (response != null)
        {

        }

        return CcLookup;



 

    public static string GetXMLFromObject(object o)
    {
        StringWriter sw = new StringWriter();
        XmlTextWriter tw = null;
        try
        {
            XmlSerializer serializer = new XmlSerializer(o.GetType());
            tw = new XmlTextWriter(sw);
            serializer.Serialize(tw, o);
        }
        catch (Exception ex)
        {
            //Handle Exception Code
        }
        finally
        {
            sw.Close();
            if (tw != null)
            {
                tw.Close();
            }
        }
        return sw.ToString();
    }

Here's a much simpler method:

 

var cardNumber = ((dynamic)apiResponse.profile.paymentProfiles[0].payment.Item).cardNumber;

I know this is an old thread, but I thought I'd post my solution anyway since I couldn't find anything when I was searching for an answer.

 

If you do a type comparison you can successfully cast the paymentMaskedType to a specific masked type and therefore gain access to its named values.

 

Just as a quick example,

 

var account = "";
var type = "";

// if item matches credit card type if (transaction.payment.Item is creditCardMaskedType) { var creditCard = (creditCardMaskedType)transaction.payment.Item; account = creditCard.cardNumber; type = creditCard.cardType; } // if item matches bank account type else if (transaction.payment.Item is bankAccountMaskedType) { var bankAccount = (bankAccountMaskedType)transaction.payment.Item; account = bankAccount.accountNumber;
type = bankAccount.accountType; }

Man, thank you! Been pulling my hair out on this one.


@jasonsmith4050 wrote:

I know this is an old thread, but I thought I'd post my solution anyway since I couldn't find anything when I was searching for an answer.

 

If you do a type comparison you can successfully cast the paymentMaskedType to a specific masked type and therefore gain access to its named values.

 

Just as a quick example,

 

var account = "";
var type = "";

// if item matches credit card type if (transaction.payment.Item is creditCardliteblueType) { var creditCard = (creditCardMaskedType)transaction.payment.Item; account = creditCard.cardNumber; type = creditCard.cardType; } // if item matches bank account type else if (transaction.payment.Item is bankAccountMaskedType) { var bankAccount = (bankAccountMaskedType)transaction.payment.Item; account = bankAccount.accountNumber;
type = bankAccount.accountType; }

Thank you so much