ISSUE API PRESTASHOP 1.7 - prestashop

I currently have a problem with the prestashop API.
I'm trying to update the amount of a combination of a product.
<?php
$request = new HttpRequest();
$request->setUrl('https://myurl.com/api/combinations/15544');
$request->setMethod(HTTP_METH_PUT);
$request->setQueryData(array(
'io_format' => 'JSON'
));
$request->setHeaders(array(
'cache-control' => 'no-cache',
'Connection' => 'keep-alive',
'Accept-Encoding' => 'gzip, deflate',
'Host' => 'myurl.com',
'Cache-Control' => 'no-cache',
'Accept' => '*/*',
'User-Agent' => 'PostmanRuntime/7.19.0',
'Authorization' => 'Basic HIDDEN',
'Content-Type' => 'application/xml'
));
$request->setBody('<?xml version="1.0" encoding="UTF-8"?>
<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<combination>
<id>15544</id>
<quantity>105</quantity>
<location></location>
<ean13></ean13>
<isbn></isbn>
<upc></upc>
<upplier_reference></upplier_reference>
<wholesale_price></wholesale_price>
<price></price>
<weight></weight>
<unit_price_impact></unit_price_impact>
<minimal_quantity>1</minimal_quantity>
<minimal_quantity>1</minimal_quantity>
<id_product>195</id_product>
<reference>E1903XLN</reference>
</combination>
</prestashop>');
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
The response from the server is correct.
When I get the declination with a get here is the return:
{
"combination": {
"id": 15544,
"id_product": "195",
"location": "",
"ean13": "",
"isbn": "",
"upc": "",
"quantity": "105",
"reference": "E1903XLN",
"supplier_reference": "",
"wholesale_price": "0.000000",
"price": "0.000000",
"ecotax": "0.000000",
"weight": "0.000000",
"unit_price_impact": "0.000000",
"minimal_quantity": "1",
"low_stock_threshold": null,
"low_stock_alert": "0",
"default_on": null,
"available_date": "0000-00-00",
"associations": {
"product_option_values": [
{
"id": "28"
},
{
"id": "32"
}
]
}
}
}
Nevertheless on prestashop in the backoffice I do not see the changes:
Image of the BO
Do you have an idea or solution ?
Thanks a lot for your help

To set an update of stock quantity for your combination you need to talk with the object StockAvailable.
Have a nice day :) !

Related

approve an order through paypal Using Saved Card Vault v2 api

