I am trying to use the updateListing method to revise listing descriptions...
https://www.etsy.com/developers/documentation/reference/listing#method_updatelisting
I went through the OAuth Authentication process successfully and am able to make an authorized request via the API as per the example in the documentation. I am having problems with the updateListing method. I am trying to revise the description but get the following error…
“Invalid auth/bad request (got a 400, expected HTTP/1.1 20X or a redirect)Expected param 'quantity'.Array”
As per the documentation, the quantity is not required (and is actually depreciated for updateListing). When I use the existing quantity to populate ‘quantity’ in the array (commented out), it complains about another field it expects. I’m not sure why I’m getting an error regarding these fields as they are not required. I would not mind using the existing attributes available from my listing to populate these fields but there is a “shipping_template_id” field which I don’t currently have available. I can’t set it to null because it expects a numeric value. When I set it to 0, it says that it’s not a valid shipping template ID. I must be doing something wrong.
Here is my code (I replaced my actual token and token secrets)…
$access_token = "my token";
$access_token_secret = "my secret";
$oauth = new OAuth(OAUTH_CONSUMER_KEY, OAUTH_CONSUMER_SECRET, OAUTH_SIG_METHOD_HMACSHA1, OAUTH_AUTH_TYPE_URI);
$oauth->setToken($access_token, $access_token_secret);
try {
$url = "https://openapi.etsy.com/v2/private/listings";
$params = array('listing_id' => $result->listing_id,
//'quantity' => $result->quantity,
//'title' => $result->title,
'description' => $new_description);
$oauth->fetch($url, $params, OAUTH_HTTP_METHOD_POST);
$json = $oauth->getLastResponse();
print_r(json_decode($json, true));
}
catch (OAuthException $e) {
echo $e->getMessage();
echo $oauth->getLastResponse();
echo $oauth->getLastResponseInfo();
}
$args = array(
'data' => array(
"quantity" => $quantity,
"title" => $title,
"description" => strip_tags($description),
"price" => $price,
"materials" => $materials,
"shipping_template_id" =>(int)$shippingTemplateId,
"non_taxable" => false,
"state" => "$ced_etsy_upload_product_type",
"processing_min" => 1,
"processing_max" => 3,
"taxonomy_id" => (int)$categoryId,
"who_made" => $who_made,
"is_supply" => true,
"when_made" => $when_made,
)
);
Please try this may be this will help you.
Related
I'm integrating Amazon Pay php SDK from documentation, but getting this error.
Here's my php implementation code:
$amazonpay_config = array(
'public_key_id' => 'XXXXXXXX',
'private_key' => 'my_private_key_path',
'region' => 'US',
'sandbox' => true
);
$payload = array(
'webCheckoutDetails' => array(
'checkoutReviewReturnUrl' => 'https://www.example.com/review',
'checkoutResultReturnUrl' => 'https://www.example.com/result'
),
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXX'
);
$headers = array('x-amz-pay-Idempotency-Key' => uniqid());
$requestResult = [
'error' => 1,
'msg' => 'Error. Can not create checkout session.',
'checkoutSession' => null,
'payloadSign' => null
];
$client = new Client($amazonpay_config);
$resultCheckOut = $client->createCheckoutSession($payload, $headers);
$resultSignPayload = $client->generateButtonSignature($payload);
if($resultCheckOut['status'] !== 201) {
return json_encode($requestResult, true);
}
else {
$requestResult = [
'error' => 0,
'msg' => null,
'checkoutSession' => json_decode($resultCheckOut['response']),
'payloadSign' => $resultSignPayload
];
return $requestResult;
}
Here's JS implementation code for generating Amazon Pay button.
amazon.Pay.renderButton('#amazon-pay-btn', {
// set checkout environment
merchantId: 'XXXXXXXX',
ledgerCurrency: 'USD',
sandbox: true,
checkoutLanguage: 'en_US',
productType: 'PayOnly',
placement: 'Cart',
buttonColor: 'Gold',
createCheckoutSessionConfig: {
payloadJSON: jsonResult['checkoutSession'],
signature: jsonResult['payloadSign'],
publicKeyId: 'XXXXXXXXXXX'
}
});
Couple of problems with the code, mainly that you aren't passing the payload and signature to the front-end correctly. For the payload, you're using jsonResult['checkoutSession'], while it should be jsonResult['payloadSign']. This doesn't contain the payload though but from the PHP code it's apparently the signature that you have put in there. The full code sample should more like this (not tested).
Back-end:
$headers = array('x-amz-pay-Idempotency-Key' => uniqid());
$requestResult = [
'error' => 1,
'msg' => 'Error. Can not create checkout session.',
'signature' => null,
'payload' => null
];
$client = new Client($amazonpay_config);
$resultCheckOut = $client->createCheckoutSession($payload, $headers);
$resultSignature = $client->generateButtonSignature($payload);
if($resultCheckOut['status'] !== 201) {
return json_encode($requestResult, true);
}
else {
$requestResult = [
'error' => 0,
'msg' => null,
'signature' => $resultSignature,
'payload' => $payload
];
return json_encode($requestResult);
}
Front-end:
amazon.Pay.renderButton('#amazon-pay-btn', {
// set checkout environment
merchantId: 'XXXXXXXX',
ledgerCurrency: 'USD',
sandbox: true,
checkoutLanguage: 'en_US',
productType: 'PayOnly',
placement: 'Cart',
buttonColor: 'Gold',
createCheckoutSessionConfig: {
payloadJSON: JSON.stringify(jsonResult['payload']),
signature: jsonResult['signature'],
publicKeyId: 'XXXXXXXXXXX'
}
});
I'm not sure how you're passing $requestResult back to the front-end, potentially there's some additional JSON encoding/decoding required to get the right string. To prevent a signature mismatch error, please make sure that the payload string used for the signature generation in the backend, and the payload string assigned to the 'payloadJSON' parameter match exactly (especially pay attention to whitespaces, escape characters, line breaks, etc.).
Two comments about this issue:
I have defined the payload as an string (that's the way current AmazonPay doc states - Link).
$payload = '{
"webCheckoutDetails": {
"checkoutReviewReturnUrl": "https://www.example.com/review",
"checkoutResultReturnUrl": "https://www.example.com/result"
},
"storeId": "amzn1.application-oa2-client.XXXXXXXXX"
}';
instead of array
$payload = array(
'webCheckoutDetails' => array(
'checkoutReviewReturnUrl' => 'https://www.example.com/review',
'checkoutResultReturnUrl' => 'https://www.example.com/result'
),
'storeId' => 'amzn1.application-oa2-client.XXXXXXXXX'
);
The signature was created, but when rendering the button and clicking on it I get the following error.
Error Message: Signature Dk4qznkoiTVqjcY8Yn1l0iLbsoIj2pEAHWVtgYrphLtFXR9BKhJJPD53It4qYOswS1T/STYMHRy5jtCHGqvLntDjuy0MrhkpoHTpYEtwdOqGHA2qk+QnSGV5LoYldQ/UkAxSG7m8s2iOr11q2sWxUjrk2M3fgzAIxDeZRjJYeAr97eGANYva3jtGDfM6cJdieInBM4dEWWxKqGIh6HxOrY5K/ga26494vAwZAGvXRhZG48FOVp/XCr0mbu6V5pkEOzRJSc+hN5WKAs/c49UsfKPx75Ce7QbaBCZZT1UiczfyYx/mBuZuysUlGmnXPhLOLTPw4+SIizH/pOQyClOQyw== does not match signedString AMZN-PAY-RSASSA-PSS dfff7a87b93cfa78685a233f2dd59e18ad0451b2e3a90af11e500fcc0ceee924 for merchant XXXXXXXX
I was some time till I realized that this was the reason of the error. Actually, while writing this, the new lines in the string were the reason. If string is only in one line, it works.
The button only needs the payload and the signed payload. The $client->createCheckoutSession is not needed. More over, the checkoutSessionId of the resultCheckOut is different from the one obtained when the checkoutReviewReturnUrl is called.
Since Soap errors are WSDL specific I'm asking this question. I'm trying to add a relation in an online accountancy application. Authenticating and getting works just fine.
This is the code I'm using (Security code and SessionID are working fine when Getting relations):
$params = array( "input" => array( "SecurityCode2" => $SecurityCode2,
"SessionID" => $SessionID,
"cRelatie" => array(
"ID" => NULL,
"AddDatum" => date("Y-m-d h:i:s"),
"Code" => "PUBID".sprintf('%04d', $vve['id']),
"Bedrijf" => $Bedrijf,
"Contactpersoon" => $Contactpersoon
)
)
);
try {
$response = $client->__soapCall("AddRelatie", $params);
}
catch (Exception $e){
echo 'Caught exception: ', $e->getMessage(), "\n";
}
I've also tried nesting the cRelatie within an array with one index called oRel (see WSDL), but that didn't work either.
Error:
Caught exception: Server was unable to process request. ---> Object reference not set to an instance of an object.
This is the WSDL location
https://soap.e-boekhouden.nl/soap.asmx?wsdl
Got it working:
There where non documented required fields
And date wasn't allowed to have time, In contrary to the WSDL
$params = array( "input" => array(
"SecurityCode2" => $SecurityCode2,
"SessionID" => $SessionID,
"oRel" => array(
"ID" => 0,
"Gb_ID" => 0,
"GeenEmail" => 0,
"NieuwsbriefgroepenCount" => 0,
"AddDatum" => date("Y-m-d"),
"Code" => "PUBID".sprintf('%04d', $vve['id']),
"Bedrijf" => $Bedrijf,
"Contactpersoon" => $Contactpersoon
)
));
I'm upgrading us to the new MailChimp v3 API.
FWIW, we're using DrewM's PHP library.
When I try to create a new campaign, I get this cryptic error message from MailChimp:
Array (
[type] => http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/
[title] => Resource Not Found
[status] => 404
[detail] => The resource 'Campaign_Collection' could not be found.
[instance] =>
)
The URL (http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary) is only partially helpful; yes a resource is missing. But what is a Campaign_Collection? Is it a Mailchimp list? A Mailchimp folder? Some sort of array-construct I need to use to specify some form of data?
Maybe it is too lat but thought it could be helpful to some other folks.
Usually Mailchimp returns "The requested resource could not be found." without telling if it is due to your list id or method etc..
Make sure you are using the correct list id. It is NOT the one you see on your URL. From the top menu, you need to go to Audience and select "All Contacts"
Then you need to go:
Audience -> Settings -> Audience Name and defaults
Then on the right column you will see "Audience ID" with a some weird, meaningless explanation as:
"Some plugins and integrations may request your Audience ID. Typically, this is what they want: abcd1234xxx."
That is the "listID" you need!
PS: If it is called as "AudienceID" then it should be updated on the API Ref. Doc as audienceID, not listID I believe.
Problem solved.
If you get the error, the 404 field is the key clue, and the detail field is a red herring.
This is the sort of error you get if you misspell an endpoint. For example:
$mailer = new MailChimp('****YOUR API KEY****');
$response = $mailer->get('/xyzzy');
// Produces this:
$response = [
"type" => "http://developer.mailchimp.com/documentation/mailchimp/guides/error-glossary/",
"title" => "Resource Not Found",
"status" => 404,
"detail" => "The resource 'Xyzzy_Collection' could not be found.",
"instance" => "",
]
>>>
Me, I had left off an 's' off the Campaigns endpoint.
$data = [
'email_address' => (isset($email) ? $email : ''),
'status' => 'subscribed',
'status_if_new' => 'subscribed',
'merge_fields' => [
'FNAME' => (isset($firstname) ? $firstname : ''),
'LNAME' => (isset($lastname) ? $lastname : ''),
'PHONE' => (isset($phone) ? $phone : ''),
],
];
$server = explode('-', $token);
$url = 'https://'.$server[1].'.api.mailchimp.com/3.0/lists/'.$list.'/members/';
$response = wp_remote_post( $url, [
'method' => 'POST',
'data_format' => 'body',
'timeout' => 45,
'headers' => [
'Authorization' => 'apikey '.$token,
'Content-Type' => 'application/json; charset=utf-8'
],
'body' => json_encode($data )
]
);
if ( is_wp_error( $response ) ) {
$error_message = $response->get_error_message();
$return['error'] = "Something went wrong: $error_message";
} else {
$return['success'] = $response;
}
Must be include merge_fields filed into body data...
I'm trying to post a LinkedIn share update via its Share on LinkedIn API using a PHP library LinkedIn-Client API. I've successfully authorized the user and I got the access token returned from it. I use the token along with this share API call. Here is my code:
$linkedInOAuth = new Happyr\LinkedIn\LinkedIn(LINKEDIN_APP_ID, LINKEDIN_APP_SECRET);
if ($accessToken) { // assume that it is retrieved from session
$linkedInOAuth->setAccessToken($accessToken);
$postParams = array(
"content" => array(
'description' => "I'm so exciting to share a post using API."
),
"visibility" => array(
"code" => "connnections-only"
)
);
$result = $linkedInOAuth->api(
"v1/people/~/shares",
array("format" => "json"),
"POST",
$postParams
);
}
However I got 400 bad request error returned from this API call.
Fatal error: Uncaught GuzzleException: 400: Client error response [url] https://api.linkedin.com/v1/people/~/shares?format=json&oauth2_access_token=xxxxxxx [status code] 400 [reason phrase] Bad Request thrown in ...\vendor\happyr\linkedin-api-client\src\Happyr\LinkedIn\Http\GuzzleRequest.php on line 26
What could be the problem?
[UPDATE on 2015-04-30 3:00 PM UTC]
LinkedIn-Client API uses Guzzle internally for HTTP requests. I tried to use GuzzleHttp directly without using Happyr\LinkedIn\LinkedIn->api(), but same error and no success.
if ($accessToken) {
$url = 'https://api.linkedin.com/v1/people/~/shares?format=json&oauth2_access_token=' . $accessToken;
$client = new GuzzleHttp\Client();
$response = $client->post($url, array(
'headers' => array(
'Content-Type' => 'application/json',
'x-li-format' => 'json'
),
'json' => array(
'comment' => 'Check out developer.linkedin.com!',
'content' => array(
'description' => 'I\'m so exciting to share a post using API.'
),
'visibility' => array(
'code' => 'connections-only'
)
)
));
}
Fatal error: Uncaught exception 'GuzzleHttp\Exception\ClientException'
with message 'Client error response [url]
https://api.linkedin.com/v1/people/~/shares?format=json&oauth2_access_token=xxxxx
[status code] 400 [reason phrase] Bad Request' in
\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php:89 Stack
trace: #0 \vendor\guzzlehttp\guzzle\src\Subscriber\HttpError.php(33):
GuzzleHttp\Exception\RequestException::create(Object(GuzzleHttp\Message\Request),
Object(GuzzleHttp\Message\Response)) #1
\vendor\guzzlehttp\guzzle\src\Event\Emitter.php(109):
GuzzleHttp\Subscriber\HttpError->onComplete(Object(GuzzleHttp\Event\CompleteEvent),
'complete') #2 \vendor\guzzlehttp\guzzle\src\RequestFsm.php(91):
GuzzleHttp\Event\Emitter->emit('complete', Object(Guz in
\vendor\guzzlehttp\guzzle\src\Exception\RequestException.php on line
89
[UPDATE on 2015-05-05 9:40 AM UTC]
I copied and used both xml and json examples of Share on LinkedIn API page. This time, the error changed to Internal Server Error.
if ($accessToken) {
$format = 'xml';
$url = 'https://api.linkedin.com/v1/people/~/shares?format='.$format.'&oauth2_access_token=' . $connect->accessToken;
$postParams = array(
"xml" => "
<share>
<comment>Check out developer.linkedin.com!</comment>
<content>
<title>LinkedIn Developer Resources</title>
<description>Leverage LinkedIn's APIs to maximize engagement</description>
<submitted-url>https://developer.linkedin.com</submitted-url>
<submitted-image-url>https://example.com/logo.png</submitted-image-url>
</content>
<visibility>
<code>anyone</code>
</visibility>
</share>",
"json" => array(
"comment" => "Check out developer.linkedin.com!",
"content" => array(
"title" => "LinkedIn Developers Resources",
"description" => "Leverage LinkedIn's APIs to maximize engagement",
"submitted-url" => "https://developer.linkedin.com",
"submitted-image-url" => "https://example.com/logo.png"
),
"visibility" => array(
"code" => "anyone"
)
)
);
$client = new GuzzleHttp\Client();
if ($format === 'xml') {
$response = $client->post($url, array(
'body' => $postParams['xml']
));
} else {
$response = $client->post($url, array(
'headers' => array(
'Content-Type' => 'application/json',
'x-li-format' => 'json'
),
'json' => $postParams['json']
));
}
}
Fatal error: Uncaught exception 'GuzzleHttp\Exception\ServerException'
with message 'Server error response [url]
https://api.linkedin.com/v1/people/~/shares?format=json&oauth2_access_token=xxxx
[status code] 500 [reason phrase] Internal Server Error'
According to the Github issue of Happyr\LinkedIn-API-client, some updates have been made in 0.5.0 and it solved my problem. However, LinkedIn has unclear documentation about its Share API. The following information have to be noted:
The comment field is the sharing update content. The name comment leads confusing.
Using the field comment, URL is optional in the sharing update content.
The content field means snapshot about the content of the URL you are sharing. To describe more clearly, it reflects open graph meta tags;
content.title overrides <meta property="og:title" content="..." />
content.description overrides <meta property="description" content="..." />
content.title overrides <meta property="og:title" content="..." />
content.submitted-url overrides <meta property="og:url" content="..." />
content.submitted-image-url overrides <meta property="og:image" content="..." />
When the content field is used, the field submitted-url is required. The rest are optional. If it is missing, 400 Bad Request would return.
The URLs included in the example codes of LinkedIn Share API would cause 500 Internal Server Error. They should not be used for testing purpose.
The following is the correct usage of API using Happyr\LinkedIn-API-client.
(1) Happyr\LinkedIn - Using the field comment
$linkedInOAuth = new Happyr\LinkedIn\LinkedIn(LINKEDIN_APP_ID, LINKEDIN_APP_SECRET);
// retrieve $accessToken from db or session
$linkedInOAuth->setAccessToken($accessToken);
$postParams = array(
'json' => array(
"comment" => "PHPLucidFrame - The simple, lightweight and flexible web application development framework http://phplucidframe.sithukyaw.com",
"visibility" => array(
"code" => "anyone"
)
)
);
$result = $linkedInOAuth->post('v1/people/~/shares', $postParams);
(2) Happyr\LinkedIn - Using the field content
$linkedInOAuth = new Happyr\LinkedIn\LinkedIn(LINKEDIN_APP_ID, LINKEDIN_APP_SECRET);
// retrieve $accessToken from db or session
$linkedInOAuth->setAccessToken($accessToken);
$postParams = array(
'json' => array(
"content" => array(
"title" => "PHPLucidFrame",
"description" => "The simple, lightweight and flexible web application development framework",
"submitted-url" => "http://phplucidframe.sithukyaw.com"
),
"visibility" => array(
"code" => "anyone"
)
)
);
$result = $linkedInOAuth->post('v1/people/~/shares', $postParams);
The following is the correct usage of API using GuzzleHttp.
(3) GuzzleHttp - Using the field comment
// retrieve $accessToken from db or session
$url = 'https://api.linkedin.com/v1/people/~/shares?format=json&oauth2_access_token=' . $accessToken;
$client = new GuzzleHttp\Client();
$response = $client->post($url, array(
"json" => array(
"comment" => "PHPLucidFrame - The simple, lightweight and flexible web application development framework http://phplucidframe.sithukyaw.com",
"visibility" => array(
"code" => "anyone"
)
)
));
(4) GuzzleHttp - Using the field content
// retrieve $accessToken from db or session
$url = 'https://api.linkedin.com/v1/people/~/shares?format=json&oauth2_access_token=' . $accessToken;
$client = new GuzzleHttp\Client();
$response = $client->post($url, array(
"json" => array(
"content" => array(
"title" => "PHPLucidFrame",
"description" => "The simple, lightweight and flexible web application development framework",
"submitted-url" => "http://phplucidframe.sithukyaw.com"
),
"visibility" => array(
"code" => "anyone"
)
)
));
The fields comment and content can also be used together.
Just a quick guess here but you might need to add json_encode to your $postParams before you send it to the API.
$result = $linkedInOAuth->api(
"v1/people/~/shares",
array("format" => "json"),
"POST",
json_encode($postParams),
);
ALTERNATIVELY
If that does not work I also notice the Linkedin Docs say the following. You could try adding these two headers (if you havent already).
By default, all API calls expect input in XML format, however if it is more covienent for your application to submit data in JSON format, you can inform the APIs that they will be receiving a JSON-formatted payload by including the following two HTTP header values in the call:
Content-Type: application/json
x-li-format: json
Your JSON post body needs to be corrected. Check:
https://developer.linkedin.com/docs/share-on-linkedin
You need to follow either one of these formats.
Share via a comment containing a URL
{
"comment": "Check out developer.linkedin.com! http://linkd.in/1FC2PyG",
"visibility": {
"code": "anyone"
}
}
Share with specific values
{
"comment": "Check out developer.linkedin.com!",
"content": {
"title": "LinkedIn Developers Resources",
"description": "Leverage LinkedIn's APIs to maximize engagement",
"submitted-url": "https://developer.linkedin.com",
"submitted-image-url": "https://example.com/logo.png"
},
"visibility": {
"code": "anyone"
}
}
I have a problem. I should do a custom gateway. I know the basics. I read the documentation. URL data to be transmitted (such as user name, the amount of the transaction). My question is how to redirect the user to the payment page of the bank? What is the command and where to give the exact url? And then the returned data must be processed what method? cURL or something else? I could not find any real solution to the problem.
Different gateway's have different needs, if your gateway uses a POST, you can use this to POST the data, and get a response.. it is better than cURL.
$response = wp_remote_post( $environment_url, array(
'method' => 'POST',
'body' => http_build_query( $payload ),
'timeout' => 90,
'sslverify' => false,
) );
// Retrieve the body's response if no errors found
$response_body = wp_remote_retrieve_body( $response );
$response_headers = wp_remote_retrieve_headers( $response );
// Payload would look something like this.
$payload = array(
"amount" => $order.get_total(),
"reference" => $order->get_order_number(),
"orderid" => $order->id,
"return_url" => $this->get_return_url($order) //return to thank you page.
);
//use this if you need to redirect the user to the payment page of the bank.
$querystring = http_build_query( $payload );
return array(
'result' => 'success',
'redirect' => $environment_url . '?' . $querystring,
);