Simple PHP SOAP request to ClickandBuy? - php

ClickandBuy provides lots of samples, but they are poorly coded and old. So I think there should be an easy PHP 5 SOAP solution for a simple SOAP payRequest with the PHP5 build in SoapClient class.
$client = new SoapClient('https://api.clickandbuy.com/webservices/pay_1_1_0.wsdl', array('encoding' => 'UTF-8'));
$client->payRequest(array('authentication'=>array(...), 'details'=>array(...)));
Works, but it returns an error:
SOAP-ERROR: Encoding: object has no 'description' property
The arguments of the payRequest method should be fine. Did anyone try to implement ClickandBuy without NuSOAP?

Try adding description property into details array:
$client->payRequest(array('authentication'=>array(...),
'details' => array(
'description' => 'paying for shoes'
)
));
Sample request:
<?xml version="1.0" encoding="UTF-8"?>
<payRequest_Request xmlns="http://api.clickandbuy.com/webservices/pay_1_1_0/">
<authentication>
<merchantID>4000</merchantID>
<projectID>1</projectID>
<token>20100623104511::9E9C3E21FE38851B8913469F13619BD645BA1DD6</token>
</authentication>
<details>
<amount>
<amount>1</amount>
<currency>EUR</currency>
</amount>
<orderDetails>
<text>My Cart</text>
</orderDetails>
<successURL>http://www.mydomain.com/success.php</successURL>
<failureURL>http://www.mydomain.com/failure.php</failureURL>
<externalID>Test123</externalID>
</details>
</payRequest_Request>

Related

Array-Properties with the SeralizedPath-Attribute can't be serialized by Serializer

I have the problem that Properties with SerializedPath attributes, which I convert to an XML via Symfony Serializer (SerializerInterface, symfony/serializer-pack), does not have an expected behavior with arrays. Instead, the AbstractObjectNormalizer throws an exception. Symfony and related packages are using v6.2.5.
My goal is to create an XML like this one, with e.g. the following Object:
<?xml version="1.0"?>
<response>
<payment>
<allowedMethods>
<include name="Method A"/>
<include name="Method B"/>
</allowedMethods>
</payment>
</response>
// This is not working
class Payment
{
#[SerializedPath('[payment][allowedMethods][include][#name]')]
public array $methods = ['Method A', 'Method B'];
}
// ...
$this->serializer->serialize(new Payment(), 'xml');
But it results to the following Exception: The element you are trying to set is already populated: "[payment][allowedMethods][include][#name]".
which is thrown in the AbstractObjectNormalizer of Symfony:
if (null !== $classMetadata && null !== $serializedPath = ($attributesMetadata[$attribute] ?? null)?->getSerializedPath()) {
$propertyAccessor = PropertyAccess::createPropertyAccessor();
if ($propertyAccessor->isReadable($data, $serializedPath) && null !== $propertyAccessor->getValue($data, $serializedPath)) {
throw new LogicException(sprintf('The element you are trying to set is already populated: "%s".', (string) $serializedPath));
}
$propertyAccessor->setValue($data, $serializedPath, $attributeValue);
return $data;
}
My expected behavior would be that it behaves identically to the scalar values and therefore recognizes the # as an XML attribute and the rest as nodes:
// This is working great!
class Payment
{
#[SerializedPath('[payment][usedMethod][#name]')]
public string $usedMethod = 'Method A';
}
<?xml version="1.0"?>
<response>
<payment>
<usedMethod name="Method A"/>
</payment>
</response>
I've been trying to identify the exact problem and find a solution for some time, but since SerializedPath is very new (since Symfony 6.2), there is no great documentation for it. Internally it uses the PropertyAccessor, but where I could not find a suitable solution either.
Can someone maybe explain me the problem in more detail or even know a solution? Or even an alternative way. I'm trying to do it via the SerializedPath to avoid all the nested DTOs that are just there to map the (not always plausible) data model of the XML.
Another quite interesting fact is, if you comment out the thrown Exception in the AbstractObjectNormalizer it kind of works (for json fully, for xml partially, because the array can only hold one entry because of the annotation key):
class Payment
{
#[SerializedPath('[payment][allowedMethods][include]')]
public array $methods = [
'#name' => 'Method A'
];
}
<?xml version="1.0"?>
<response>
<payment>
<allowedMethods>
<include name="Method A"/>
</allowedMethods>
</payment>
</response>