The reason why we would want to use the vault is so that we don’t have to store sensitive credit card information on our own servers. We simply reference the payment method via a provided vault ID, meaning that we don’t have to deal with many PCI compliance regulations with storing the credit cards ourselves.
<?php
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => 'https://api-m.sandbox.paypal.com/v2/checkout/orders',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => '',
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POSTFIELDS =>'{
"intent": "CAPTURE",
"purchase_units": [
{
"items": [
{
"name": "T-Shirt",
"description": "Green XL",
"quantity": "1",
"unit_amount": {
"currency_code": "USD",
"value": "100.00"
}
}
],
"amount": {
"currency_code": "USD",
"value": "100.00",
"breakdown": {
"item_total": {
"currency_code": "USD",
"value": "100.00"
}
}
}
}
],
"application_context": {
"return_url": "https://example.com/return",
"cancel_url": "https://example.com/cancel"
}
}',
CURLOPT_HTTPHEADER => array(
'Content-Type: application/json',
'Prefer: return=representation',
'PayPal-Request-Id: 232b4c61-b6f7-4c1b-b39c-43e82a1c6daa',
'Authorization: Bearer '
),
));
$response = curl_exec($curl);
curl_close($curl);
echo $response;
A successful request returns the HTTP 201 Created status code and a JSON response body that includes by default a minimal response with the ID, status, and HATEOAS links. If you require the complete order resource representation, you must pass the Prefer: return=representation request header. This header value is not the default.
Example:
{
"id": "1SX99239FX399905E",
"intent": "CAPTURE",
"status": "CREATED",
"purchase_units": [
{
"reference_id": "default",
"amount": {
"currency_code": "USD",
"value": "100.00",
"breakdown": {
"item_total": {
"currency_code": "USD",
"value": "100.00"
}
}
},
"payee": {
"email_address": "john_merchant#example.com",
"merchant_id": "C7CYMKZDG8D6E"
},
"items": [
{
"name": "T-Shirt",
"unit_amount": {
"currency_code": "USD",
"value": "100.00"
},
"quantity": "1",
"description": "Green XL"
}
]
}
],
"create_time": "2022-07-20T00:20:41Z",
"links": [
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/1SX99239FX399905E",
"rel": "self",
"method": "GET"
},
{
"href": "https://www.sandbox.paypal.com/checkoutnow?token=1SX99239FX399905E",
"rel": "approve",
"method": "GET"
},
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/1SX99239FX399905E",
"rel": "update",
"method": "PATCH"
},
{
"href": "https://api.sandbox.paypal.com/v2/checkout/orders/1SX99239FX399905E/capture",
"rel": "capture",
"method": "POST"
}
]
}
What I need is to be able to integrate from the paypal vault the cards returned in v1 with the credit card id CARD-1YE76616JL1119629MCSXFCY
In the documentation I don't see a way to make a payment through the vault in version v1 it could be done but in this one I still don't know how
The sample code was as it was previously done before v2
public function CreatePaymentUsingSavedCardVault($requestData, $credit_card_id) {
try {
///$card = new CreditCard();
//$card->setId($credit_card_id);
// ### Credit card token
// Saved credit card id from CreateCreditCard.
$creditCardToken = new CreditCardToken();
$creditCardToken->setCreditCardId($credit_card_id);
// ### FundingInstrument
// A resource representing a Payer's funding instrument.
// For stored credit card payments, set the CreditCardToken
// field on this object.
$fi = new FundingInstrument();
$fi->setCreditCardToken($creditCardToken);
// ### Payer
// A resource representing a Payer that funds a payment
// For stored credit card payments, set payment method
// to 'credit_card'.
$payer = new Payer();
$payer->setPaymentMethod("credit_card");
$payer->setFundingInstruments(array($fi));
// ### Itemized information
// (Optional) Lets you specify item wise information
$itemListArray = array();
if(isset($requestData['orderItems'])){
foreach ($this->checkEmptyObject($requestData['orderItems']) as $value) {
$item = new Item();
$array = array_filter($value);
if (count($array) > 0) {
$this->setArrayToMethods($array, $item);
array_push($itemListArray, $item);
}
}
}
$itemList = new ItemList();
if(!empty($itemListArray)){
$itemList->setItems($itemListArray);
}
// ### Additional payment details
// Use this optional field to set additional payment information such as tax, shipping charges etc.
if (isset($requestData['paymentDetails'])) {
$details = new Details();
$this->setArrayToMethods($this->checkEmptyObject($requestData['paymentDetails']), $details);
}
// ### Amount
// Lets you specify a payment amount. You can also specify additional details such as shipping, tax.
$amount = new Amount();
if (isset($requestData['amount'])) {
$this->setArrayToMethods($this->checkEmptyObject($requestData['amount']), $amount);
}
$detailsArray = $this->checkEmptyObject((array)$details);
if (!empty($detailsArray)) {
$amount->setDetails($details);
}
// ### Transaction
// A transaction defines the contract of a payment - what is the payment for and who is fulfilling it.
$transaction = new Transaction();
$amountArray = $this->checkEmptyObject((array)$amount);
if(!empty($amountArray)){
$transaction->setAmount($amount);
}
$itemListArray = $this->checkEmptyObject((array)$itemList);
if (!empty($itemListArray)) {
$transaction->setItemList($itemList);
}
if (isset($requestData['transaction'])){
$this->setArrayToMethods($this->checkEmptyObject($requestData['transaction']), $transaction);
}
// ### Payment
// A Payment Resource; create one using the above types and intent set to sale 'sale'
$payment = new Payment();
$payment->setIntent($requestData['intent']);
$payerArray = $this->checkEmptyObject((array)$payer);
if(!empty($payerArray)){
$payment->setPayer($payer);
}
$transactionArray = $this->checkEmptyObject((array)$transaction);
if(!empty($transactionArray)){
$payment->setTransactions(array($transaction));
}
$requestArray = clone $payment;
$payment->create($this->_api_context);
$returnArray['RESULT'] = 'Success';
$returnArray['PAYMENT'] = $payment->toArray();
$returnArray['RAWREQUEST']=$requestArray->toJSON();
$returnArray['RAWRESPONSE']=$payment->toJSON();
$paypal = new PayPal(array());
$paypal->TPV_Parse_Request($payment->toArray(), array(), 24, true, false, 'PayPal_Rest');
return $returnArray;
} catch (\PayPal\Exception\PayPalConnectionException $ex) {
return $this->createErrorResponse($ex);
}
}

