DocuSign Connect Local Testing - docusignapi

I am doing some local testing for DocuSign Connect.
I have a dynamic IP address so I am unable to set the URL under DocuSign Connect to publish messages to my local server.
I am thinking of simulating a POST request from DocuSign Connect and I'm wondering if anyone has a sample POST request that I can tap on?

I've edited the GUIDs, IPs and signer/sender information, but here's an example of a Envelope - Delivered message with the following configuration:
<?xml version="1.0" encoding="utf-8"?>
<DocuSignEnvelopeInformation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.docusign.net/API/3.0">
<EnvelopeStatus>
<RecipientStatuses>
<RecipientStatus>
<Type>Signer</Type>
<Email>testemail+12354#test.com</Email>
<UserName>Signer Name</UserName>
<RoutingOrder>1</RoutingOrder>
<Sent>2016-06-20T15:41:01.78</Sent>
<Delivered>2016-06-20T15:41:26.133</Delivered><DeclineReason xsi:nil="true"/>
<Status>Delivered</Status>
<RecipientIPAddress>123.123.12.22</RecipientIPAddress><CustomFields/>
<TabStatuses>
<TabStatus>
<TabType>SignHere</TabType>
<Status>Active</Status>
<XPosition>412</XPosition>
<YPosition>207</YPosition>
<TabLabel>Signature 1</TabLabel>
<TabName>Sign Here</TabName><TabValue/>
<DocumentID>1</DocumentID>
<PageNumber>1</PageNumber><OriginalValue/></TabStatus>
<TabStatus>
<TabType>DateSigned</TabType>
<Status>NA</Status>
<XPosition>859</XPosition>
<YPosition>364</YPosition>
<TabLabel>Date Signed</TabLabel>
<TabName>Date Signed</TabName><TabValue/>
<DocumentID>1</DocumentID>
<PageNumber>1</PageNumber><OriginalValue/></TabStatus>
</TabStatuses>
<AccountStatus>Active</AccountStatus>
<EsignAgreementInformation>
<AccountEsignId>xxxxxxxx-b74b-4c31-b8f7-fe33af69a315</AccountEsignId>
<UserEsignId>xxxxxxxx-7672-436b-bcf9-a45c9b53247c</UserEsignId>
<AgreementDate>2016-06-20T15:41:26.133</AgreementDate>
</EsignAgreementInformation>
<RecipientId>xxxxxxxx-36be-49b5-8c63-c256b1f261ab</RecipientId>
</RecipientStatus>
</RecipientStatuses>
<TimeGenerated>2016-06-20T15:41:46.2761003</TimeGenerated>
<EnvelopeID>xxxxxxxx-f2ac-489d-babd-d7554ca1b2de</EnvelopeID>
<Subject>Please DocuSign this document: SamplePDF.pdf</Subject>
<UserName>Test Sender</UserName>
<Email>senderemail#test.com</Email>
<Status>Delivered</Status>
<Created>2016-06-20T15:40:33.64</Created>
<Sent>2016-06-20T15:41:01.827</Sent>
<Delivered>2016-06-20T15:41:26.18</Delivered>
<ACStatus>Original</ACStatus>
<ACStatusDate>2016-06-20T15:40:33.64</ACStatusDate>
<ACHolder>Test Sender</ACHolder>
<ACHolderEmail>senderemail#test.com</ACHolderEmail>
<ACHolderLocation>DocuSign</ACHolderLocation>
<SigningLocation>Online</SigningLocation>
<SenderIPAddress>12.163.90.22
</SenderIPAddress><EnvelopePDFHash/>
<CustomFields>
<CustomField>
<Name>Storage?</Name>
<Show>True</Show>
<Required>False</Required><Value/></CustomField>
<CustomField>
<Name>AccountId</Name>
<Show>false</Show>
<Required>false</Required>
<Value>123456</Value>
<CustomFieldType>Text</CustomFieldType>
</CustomField>
<CustomField>
<Name>AccountName</Name>
<Show>false</Show>
<Required>false</Required>
<Value>DocuSign Demo</Value>
<CustomFieldType>Text</CustomFieldType>
</CustomField>
<CustomField>
<Name>AccountSite</Name>
<Show>false</Show>
<Required>false</Required>
<Value>demo</Value>
<CustomFieldType>Text</CustomFieldType>
</CustomField>
</CustomFields>
<AutoNavigation>true</AutoNavigation>
<EnvelopeIdStamping>true</EnvelopeIdStamping>
<AuthoritativeCopy>false</AuthoritativeCopy>
<DocumentStatuses>
<DocumentStatus>
<ID>1</ID>
<Name>SamplePDF.pdf</Name><TemplateName/>
<Sequence>1</Sequence>
</DocumentStatus>
</DocumentStatuses>
</EnvelopeStatus>
<TimeZone>AUS Eastern Standard Time</TimeZone>
<TimeZoneOffset>10</TimeZoneOffset>
</DocuSignEnvelopeInformation>
If Include Documents and Include CoC are ticked each document in the envelope (including CoC) will come through in a separate byte stream:
<DocumentPDFs>
<DocumentPDF>
<Name>SamplePDF.pdf</Name>
<PDFBytes>
{bytestream}
</PDFBytes>
<DocumentID>1</DocumentID>
<DocumentType>CONTENT</DocumentType>
</DocumentPDF>
<DocumentPDF>
<Name>CertificateOfCompletion_{envelopeI}.pdf</Name>
<PDFBytes>
{bytestream}
</PDFBytes>
<DocumentType>SUMMARY</DocumentType>
</DocumentPDF>
</DocumentPDFs>

