In sample-code-csharp-master.zip from 3/23/2017 5:14 PM setting GetCustomerProfile's unmaskExpirationDate to true returns expirationDate "XXXX". Would Authorize.Net fix GetCustomerProfile so setting unmaskExpirationDate to true returns the actual expiration date? The Authorize.NET\Utility\HttpXmlUtility.cs code in the if statement below returned unmasked expiration dates:
if (type.FullName == "AuthorizeNet.APICore.getCustomerProfileRequest")
but the else code from sdk-dotnet-master.zip 3/23/2017 12:30 PM returned "XXXX", rather than expiration date. The else code did not send <unmaskExpirationDate> to Authorize.Net in the webRequest.GetRequestStream(). See second code chunk below.
public ANetApiResponse Send(ANetApiRequest apiRequest) { //Authenticate it AuthenticateRequest(apiRequest); HttpWebRequest webRequest = (HttpWebRequest)WebRequest.Create(_serviceUrl); webRequest.Method = "POST"; webRequest.ContentType = "text/xml"; webRequest.KeepAlive = true; //set the http connection timeout var httpConnectionTimeout = AuthorizeNet.Environment.getIntProperty(Constants.HttpConnectionTimeout); webRequest.Timeout = (httpConnectionTimeout != 0 ? httpConnectionTimeout : Constants.HttpConnectionDefaultTimeout); //set the time out to read/write from stream var httpReadWriteTimeout = AuthorizeNet.Environment.getIntProperty(Constants.HttpReadWriteTimeout); webRequest.ReadWriteTimeout = (httpReadWriteTimeout != 0 ? httpReadWriteTimeout : Constants.HttpReadWriteDefaultTimeout); // Serialize the request var type = apiRequest.GetType(); if (type.FullName == "AuthorizeNet.APICore.getCustomerProfileRequest") { var req = (getCustomerProfileRequest)apiRequest; var s3 = "<?xml version=\"1.0\" encoding=\"utf-8\"?><getCustomerProfileRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" " + "xmlns:xsd =\"http://www.w3.org/2001/XMLSchema\" xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">" + "<merchantAuthentication><name>" + req.merchantAuthentication.name + "</name>" + "<transactionKey>" + req.merchantAuthentication.Item + "</transactionKey></merchantAuthentication>" + "<customerProfileId>" + req.customerProfileId + "</customerProfileId>" + "<unmaskExpirationDate>" + (req.unmaskExpirationDate ? "true" : "false") + "</unmaskExpirationDate>" + "</getCustomerProfileRequest>"; byte[] bytes = Encoding.UTF8.GetBytes(s3); webRequest.GetRequestStream().Write(bytes, 0, bytes.Length); } else { var serializer = new XmlSerializer(type); XmlWriter writer = new XmlTextWriter(webRequest.GetRequestStream(), Encoding.UTF8); serializer.Serialize(writer, apiRequest); writer.Close(); } // Get the response WebResponse webResponse = webRequest.GetResponse(); // Load the response from the API server into an XmlDocument. var xmlDoc = new XmlDocument(); xmlDoc.Load(XmlReader.Create(webResponse.GetResponseStream(), new XmlReaderSettings())); var response = DecideResponse(xmlDoc); CheckForErrors(response, xmlDoc); return response; }
You can put the following code after var type = apiRequest.GetType(); to put apiRequest in a string.
var type = apiRequest.GetType(); var serializer2 = new XmlSerializer(type); MemoryStream memoryStream = new MemoryStream(); XmlWriter writer2 = new XmlTextWriter(memoryStream, Encoding.UTF8); serializer2.Serialize(writer2, apiRequest); memoryStream.Position = 0; var streamReader = new StreamReader(memoryStream); var s = streamReader.ReadToEnd(); streamReader.Dispose(); memoryStream.Dispose();
Hi @bobjones,
Can I ask you to clarify? Are you talking about the GetCustomerProfile.cs sample?
Are you saying that if you add change the request code to send unmaskExpirationDate, the expiration date is still returned masked?
For reference, here's the section where you'd add code to send unmaskExpirationDate, starting at line 28:
var request = new getCustomerProfileRequest(); request.customerProfileId = customerProfileId; request.unmaskExpirationDate = true;
03-28-2017 11:35 AM
I tried 2 separate test cases: 1) from sample-code-csharp-master.zip and 2) from sdk-dotnet-master.zip:
1) Correct, in sample-code-csharp-master\CustomerProfiles\GetCustomerProfile.cs I changed
var request = new getCustomerProfileRequest();
request.customerProfileId = customerProfileId;
to
var request = new getCustomerProfileRequest();
request.customerProfileId = customerProfileId;
request.unmaskExpirationDate = true;
Which returned profile.paymentProfiles[0].payment.item.expirationDate as "XXXX". Though request.unmaskExpirationDate = true; should return unmasked dates like "2018-01"
2) In sdk-dotnet-master.zip Authorize.NET\Utility\HttpXmlUtility.cs
public ANetApiResponse Send(ANetApiRequest apiRequest) {
...
var type = apiRequest.GetType();
var serializer = new XmlSerializer(type);
XmlWriter writer = new XmlTextWriter(webRequest.GetRequestStream(), Encoding.UTF8);
serializer.Serialize(writer, apiRequest);
writer.Close();
is not putting <unmaskExpirationDate>true</unmaskExpirationDate> in serialized version of the apiRequest. Perhaps the Authorize.NET\Api\Contracts\V1\AnetApiSchema.generated.cs serialization code has an error, though I didn't spot the error:
[System.CodeDom.Compiler.GeneratedCodeAttribute("xsd", "2.0.50727.3038")]
[System.SerializableAttribute()]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Xml.Serialization.XmlTypeAttribute(AnonymousType=true, Namespace="AnetApi/xml/v1/schema/AnetApiSchema.xsd")]
[System.Xml.Serialization.XmlRootAttribute(Namespace="AnetApi/xml/v1/schema/AnetApiSchema.xsd", IsNullable=false)]
public partial class getCustomerProfileRequest : ANetApiRequest {
/// <remarks/>
public string customerProfileId;
/// <remarks/>
public bool unmaskExpirationDate;
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool unmaskExpirationDateSpecified;
}
The following code after var type = apiRequest.GetType(); to put apiRequest in a string.
var type = apiRequest.GetType();
var serializer2 = new XmlSerializer(type);
MemoryStream memoryStream = new MemoryStream();
XmlWriter writer2 = new XmlTextWriter(memoryStream, Encoding.UTF8);
serializer2.Serialize(writer2, apiRequest);
memoryStream.Position = 0;
var streamReader = new StreamReader(memoryStream);
var s = streamReader.ReadToEnd();
streamReader.Dispose();
memoryStream.Dispose();
var s contains the following, which is missing <unmaskExpirationDate>true</unmaskExpirationDate>:
<?xml version=\"1.0\" encoding=\"utf-8\"?><getCustomerProfileRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd=\"http://www.w3.org/2001/XMLSchema\" xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\"><merchantAuthentication><name>xxxxxxxxxx</name><transactionKey>xxxxxxxxxxxxxxxx</transactionKey></merchantAuthentication><customerProfileId>nnnnnnnnnn</customerProfileId></getCustomerProfileRequest>
rather than the following
<?xml version=\"1.0\" encoding=\"utf-8\"?><getCustomerProfileRequest xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xmlns:xsd =\"http://www.w3.org/2001/XMLSchema\" xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\"><merchantAuthentication><name>xxxxxxxxxx</name><transactionKey>xxxxxxxxxxxxxxxx</transactionKey></merchantAuthentication><customerProfileId>nnnnnnnnnn</customerProfileId><unmaskExpirationDate>true</unmaskExpirationDate></getCustomerProfileRequest>
03-28-2017 12:40 PM
Thanks, @bobjones. This is really helpful. We have code in the SDK to mask sensitive data for things like logging, and my initiatl thought was that this code was going nuts and masking things that shouldn't be masked. However, if it's really just never getting that parameter in the request, that would be another issue entirely.
I'll go ahead and open an issue for the SDK on GitHub, so that the SDK developers can take a look at it and hopefully get it fixed.
Thanks again.
03-28-2017 01:30 PM
Does Authorize.Net send me another email when the fix is on Github sdk-dotnet-master.zip and sample-code-csharp-master.zip? I'd like to remove my custom XML in Authorize.NET\Utility\HttpXmlUtility.cs. This is my first Authorize.Net bug fix request.
03-28-2017 01:44 PM
In your case, I would suggest going to the .Net SDK repository and the C# sample code repository on GitHub, then clicking the "Watch" button on the upper right of each page. That would subscribe you to notifications for each repository so that when something is changed, you'll get an email.
03-28-2017 01:54 PM
Are SDK code releases done quarterly?
How about adding a Message to "Setting GetCustomerProfile's unmaskExpirationDate to true returns expirationDate XXXX" to send me an email when it is fixed? The email would be more convenient to me than searching github entries like "Merge pull request #164 from AuthorizeNet/future", https://github.com/AuthorizeNet/sdk-dotnet/pull/164. Though I don't know if Authorize.Net's bug tracking capabilities allow such a response.
I checked the Post's Subscriptions, "Email me when someone replies".
04-05-2017 06:57 AM
Hi @bobjones,
I can try, but I can't guarantee anything. If this is fixed in a future SDK release, then:
In short, I'm human and tasking a human with what should be an automated process is potentially troublesome. We don't have any way in our internal bug tracking to automatically email an external party when something's fixed. However, that's why we use GitHub for our SDK development. Since everything happens in the open out there, it's a lot easier for someone to see what happens and when.
GitHub doesn't seem to have a way to just subscribe to a particular issue to get updates on it, but if you comment on the issue, then you're recorded as being involved, so you can get notifications of any update to that issue itself. That way, you don't have to be notified of all commits or changes if you don't want to.
Your issue is at https://github.com/AuthorizeNet/sdk-dotnet/issues/169 if you'd like to comment on that to get notifications.
Sorry we don't have an easier way to track what you've reported. I still really appreciate that you took the time to report this, and wish I had a better way to keep you in the loop.
04-05-2017 11:08 AM
I've been waiting for this feature for YEARS and gave up several times in the past.
Now I see that the SOAP API is deprecated I finally made the push over to the AuthorizeNET nuget package for .NET.
My first attempt returned XXXX-XX for the expiration date, then I made one small change and now finally I get back "2017-01" for the expiration date via this request.
var request = new getCustomerProfileRequest
{
customerProfileId = "1506932163",
unmaskExpirationDate = true,
unmaskExpirationDateSpecified = true // yes this is dumb but it works
};
var controller = new getCustomerProfileController(request);
controller.Execute();
var response = controller.GetApiResponse();
string expirationDate = (response.profile.paymentProfiles.First().payment.Item as creditCardMaskedType).expirationDate;
WOOHOO!!!! expirationDate == "2017-01"
05-24-2017 09:58 PM
I'm using the similar account to attach with my affiliate program. Its easy to get payment from individual account. I tried it with my dispose it well website.