I want to combine GET & PUT call in single script using PHP or Python, currently I am using Postman

This is my GET API call in POSTMAN
{
"stock_available": {
"id": 271,
"id_product": "231",
"id_product_attribute": "0",
"id_shop": "1",
"id_shop_group": "0",
"quantity": "0",
"depends_on_stock": "0",
"out_of_stock": "0",
"location": ""
}
}
This is where I am converting response into variable
const response = pm.response.json();
pm.globals.set("quantity", response.stock_available.quantity);
This is PUT call I want to make
<?xml version="1.0" encoding="UTF-8"?>
<prestashop xmlns:xlink="http://www.w3.org/1999/xlink">
<stock_available>
<id>1445</id>
<id_product>1406</id_product>
<id_product_attribute>0</id_product_attribute>
<id_shop>1</id_shop>
<id_shop_group>0</id_shop_group>
<quantity>{{quantity}}</quantity>
<depends_on_stock>0</depends_on_stock>
<out_of_stock>2</out_of_stock>
<location></location>
</stock_available>
</prestashop>
My solution:
<?php
define('DEBUG', false);
ini_set('display_errors','on');
define('PS_SHOP_PATH', '*your url here*');
define('PS_WS_AUTH_KEY', '*your api key here*');
try {
$webService= new PrestaShopWebservice(PS_SHOP_PATH, PS_WS_AUTH_KEY, DEBUG);
$xml = $webService->get([
'resource' => 'stock_availables',
'id' => 231,
]);
$quantity = $xml->stock_available->quantity;
$xml = $webService->get([
'resource' => 'stock_availables',
'id' => 1406,
]);
$xml->stock_available->quantity = $quantity;
$opt['putXml'] = $xml->asXML();
$opt['id'] = 1406;
$opt['resource'] = 'stock_availables';
$xml = $webService->edit($opt);
}catch (PrestaShopWebserviceException $ex) {
echo "Error:<br>";
echo $ex->getMessage();
exit(1);
}

React Native use Twitter search API with Application-only authentication

I am new to React Native and want to build an App that uses the Twitter search API to display Tweets. No need for User Authentication.
I've been struggling the last two nights to get this working and starting to get frustrated xD.
I've tried building the request using Fetch and XMLHttpRequest with no luck. Also I tried several packages enabling OAuth 2.0 which also didn't work. I have the feeling I'm over complicating things as all I want to do is use the Application-only authentication and use the Standard search API.
Does anyone out there please have a code snippet on how to do this in react native without any extra packages? Is it possible at all with "just" Fetch or XMLHttpRequest?
Thanks in advance
Edit: Here's my code so far
var base64 = require('base-64');
var credentials = encodeURIComponent(key) + ":" + encodeURIComponent(secret);
var encoded = new Buffer(credentials).toString('base64');
console.log(encoded);
fetch('https://api.twitter.com/oauth2/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Authorization': 'Basic ' + encoded
},
body: {
'grant_type': 'client_credentials'
},
}).then((response) => console.log(response))
Here the response:
Response {
"_bodyBlob": Blob {
"_data": Object {
"blobId": "8dea4e53-7b39-4b78-b1a5-d7ef5a58de48",
"offset": 0,
"size": 114,
},
},
"_bodyInit": Blob {
"_data": Object {
"blobId": "8dea4e53-7b39-4b78-b1a5-d7ef5a58de48",
"offset": 0,
"size": 114,
},
},
"headers": Headers {
"map": Object {
"cache-control": Array [
"public, max-age=0",
],
"content-disposition": Array [
"attachment; filename=json.json",
],
"content-type": Array [
"application/json;charset=utf-8",
],
"date": Array [
"Wed, 16 May 2018 16:55:48 GMT",
],
"expires": Array [
"Tue, 31 Mar 1981 05:00:00 GMT",
],
"last-modified": Array [
"Wed, 16 May 2018 16:55:48 GMT",
],
"ml": Array [
"A",
],
"server": Array [
"tsa_o",
],
"status": Array [
"403 Forbidden",
],
"strict-transport-security": Array [
"max-age=631138519",
],
"x-connection-hash": Array [
"b6dde5b876b934c8dcdb059ef0c400fa",
],
"x-content-type-options": Array [
"nosniff",
],
"x-frame-options": Array [
"DENY",
],
"x-response-time": Array [
"105",
],
"x-transaction": Array [
"0084737c0054c4dc",
],
"x-tsa-request-body-time": Array [
"26",
],
"x-twitter-response-tags": Array [
"BouncerCompliant",
],
"x-ua-compatible": Array [
"IE=edge,chrome=1",
],
"x-xss-protection": Array [
"1; mode=block; report=https://twitter.com/i/xss_report",
],
},
},
"ok": false,
"status": 403,
"statusText": undefined,
"type": "default",
"url": "https://api.twitter.com/oauth2/token",
}
So, I'm happy to report I got this working.
Main problem was the encoding of the Request Body.
Here"s the working code to authenticate and get a bearer token. Then using this token to use the search API:
_getBearer = () => {
var details = {
'grant_type': 'client_credentials'
};
var formBody = [];
for (var property in details) {
var encodedKey = encodeURIComponent(property);
var encodedValue = encodeURIComponent(details[property]);
formBody.push(encodedKey + "=" + encodedValue);
}
formBody = formBody.join("&");
var key = "xxx";
var secret = "yyy";
var base64 = require('base-64');
var credentials = encodeURIComponent(key) + ":" + encodeURIComponent(secret);
var encoded = new Buffer(credentials).toString('base64');
console.log("Created encoded credentials: " + encoded);
fetch('https://api.twitter.com/oauth2/token', {
method: 'POST',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8',
'Authorization': 'Basic ' + encoded
},
body: formBody
}).then((response) => response.json())
.then((responseData) => {
bearerToken = responseData.access_token;
console.log("Got Bearer: " + responseData.access_token);
this._loadTweet();
})
.catch((error) => {
console.error(error);
Alert.alert('Alert Title failure' + JSON.stringify(error))
});
_loadTweet = () => {
console.log("start load tweet");
fetch('https://api.twitter.com/1.1/search/tweets.json?q=love', {
method: 'GET',
headers: {
'Authorization': "Bearer " + bearerToken
}
}).then((response) => response.json())
.then((responseData) => {
console.log(JSON.stringify(responseData));
})
.catch((error) => {
console.error(error);
Alert.alert('Alert Title failure' + JSON.stringify(error))
});
};
};

How does the Podio API Endpoint to update a view work?

When I viewed the documentation for the "Update View" endpoint there was very little information available (see https://developers.podio.com/doc/views/update-view-20069949). The current documentation states that the endpoint accepts one parameter,
view_id but it seems that an API consumer would also want to be able to supply additional details to modify the view's definition.
Is there any example code available to demonstrate how this endpoint should be used?
The Podio Ruby client provides code that uses this endpoint. If you take a look here you can see that the endpoint expects a JSON body to be supplied in the PUT that specifies the new view's definition. In the Ruby code it's referred to as "attributes" and this is consistent with the API documentation for the other View operations. Here is an example HTTP request:
PUT /view/31011898 HTTP/1.1
Host: api.podio.com
Authorization: OAuth2 your_oauth2_token_here
Content-Type: application/json
Cache-Control: no-cache
{
"layout": "table",
"name": "SPAM",
"rights": [
"delete",
"view",
"update"
],
"fields": {},
"sort_desc": false,
"created_by": {
"user_id": <creator user id>,
"space_id": null,
"image": {
"hosted_by": "podio",
"hosted_by_humanized_name": "Podio",
"thumbnail_link": "https://d2cmuesa4snpwn.cloudfront.net/public/",
"link": "https://d2cmuesa4snpwn.cloudfront.net/public/",
"file_id": <some file id>,
"external_file_id": null,
"link_target": "_blank"
},
"profile_id": <profile id>,
"org_id": null,
"link": "https://podio.com/users/<user id>",
"avatar": <avatar id>,
"type": "user",
"last_seen_on": "2016-10-27 19:58:22",
"name": "Podio TESTER"
},
"sort_by": "created_on",
"items": 0,
"created_on": "2016-10-27 19:58:26",
"private": true,
"filters": [],
"filter_id": 31011898,
"groupings": {},
"type": "private",
"view_id": 31011898,
"grouping": {}
}
Here's a PHP version, authentication performed prior to request:
// UPDATE VIEW
$authorization = 'Authorization: Bearer '.$auth_token;
$json = json_encode(array(
"sort_desc" => false,
"filters" => array(
999994986 => array(
"to" => 10000,
"from" => 0.01
),
999999204 => array(
"to" => $end,
"from" => $first
)
)
));
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => "https://api.podio.com/view/99999909",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 0,
CURLOPT_FOLLOWLOCATION => true,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PUT",
CURLOPT_POSTFIELDS =>$json,
CURLOPT_HTTPHEADER => array(
$authorization,
"Content-Type: application/json"
),
));
$response = curl_exec($curl);
curl_close($curl);

Creating a Paymill callback