Related

Recipient type for the original signer is not changed from signer to CarbonCopy

I have goan through the answer for below question
Docusign call back from Docusign Connect not happening on change signer_
My question is - In the callback ( using legacy data format ) I dont see reciepient's type changed to "CarbonCopy" for original signer who has delegated to another signer rather I see the "delegated to" having "Signer" as type in the callback.
Is this something related to Connect configuration? I didn't found relevant setting actually.
This works for my demo account though, but not for customer's DocuSign account.
I have handled this "CarbonCopy" tag in the integration so this is needed information for me.
Is there any setting at account level that controls the recipient type for the original signer is changed from signer to CarbonCopy?
Edit-
In Below sample, mainsigner#yyy.com has delegated to delegatedto#yyy.com , So I would expect a new RecipientStatus node for mainsigner#yyy.com with Type as "CarbonCopy"
<?xml version="1.0" encoding="utf-8"?>
<DocuSignEnvelopeInformation xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns="http://www.docusign.net/API/3.0">
<EnvelopeStatus>
<RecipientStatuses>
<RecipientStatus>
<Type>CarbonCopy</Type>
<Email>abc#xxx.com</Email>
<UserName>ABC</UserName>
<RoutingOrder>1</RoutingOrder>
<Sent>2021-10-28T11:51:53.177</Sent>
<DeclineReason/>
<Status>Completed</Status>
<RecipientIPAddress/>
<CustomFields>
<CustomField>NonSignerCarbonCopy</CustomField>
<CustomField/>
<CustomField/>
</CustomFields>
<AccountStatus>Active</AccountStatus>
<RecipientId>d4bee1ca-8af2-4d45-83b9-xxxxxxxxx</RecipientId>
</RecipientStatus>
<RecipientStatus>
<Type>Signer</Type>
<Email>delegatedto#yyy.com</Email>
<UserName>delegatedto</UserName>
<RoutingOrder>1</RoutingOrder>
<Sent>2021-11-04T07:44:41.59</Sent>
<Delivered>2021-11-04T07:55:46.007</Delivered>
<Signed>2021-11-04T07:56:03.007</Signed>
<DeclineReason/>
<Status>Completed</Status>
<RecipientIPAddress>ipaddress</RecipientIPAddress>
<CustomFields>
<CustomField>S||mainsigner#yyy.com</CustomField>
<CustomField/>
<CustomField/>
</CustomFields>
<TabStatuses>
<TabStatus>
<TabType>SignHere</TabType>
<Status>Signed</Status>
<XPosition>187</XPosition>
<YPosition>508</YPosition>
<TabLabel>Sign Here</TabLabel>
<TabName>SignHere</TabName>
<TabValue/>
<DocumentID>336845219</DocumentID>
<PageNumber>2</PageNumber>
</TabStatus>
<TabStatus>
<TabType>DateSigned</TabType>
<Status>Signed</Status>
<XPosition>195</XPosition>
<YPosition>816</YPosition>
<TabLabel>Date Signed</TabLabel>
<TabName>DateSigned</TabName>
<TabValue>11/4/2021 | 7:56 AM PDT</TabValue>
<DocumentID>336845219</DocumentID>
<PageNumber>2</PageNumber>
</TabStatus>
</TabStatuses>
<RecipientAttachment>
<Attachment>
<Data>somedaata</Data>
<Label>DSXForm</Label>
</Attachment>
</RecipientAttachment>
<AccountStatus>Closed</AccountStatus>
<EsignAgreementInformation>
<AccountEsignId>GUID</AccountEsignId>
<UserEsignId>GUID</UserEsignId>
<AgreementDate>2021-11-04T07:55:46.007</AgreementDate>
</EsignAgreementInformation>
<FormData>
<xfdf>
<fields>
<field name="DateSigned">
<value>11/4/2021 | 7:56 AM PDT</value>
</field>
</fields>
</xfdf>
</FormData>
<RecipientId>98525aa9-ae3e-4d1c-aa48-xxxxxxxxxx</RecipientId>
</RecipientStatus>
</RecipientStatuses>
<TimeGenerated>2021-11-04T07:56:23.8331339</TimeGenerated>
<EnvelopeID>ee738247-57a4-49d7-8914-xxxxxxxx</EnvelopeID>
<Subject>C345</Subject>
<UserName>Admin</UserName>
<Email>Admin#yyy.com</Email>
<Status>Completed</Status>
<Created>2021-10-28T11:51:51.707</Created>
<Sent>2021-11-04T07:44:41.637</Sent>
<Delivered>2021-11-04T07:55:46.273</Delivered>
<Signed>2021-11-04T07:56:03.007</Signed>
<Completed>2021-11-04T07:56:03.007</Completed>
<ACStatus>Original</ACStatus>
<ACStatusDate>2021-10-28T11:51:51.707</ACStatusDate>
<ACHolder>Admin</ACHolder>
<ACHolderEmail>Admin#yyy.com</ACHolderEmail>
<ACHolderLocation>DocuSign</ACHolderLocation>
<SigningLocation>Online</SigningLocation>
<SenderIPAddress>ipaddress </SenderIPAddress>
<EnvelopePDFHash/>
<CustomFields/>
<AutoNavigation>true</AutoNavigation>
<EnvelopeIdStamping>true</EnvelopeIdStamping>
<AuthoritativeCopy>false</AuthoritativeCopy>
<DocumentStatuses>
<DocumentStatus>
<ID>888888888</ID>
<Name>C3459</Name>
<TemplateName/>
<Sequence>1</Sequence>
</DocumentStatus>
</DocumentStatuses>
</EnvelopeStatus>
<DocumentPDFs>
<DocumentPDF>
<Name>CertificateOfCompletion_GUID.pdf</Name>
<PDFBytes>Bn8iUlJSRa7MTExKzHx1DNb//bFeKyLoldo39X9/S
.........
and here are the subscribed events
Envelope Sent
Envelope Signed/Completed
Envelope Declined
Envelope Voided
Recipient Signed/Completed
Recipient Declined

Routing Order / Signing Group information in the connect response?

I´m trying to understand the response the connect API (using the webhook status updates) sends. The documentation says, the answer only provides XML elements of EvenvelopeStatus type (plus document PDFs, if requested). This does not include current routing order information or signing group information, right?
Does anyone know, if this is true and if there is a workaround, how to get the current routing order within the connect message without parsing the recipients status?
If one of the recipients is a signing group, will the name and email field remain empty until one of the group members has viewed / signed the document? Then I would expect the name / email field to be filled with the actual signer.
Thank you for your help!
I found the answers to my questions by debugging the interface. It is like expected: names of signing groups are reported in the name tag and replaced by the actual signers name after signing has been completed. Routing status has to be "calculated" by interpreting the recipients status - no overall routing info like in the envelope:get service call.
Current routing situation can be determined from the notification message. See the status attributes for the envelope's recipients.
You need to infer the current routing status by looking at the status values for the recipients. Here is an example notification. You can see that one of the recipients is in completed status and the other is in sent status.
Remember that multiple recipients can be in sent status at the same time if the envelope is using parallel routing.
<?xml version="1.0" encoding="utf-8"?>
<DocuSignEnvelopeInformation
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://www.docusign.net/API/3.0">
<EnvelopeStatus>
<RecipientStatuses>
<RecipientStatus>
<Type>Signer</Type>
<Email>Sam.Spade#example.com</Email>
<UserName>Sam Spade</UserName>
<RoutingOrder>1</RoutingOrder>
<Sent>2019-05-07T10:43:40.073</Sent>
<Delivered>2019-05-07T10:44:06.023</Delivered>
<Signed>2019-05-07T10:44:12.323</Signed>
<DeclineReason xsi:nil="true"/>
<Status>Completed</Status>
<RecipientIPAddress>141.226.10.195</RecipientIPAddress>
<CustomFields/>
<TabStatuses>
<TabStatus>
<TabType>SignHere</TabType>
<Status>Signed</Status>
<XPosition>341</XPosition>
<YPosition>697</YPosition>
<TabLabel>Sign Here</TabLabel>
<TabName>SignHere</TabName>
<DocumentID>1</DocumentID>
<PageNumber>1</PageNumber>
</TabStatus>
<TabStatus>
<TabType>SignHere</TabType>
<Status>Signed</Status>
<XPosition>416</XPosition>
<YPosition>412</YPosition>
<TabLabel>Sign Here</TabLabel>
<TabName>SignHere</TabName>
<DocumentID>2</DocumentID>
<PageNumber>1</PageNumber>
</TabStatus>
<TabStatus>
<TabType>SignHere</TabType>
<Status>Signed</Status>
<XPosition>416</XPosition>
<YPosition>316</YPosition>
<TabLabel>Sign Here</TabLabel>
<TabName>SignHere</TabName>
<DocumentID>3</DocumentID>
<PageNumber>1</PageNumber>
</TabStatus>
</TabStatuses>
<AccountStatus>Active</AccountStatus>
<RecipientId>64d1f093-d51e-4d38-914e-3255f46c0e18</RecipientId>
</RecipientStatus>
<RecipientStatus>
<Type>Signer</Type>
<Email>Susan.smith#example.com</Email>
<UserName>Susan Smith</UserName>
<RoutingOrder>2</RoutingOrder>
<Sent>2019-05-07T10:44:13.76</Sent>
<DeclineReason xsi:nil="true"/>
<Status>Sent</Status>
<RecipientIPAddress/>
<CustomFields/>
<AccountStatus>Active</AccountStatus>
<RecipientId>ad82fdb5-dfe9-479e-a4ca-0032a51b076a</RecipientId>
</RecipientStatus>
</RecipientStatuses>
<TimeGenerated>2019-05-07T10:47:56.4026603</TimeGenerated>
<EnvelopeID>a65c99da-39aa-488f-909a-1b3964634758</EnvelopeID>
<Subject>Please sign this document set</Subject>
<UserName>Sam Spade</UserName>
<Email>Sam.Spade#example.com</Email>
<Status>Sent</Status>
<Created>2019-05-07T10:43:27.943</Created>
<Sent>2019-05-07T10:44:13.79</Sent>
<ACStatus>Original</ACStatus>
<ACStatusDate>2019-05-07T10:43:27.943</ACStatusDate>
<ACHolder>Sam Spade</ACHolder>
<ACHolderEmail>Sam.Spade#example.com</ACHolderEmail>
<ACHolderLocation>DocuSign</ACHolderLocation>
<SigningLocation>Online</SigningLocation>
<SenderIPAddress>141.226.10.195 </SenderIPAddress>
<EnvelopePDFHash/>
<CustomFields>
<CustomField>
<Name>Order ID</Name>
<Show>True</Show>
<Required>False</Required>
<Value/>
</CustomField>
<CustomField>
<Name>Sales order</Name>
<Show>True</Show>
<Required>False</Required>
<Value>16</Value>
</CustomField>
<CustomField>
<Name>AccountId</Name>
<Show>false</Show>
<Required>false</Required>
<Value>3964103</Value>
<CustomFieldType>Text</CustomFieldType>
</CustomField>
<CustomField>
<Name>AccountName</Name>
<Show>false</Show>
<Required>false</Required>
<Value>World Wide Corp</Value>
<CustomFieldType>Text</CustomFieldType>
</CustomField>
<CustomField>
<Name>AccountSite</Name>
<Show>false</Show>
<Required>false</Required>
<Value>demo</Value>
<CustomFieldType>Text</CustomFieldType>
</CustomField>
</CustomFields>
<AutoNavigation>true</AutoNavigation>
<EnvelopeIdStamping>true</EnvelopeIdStamping>
<AuthoritativeCopy>false</AuthoritativeCopy>
<DocumentStatuses>
<DocumentStatus>
<ID>1</ID>
<Name>Order acknowledgement</Name>
<TemplateName/>
<Sequence>1</Sequence>
</DocumentStatus>
<DocumentStatus>
<ID>2</ID>
<Name>Battle Plan</Name>
<TemplateName/>
<Sequence>2</Sequence>
</DocumentStatus>
<DocumentStatus>
<ID>3</ID>
<Name>Lorem Ipsum</Name>
<TemplateName/>
<Sequence>3</Sequence>
</DocumentStatus>
</DocumentStatuses>
</EnvelopeStatus>
</DocuSignEnvelopeInformation>

In Python, how to set _soapheaders for Zeep using Dictionaries?

In working with a SOAP api, the wsdl spec describes the api key passed in the header in a complex namespaced structure as well as additional non-namespaced XML that relates to a paging mechanism for accessing bulk results successively:
Specification:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns="https://webservice_address_here">
<soapenv:Header>
<ns:apiKey>
<api_key>***</api_key>
</ns:apiKey>
<pager>
<page>1</page>
<per_page>100</per_page>
</pager>
</soapenv:Header>
</soapenv:Envelope>
API Documentation:
Pagination; this method returns paginated results. To specify pages or
results per page, use the pager header:
<soapenv:Header>
<ns:pager>
<page>1</page>
<per_page>100</per_page>
</ns:pager>
</soapenv:Header> Max per page is 100
Pagination information is returned in a pager header:
<soapenv:Header>
<ns:pager>
<page>1</page>
<per_page>100</per_page>
<next_page>2</next_page>
<page_items>100</page_items>
<total_items>2829</total_items>
<total_pages>29</total_pages>
</ns:pager>
</soapenv:Header>
The answer, How to set soap headers in zeep when header has multiple elements, describes a similar scenario, without the namespace "ns" but with "acm." I have not been successful in using this method.
This works, allowing access to the api but without the pager making it mostly useless for any methods that return more than 100 results:
from zeep import Client, xsd
# Generate the header structure
header = xsd.Element(
'{wsdl}AuthenticateRequest',
xsd.ComplexType([xsd.Element("{wsdl}api_key", xsd.String())])
)
# Insert values into header placeholders
self._header_value = header(api_key=self.api_key)
This does not work:
from zeep import Client, xsd
# Generate the header structure
header = xsd.Element(
'Header',
xsd.ComplexType([
xsd.Element(
'{wsdl}AuthenticateRequest',
xsd.ComplexType([
xsd.Element('{wsdl}api_key', xsd.String()),
])
),
xsd.Element(
'pager',
xsd.ComplexType([
xsd.Element('page', xsd.String()),
xsd.Element('per_page', xsd.String()),
])
),
])
)
# ERROR HERE: Insert values into header placeholders
self._header_value = header(api_key=self.api_key, pager={'page':1,'per_page':100})
Error: TypeError: ComplexType() got an unexpected keyword argument 'api_key'. Signature: AuthenticateRequest: {api_key: xsd:string}, pager: {page: xsd:string, per_page: xsd:string}
This also does not work:
header = xsd.Element(
'{wsdl}AuthenticateRequest',
xsd.ComplexType([xsd.Element("{wsdl}api_key", xsd.String())]),
xsd.Element(
'pager',
xsd.ComplexType([
xsd.Element('page', xsd.String()),
xsd.Element('per_page', xsd.String()),
])
)
)
# ERROR HERE: Insert values into header placeholders
self._header_value = header(api_key=self.api_key, pager={"page":1,"per_page":100})
'pager' is not defined in the wsdl but the server expects that it could be there.
TypeError: ComplexType() got an unexpected keyword argument 'pager'.
Signature: api_key: xsd:string
Recent Failed (2022) Attempt Using #markoan answer:
def get_pager(self, page: int = 1, per_page: int = 100):
""" Create header that contains the page and records per page. """
pager_header = xsd.Element(
'pager',
xsd.ComplexType([
xsd.Element(
'page', xsd.Integer()
),
xsd.Element(
'per_page', xsd.Integer()
)
])
)
return pager_header(page=page, per_page=per_page)
def call(self, endpoint: str, *args, **kwargs):
"""Allows calling of any client service defined in the WSDL."""
# get the endpoint
endpoint = getattr(self.client.service, endpoint)
# get SOAP authentication header which includes the API key embedded from CFG
headers = [self.get_header()]
# add the pager complex element to headers if required in kwargs
if page := kwargs.get("page"):
per_page = kwargs.get("per_page") or 100
headers.append(self.get_pager(page, per_page))
# call the endpoint with provided unnamed and named parameters if any
result = endpoint(*args, **kwargs, _soapheaders=headers)
# serialize and return result
return self.serialize(result)
What is the simplest way using Zeep to set the namespace api_key and non-namespaced complex pager element?
I find it's easier to work with Zeep if we have a valid and complete WSDL.
A simple API service WSDL that expects an element without namespace would import a schema with no namespace like this:
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions targetNamespace="http://tempuri.org/" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:tm="http://microsoft.com/wsdl/mime/textMatching/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:mime="http://schemas.xmlsoap.org/wsdl/mime/" xmlns:tns="http://tempuri.org/" xmlns:s="http://www.w3.org/2001/XMLSchema" xmlns:soap12="http://schemas.xmlsoap.org/wsdl/soap12/" xmlns:http="http://schemas.xmlsoap.org/wsdl/http/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" >
<wsdl:types>
<s:schema elementFormDefault="qualified" targetNamespace="http://tempuri.org/">
<s:import schemaLocation="namespaceLessElement.xsd"/>
<s:element name="Api" minOccurs="0" maxOccurs="1">
</s:element>
<s:element name="ApiResponse">
<s:complexType>
<s:sequence>
<s:element minOccurs="1" maxOccurs="1" name="ApiResult" type="s:int"/>
</s:sequence>
</s:complexType>
</s:element>
<s:element name="apiKey">
<s:complexType>
<s:sequence>
<s:element name="api_key" type="s:string"></s:element>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
</wsdl:types>
<wsdl:message name="ApiSoapIn">
<wsdl:part name="parameters" element="tns:Api"/>
</wsdl:message>
<wsdl:message name="ApiSoapOut">
<wsdl:part name="parameters" element="tns:ApiResponse"/>
</wsdl:message>
<wsdl:message name="ApiKeyHeader">
<wsdl:part name="ApiKeyHeaderParam" element="tns:apiKey"/>
</wsdl:message>
<wsdl:message name="PagerHeader">
<wsdl:part name="PagerHeaderParam" ref="pager"/>
</wsdl:message>
<wsdl:portType name="ApiSoap">
<wsdl:operation name="Api">
<wsdl:documentation>This is a test WebService. Returns a number</wsdl:documentation>
<wsdl:input message="tns:ApiSoapIn"/>
<wsdl:output message="tns:ApiSoapOut"/>
</wsdl:operation>
</wsdl:portType>
<wsdl:binding name="ApiSoap" type="tns:ApiSoap">
<soap:binding transport="http://schemas.xmlsoap.org/soap/http"/>
<wsdl:operation name="Api">
<soap:operation soapAction="http://tempuri.org/Api" style="document"/>
<wsdl:input>
<soap:header message="tns:ApiKeyHeader" part="ApiKeyHeaderParam" use="literal"/>
<soap:header message="tns:PagerHeader" part="PagerHeaderParam" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
</wsdl:binding>
<wsdl:service name="ApiTest">
<wsdl:port name="ApiSoap" binding="tns:ApiSoap">
<soap:address location="http://superpc:8082/"/>
</wsdl:port>
</wsdl:service>
</wsdl:definitions>
With namespaceLessElement.xsd:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<s:schema xmlns:s="http://www.w3.org/2001/XMLSchema"
elementFormDefault="qualified">
<s:element name="pager">
<s:complexType>
<s:sequence>
<s:element name="page" type="s:int"></s:element>
<s:element name="per_page" type="s:int"></s:element>
</s:sequence>
</s:complexType>
</s:element>
</s:schema>
Note how the operation definition that expects header values points to correct messages:
<wsdl:operation name="Api">
<soap:operation soapAction="http://tempuri.org/Api" style="document"/>
<wsdl:input>
<soap:header message="tns:ApiKeyHeader" part="ApiKeyHeaderParam" use="literal"/>
<soap:header message="tns:PagerHeader" part="PagerHeaderParam" use="literal"/>
<soap:body use="literal"/>
</wsdl:input>
<wsdl:output>
<soap:body use="literal"/>
</wsdl:output>
</wsdl:operation>
and these in turn reference correct elements:
<wsdl:message name="ApiKeyHeader">
<wsdl:part name="ApiKeyHeaderParam" element="tns:apiKey"/>
</wsdl:message>
<wsdl:message name="PagerHeader">
<wsdl:part name="PagerHeaderParam" ref="pager"/>
</wsdl:message>
You should check in the WSDL of your web service that the operation describes both headers and that it includes a schema definition for both elements. In the example WSDL the service namespace is targetNamespace="http://tempuri.org/" but this should point to your web service URL.
So assuming your WSDL is valid and complete, we need to define the Client pointing to the WSDL and then set the header values using the _soapheaders parameter, similar to the method I used here but building the content reference. Zeep can take care of the different namespaces but I found issues with empty ones:
transport = Transport(cache=SqliteCache())
self.Test = Client(wsdl='http://my-endpoint.com/production.svc?wsdl', transport=transport)
# Header objects
apiKey_header = xsd.Element(
'{http://tempuri.org/}apiKey',
xsd.ComplexType([
xsd.Element(
'api_key', xsd.String()
)
])
)
pager_header = xsd.Element(
'pager',
xsd.ComplexType([
xsd.Element(
'page', xsd.Integer()
),
xsd.Element(
'per_page', xsd.Integer()
)
])
)
apiKey_header_value = apiKey_header( api_key=key)
pager_header_value = pager_header( page=page, per_page=perpage)
# Request
response = self.Test.service.Api( _soapheaders=[apiKey_header_value, pager_header_value] )
logger.debug("Result={1}".format(response))
# Prints: Result=2 (or whatever value the test API sends)
EDIT: Example of generated XML request:
<soap-env:Envelope xmlns:soap-env="http://schemas.xmlsoap.org/soap/envelope/">
<soap-env:Header>
<ns0:apiKey xmlns:ns0="http://tempuri.org/">
<api_key>1230011</api_key>
</ns0:apiKey>
<pager>
<page>2</page>
<per_page>10</per_page>
</pager>
</soap-env:Header>
<soap-env:Body>
<ns0:Api xmlns:ns0="http://tempuri.org/"/>
</soap-env:Body>
</soap-env:Envelope>
Make sure that the header that has a namespace is defined with the correct URL.
If you still have problems it may mean your WSDL does not define all elements or that it's not linking correctly to external XSDs. In those cases one option is to save a local copy os the WSDL and linked XSDs, then edit the files to fix references and then point Zeep to that local file instead.

