I am receiving the following error when attempting to submit through the BulkRequestTransmitter Web Service. The Composition Guide is less than helpful as far as this message goes, and when I compare my SOAP XML with the SOAP from the Composition Guide, they seem to be apples-to-apples. I'm hoping that another set of eyes may be able to see where the problem is.
The message was not formatted properly and/or cannot be interpreted. Please review the XML standards outlined in Section 3 of the AIR Submission Composition and Reference Guide located at https://www.irs.gov/for-Tax-Pros/Software-Developers/Information-Returns/Affordable-Care-Act-Information-Return-AIR-Program, correct any issues, and try again.
What I've Tried:
- Attempted to submit with (and without) whitespace in the SOAP Envelope.
- Attempted to submit with the Form Data XML in XML format.
Attempted to submit with the Form Data inbase64string
format (as this submission was).Added theds
prefix to the Signature elements. Used this SO post in order to add the prefix to the Signature elements.- Added the Form Data in "Pretty Print" format and as according to the updated Composition Guide (v4.2).
- Copied the formatting of the
MIME
for theBulkTransmitterService
request outlined in section 10.3 of the Composition Guide. - Created two solutions: 1.) Manually creating the XML necessary for the SOAP requests and sending via
HttpWebRequest
object; 2.) Sending a submission request via theWSDL
imported to the project as aService Reference
, using custom encoders forGZip and Mtom Encoding
and manually creating the XML necessary for the SOAP Status Request (sent viaHttpWebRequest
).
Update #1
Updated the request based on some new additions.
Added theds
prefix to the Signature elements.- Added the Form Data in "Pretty Print" format and as according to the updated Composition Guide (v4.2: Section 5.4.2).
Update #2
I began to manually create the SOAP
.xml file within a new instance of Visual Studio importing the schema references as necessary. I'm doing this outside of any sort of application creation.
In doing so, I was able to find some additional bugs in the SOAP
I was creating through my application (thank you for intellisense!). The bugs that I found were within the Manifest XML, as they didn't conform to the IRS schema.
I will be looking into these in the next 24 hours and update accordingly.
Theurn:MailingAddressGrp
should have a child of eitherurn:USAddressGrp
orurn:ForeignAddressGrp
. That child should then contain the proper address elements. My code is currently missing the direct child of theurn:MailingAddressGrp
.The value forurn1:DocumentSystemFileNm
ofForm1094C_Request_[TCC]_yyyyMMddThhmmssfffZ.xml
is incorrect. I'm not entirely sure what it should be just yet.Theurn1:BulkExchangeFile
element, is having an issue related to thexop:Include
element I have within. The schema wants a base64Binary type.
Update #2.5
- Updated my XML generation process to include the
USAddressGrp
element. - Discovered that I had one extra character in the milliseconds (four instead of three). Once I corrected this, along with removing the string "Form" from the beginning of the file name, the value for the
urn1:DocumentSystemFileNm
was able to validate against the schema successfully.
Update #3
- Updated the Full Request based on the updates I have made. At this point, I am unable to deduce what is wrong with my request. If anyone sees anything glaring, please help!
Update #4
Updated the Full Request based on additional updates made. Removed the
ds
prefix from the Signature based on another SO user's feedback. This user has gotten these requests to work without having to append theds
prefix to the Signature after the fact and re-compute the signature.The SO user also confirmed that his requests are working with an
<inc:Include>
element being setup as a child element of the<BulkExchangeFile>
element.- Confirmed the
MIME
headers are correct as per the sample in section 10.3 of the Composition Guide.
Update #5
I currently have two solutions: one which is sending manually creating the XML necessary for the SOAP requests and sending via
HttpWebRequest
; and one which is using theWSDL Service Reference
for the Submission Request, using the custom encoders outlined below, and manually creating the XML necessary for the SOAP Request of the Status.As of this update, Solution 1 gives me the error above when making a Submission Request, and gives me the error below when making the Status Request. However, when using Solution 2, both requests (Submission and Status) give me the error below.
I am looking into possible certificate issues to see if they make any progress with either of these solutions.
Update #6
There were a number of issues I ran into which caused me to be delayed. I'll spare you the nitty-gritty details, however, the short of it is that we did not have the Security Certificate registered with the IRS system, nor did we have the Certificate installed properly so that I could access the information through the X509Store
. Finally these things got done, and I was able to test submitting data to the IRS from the server (vs. my localmachine which did not have the proper certificate). Unfortunately, I am still receiving the WS-Security error detailed below. I have updated the Full Request with what I am currently sending.
An Error Occurred with message: The WS Security Header in the message is invalid. Please review the transmission instructions outlined in Section 5 of the AIR Submission Composition and Reference Guide located at https://www.irs.gov/for-Tax-Pros/Software-Developers/Information-Returns/Affordable-Care-Act-Information-Return-AIR-Program, correct any issues, and try again.
All line breaks in the MIME headers are as-is, and I believe the line breaks are what is expected. The FormData attachment is being sent as Pretty Print while the SOAP Envelope is not; The SOAP Envelope in this post is formatted for readability.
UPDATE #7:
Thanks to users: jstill and fatherOfWine with what they have posted below, and to Bon for earlier assistance on this project. I have broken through one wall in getting the Submission to work. It is now working. The Status request is also working. However, I need to figure out how to process it in order to pull the status and the attachment (error data file) out of it.
Full Request:
Content-Encoding: gzip
Accept-Encoding: gzip, deflate
Content-Type: multipart/related; type="application/xop+xml"; start="<rootpart>"; start-info="text/xml"; boundary="MIME_boundary"
SOAPAction: BulkRequestTransmitter
MIME-Version: 1.0
Host: la.www4.irs.gov
--MIME_Boundary
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml"
Content-Transfer-Encoding: 8bit
Content-Id: <root_part>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Header>
<Security xmlns:h="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Signature Id="SIG-E77c57b78ebc54e989bfc9e43604a04a4" xmlns="http://www.w3.org/2000/09/xmldsig#">
<SignedInfo>
<CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#WithComments" />
<SignatureMethod Algorithm="http://www.w3.org/2000/09/xmldsig#rsa-sha1" />
<Reference URI="#TS-Eb4799bee41bb4df0a72f52832d283ef7">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>[TimestampDigestValue]</DigestValue>
</Reference>
<Reference URI="#id-E5f1ed32aab8f4578adeee5debd851a62">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>[ACABusinessHeaderDigestValue]</DigestValue>
</Reference>
<Reference URI="#id-E4a71164001994d7f865fc7ddb8055350">
<DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" />
<DigestValue>[ManifestDigestValue]</DigestValue>
</Reference>
</SignedInfo>
<SignatureValue>[SignatureValue]</SignatureValue>
<KeyInfo Id="KI-E2309cb142e1a4076a2e71373e6e6b75f">
<SecurityTokenReference d6p1:Id="STR-E2751169ee468470290fe5e8bfb34589e" xmlns:d6p1="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<KeyIdentifier EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3">[KeyIdentifier]</KeyIdentifier>
</SecurityTokenReference>
</KeyInfo>
</Signature>
<a:Timestamp a:Id="TS-Eb4799bee41bb4df0a72f52832d283ef7" xmlns="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<a:Created>2016-05-18T09:51:05.856Z</a:Created>
<a:Expires>2016-05-18T10:01:05.856Z</a:Expires>
</a:Timestamp>
</Security>
<ACATransmitterManifestReqDtl a:Id="id-E4a71164001994d7f865fc7ddb8055350" xmlns:h="urn:us:gov:treasury:irs:ext:aca:air:7.0" xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="urn:us:gov:treasury:irs:ext:aca:air:7.0">
<PaymentYr>2015</PaymentYr>
<PriorYearDataInd>0</PriorYearDataInd>
<EIN xmlns="urn:us:gov:treasury:irs:common">000000301</EIN>
<TransmissionTypeCd>O</TransmissionTypeCd>
<TestFileCd>T</TestFileCd>
<OriginalReceiptId />
<TransmitterNameGrp>
<BusinessNameLine1Txt />
</TransmitterNameGrp>
<CompanyInformationGrp>
<CompanyNm>Selitestthree</CompanyNm>
<MailingAddressGrp>
<USAddressGrp>
<AddressLine1Txt>6689 Willow Court</AddressLine1Txt>
<CityNm xmlns="urn:us:gov:treasury:irs:common">Beverly Hills</CityNm>
<USStateCd>CA</USStateCd>
<USZIPCd xmlns="urn:us:gov:treasury:irs:common">90211</USZIPCd>
</USAddressGrp>
</MailingAddressGrp>
<ContactNameGrp>
<PersonFirstNm>Rose</PersonFirstNm>
<PersonLastNm>Lincoln</PersonLastNm>
</ContactNameGrp>
<ContactPhoneNum>5559876543</ContactPhoneNum>
</CompanyInformationGrp>
<VendorInformationGrp>
<VendorCd>I</VendorCd>
<ContactNameGrp>
<PersonFirstNm>ContactFirstName</PersonFirstNm>
<PersonLastNm>ContactLastName</PersonLastNm>
</ContactNameGrp>
<ContactPhoneNum>ContactPhoneNumber</ContactPhoneNum>
</VendorInformationGrp>
<TotalPayeeRecordCnt>3</TotalPayeeRecordCnt>
<TotalPayerRecordCnt>1</TotalPayerRecordCnt>
<SoftwareId>PPACA</SoftwareId>
<FormTypeCd>1094/1095C</FormTypeCd>
<BinaryFormatCd xmlns="urn:us:gov:treasury:irs:common">application/xml</BinaryFormatCd>
<ChecksumAugmentationNum xmlns="urn:us:gov:treasury:irs:common">6b2512ce28f603f76261923d297738e5</ChecksumAugmentationNum>
<AttachmentByteSizeNum xmlns="urn:us:gov:treasury:irs:common">14076</AttachmentByteSizeNum>
<DocumentSystemFileNm>1094C_Request_[TCC]_20160518T215105716Z.xml</DocumentSystemFileNm>
</ACATransmitterManifestReqDtl>
<ACABusinessHeader a:Id="id-E5f1ed32aab8f4578adeee5debd851a62" xmlns:h="urn:us:gov:treasury:irs:msg:acabusinessheader" xmlns:a="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns="urn:us:gov:treasury:irs:msg:acabusinessheader">
<UniqueTransmissionId xmlns="urn:us:gov:treasury:irs:ext:aca:air:7.0">51958882-c653-4eab-8dfb-287ecc555aaa:SYS12:[TCC]::T</UniqueTransmissionId>
<Timestamp xmlns="urn:us:gov:treasury:irs:common">2016-05-18T14:51:05.8568594-07:00</Timestamp>
</ACABusinessHeader>
</s:Header>
<s:Body xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<ACABulkRequestTransmitter xmlns="urn:us:gov:treasury:irs:msg:irsacabulkrequesttransmitter" version="1.0">
<BulkExchangeFile xmlns="urn:us:gov:treasury:irs:common">
<inc:Include href="cid:1094C_Request_BB0S4_20160518T215105716Z.xml" xmlns:inc="http://www.w3.org/2004/08/xop/include" />
</BulkExchangeFile>
</ACABulkRequestTransmitter>
</s:Body>
</s:Envelope>
--MIME_Boundary
Content-Type: text/xml; charset=us-ascii
Content-Transfer-Encoding: 7bit
Content-Id: <1094C_Request_[TCC]_20160518T215105716Z.xml>
Content-Disposition: attachment; name="1094C_Request_[TCC]_20160518T215105716Z.xml"
[PrettyPrintFormDataXml]
--MIME_boundary--
Adding the ds prefix is actually what is breaking this. The SignatureValue element contains the x509 hash of the serialized SignedInfo element (this is where having consistent whitespace matters).
By modifying the SignedInfo element, the authentication will fail when the IRS compares the SignatureValue hash you send against their computation of the SignedInfo hash using the certificate you uploaded and associated with the provided TCC.
Just remove your modification of the SignedInfo element and all should be good. It works for me.
This was an edit made to the above post, which added more information to jstill's post. Unfortunately, peer reviewers rejected it.
In addition to the changes jstill made to the Status'
Reference.cs
file, I also had to include theBulkExchangeFileType
andIncludeFileType
updates he made to the Submission'sReference.cs
file in order to get theDeserializer
method to function partially.The
Deserializer
method will return theTransmissionStatusCd
and theReceiptId
elements as expected, however, it will not populate theErrorDataFile
element properly.Since, at this time, I am unable to get the
ErrorDataFile
object populated properly, I am not utilizing theACABulkRequestTransmitterStatusDetailResponseType
object to capture the response returned from the Status Web Service. Instead, I have chosen to read theResponseStream
into astring
object and parse the (up to) twoMIME
parts of the response, and process those as necessary.Additional changes to the Status' Reference.cs
Don't know if it will resolve your issue, but nevertheless i give it a shot. Sometimes help comes from very unexpected sources :)
And I think the message you've got in the response also have something to do with Signature element. I think they want Signature element to have some prefix("ds" preferably, I guess). But here I am not sure on 100%.
You see, I am battling same battle as you. And my message security timestamp has prefix "u" and they do not complain about it. Though they didn't like binarysecuritytoken ever.:) I am struggling to generate signature to the IRS liking. WCF is very secretive and does not allow easy prefix changing on soap envelope or allow to choose CanonicalizationMethod algorithm for a signature.
UPDATE: Been able to successfully send request to the service. Tell you at once: prefixes are unimportant. What was important: CorrectedInd tag must be present in Form1095BUpstreamDetail and attributes recordType="String" lineNum="0" also must be present.
UPDATE2: Another thing that I've changed I've placed ACABusinessHeader before ManifestDtl. Here are my settings: I am using WCF as carrier and SignedXml to generate signature. Also I am using custom gZip encoder(for obvious reasons0 and custom MtomEncoder to read response from service(yes, yes it's MTOMed:)) can you believe those pokemons?!?!?) and that's not all: they send response as multipart document with only 1 part!:)) I had to adjust my encoder to handle that. And voilà, service started to behave. Hope it might help.
UPDATE3 First of all make sure data in attachment file correspond to the test scenario you are using as guinea pig. I, probably, sound like a broken record, but that's REALLY important. Now I'll cut the stuff and present what I have. It's a bit crude, but it does the trick.:)
1.Here is config file portion:
1.1.Make sure system.serviceModel element contains following portion:
1.2. Make sure binding element contains this:
1.3. Change binding of BulkRequestTransmitterPort endpoit under client element to "customBinding"(and change binding name to the name of the custom binding as well) and make sure it contains following portion:
Also client element should contain following portion:
GZip encoder you could get from following link: https://msdn.microsoft.com/en-us/library/cc138373(v=vs.90).aspx Just download WCF example and dully move whole GZipMessageEncoder project under your project.
Get MTOMEncoder(which I renamed from SwaEncoder for clarity reasons) from this link: Soap-with-Attachments Move following classes into GZipMessageEncoder project:
MimeContent, MimeParser, MimePart, MTOMEncoder
Modify GZipMessageEncoder class like this:
4.1. Add following code at the beginning of the class:
4.2. Modify Method WriteMessage(Message message, int maxMessageSize, BufferManager bufferManager, int messageOffset) like this:
4.3. Override couple more methods like this:
4.4. Make sure GZipMessage constructor looks like this:
5. Make sure GZipMessageEncodingBindingElement class has following method:
Modify MTOMEncoder class. Make sure that following method looks like this:
GZipMessageEncoderFactory class constructor should look like this:
This is how I call the service:
Modify Mime Part:
9.1. Add new method:
9.2. Add property:
Modify MimeParser SerializeMimeContent() method: replace this block of code:
with this:
And that's should be it! Kick off your shoes and dig the blues!:)))
First off, a quick disclaimer. This answer was made possible by the great stuff provided by fatherOfWine, Russ, and Bon across this and other SO questions. All I really did was combine a bunch of stuff from them them and hack through the issues I still had until it worked. More importantly, the code provided here is BAD and should probably not be used as-is. I plan on cleaning this up quite a bit now that I know what works, and I'd recommend anyone making use of it to do the same. A big thing that will likely jump out to anyone looking at this is the plethora of static variables I used as a quick hack to get to things all through the pipeline. Seriously, don't use this as-is in production, it is the product of many hours of just throwing things at the wall until something stuck, but it should provide a good starting point to get something better going.
There's too much code to really include it all here, so I'll just go through some highlights and general discoveries then include a link to the VS solution.
Outside of getting all the gzip and MTOM stuff setup (again, thanks a million to fatherOfWine for that help) the bulk of what finally worked for me is done in single general-use class (which I cleverly called "General"). Again, this is bad code and was the product of just needing to get something (anything!) to work properly. I'll go ahead and include it here in the answer though in case it provides a quick "ah ha!" to anyone else working this problem.
Here is the complete solution, just needs all of your own data supplied (including the complete attachment file with all the payee and payer records, which is outside the scope of this but should be pretty easy to generate). Also note that this is submission of forms only, not status checks. When I get that working I'll try to remember to return and update this answer (but if someone else already has it and wants to share, that'd be pretty rad as well).
Edit for Status Service
I've combined a cleaned up version of the classes generated from the wsdl and my own junk code to get messages through and process the responses. Note that this isn't 100% tested yet, needs sanity checks, etc. but like the previous stuff should at least help anyone else struggling with this mess. Usage here is pretty straightforward:
And here is the full class (with bonus generated classes namespace):
See my second answer for the status service code
For those running into the following error:
It appears there is an issue on the IRS side with the size they are expecting (as per the Documentation) and the size they actually accept. Originally, I had the following code:
I replaced the above code with the following, and the error I was receiving was resolved.
It appears as though the Web Service is actually expecting the size of the file content and not the size of the actual file. The difference in size pertaining to the test scenarios was approximately 3 bytes. I assume that is because retreiving the size of the file adds some additional file-related information not belonging to the actual content.
I have notified the IRS about this issue regarding their documentation.
Seconds answer to include status service, rather than just another link that could disappear.
Here is the main class:
Here is the relevant base xml:
For this one, the main change I needed to make to the WSDL-generated classes was the following: