I am trying to develop an application that uses the ListMatchingProducts method.
The end result will be an application that searches for a given product which is already in an internal stock database and present the results to the user so they can select which Amazon product is a correct match for the one in their database.
The PHP Client Library I found is linked here.
I have edited Samples/.config.inc.php correctly (I have removed the comments and redacted the sensitive information):
define('AWS_ACCESS_KEY_ID', '/*REDACTED BUT SET CORRECTLY*/');
define('AWS_SECRET_ACCESS_KEY', '/*REDACTED BUT SET CORRECTLY*/');
define('APPLICATION_NAME', 'STES_MWS_STOCK_SYNC_APP');
define('APPLICATION_VERSION', '0.1');
define ('MERCHANT_ID', '/*REDACTED BUT SET CORRECTLY*/');
define ('MARKETPLACE_ID', 'A1F83G8C2ARO7P'); // Marketplace ID for the UK
I have also uncommented the appropriate line in Samples/ListMatchingProductsSample.php:
$serviceUrl = "https://mws-eu.amazonservices.com/Products/2011-10-01";
Executing this script, however, yeilds the following message (I've redacted some of the XML response):
Caught Exception: Required parameter MarketplaceId not found
Response Status Code: 400
Error Code: MissingParameter
Error Type: Sender
Request ID: /*REDACTED UUID-LIKE STRING*/
XML: <?xml version="1.0"?>
<ErrorResponse xmlns="http://mws.amazonservices.com/schema/Products/2011-10-01"><Error><Type>Sender</Type><Code>MissingParameter</Code><Message>Required parameter MarketplaceId not found</Message><Detail/></Error><RequestID>/*REDACTED UUID-LIKE STRING*/</RequestID></ErrorResponse>
ResponseHeaderMetadata: RequestId: /*REDACTED UUID-LIKE STRING*/, ResponseContext: /*REDACTED LONG STRING*/, Timestamp: 2017-04-24T13:25:33.533Z, Quota Max: 719.0, Quota Remaining: 719.0, Quota Resets At: 2017-04-24T14:03:00.000Z
As this client library has been around since 2011 I find it difficult to believe this is actually incorrect code in the sample, but I can't seem to find where I've gone wrong; scanning through the code I can't find a reference to the MARKETPLACE_ID constant defined in Samples/.config.inc.php
Before I write my own client library (which I had hoped to avoid for such a simple app) I wondered:
Has anyone else had come across this problem and fixed it (and if so, how)?
Is there a newer version of the library I'm not finding?
Can anyone suggest an alternate library if this one really is broken?
-- EDIT --
For completeness, here is the code I am trying to run - the sample code - minus comments:
require_once('.config.inc.php');
$serviceUrl = "https://mws-eu.amazonservices.com/Products/2011-10-01";
$config = array (
'ServiceURL' => $serviceUrl,
'ProxyHost' => null,
'ProxyPort' => -1,
'ProxyUsername' => null,
'ProxyPassword' => null,
'MaxErrorRetry' => 3,
);
$service = new MarketplaceWebServiceProducts_Client(
AWS_ACCESS_KEY_ID,
AWS_SECRET_ACCESS_KEY,
APPLICATION_NAME,
APPLICATION_VERSION,
$config);
$request = new MarketplaceWebServiceProducts_Model_ListMatchingProductsRequest();
$request->setSellerId(MERCHANT_ID);
invokeListMatchingProducts($service, $request);
function invokeListMatchingProducts(MarketplaceWebServiceProducts_Interface $service, $request)
{
try {
$response = $service->ListMatchingProducts($request);
echo ("Service Response\n");
echo ("=============================================================================\n");
$dom = new DOMDocument();
$dom->loadXML($response->toXML());
$dom->preserveWhiteSpace = false;
$dom->formatOutput = true;
echo $dom->saveXML();
echo("ResponseHeaderMetadata: " . $response->getResponseHeaderMetadata() . "\n");
} catch (MarketplaceWebServiceProducts_Exception $ex) {
echo("Caught Exception: " . $ex->getMessage() . "\n");
echo("Response Status Code: " . $ex->getStatusCode() . "\n");
echo("Error Code: " . $ex->getErrorCode() . "\n");
echo("Error Type: " . $ex->getErrorType() . "\n");
echo("Request ID: " . $ex->getRequestId() . "\n");
echo("XML: " . $ex->getXML() . "\n");
echo("ResponseHeaderMetadata: " . $ex->getResponseHeaderMetadata() . "\n");
}
}
Frankly it seems like the "samples" are a bit naff.
Looking at the code, it seems likely you need to set the marketplaceId manually, either in the constructor via an associative array or as a setter method call.
e.g.
$request->setMarketplaceId(MARKETPLACE_ID)
Related
I try to sign test bitcoin-cash transaction, and then broadcast.
For bitwasp version 0.0.35.0, the code is:
$utxoOwnerPrivateKey = 'MyPrIvAtEKey';//public key is "16Dbmp13CqdLVwjXrd6amF48t7L8gYSGBj", note - the real private key is another
$utxo = '5e44cdab9cb4a4f1871f2137ab568bf9ef2760e52816971fbaf0198f19e28378';
$utxoAmount = 598558;
$reciverPublicKey = '1EjCxux1FcohsBNGzY9KdF59Dz7MYHQyPN';
$fee = 1000;
$addressCreator = new \Btccom\BitcoinCash\Address\AddressCreator();
$networkObject = \Btccom\BitcoinCash\Network\NetworkFactory::bitcoinCash();
$keyPairInput = \BitWasp\Bitcoin\Key\PrivateKeyFactory::fromWif($utxoOwnerPrivateKey, null, $networkObject);
$outpoint = new \BitWasp\Bitcoin\Transaction\OutPoint(\BitWasp\Buffertools\Buffer::hex($utxo, 32), 0);
$transaction = \BitWasp\Bitcoin\Transaction\TransactionFactory::build()
->spendOutPoint($outpoint)
->payToAddress($utxoAmount - $fee, $addressCreator->fromString($reciverPublicKey, $networkObject) )
->get();
echo "Unsigned transaction: " . $transaction->getHex() . '<BR><BR>';
$signScript = \BitWasp\Bitcoin\Script\ScriptFactory::scriptPubKey()->payToPubKeyHash($keyPairInput->getPublicKey()->getPubKeyHash());
$txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($utxoAmount - $fee, $signScript);
$signer = new \BitWasp\Bitcoin\Transaction\Factory\Signer($transaction);
$signatureChecker = \Btccom\BitcoinCash\Transaction\Factory\Checker\CheckerCreator::fromEcAdapter( \BitWasp\Bitcoin\Bitcoin::getEcAdapter() ); // for version 0.0.35
$signer->setCheckerCreator( $signatureChecker ); // for version 0.0.35
$input = $signer->input(0, $txOut);
$signatureType = \Btccom\BitcoinCash\Transaction\SignatureHash\SigHash::ALL | \Btccom\BitcoinCash\Transaction\SignatureHash\SigHash::BITCOINCASH;
$input->sign($keyPairInput, $signatureType);
$signed = $signer->get();
echo "Witness serialized transaction: " . $signed->getHex() . '<BR><BR>';
echo "Base serialized transaction: " . $signed->getBaseSerialization()->getHex() . '<BR><BR>';
echo "Script validation result: " . ($input->verify() ? "yes\n" : "no\n"). '<BR><BR>';
die();
In this case I get the result:
Script validation result: no
Trying to broadcast the BCH transaction gives an error:
An error occured:
16: mandatory-script-verify-flag-failed (Signature must be zero for failed CHECK(MULTI)SIG operation). Code:-26
I think, it means, that signature is wrong. If we remove the flag $signatureType (keep this default), then Script validation result will be yes, but broadcasting will give an error:
16: mandatory-script-verify-flag-failed (Signature must use SIGHASH_FORKID). Code:-26
I think, it means - transaction signed as in bitcoin network, must to be signed by bitcoin-cash rules. Maybe I'm wrong. But bitcoin transaction signing is fine. Bitwasp has no manuals, how to sign a bitcoin-cash transactions, I have the same code for bitwasp v.0.0.34.2 (without addon "btccom/bitwasp-bitcoin-bch-addon", using $signer->redeemBitcoinCash(true); function) but it gives the same result.
It is interesting that in code of bitcoin-cash signer it takes the inner variable amount and include it in hash:
$hasher = new V1Hasher($this->transaction, $this->amount);
But for bitcoin bitwasp doesn't take the amount, presumably it takes an amount from the transaction.
Help me please to sign the transaction, bitwasp has only bitcoin examples, not bitcoin-cash. It is very difficult to find any informaion about php altcoins signing without third-party software. Regards.
This code to sign a bitcoin-cash transaction with PHP bitwasp v.0.0.35 library is works!
$unspendedTx = '49343e0a4ef29b819f87df1371c6f8eafa1f235074a27fb6aa5f4ab4c48e5c16';
$utxOutputIndex = 0;
$utxoPrivateKey = 'MyPrIvAtEKey';
$utxoAmount = 300000;
$reciverPublicKey = '1E8XaWNsCWyVaZaWTLh8uBdAZjLQqwWmzM';
$fee = 1000;
$networkObject = \Btccom\BitcoinCash\Network\NetworkFactory::bitcoinCash();
$outpoint = new \BitWasp\Bitcoin\Transaction\OutPoint(\BitWasp\Buffertools\Buffer::hex($unspendedTx, 32), $utxOutputIndex /* index of utxo in transaction, generated it */);
$destination = \BitWasp\Bitcoin\Script\ScriptFactory::scriptPubKey()->payToPubKeyHash( (new \Btccom\BitcoinCash\Address\AddressCreator())->fromString($reciverPublicKey)->getHash() );
$transaction = \BitWasp\Bitcoin\Transaction\TransactionFactory::build()
->spendOutPoint($outpoint)
->output($utxoAmount - $fee, $destination)
->get();
echo "Unsigned transaction: " . $transaction->getHex() . '<BR><BR>';
$keyPairInput = \BitWasp\Bitcoin\Key\PrivateKeyFactory::fromWif($utxoPrivateKey, null, $networkObject);
$txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($utxoAmount, \BitWasp\Bitcoin\Script\ScriptFactory::scriptPubKey()->payToPubKeyHash( $keyPairInput->getPubKeyHash() ) );
$signer = new \BitWasp\Bitcoin\Transaction\Factory\Signer($transaction);
$signatureChecker = \Btccom\BitcoinCash\Transaction\Factory\Checker\CheckerCreator::fromEcAdapter( \BitWasp\Bitcoin\Bitcoin::getEcAdapter() ); // for version 0.0.35
$signer->setCheckerCreator( $signatureChecker ); // for version 0.0.35
$input = $signer->input(0, $txOut);
$signatureType = \Btccom\BitcoinCash\Transaction\SignatureHash\SigHash::ALL | \Btccom\BitcoinCash\Transaction\SignatureHash\SigHash::BITCOINCASH;
$input->sign($keyPairInput, $signatureType);
$signed = $signer->get();
echo "Transaction: " . $signed->getHex() . '<BR><BR>';
die();
I had broadcasted this PHP-generated test transaction, see link to tx. Problaly the problem was in
->payToAddress($utxoAmount - $fee, $addressCreator->fromString($reciverPublicKey, $networkObject) )
Maybe payToAddress has a bug, because "hand" script creation gives another transaction. Second:
$txOut = new \BitWasp\Bitcoin\Transaction\TransactionOutput($utxoAmount - $fee, $signScript);
We must to create tx input(previous output) without the fee.
Used libraries ( composer.json ):
{
"require" : {
"php" : ">=7.0",
"bitwasp/bitcoin": "0.0.35.0",
"btccom/bitwasp-bitcoin-bch-addon" : "0.0.2"
}
}
Hope, this will help for all altcoin api creators on PHP.
I have working with SOAP in yii2 and I got an error when I tried to process a soap call
This my soap request :
$xmlInput = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://ws.api.interfaces.sessions.uams.amdocs\" xmlns:util=\"http://utils.uams.amdocs\" xmlns:web=\"http://webservices.fw.jf.amdocs\"><soapenv:Header/><soapenv:Body><ws:createUser><ws:aCreateUserInfo><util:userId>" . strtoupper($Userid) . "</util:userId><util:effDate>" . $Effdate . "T00:00:09+07:00</util:effDate><util:expDate>" . $Expdate . "T00:00:09+07:00</util:expDate><util:password>" . $this->randomPassword(8) . "</util:password><util:userRoles><ws:item>" . $Role . "</ws:item></util:userRoles></ws:aCreateUserInfo><ws:_awsi_header><web:securedTicket>" . $Ticket . "</web:securedTicket></ws:_awsi_header></ws:createUser></soapenv:Body></soapenv:Envelope>";
Finally I got a response like this :
<?xml version="1.0" encoding="utf-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"><soapenv:Body><soapenv:Fault><faultcode>soapenv:Server.userException</faultcode><faultstring>org.xml.sax.SAXException: SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.</faultstring><detail><faultData><cause xsi:nil="true"/><exception xsi:nil="true"/><message>SimpleDeserializer encountered a child element, which is NOT expected, in something it was trying to deserialize.</message></faultData><ns1:hostname xmlns:ns1="http://xml.apache.org/axis/">ocsbrntapp4</ns1:hostname></detail></soapenv:Fault></soapenv:Body></soapenv:Envelope>
Anybody can help me to fix this issue? Thank you
Try downloading SOAP UI and do a request from there. You will easily be able to see what you are missing.
https://www.soapui.org/downloads/latest-release.html
SOAP UI will automatically tell you exactly what the xml should look like when you post to web service so it is very easy to see where you made a mistake.
Your problem is probably caused by incorrect escaped xml file.
please examine $xmlInput
Based on your code, I would assome that the problem is inside your "$this->randomPassword(8)" function, but without seeing this function I am just asuming.
if you output $xmlInput and see illegal xml characters in there, you can escape them in 2 ways.
1) $xmlInput = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://ws.api.interfaces.sessions.uams.amdocs\" xmlns:util=\"http://utils.uams.amdocs\" xmlns:web=\"http://webservices.fw.jf.amdocs\"><soapenv:Header/><soapenv:Body><ws:createUser><ws:aCreateUserInfo><util:userId>" . strtoupper($Userid) . "</util:userId><util:effDate>" . $Effdate . "T00:00:09+07:00</util:effDate><util:expDate>" . $Expdate . "T00:00:09+07:00</util:expDate><util:password><![CDATA[" . htmlentities($this->randomPassword(8), ENT_XHTML, 'UTF-8') . "]]></util:password><util:userRoles><ws:item>" . $Role . "</ws:item></util:userRoles></ws:aCreateUserInfo><ws:_awsi_header><web:securedTicket>" . $Ticket . "</web:securedTicket></ws:_awsi_header></ws:createUser></soapenv:Body></soapenv:Envelope>";
2) $xmlInput = "<soapenv:Envelope xmlns:soapenv=\"http://schemas.xmlsoap.org/soap/envelope/\" xmlns:ws=\"http://ws.api.interfaces.sessions.uams.amdocs\" xmlns:util=\"http://utils.uams.amdocs\" xmlns:web=\"http://webservices.fw.jf.amdocs\"><soapenv:Header/><soapenv:Body><ws:createUser><ws:aCreateUserInfo><util:userId>" . strtoupper($Userid) . "</util:userId><util:effDate>" . $Effdate . "T00:00:09+07:00</util:effDate><util:expDate>" . $Expdate . "T00:00:09+07:00</util:expDate><util:password><![CDATA[" . $this->randomPassword(8) . "]]></util:password><util:userRoles><ws:item>" . $Role . "</ws:item></util:userRoles></ws:aCreateUserInfo><ws:_awsi_header><web:securedTicket>" . $Ticket . "</web:securedTicket></ws:_awsi_header></ws:createUser></soapenv:Body></soapenv:Envelope>";
Basically check the contents of $xmlInput and, make sure that all values are escaped properly.
I'm going through tutorials on webservices and SOAP. In learning about these, I created a php file to act on the WSDL provided by w3schools that converts temperatures between Celsius and Fahrenheit.
I wrote the following PHP code which fires successfully:
$wsdl = "http://www.w3schools.com/webservices/tempconvert.asmx?WSDL";
$soapClient = new SoapClient($wsdl);
// print_r ($soapClient->__getFunctions());
// print_r ($soapClient->__getTypes());
$parameters = array("Celsius" => "0");
$result = $soapClient->__soapCall("CelsiusToFahrenheit", array($parameters) );
echo "key: " . key($result) . "<br />" ;
echo "value: " . current($result) . "<br />" ;
The browser successfully returns the following:
key: CelsiusToFahrenheitResult
value: 32
I then tried to use the SoapClient methods __getLastRequest() and __getLastRequestHeaders() to take a look at the headers that were sent and see how they compare to what I had been reading and both method calls returned null
echo "Last call headers: <br />";
echo $soapClient->__getLastRequestHeaders();
echo "<br />" ;
echo "Last call headers: <br />";
echo $soapClient->__getLastRequest();
I reviewed the notes and example in the php manual for _getLastRequestHeaders() and it looks like everything is set up correctly. I can't tell what I'm doing wrong :/
Any help would be appreciated!
If you don't set trace to true in the options argument of the constructor of the SoapClient, it won't store these. So simply put, this will work for you:
$soapClient = new SoapClient($wsdl, array('trace' => true));
... which the manual page you linked to explicitly states:
Note:
This function only works if the SoapClient object was created with the trace option set to TRUE.
I am new to Web Services and am struggling to access/read the XML data using PHP (my website that will be using the data is in PHP).
The WSDL Url: http://services.mywheels.co.za/BWAVehicleStockService.svc?wsdl
I need to get access and read the Vehicle stock information but cant see to access anything.
the Array vehicle are stored under: http://services.mywheels.co.za/BWAVehicleStockService.svc?xsd=xsd2 .
i am using this code but it doesnt give my any data. I also have a GUID that i need to pass but have no idea how to add it to the header.
<?PHP
define('NEWLINE', "<br />\n");
// SOAP client
$wsdl = 'http://services.mywheels.co.za/BWAVehicleStockService.svc?wsdl';
$soapClient = new SoapClient($wsdl, array('cache_wsdl' => 0));
// SOAP call
$parameters->ArrayOfVehicle->Vehicle;
try
{
$result = $soapClient->GetVehicleStock($parameters);
}
catch (SoapFault $fault)
{
echo "Fault code: {$fault->faultcode}" . NEWLINE;
echo "Fault string: {$fault->faultstring}" . NEWLINE;
if ($soapClient != null)
{
$soapClient = null;
}
exit();
}
$soapClient = null;
echo "<pre>\n";
print_r($result);
echo "</pre>\n";
echo "Return value: {$result->GetDataResult}" . NEWLINE;
?>
if someone can help or point me in the right direction with this that would be great.
Thanks
You can add headers using __setSoapHeaders():
$h = new SoapHeader('http://tempuri.org/', 'Guid', '123');
$soapClient->__setSoapHeaders($h);
I had to read the WSDL itself to find out what namespace I should use; in this case they refer to Guid as tns:Guid and from the top you can read what URI is used to express that, hence http://tempuri.org.
I would like to create new contacts and leads using php. I can't quite figure out how to call the methods of the mscrm 3 web service.
The php soap class seems quite simple to use. I am able to connect and authenticate to the crm web service and get a list of available functions however I am unsure how to go about calling them.
I have seen examples for mscrm 4.0 which seem to involve masses of XML including soap headers and envelopes.
I am under the impression that using a soap class bypasses this and will write all the extra xml for me so all I need to do is call a function with an array of parameters?
Am I completely wrong here ?
Has anyone done this with mscrm 3 that can provide some sample code, or perhaps give me a few pointers as how to correctly call the Create() method ?
I have been able to get this working by using Nusoap and after construction the XML message as a series of strings using the send method instead of call. This now works as expected. It seemed that using the call method was returning different XML than what was required by the ms crm 3 web service.
Any decent SOAP toolkit will automagically spit out the correct XML. Check out this guy:
http://us2.php.net/xmlrpc_encode_request
require_once ('/var/mtp/lib/vendor/nusoap/lib/nusoap.php');
$login ='domain\username';
$pass ='password';
$useCURL = true;
$client = new nusoap_client('http://server:5555/mscrmservices/2006/crmservice.asmx?wsdl', 'wsdl');
$client->setCredentials($login, $pass, 'ntlm');
$client->setUseCurl($useCURL);
$client->useHTTPPersistentConnection();
$client->soap_defencoding = 'UTF-8';
$err = $client->getError();
if ($err) {
echo '<h2>Constructor error</h2><pre>' . $err . '</pre>';
echo '<h2>Debug</h2><pre>' . htmlspecialchars($client->getDebug(), ENT_QUOTES) . '</pre>';
exit();
}
$soapHeader='<soap:Header>' .
'<CallerId xmlns="http://schemas.microsoft.com/crm/2006/WebServices">'.
'<CallerGuid xmlns="http://schemas.microsoft.com/crm/2006/CoreTypes">00000000-0000-0000-0000-000000000000</CallerGuid></CallerId>' .
'</soap:Header>';
$soapBody='<soap:Body>' .
'<entity xmlns="http://schemas.microsoft.com/crm/2006/WebServices" xsi:type="lead">' .
'<ownerid type="Owner">2408c7dc-c0a3-dd11-b3cd-001a4bd3009a</ownerid>' .
'<firstname>Fred</firstname>' .
'<lastname>Bloggs</lastname>' .
'</entity>' .
'</soap:Body>';
$xml = '<?xml version="1.0" encoding="utf-8"?>' .
'<soap:Envelope' .
' xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"' .
' xmlns:xsd="http://www.w3.org/2001/XMLSchema"' .
' xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">' .
$soapHeader .
$soapBody .
'</soap:Envelope>';
//SOAP call
$result = $client->send($xml,'http://schemas.microsoft.com/crm/2006/WebServices/Create' );
//result
if ($client->fault) { //check for fault
echo '<p><b>Fault: ';
print_r($result);
echo '</b></p>';
}
else { //no fault
$err = $client->getError();
if ($err) { // error
echo 'Error: ' . $err . '';
echo "\n\n# # # # # # # Request # # # # # # #\n";
var_dump($client->request);
echo "\n\n# # # # # # Response # # # # # # #\n";
var_dump($client->response);
}
else { // display the result
print_r($result);
}
}
I was also struggling to get Dynamics CRM SOAP working with PHP but after a while I managed to get it working; http://www.ifc0nfig.com/working-with-microsoft-dynamics-crm-4-0-soap-interface-with-php-and-nusoap/ - You can download a small class I created which may be of use :)