Sending soap request with attributes using PHP SoapClient - php

I`m having remote wsdl API that requires some xml attributes in request.
Integration of this API must be made usind PHP (and possibly SoapClient).
I`m creating SimpleXMLElement() object like
<?xml version="1.0" encoding="UTF-8"?>
<Body>
<FlightMatrixRequest xmlns="http://www.somesite.com/webservices">
<flightMatrixRQ Target="Test" Version="1.0">
<AirItinerary DirectionInd="OneWay">
<OriginDestinationOptions>
<OriginDestinationOption>
<FlightSegment DepartureDateTime="2022-05-30T00:00:00+11:00"
ArrivalDateTime="2022-05-30T00:00:00+11:00" RPH="1">
<DepartureAirport LocationCode="BKK"/>
<ArrivalAirport LocationCode="CNX"/>
<MarketingAirline Code="SL"/>
</FlightSegment>
</OriginDestinationOption>
</OriginDestinationOptions>
</AirItinerary>
<TravelerInfoSummary>
<AirTravelerAvail>
<AirTraveler>
<PassengerTypeQuantity Code="ADT" Quantity="1"/>
</AirTraveler>
</AirTravelerAvail>
<AirTravelerAvail>
<AirTraveler>
<PassengerTypeQuantity Code="CNN" Quantity="1"/>
</AirTraveler>
</AirTravelerAvail>
<AirTravelerAvail>
<AirTraveler>
<PassengerTypeQuantity Code="INF" Quantity="1"/>
</AirTraveler>
</AirTravelerAvail>
</TravelerInfoSummary>
</flightMatrixRQ>
</FlightMatrixRequest>
</Body>
Converting it to array using
$array = json_decode(json_encode($xml), true);
Then requesting
$soapClient->__soapCall($method, $array)
And getting errors from API
$soapClient->__getLastRequest() returns
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://www.somesite.com/webservices"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
<env:Body>
<ns1:FlightMatrixRequest>
<ns1:flightMatrixRQ>
<ns1:AirItinerary>
<ns1:OriginDestinationOptions>
<ns1:OriginDestinationOption>
<ns1:FlightSegment>
<ns1:DepartureAirport/>
<ns1:ArrivalAirport/>
<ns1:MarketingAirline/>
</ns1:FlightSegment>
</ns1:OriginDestinationOption>
</ns1:OriginDestinationOptions>
</ns1:AirItinerary>
<ns1:TravelerInfoSummary>
<ns1:AirTravelerAvail>
<ns1:AirTraveler>
<ns1:PassengerTypeQuantity/>
<ns1:PassengerIdentificationDocument xsi:nil="true"/>
</ns1:AirTraveler>
</ns1:AirTravelerAvail>
<ns1:AirTravelerAvail>
<ns1:AirTraveler>
<ns1:PassengerTypeQuantity/>
<ns1:PassengerIdentificationDocument xsi:nil="true"/>
</ns1:AirTraveler>
</ns1:AirTravelerAvail>
<ns1:AirTravelerAvail>
<ns1:AirTraveler>
<ns1:PassengerTypeQuantity/>
<ns1:PassengerIdentificationDocument xsi:nil="true"/>
</ns1:AirTraveler>
</ns1:AirTravelerAvail>
</ns1:TravelerInfoSummary>
</ns1:flightMatrixRQ>
</ns1:FlightMatrixRequest>
</env:Body>
</env:Envelope>
As you may see there is no attribute`s data, like DepartureDateTime/LocationCode etc.
Could not find any solution for this case. Possible it may be fixed by using regular curl request with prepared body/headers but it does not look like a good idea.
Any ideas?

Related

How to sign outgoing soap request without using wsf/php?

I am looking how to sign soap header using PHP.
The soap service is built by apache rampart, which is exactly same as sample 2 in https://axis.apache.org/axis2/java/rampart/samples.html.
Now, I have a soap client develop by using PHP.
I have no idea how to sign the entire headers and body.
I can make my soap request as following
<?xml version="1.0" encoding="UTF-8" ?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://ws.globesteel.com" xmlns:ns2="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd" xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:ns3="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<SOAP-ENV:Header>
<ns3:Security SOAP-ENV:mustUnderstand="1">
<ns2:Timestamp>
<ns2:Created>2016-07-13T08:16:02Z</ns2:Created>
<ns2:Expires>2016-07-20T06:56:02Z</ns2:Expires>
</ns2:Timestamp>
<ns3:Signature>
<ns3:SignedInfo>
<Signature>
<SignedInfo>
<CanonicalizationMethod>
<Algorithm>http://www.w3.org/2001/10/xml-exc-c14n#</Algorithm>
</CanonicalizationMethod>
<SignatureMethod>
<Algorithm>http://www.w3.org/2000/09/xmldsig#rsa-sha1</Algorithm>
</SignatureMethod>
<Reference>
<SOAP-ENC:Struct>
<Transforms>
<SOAP-ENC:Struct>
<Algorithm>http://www.w3.org/2001/10/xml-exc-c14n#</Algorithm>
</SOAP-ENC:Struct>
</Transforms>
<DigestMethod>
<Algorithm>http://www.w3.org/2000/09/xmldsig#sha1</Algorithm>
</DigestMethod>
<DigestValue>8f6c3a934fc237673e9f1a12793f5507b8103e4a</DigestValue>
<URI>#_body</URI>
<Id/>
</SOAP-ENC:Struct>
<SOAP-ENC:Struct>
<Transforms>
<SOAP-ENC:Struct>
<Algorithm>http://www.w3.org/2001/10/xml-exc-c14n#</Algorithm>
</SOAP-ENC:Struct>
</Transforms>
<DigestMethod>
<Algorithm>http://www.w3.org/2000/09/xmldsig#sha1</Algorithm>
</DigestMethod>
<DigestValue></DigestValue>
<URI>#_control</URI>
<Id/>
</SOAP-ENC:Struct>
</Reference>
</SignedInfo>
<SignatureValue>Yu/DkCbKXAoalySGM2XdieRYhk1rnwhFKNcklXn5l+YgNk3AXEnpr4yDAlReYgU3FGOZh0XGUn8hGWwEs28S+xjrROgb3G/SYKVKbS3EmAU/vLBa+lABn/0NDoGdR/iIv9C7XAr/OBhE++cHA+lktZSS1SUPtfG5BAifN/RtfkE=</SignatureValue>
<KeyInfo>aqePjuZzE1lzwMMtquksvNJsbmI=</KeyInfo>
</Signature>
</ns3:SignedInfo>
</ns3:Signature>
</ns3:Security>
</SOAP-ENV:Header>
<SOAP-ENV:Body>
<ns1:GetAvailableSecurityQuestions/>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
But I still get error return "Message is not signed".
After 2 weeks of pain, I finally solved this by using https://github.com/robrichards/xmlseclibs

Parsing XML with PHP

I know taht there already are many question about this subject but I haven't find the solution for my problem.
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Header>
<PeopleCountingServiceHeader xmlns="http://localhost/countingws/">
<Username>username</Username>
<Password>password</Password>
<Camera>essai</Camera>
</PeopleCountingServiceHeader>
</soap:Header>
<soap:Body>
<InsertData xmlns="http://ai-sense.com/counting/">
<impacts>
<Impact>
<TimeStamp>2014-10-23T15:17:51.879</TimeStamp>
<Type>Output</Type>
<Layer>0</Layer>
</Impact>
<Impact>
<TimeStamp>2014-10-23T15:17:52.753</TimeStamp>
<Type>Input</Type>
<Layer>0</Layer>
</Impact>
<Impact>
<TimeStamp>2014-10-23T15:17:54.375</TimeStamp>
<Type>Output</Type>
<Layer>0</Layer>
</Impact>
<Impact>
<TimeStamp>2014-10-23T15:17:55.186</TimeStamp>
<Type>Input</Type>
<Layer>0</Layer>
</Impact>
<Impact>
<TimeStamp>2014-10-23T15:18:28.897</TimeStamp>
<Type>Output</Type>
<Layer>0</Layer>
</Impact>
<Impact>
<TimeStamp>2014-10-23T15:18:29.771</TimeStamp>
<Type>Input</Type>
<Layer>0</Layer>
</Impact>
<Impact>
<TimeStamp>2014-10-23T15:22:41.219</TimeStamp>
<Type>Output</Type>
<Layer>0</Layer>
</Impact>
</impacts>
</InsertData>
</soap:Body>
</soap:Envelope>
And I want to retrieve for example the username.
I have already try somethinf like this :
$request =simplexml_load_file("php://input", NULL, TRUE);
echo "request: "$request->{"soap:Header"}->PeopleCountingServiceHeader->Username;
How can I access to my datas ?
This is not just XML, but SOAP. PHP has a specific extension for it: ext/soap.
SOAP is an XML format to transfer objects between systems. You could parse it manually, but a specific SOAP implementation is a lot more convenient.
If you parse in manually you have to consider the namespaces. Here are 3 namespaces in your example XML:
http://schemas.xmlsoap.org/soap/envelope/ - the SOAP envelope, using a soap prefix/alias
http://localhost/countingws/ - elements inside soap:Header, no prefix/alias
http://ai-sense.com/counting/ - elements inside soap:Body, no prefix/alias

Creating paypal invoice with agelleye: error 520002

i get an error, 520002 - Internal Error from PayPal, when I try to create and send an invoice.
I can do it with ci-merchant but no with angelleye (for codeigniter). When I try to create it I get this errors:
<?xml version="1.0" encoding="utf-8"?>
<CreateAndSendInvoiceRequest xmlns="http://svcs.paypal.com/types/ap">
<requestEnvelope xmlns="">
<detailLevel>ReturnAll</detailLevel>
<errorLanguage>en_US</errorLanguage>
</requestEnvelope>
<invoice xmlns="">
<merchantEmail xmlns="">lalanzaos#gmail.com</merchantEmail>
<payerEmail xmlns="">oscar73#gmail.com</payerEmail>
<itemList xmlns="">
<item xmlns="">
<name xmlns="">Clases de idiomas (Español)</name>
<description xmlns="">Dia/s: 2014-08-08</description>
<date xmlns="">2014-08-22</date>
<quantity xmlns="">1</quantity><unitPrice xmlns="">11.00</unitPrice>
</item>
</itemList>
<currencyCode xmlns="">USD</currencyCode>
<invoiceDate xmlns="">2014-08-22</invoiceDate>
<dueDate xmlns="">2014-08-22</dueDate>
<referrerCode xmlns="">AngellEYE_PHPClass</referrerCode>
</invoice>
</CreateAndSendInvoiceRequest>
<?xml version='1.0' encoding='UTF-8'?>
<ns3:FaultMessage xmlns:ns3="http://svcs.paypal.com/types/common" xmlns:ns2="http://svcs.paypal.com/types/pt">
<responseEnvelope>
<timestamp>2014-08-22T04:12:25.170-07:00</timestamp>
<ack>Failure</ack>
<correlationId>87f10d36a1e29</correlationId>
<build>11737381</build>
</responseEnvelope>
<error>
<errorId>520002</errorId>
<domain>PLATFORM</domain>
<subdomain>Application</subdomain>
<severity>Error</severity>
<category>Application</category>
<message>Internal Error</message>
</error>
</ns3:FaultMessage>
It seems that the date format is not being correctly passed . It should be like below :
<invoiceDate xmlns="">2014-08-23T22:33:35</invoiceDate>
<dueDate xmlns="">2014-08-24T22:33:35</dueDate>
It should be working fine with this formatting .

Authorize.net Update recurrent billing using ARB

Does Authorize.net ARP API accept XML data if the data field is empty ? Do we need to have the data on all the XML elements ?
I used the following XML for updating the subscription.
<?xml version="1.0" encoding="utf-8"?>
<ARBUpdateSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<merchantAuthentication>
<name>435345345345</name>
<transactionKey>sdfsdfsdfsdf</transactionKey>
</merchantAuthentication>
<refId>155969e50PGj</refId>
<subscriptionId>234324</subscriptionId>
<subscription>
<amount>75</amount>
<customer>
<id>155969</id>
<email></email>
<phoneNumber></phoneNumber>
</customer>
<billTo>
<firstName></firstName>
<lastName></lastName>
<company></company>
<address></address>
<city></city>
<state></state>
<zip></zip>
<country></country>
</billTo>
<shipTo>
<firstName></firstName>
<lastName></lastName>
<company></company>
<address></address>
<city></city>
<state></state>
<zip></zip>
<country></country>
</shipTo>
</subscription>
</ARBUpdateSubscriptionRequest>
I got the following error :
<?xml version="1.0" encoding="utf-8"?>
<ARBUpdateSubscriptionResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<refId>155969e50PGj</refId>
<messages>
<resultCode>Error</resultCode>
<message>
<code>E00014</code>
<text>Bill-To First Name is required.</text>
</message>
<message>
<code>E00014</code>
<text>Bill-To Last Name is required.</text>
</message>
</messages>
</ARBUpdateSubscriptionResponse>
ARBUpdateSubscriptionRequest is required other XML in request
<?xml version="1.0" encoding="utf-8"?>
<ARBUpdateSubscriptionRequest xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<merchantAuthentication>
<name>mytestacct</name>
<transactionKey>112223344</transactionKey>
</merchantAuthentication>
<refId>Sample</refId>
<subscriptionId>100748</subscriptionId>
<subscription>
<payment>
<creditCard>
<cardNumber>4111111111111111</cardNumber>
<expirationDate>2010-08</expirationDate>
</creditCard>
</payment>
</subscription>
</ARBUpdateSubscriptionRequest>

Pulling values from CIM - authorize.net

I've got my script worked out to grab information from the CIM:
$content =
"<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
"<getCustomerProfileRequest xmlns=\"AnetApi/xml/v1/schema/AnetApiSchema.xsd\">" .
merchantAuthenticationBlock().
"<customerProfileId>$cid</customerProfileId>" .
"</getCustomerProfileRequest>";
$response = send_xml_request($content);
$parsedresponse = parse_api_response($response);
So how, now, do I write the returned value to a variable?
I've tried:
$customerPaymentProfileId = $parsedresponse->customerPaymentProfileId;
$customerShippingAddressId = $parsedresponse->customerShippingAddressId;
But this returns the variables empty. I feel like I'm missing something simple.
To see the structure of $parsedresponse do either print_r($parsedresponse) or var_dump($parsedresponse). From there you can see how the array is structured and get your values from there.
FYI, the payment profiles are in an array so you will need to loop through them to get their values. Assuming parsedresponse is the root XML node you can get them like this:
foreach ($parsedresponse->profile->paymentProfiles as $profile)
{
echo $profile->customerPaymentProfileId;
}
FYI, this is a sample array structure for this response (From the AuthnetXML Sample Code. I am the author of this library):
<?xml version="1.0" encoding="utf-8"?>
<getCustomerProfileResponse xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="AnetApi/xml/v1/schema/AnetApiSchema.xsd">
<messages>
<resultCode>Ok</resultCode>
<message>
<code>I00001</code>
<text>Successful.</text>
</message>
</messages>
<profile>
<merchantCustomerId>12345</merchantCustomerId>
<email>user#example.com</email>
<customerProfileId>5427896</customerProfileId>
<paymentProfiles>
<billTo>
<firstName>John</firstName>
<lastName>Smith</lastName>
<address>123 Main Street</address>
<city>Townsville</city>
<state>NJ</state>
<zip>12345</zip>
<phoneNumber>800-555-1234</phoneNumber>
</billTo>
<customerPaymentProfileId>4796541</customerPaymentProfileId>
<payment>
<creditCard>
<cardNumber>XXXX1111</cardNumber>
<expirationDate>XXXX</expirationDate>
</creditCard>
</payment>
</paymentProfiles>
<paymentProfiles>
<billTo>
<firstName>John</firstName>
<lastName>Doe</lastName>
<company/>
<address>123 Main St.</address>
<city>Bellevue</city>
<state>WA</state>
<zip>98004</zip>
<country>USA</country>
<phoneNumber>800-555-1234</phoneNumber>
<faxNumber>800-555-1234</faxNumber>
</billTo>
<customerPaymentProfileId>4796585</customerPaymentProfileId>
<payment>
<creditCard>
<cardNumber>XXXX1111</cardNumber>
<expirationDate>XXXX</expirationDate>
</creditCard>
</payment>
</paymentProfiles>
<shipToList>
<firstName>John</firstName>
<lastName>Smith</lastName>
<address>123 Main Street</address>
<city>Townsville</city>
<state>NJ</state>
<zip>12345</zip>
<phoneNumber>800-555-1234</phoneNumber>
<customerAddressId>4907537</customerAddressId>
</shipToList>
<shipToList>
<firstName>John</firstName>
<lastName>Doe</lastName>
<company/>
<address>123 Main St.</address>
<city>Bellevue</city>
<state>WA</state>
<zip>98004</zip>
<country>USA</country>
<phoneNumber>800-555-1234</phoneNumber>
<faxNumber>800-555-1234</faxNumber>
<customerAddressId>4907591</customerAddressId>
</shipToList>
</profile>
</getCustomerProfileResponse>

Categories