OC 2.0 Fedex shipping method not working

We tried to Fedex shipping method in our opencart website.
It Display the "Error" text.
ERRORERRORcrs691The PurposeOfShipmentType is null, empty or invalid.
The PurposeOfShipmentType is null, empty or invalid.crs1000
Use this xml
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="http://fedex.com/ws/rate/v13">
<SOAP-ENV:Body>
<RateRequest>
<WebAuthenticationDetail>
<UserCredential>
<Key>XXXXX</Key>
<Password>XXXXX</Password>
</UserCredential>
</WebAuthenticationDetail>
<ClientDetail>
<AccountNumber>XXXXX</AccountNumber>
<MeterNumber>XXXXX</MeterNumber>
</ClientDetail>
<TransactionDetail>
<CustomerTransactionId>MY-RATE-REQUEST</CustomerTransactionId>
</TransactionDetail>
<Version>
<ServiceId>crs</ServiceId>
<Major>13</Major>
<Intermediate>0</Intermediate>
<Minor>0</Minor>
</Version>
<ReturnTransitAndCommit>true</ReturnTransitAndCommit>
<RequestedShipment>
<ShipTimestamp>2012-10-09T14:28:07.9489435+05:30</ShipTimestamp>
<DropoffType>REGULAR_PICKUP</DropoffType>
<PackagingType>YOUR_PACKAGING</PackagingType>
<Shipper>
<Address>
<StreetLines>Sardarnagar Main Road, Rajkot</StreetLines>
<City>Rajkot</City>
<StateOrProvinceCode>GJ</StateOrProvinceCode>
<PostalCode>360001</PostalCode>
<CountryCode>IN</CountryCode>
</Address>
</Shipper>
<Recipient>
<Address>
<StreetLines>Radhekrishna App. Main Road , Rajkot</StreetLines>
<City>Bhuj</City>
<StateOrProvinceCode>GJ</StateOrProvinceCode>
<PostalCode>370001</PostalCode>
<CountryCode>IN</CountryCode>
</Address>
</Recipient>
<ShippingChargesPayment>
<PaymentType>SENDER</PaymentType>
<Payor>
<ResponsibleParty>
<AccountNumber>XXXXX</AccountNumber>
</ResponsibleParty>
</Payor>
</ShippingChargesPayment>
<CustomsClearanceDetail>
<DutiesPayment>
<PaymentType>RECIPIENT</PaymentType>
</DutiesPayment>
<DocumentContent>NON_DOCUMENTS</DocumentContent>
<CustomsValue>
<Currency>INR</Currency>
<Amount>299.000000</Amount>
</CustomsValue>
<CommercialInvoice>
<Purpose>NOT_SOLD</Purpose>
</CommercialInvoice>
</CustomsClearanceDetail>
<RateRequestTypes>ACCOUNT</RateRequestTypes>
<RateRequestTypes>LIST</RateRequestTypes>
<PackageCount>1</PackageCount>
<RequestedPackageLineItems>
<SequenceNumber>1</SequenceNumber>
<GroupPackageCount>1</GroupPackageCount>
<Weight>
<Units>KG</Units>
<Value>1</Value>
</Weight>
</RequestedPackageLineItems>
</RequestedShipment>
</RateRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

Setting Flag for an Email in ActiveSync

Trying to set status Flag for an email using ActiveSync. Below is my request. I receive status 6. What's wrong with my request?
Request
<Sync xmlns="AirSync:" xmlns:email="Email:" xmlns:tasks="Tasks:" >
<Collections>
<Collection>
<SyncKey>648263900</SyncKey>
<CollectionId>11</CollectionId>
<GetChanges>0</GetChanges>
<Commands>
<Change>
<ServerId>11:2</ServerId>
<ApplicationData>
<email:Flag>
<email:Status>1</email:Status>
<email:FlagType>Follow Up</email:FlagType>
<tasks:StartDate>113-04-23T05:30:00.000Z</tasks:StartDate>
<tasks:UTCStartDate>113-04-23T05:30:00.000Z</tasks:UTCStartDate>
<tasks:DueDate>113-04-26T05:30:00.000Z</tasks:DueDate>
<tasks:UTCDueDate>113-04-26T05:30:00.000Z</tasks:UTCDueDate>
</email:Flag>
</ApplicationData>
</Change>
</Commands>
</Collection>
</Collections>
Response I receive
<?xml version="1.0"?>
<!DOCTYPE ActiveSync PUBLIC "-//MICROSOFT//DTD ActiveSync//EN" "http://www.microsoft.com/">
<Sync xmlns="AirSync:">
<Collections>
<Collection>
<SyncKey>648263900</SyncKey>
<CollectionId>11</CollectionId>
<Status>1</Status>
<Responses>
<Change>
<ServerId>11:2</ServerId>
<Status>6</Status>
</Change>
</Responses>
</Collection>
</Collections>
</Sync>
Change email:FlagType from Follow Up to for Follow Up.
And add </Sync> in the end.
Try:
<?xml version="1.0" encoding="utf-8"?>
<Sync xmlns="AirSync:" xmlns:email="Email:" xmlns:tasks="Tasks:" >
<Collections>
<Collection>
<SyncKey>648263900</SyncKey>
<CollectionId>11</CollectionId>
<GetChanges>0</GetChanges>
<Commands>
<Change>
<ServerId>11:2</ServerId>
<ApplicationData>
<email:Flag>
<email:Status>1</email:Status>
<email:FlagType>for Follow Up</email:FlagType>
<tasks:StartDate>113-04-23T05:30:00.000Z</tasks:StartDate>
<tasks:UTCStartDate>113-04-23T05:30:00.000Z</tasks:UTCStartDate>
<tasks:DueDate>113-04-26T05:30:00.000Z</tasks:DueDate>
<tasks:UTCDueDate>113-04-26T05:30:00.000Z</tasks:UTCDueDate>
</email:Flag>
</ApplicationData>
</Change>
</Commands>
</Collection>
</Collections>
</Sync>
See more: MS-ASEMAIL

Resources