I am developing a webapp using rails 3.2.
I am trying to build a callback method for Paymill that will be used to catch Transaction success events.
This is my controller. It´s very simple and it works fine when I make a simulated POST request using either CURL or a Firefox plugin and using the JSON body that Paymill documentation states is the correct one.
Unfortunately when using Paymills own test script (made in PHP) it failes.
class Admin::TransactionsController < ActionController::Base
def create
transaction = Transaction.new
transaction.client_id = params[:event][:event_resource][:client][:id]
transaction.trans_id = params[:event][:event_resource][:id]
transaction.amount = params[:event][:event_resource][:amount]
transaction.currency = params[:event][:event_resource][:currency]
transaction.save
render :nothing => true
end
end
This is the JSON body that the documentation says it will attach to callback event:
{
"event": {
"event_type": "transaction.succeeded",
"event_resource": {
"id": "tran_d06aae1df72af329c39367cde9ed19",
"amount": "12345",
"origin_amount": 12345,
"status": "closed",
"description": "test paymill",
"livemode": false,
"refunds": null,
"currency": "USD",
"created_at": 1375457696,
"updated_at": 1375457696,
"response_code": 20000,
"short_id": null,
"is_fraud": false,
"invoices": [],
"app_id": null,
"fees": [],
"payment": {
"id": "pay_46ee3be859eedb72d325adcb6",
"type": "creditcard",
"client": "client_d94e1e3efbc59073629df",
"card_type": "visa",
"country": null,
"expire_month": "1",
"expire_year": "2014",
"card_holder": null,
"last4": "1111",
"created_at": 1375457695,
"updated_at": 1375457696,
"app_id": null
},
"client": {
"id": "client_d941e3efbc59e073629df",
"email": null,
"description": null,
"created_at": 1375457696,
"updated_at": 1375457696,
"app_id": null,
"payment": [],
"subscription": null
},
"preauthorization": null
}
}
}
When making the request with the PHP test script the body arrives in this shape
and Rails throughs errors:
string(1712) ""{\n \"event\": {\n \"event_type\": \"transaction.succeeded\",\n \"event_resource\": {\n \"id\": \"tran_d06aae1f72af329c39367cde9ed19\",\n \"amount\": \"12345\",\n \"origin_amount\": 12345,\n \"status\": \"closed\",\n \"description\": \"test paymill\",\n \"livemode\": false,\n \"refunds\": null,\n \"currency\": \"USD\",\n \"created_at\": 1375457696,\n \"updated_at\": 1375457696,\n \"response_code\": 20000,\n \"short_id\": null,\n \"is_fraud\": false,\n \"invoices\": [],\n \"app_id\": null,\n \"fees\": [],\n \"payment\": {\n \"id\": \"pay_46ee3b85f9eedb72d325adcb6\",\n \"type\": \"creditcard\",\n \"client\": \"client_d941e3effbc59073629df\",\n \"card_type\": \"visa\",\n \"country\": null,\n \"expire_month\": \"1\",\n \"expire_year\": \"2014\",\n \"card_holder\": null,\n \"last4\": \"1111\",\n \"created_at\": 1375457695,\n \"updated_at\": 1375457696,\n \"app_id\": null\n },\n \"client\": {\n \"id\": \"client_d941e3efbc59073629df\",\n \"email\": null,\n \"description\": null,\n \"created_at\": 1375457696,\n \"updated_at\": 1375457696,\n \"app_id\": null,\n \"payment\": [],\n \"subscription\": null\n },\n \"preauthorization\": null\n }\n }\n}""
The error I get from Rails is this now:
Error occurred while parsing request parameters
NoMethodError - undefined method `each' for #<String:0x007fc820a1fc08>:
What is going on? It´s like Rails treats this body like faulty text? If I remove this line from the PHP (and thus does not JSON encode the body before sending) it works fine and I get no errors. And it doesn´t matter if I the create method is empty. Something is happening before this method gets called?
json_encode($http_body);
Thankful for all help! I will soon start to cry.
Where did you get the test script from? The one I have here, does contain the body in plain text and so it does not need json encoding anymore, this should work (replace <YOUR_TARGET_URL> with your URL):
<?php
$http_body = '{
"event" : {
"event_type" : "transaction.succeeded",
"event_resource" :
{"id":"__TRANSACTION_ID__","amount":"12345","origin_amount":12345,"status":"closed","description":"test paymill","livemode":false,"refunds":null,"currency":"SEK","created_at":1375457696,"updated_at":1375457696,"response_code":20000,"short_id":null,"is_fraud":false,"invoices":[],"app_id":null,"fees":[],"payment":{"id":"__PAYMNET_ID__","type":"creditcard","client":"__CLIENT_ID__","card_type":"visa","country":null,"expire_month":"1","expire_year":"2014","card_holder":null,"last4":"1111","created_at":1375457695,"updated_at":1375457696,"app_id":null},"client":{"id":"__CLIENT_ID__","email":null,"description":null,"created_at":1375457696,"updated_at":1375457696,"app_id":null,"payment":[],"subscription":null},"preauthorization":null}
}
}';
$curl = curl_init();
$curlOpts = array(
CURLOPT_URL => '',
CURLOPT_RETURNTRANSFER => true,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSLVERSION => 3,
CURLOPT_TIMEOUT => 60,
CURLOPT_CONNECTTIMEOUT => 60,
CURLOPT_HTTPHEADER => array('Content-type: application/json'),
CURLOPT_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
CURLOPT_MAXREDIRS => 5
);
$curlOpts[CURLOPT_URL] = '<__YOUR_TARGET_URL__>';
$curlOpts[CURLOPT_POSTFIELDS] = $http_body;
curl_setopt_array($curl, $curlOpts);
$result = curl_exec($curl);
$responseInfo = curl_getinfo( $curl );
var_dump($responseInfo);
var_dump($result);
curl_close($curl);
exit;