PHP native, ignores namespace in soapvar

I recently created a php web service using php native soap. I have created the wsdl, xsd and the php code to construct the response.
In my soapvar when I construct the soap arrayObject using the namespace prefix, some nodes have it and some don't.
What I want is all the nodes have the "ns1:" prefix or none of them.
In order to overcome the issue I removed the namespace from soapvar. So this removed the ns prefix But I always have the message from my wsdl "retrieveDataResponse" node with "ns1:" prefix and and all the rest I constructed without.
In my php I have nested foreach run in every node and children adding "XSD_STRING" or "SOAP_ENC_OBJECT" depending on the enc_type.
My soapvar in php in the foreach is :
$dataStruct[] = new SoapVar($ListOfDataStruct, SOAP_ENC_OBJECT, null, null, 'ListOfData', 'http://localhost/soap/retrieveCstData');
My XML response is
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://localhost/soap/retrieveCstData">
<SOAP-ENV:Body>
<ns1:retrieveDataResponse>
<ns1:cstData>
<ns1:Description>Discription N/A</ns1:Description>
<ns1:ListOfData>
<ns1:Customer-Data-Header>
<ns1:AssetDescription>Basic 12 Months</ns1:AssetDescription>
<ns1:AssetId>1-3QGMHQ9</ns1:AssetId>
<ns1:ProductDescription>Basic 12 Months</ns1:ProductDescription>
<ns1:ProductId>1-2E543A</ns1:ProductId>
<ns1:ProductName>Basic Product Subscription</ns1:ProductName>
<ns1:ListOfCstData-Asset>
<ns1:CstData-Asset>
<AssetIntegrationId>1-3Q3KSNI</AssetIntegrationId>
<ProductName>Basic Product Subscription</ProductName>
<ProductPartNumber>SAT0028</ProductPartNumber>
<StartDate>08/19/2015 21:00:00</StartDate>
<Status>Active</Status>
<ListOfProductXA/>
<ListOfAddress/>
<ListOfContact/>
</ns1:CstData-Asset>
</ns1:ListOfCstData-Asset>
</ns1:Customer-Data-Header>
<ns1:Customer-Data-Header>
<ns1:AssetId>1-7MRO-241</ns1:AssetId>
<ns1:ProductDescription>SubProduct A</ns1:ProductDescription>
<ns1:ProductId>1-65TVM</ns1:ProductId>
<ns1:ProductName>SubProduct A Type</ns1:ProductName>
<ns1:ProductType>Product</ns1:ProductType>
<ns1:ListOfCstData-Asset>
<ns1:CstData-Asset>
<AssetIntegrationId>1-5T126KG</AssetIntegrationId>
<ProductName>Asset-Product 1</ProductName>
<ProductPartNumber>N/A</ProductPartNumber>
<StartDate>08/16/2016 21:00:00</StartDate>
<Status>Active</Status>
<ListOfProductXA/>
<ListOfAddress/>
<ListOfContact/>
</ns1:CstData-Asset>
<ns1:CstData-Asset>
<AssetIntegrationId>W-C5PLG-11H-1</AssetIntegrationId>
<ProductName>SubProduct A Type</ProductName>
<ProductPartNumber>Data Packets</ProductPartNumber>
<RegisteredDate>02/21/1978</RegisteredDate>
<ServiceID>#56487%</ServiceID>
<StartDate>02/21/1978 00:00:00</StartDate>
<ListOfProductXA/>
<ListOfAddress>
<CutAddress>
<AddressType>Installation</AddressType>
<TEK>1651</TEK>
<Type>Old</Type>
<Country>US</Country>
<StreetNumberFrom>37</StreetNumberFrom>
<PostalCode>66857</PostalCode>
<State>CA</State>
<StreetName>
<State>JAX Avenue</State>
</StreetName>
</CutAddress>
</ListOfAddress>
<ListOfContact>
<Contact>
<ActiveStatus>Y</ActiveStatus>
<IsPrimaryMVG>Y</IsPrimaryMVG>
<CellularPhone>555687676</CellularPhone>
<FirstName>Jhon</FirstName>
<LastName>Doe</LastName>
<PreferredCommunicationMethod>SMS</PreferredCommunicationMethod>
<ContactType>Technical</ContactType>
</Contact>
</ListOfContact>
</ns1:CstData-Asset>
</ns1:ListOfCstData-Asset>
</ns1:Customer-Data-Header>
<ns1:Customer-Data-Header>
<ns1:AssetDescription>Satelite 80CM</ns1:AssetDescription>
<ns1:AssetId>1-3QGMHX9</ns1:AssetId>
<ns1:ProductDescription>Satelite 80CM</ns1:ProductDescription>
<ns1:ProductId>1-2DIYLT</ns1:ProductId>
<ns1:ProductName>TV SAT</ns1:ProductName>
<ns1:ProductType>Product</ns1:ProductType>
<ns1:ListOfCstData-Asset>
<ns1:CstData-Asset>
<SubscriberId>664668941</SubscriberId>
<Comments>Suspension/Reactivation</Comments>
<AssetIntegrationId>1-3Q3KSNJ</AssetIntegrationId>
<ProductName>TV SAT</ProductName>
<ProductPartNumber>TV_SAT</ProductPartNumber>
<ServiceID>9995654321587</ServiceID>
<StartDate>08/19/2015 21:00:00</StartDate>
<Status>Active</Status>
<ListOfProductXA/>
<ListOfAddress>
<CutAddress>
<AddressType>Installation</AddressType>
<TEK>1651</TEK>
<Type>Old</Type>
<Area>CA</Area>
<Country>US</Country>
<StreetNumberFrom>37</StreetNumberFrom>
<ResidenceType>Business</ResidenceType>
<Floor>0</Floor>
<MailBox>US</MailBox>
<PostalCode>66857</PostalCode>
<State>CA</State>
<StreetName>JAX AVENUE</StreetName>
<District>DownTown</District>
</CutAddress>
</ListOfAddress>
<ListOfContact/>
</ns1:CstData-Asset>
</ns1:ListOfCstData-Asset>
</ns1:Customer-Data-Header>
</ns1:ListOfData>
</ns1:retrieveDataResponse>
</ns1:retrieveDataResponse>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
So as you can see prefix is not in every node.
Well I found the problem.
In one of the many foreach loops I used a previous declared arrayObject instead of the array key.
So soapvar does not ingone the namespace :)

php soap - send request for multidimensional array

First up, I'm trying to send a soap request using PHP SOAP and the XML that the service accepts is as shown below.
<U_MemberReservedTransaction xmlns="http://tempuri.org/">
<UserID>string</UserID>
<password>string</password>
<memberReservedTransactionRequest>
<memberReservedTransactions>
<ReservedType>string</ReservedType>
<Firstname>string</Firstname>
<Surname>string</Surname>
<IcNew>string</IcNew>
</memberReservedTransactions>
<memberReservedTransactions>
<ReservedType>string</ReservedType>
<Firstname>string</Firstname>
<Surname>string</Surname>
<IcNew>string</IcNew>
</memberReservedTransactions>
</memberReservedTransactionRequest>
</U_MemberReservedTransaction>
Just to summarize what the service is expecting, the service is to receive an array of memberReservedTransactions. My SOAP request call looks like below currently.
$client->callService('U_MemberReservedTransaction', array(
'UserID'=>'test1',
'password'=>'password',
'memberReservedTransactionRequest' => array(
'memberReservedTransaction' => array (
array(
'ReservedType'=>'Renew',
'Firstname'=>'',
'Surname'=>'',
'IcNew'=>''
)
)
)
));
As for what i'm expecting in return is a multidimensional array but my concern now is getting my request accepted.
Note : I'm getting a 500 Internal Server Error
Please help :<

DHL, Soap, PHP - not understanding

I have to make a SOAP-Request with PHP to the DHL Carrier Service to generate batch labels. Somehow, I can't understand how it works. I wrote this code:
<?php
require_once('lib/Zend/Soap/Client.php');
require_once('lib/Zend/Soap/Client/Common.php');
$client = new Zend_Soap_Client('http://test-intraship.dhl.com/ws/1_0/ISService/DE.wsdl',
array(
'soap_version'=>SOAP_1_1
,'encoding' => 'UTF-8'
,'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_DEFLATE
,'location'=>'https://test-intraship.dhl.com/intraship.57/jsp/Login_WS.jsp'
)
);
$location = 'https://test-intraship.dhl.com/intraship.57/jsp/Login_WS.jsp';
$request = '
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:cis="http://dhl.de/webservice/cisbase" xmlns:de="http://de.ws.intraship">
<soap:Header><cis:Authentification><cis:user>magento</cis:user><cis:signature>m1a2$!</cis:signature><cis:accountNumber>5000000000</cis:accountNumber><cis:type>0</cis:type></cis:Authentification>
</soap:Header>
<soap:Body><de:CreateShipmentDDRequest>
<cis:Version>
<cis:majorRelease>1</cis:majorRelease>
<cis:minorRelease>0</cis:minorRelease></cis:Version><ShipmentOrder><SequenceNumber>1</SequenceNumber><Shipment><ShipmentDetails><ProductCode>EPN</ProductCode><ShipmentDate>2012-10-03</ShipmentDate><DeclaredValueOfGoods>10.2</DeclaredValueOfGoods><DeclaredValueOfGoodsCurrency>EUR</DeclaredValueOfGoodsCurrency><cis:EKP>5000000000</cis:EKP><Attendance><cis:partnerID>01</cis:partnerID></Attendance><CustomerReference>Auftrag 12883884</CustomerReference><ShipmentItem><WeightInKG>12</WeightInKG><LengthInCM>1</LengthInCM><WidthInCM>1</WidthInCM><HeightInCM>10</HeightInCM><PackageType>PK</PackageType></ShipmentItem><Service><ShipmentServiceGroupIdent><ReturnReceipt>false</ReturnReceipt></ShipmentServiceGroupIdent></Service><Service><ShipmentServiceGroupIdent><Personally>false</Personally></ShipmentServiceGroupIdent></Service><Service><ServiceGroupDHLPaket><Multipack>False</Multipack></ServiceGroupDHLPaket></Service><BankData><cis:accountOwner>DHL.de</cis:accountOwner><cis:accountNumber>1234567891</cis:accountNumber><cis:bankCode>87050000</cis:bankCode><cis:bankName>Sparkasse Chemnitz</cis:bankName><cis:iban>DE34870500001234567891</cis:iban><cis:note>Notiz Bank</cis:note><cis:bic>CHEKDE81XXX</cis:bic></BankData></ShipmentDetails><Shipper><Company><cis:Person><cis:firstname></cis:firstname><cis:lastname>Deutsche Post IT BRIEF GmbH</cis:lastname></cis:Person></Company><Address><cis:streetName>Heinrich-Brüning-Str.</cis:streetName><cis:streetNumber>7</cis:streetNumber><cis:Zip><cis:germany>53113</cis:germany></cis:Zip><cis:city>Bonn</cis:city><cis:Origin><cis:countryISOCode>DE</cis:countryISOCode></cis:Origin></Address><Communication><cis:phone>3935644</cis:phone><cis:email>dhl#dhl.com</cis:email><cis:contactPerson>IT Systeme Marketing Vertrieb</cis:contactPerson></Communication></Shipper><Receiver><Company><cis:Company><cis:name1>DHL Vertriebs GmbH Co. OHG</cis:name1></cis:Company></Company><Address><cis:streetName>Neue Poststr.</cis:streetName><cis:streetNumber>1</cis:streetNumber><cis:Zip><cis:other>08496</cis:other></cis:Zip><cis:city>Neumark</cis:city><cis:Origin><cis:countryISOCode>DE</cis:countryISOCode></cis:Origin></Address><Communication><cis:phone>3935655</cis:phone><cis:email>dhl#dhl.com</cis:email><cis:contactPerson>CIS 1J4</cis:contactPerson></Communication></Receiver><ExportDocument><InvoiceType>proforma</InvoiceType><InvoiceDate>2012-10-03</InvoiceDate><InvoiceNumber>444444</InvoiceNumber><ExportType>1</ExportType><ExportTypeDescription>für Sonstiges</ExportTypeDescription><CommodityCode>8888888</CommodityCode><TermsOfTrade>CIP</TermsOfTrade><Amount>2000</Amount><Description>777777</Description><CountryCodeOrigin>DE</CountryCodeOrigin><AdditionalFee>3.12</AdditionalFee><CustomsValue>2.23</CustomsValue><CustomsCurrency>EUR</CustomsCurrency><PermitNumber>666666</PermitNumber><AttestationNumber>?</AttestationNumber><ExportDocPosition><Description>Harddisk</Description><CountryCodeOrigin>DE</CountryCodeOrigin><CommodityCode>123456</CommodityCode><Amount>200</Amount><NetWeightInKG>1</NetWeightInKG><GrossWeightInKG>1.2</GrossWeightInKG><CustomsValue>200</CustomsValue><CustomsCurrency>EUR</CustomsCurrency></ExportDocPosition></ExportDocument></Shipment><LabelResponseType>URL</LabelResponseType></ShipmentOrder></de:CreateShipmentDDRequest></soap:Body></soap:Envelope>
';
$clientCommon = new Zend_Soap_Client_Common($client, 'http://test-intraship.dhl.com/ws/1_0/ISService/DE.wsdl',
array(
'soap_version'=>SOAP_1_1
,'encoding' => 'UTF-8'
,'compression' => SOAP_COMPRESSION_ACCEPT | SOAP_COMPRESSION_DEFLATE
,'location'=>'https://test-intraship.dhl.com/intraship.57/jsp/Login_WS.jsp'
));
$response = $client->_doRequest($clientCommon, trim($request), $location, 'createShipmentDD', SOAP_1_1);
print_r($response);
?>
The XML code is copied from the DHL test tool, the access data are standard test data, which should actually always work. But I always become a "Wrong login data"-message. Why can it be?
I tried to find something out with the SoapUI programm but I don't seem to understand how all this stuff work.
Can you please give me some help?
The URL you are trying sending your SOAP-Request to (https://test-intraship.dhl.com/intraship.57/jsp/Login_WS.jsp) is not used as an Web Service endpoint - it is the Single-Sign-On URL for logging in your customer to the DHL Intraship Customer Portal (you can submit parceldata manually there).
The endpoint for the Web Service is http://test-intraship.dhl.com/ws/1_0/de/ISService (Source: https://entwickler.dhl.de/group/ep/webservices/intraship/quick-start)
You may need more information from DHL
https://test-intraship.dhl.com/intraship.57/jsp/Login_WS.jsp
To Login this URL you need User name and password, This information is other than cis:Authentification section you passed in soap:Header node.
This new User name and password you need to set in new "Zend_Soap_Client_Common" object.

How-to make a SOAP web service call to a .NET web service w/o "unable to deserialize request" error?

I am trying to make a web service call from PHP to a SOAP web service with a sample request which looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ws="http://ws.somedomain.com/">
<soapenv:Header/>
<soapenv:Body>
<ws:SearchMarketplaceSku>
<ws:Request>
<ws:Security>
<ws:PartnerKey>[suppressed]</ws:PartnerKey>
<ws:Password>[suppressed]</ws:Password>
</ws:Security>
<ws:AvailableOnDate>2012-04-03T00:00:00</ws:AvailableOnDate>
<ws:IncludeStateDetails>true</ws:IncludeStateDetails>
<ws:State>CA</ws:State>
</ws:Request>
</ws:SearchMarketplaceSku>
</soapenv:Body>
</soapenv:Envelope>
The PHP code being used is:
$soapClient = new SoapClient($wsdlUrl);
$ap_param = array('PartnerKey' => $PartnerKey, 'Password' => $metapackPassword, 'AvailableOnDate' => '2012-04-03T00:00:00','IncludeStateDetails'=>true, 'State'=>'CA');
$info = $soapClient->__call("SearchMarketplaceSku", $ap_param);
The web service call results in an "Request was not specified properly; server unable to deserialize request" error? What is the problem? Does the $ap_param array need to include all the nested nodes coressponding with the XML? Is there an easier way to make this call using "WSDL" mode?
Thanks for your help
PartnerKey and Password has to be in an Array under the key Security:
$ap_param = array(
'Security' => array(
'PartnerKey' => $PartnerKey,
'Password' => $metapackPassword
),
'AvailableOnDate' => '2012-04-03T00:00:00',
'IncludeStateDetails'=>true, 'State'=>'CA'
);

Categories