In this third and final part of our eBay Trading API series, we’ll be building the product adding functionality into our application.

在我们的eBay交易API系列的第三个也是最后一个部分中,我们将构建将功能添加到我们的应用程序中的产品。

创造新产品 (Creating new Products)

Now that we’re done with the store settings, we can begin with writing the code for the controller that would handle the creation of products. Under the controllers directory, create a new file and name it Product.php.

既然我们已经完成了商店设置,那么我们就可以开始为处理产品创建的控制器编写代码。 在controllers目录下,创建一个新文件,并将其命名为Product.php

<?php
class Product extends \SlimController\SlimController{
}

Next, create the newAction method. This will render the new.twig file under the templates/product directory. This is the view that renders the form for creating new products.

接下来,创建newAction方法。 这将在templates/product目录下呈现new.twig文件。 这是呈现用于创建新产品的表单的视图。

public function newAction(){
$page_data = array(
'is_productpage' => 'true'
);
$this->render('product/new', $page_data);
}

Next create the view:

接下来创建视图:

{% extends "/base.twig" %}
{% block content %}
{{ parent() }}
<div class="row">
<div class="col-md-4">
<div class="alert alert-{{ flash.message.type }}">
{{ flash.message.text }}
{% for r in flash.message.data %}
<li>{{ r[0] }}</li>
{% endfor %}
</div>
</div>
</div>
<div class="row">
<div class="col-md-6">
<form class="form-horizontal" method="POST" action="{{ baseUrl }}/products/create">
<fieldset>
<legend>Create new Product</legend>
<div class="form-group">
<label for="title" class="col-lg-2 control-label">Title</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="title" name="title" value="{{ flash.form.title }}">
</div>
</div>
<div class="form-group">
<label for="category" class="col-lg-2 control-label">Category</label>
<div class="col-lg-10" id="categories-container">
</div>
</div>
<div class="form-group">
<label for="price" class="col-lg-2 control-label">Price</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="price" name="price" value="{{ flash.form.price }}">
</div>
</div>
<div class="form-group">
<label for="quantity" class="col-lg-2 control-label">Quantity</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="quantity" name="quantity" value="{{ flash.form.quantity }}">
</div>
</div>
<div class="form-group">
<label for="brand" class="col-lg-2 control-label">Brand</label>
<div class="col-lg-10">
<input type="text" class="form-control" id="brand" name="brand" value="{{ flash.form.brand }}">
</div>
</div>
<div class="form-group">
<label for="description" class="col-lg-2 control-label">Description</label>
<div class="col-lg-10">
<textarea class="form-control" rows="3" id="description" name="description" value="{{ flash.form.description }}">{{ flash.form.description }}</textarea>
</div>
</div>
<div class="form-group">
<div class="col-lg-10 col-lg-offset-2">
<button type="submit" class="btn btn-primary">Add Product</button>
</div>
</div>
</fieldset>
</form>
</div>
<div class="col-md-6">
<h5>Upload Photos</h5>
<form action="{{ baseUrl }}/upload" method="POST" class="dropzone" id="photosdropzone" enctype="multipart/form-data"></form>
</div>
</div>
{% include 'partials/categories.html' %}
{% endblock %}

Breaking it down, at the beginning is where we output the alert message. We’ll pass along the values for this later on when we add the code for creating products. flash is a global variable where session data that we pass along is temporarily saved:

分解它,一开始就是我们输出警报消息的地方。 我们稍后会在添加用于创建产品的代码时传递其值。 flash是一个全局变量,临时存储我们传递的会话数据:

<div class="alert alert-{{ flash.message.type }}">
{{ flash.message.text }}
{% for r in flash.message.data %}
<li>{{ r[0] }}</li>
{% endfor %}
</div>

Next is the product title and other required product details. Take note that only the product title, description, quantity, price, and a product image are required in most cases. Here, we’ve added brand because in some cases it’s required. The general term for this kind of field is a conditional field. It usually depends on the category of the product whether it’s required or not. Some categories require more fields than others so be sure to check the documentation on the AddItem API Call to make sure you’re not missing anything.

接下来是产品标题和其他必需的产品详细信息。 请注意,在大多数情况下,仅需要产品标题,描述,数量,价格和产品图片。 在这里,我们添加了品牌,因为在某些情况下是必需的。 这种字段的总称是条件字段。 是否需要通常取决于产品类别。 某些类别比其他类别需要更多的字段,因此请务必检查AddItem API调用上的文档以确保您没有遗漏任何内容。

<input type="text" class="form-control" id="title" name="title" value="{{ flash.form.title }}">

For the product category, we’re going to load it later on via AJAX since it will depend on the product title entered by the user.

对于产品类别,我们稍后将通过AJAX加载它,因为它取决于用户输入的产品标题。

<label for="category" class="col-lg-2 control-label">Category</label>
<div class="col-lg-10" id="categories-container">
</div>

Next is the form that the user will use for uploading the product images:

接下来是用户用来上传产品图片的表单:

<form action="{{ baseUrl }}/upload" method="POST" class="dropzone" id="photosdropzone" enctype="multipart/form-data"></form>

This uses the /upload route for processing the uploaded files. Declare the method for processing this route in the Product class:

这使用/upload路由来处理上传的文件。 在“ Product类中声明处理此路线的方法:

public function uploadAction(){
$storage = new \Upload\Storage\FileSystem('uploads');
$file = new \Upload\File('file', $storage);
$new_filename = uniqid();
$file->setName($new_filename);
$_SESSION['uploads'][] = $new_filename . '.' . $file->getExtension();
$file->addValidations(array(
new \Upload\Validation\Mimetype(array('image/png', 'image/gif', 'image/jpg')),
new \Upload\Validation\Size('6M')
));
$errors = array();
try{
$file->upload();
}catch(Exception $e){
$errors = $file->getErrors();
}
$response_data = array(
'errors' => $errors
);
echo json_encode($response_data);
}

Breaking the uploadAction() method down, first we specify the upload path. In this case we’re using the uploads directory. Make sure you give it the necessary directory permissions so we can actually upload files to it:

uploadAction()方法,首先我们指定上传路径。 在这种情况下,我们使用的是uploads目录。 确保您为其授予了必要的目录权限,以便我们可以实际将文件上传到该目录:

$storage = new \Upload\Storage\FileSystem('uploads');

Next, we specify the field we use for uploading files. Going back to the form for uploading, we didn’t specify any <input type="file"> fields in there. That’s because we don’t need to. By default dropzone uses file as the default field name for uploading files so we specify it as the first argument for the File method, the second argument is the storage which we created earlier:

接下来,我们指定用于上传文件的字段。 回到上载表格,我们没有在其中指定任何<input type="file">字段。 那是因为我们不需要。 默认情况下,dropzone使用file作为上传文件的默认字段名称,因此我们将其指定为File方法的第一个参数,第二个参数是我们之前创建的存储:

$file = new \Upload\File('file', $storage);

Next, we give the file a unique name. You can be creative here if you want, but if you’re not feeling creative then just use the uniqid() method to generate a unique file name:

接下来,我们为文件指定一个唯一的名称。 如果需要,您可以在这里发挥创造力,但是如果您不觉得有创造力,则只需使用uniqid()方法生成唯一的文件名:

$new_filename = uniqid();
$file->setName($new_filename);

Push the file name into the uploads session item so we can use it later on.

将文件名推送到上uploads会话项中,以便我们稍后使用。

$_SESSION['uploads'][] = $new_filename . '.' . $file->getExtension();

Next, we add some file validation. We just tell it to only accept png, gif, and jpg images, and the max file size should only be 6Mb.

接下来,我们添加一些文件验证。 我们只是告诉它仅接受png,gif和jpg图片,并且最大文件大小应仅为6Mb。

$file->addValidations(array(
new \Upload\Validation\Mimetype(array('image/png', 'image/gif', 'image/jpg')),
new \Upload\Validation\Size('6M')
));

Lastly, we try to upload the file and assign any errors we get and return them to the client side. But we won’t really be making use of this error on the client side since dropzone already has us covered. It displays an x mark for the uploaded file if the file didn’t pass the validation:

最后,我们尝试上传文件并分配所有错误,然后将其返回给客户端。 但是我们真的不会在客户端使用此错误,因为dropzone已经覆盖了我们。 如果文件未通过验证,它将显示上载文件的x标记:

$errors = array();
try{
$file->upload();
}catch(Exception $e){
$errors = $file->getErrors();
}
$response_data = array(
'errors' => $errors
);
echo json_encode($response_data);

Going back to the template for adding new products, we include a partial. This is the template that will be used for showing the suggested product categories.

回到添加新产品的模板,我们包括一个部分。 这是用于显示建议的产品类别的模板。

{% include 'partials/categories.html' %}

It contains the following:

它包含以下内容:

{% raw %}
<script id="categories-template" type="text/x-handlebars-template">
{{#each categories}}
<div class="radio">
<label>
<input type="radio" name="category_id" id="category_id" value="{{id}}">
{{name}}
</label>
</div>
{{/each}}
</script>
{% endraw %}

In the above template, we’re using Handlebars. Its syntax collides with twig syntax so we have to wrap it in {% raw %} tags to make sure twig doesn’t parse it.

在上面的模板中,我们使用的是车把。 它的语法与Twig语法冲突,因此我们必须将其包装在{% raw %}标记中,以确保twig不会解析它。

Next, create the dropzone-options.js file under the /assets/js directory and add the following:

接下来,在/assets/js目录下创建dropzone-options.js文件,并添加以下内容:

(function(){
Dropzone.options.photosdropzone = {
acceptedFiles: "image/*",
autoProcessQueue: true,
uploadMultiple: false,
maxFiles: 5
};
})();

That allows us to specify the options for the dropzone. Here’s a breakdown of each option:

这使我们可以为dropzone指定选项。 以下是每个选项的细分:

  • acceptedFiles – the type of file that can be uploaded.

    acceptedFiles –可以上传的文件类型。

  • autoProcessQueue – a boolean value for specifying whether to process the queue immediately or not.

    autoProcessQueue –一个布尔值,用于指定是否立即处理队列。

  • uploadMultiple – a boolean value for specifying whether to allow multiple file uploads. In this case we selected false but it doesn’t mean we can’t upload more than one image. It means that we can’t upload more than one image at the same time.

    uploadMultiple –一个布尔值,用于指定是否允许多个文件上传。 在这种情况下,我们选择了false但这并不意味着我们不能上传多个图像。 这意味着我们不能同时上传多个图像。

  • maxFiles – an integer value for specifying the max number of files which can be uploaded.

    maxFiles –一个整数值,用于指定可以上传的最大文件数。

Next, create the new-product.js file and add the following:

接下来,创建new-product.js文件并添加以下内容:

(function(){
var categories_template = Handlebars.compile($("#categories-template").html());
$('#title').blur(function(){
var title = $(this).val();
$.post(
'/tester/ebay_trading_api/categories',
{
'title' : title
},
function(response){
var categories = JSON.parse(response);
var html = categories_template({'categories' : categories});
$('#categories-container').html(html);
}
);
});
})();

What the code above does is make a POST request every time the user tabs out of the product title field. The request then returns an array of objects containing the suggested categories based on the product title. The method which is used in this call is in the Product class. What it does is call the getSuggestedCategories() method in the Ebay class, passing in the product title as the argument. The response is then converted into a JSON string and echoed out:

上面的代码所做的是,每当用户从产品标题字段中跳出时,便发出POST请求。 然后,该请求将返回一个对象数组,其中包含基于产品标题的建议类别。 此调用中使用的方法在Product类中。 它的作用是在Ebay类中调用getSuggestedCategories()方法,并传入产品标题作为参数。 然后将响应转换为JSON字符串并回显:

public function categoriesAction(){
$suggested_categories = $this->app->ebay->getSuggestedCategories($_POST['title']);
echo json_encode($suggested_categories);
}

Open up the Ebay class and add the following method:

打开Ebay类并添加以下方法:

public function getSuggestedCategories($title){
$requestBody = '<?xml version="1.0" encoding="utf-8"?>
<GetSuggestedCategoriesRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<RequesterCredentials>
<eBayAuthToken>' . $this->user_token . '</eBayAuthToken>
</RequesterCredentials>
<Query>' . $title . '</Query>
</GetSuggestedCategoriesRequest>';
$response = $this->request('GetSuggestedCategories', $requestBody);
$suggested_categories = array();
if($response->Ack == 'Success'){
foreach($response->SuggestedCategoryArray->SuggestedCategory as $category){
$suggested_categories[] = array(
'id' => json_decode(json_encode($category->Category->CategoryID), true)[0],
'name' => json_decode(json_encode($category->Category->CategoryName), true)[0]
);
}
}
return $suggested_categories;
}

What the method above does is make a request to the GetSuggestedCategories API method. This call accepts the product title as its argument, as passed in the Query field. If the call is successful, it returns an array of suggested categories. We just need to extract the category id and category name from the result it returns.

上面的方法所做的是向GetSuggestedCategories API方法发出请求。 此调用接受产品标题作为其参数,如在Query字段中传递的那样。 如果调用成功,则返回建议类别的数组。 我们只需要从返回的结果中提取类别ID和类别名称即可。

Now we’re ready to write the createAction method. This is where we save the product details into the database and create the product on ebay.

现在,我们准备编写createAction方法。 这是我们将产品详细信息保存到数据库中并在ebay上创建产品的地方。

public function createAction(){
$v = new Valitron\Validator($_POST);
$v->rule('required', array('title', 'category_id', 'price', 'quantity', 'brand', 'description'));
$v->rule('numeric', 'price');
$v->rule('integer', 'quantity');
if($v->validate()){
if($query = $this->app->db->prepare("INSERT INTO products SET title = ?, category_id = ?, price = ?, qty = ?, brand = ?, description = ?")){
$store_settings_result = $this->app->db->query("SELECT payment_profile, return_profile, shipping_profile, out_of_stock_control, get_it_fast, category_prefill,
category_mapping, condition_type, country_code_type, currency_code, dispatch_time, optimal_picturesize,
listing_duration, listing_type, item_location, postal_code, store_name, county,
street, ebay_website, shippingservice_priority, shipping_service, shippingservice_cost, shippingservice_additionalcost
FROM store_settings WHERE id = 1");
$store_settings = $store_settings_result->fetch_object();
$response = $this->app->ebay->addItem($store_settings, $_POST);
if($response->Ack == 'Success'){
$title = $_POST['title'];
$category_id = $_POST['category_id'];
$price = $_POST['price'];
$qty = $_POST['quantity'];
$brand = $_POST['brand'];
$description = $_POST['description'];
$query->bind_param("ssdiss", $title, $category_id, $price, $qty, $brand, $description);
$query->execute();
$this->app->flash('message', array('type' => 'success', 'text' => 'Product was created!'));
}else{
$long_message = json_decode(json_encode($response->Errors->LongMessage), true);
$this->app->flash('message', array('type' => 'danger', 'text' => $long_message[0]));
}
}
}else{
$this->app->flash('form', $_POST);
$this->app->flash('message', array(
'type' => 'danger',
'text' => 'Please fix the following errors',
'data' => $v->errors())
);
}
$this->app->redirect('/tester/ebay_trading_api/products/new');
}

Breaking it down. First, we declare a new instance of valitron, passing in all the values that are currently stored in the $_POST global variable:

分解。 首先,我们声明一个新的valitron实例,传入当前存储在$_POST全局变量中的所有值:

$v = new Valitron\Validator($_POST);

Next we add the rules. Basically all the fields are required, the price should be a numeric value, and the quantity should be an integer. We specified that using the rule method which takes up the actual rule as the first argument, and the name of the field as the second argument:

接下来,我们添加规则。 基本上所有字段都是必填字段,价格应为数字值,数量应为整数。 我们指定使用rule方法,该方法将实际规则作为第一个参数,并将字段名称作为第二个参数:

$v->rule('required', array('title', 'price', 'quantity', 'brand', 'description'));
$v->rule('numeric', 'price');
$v->rule('integer', 'quantity');

Next we validate using the validate() method. If this returns true then the validation passed, otherwise it didn’t. If it returns false then we take all the POST data and save it into the session along with the error messages returned by valitron.

接下来,我们使用validate()方法进行validate() 。 如果返回true则验证通过,否则验证通过。 如果它返回false那么我们将所有POST数据与valitron返回的错误消息一起保存到会话中。

$this->app->flash('form', $_POST);
$this->app->flash('message', array(
'type' => 'danger',
'text' => 'Please fix the following errors',
'data' => $v->errors())
);

If the validation passes, we retrieve the store settings from the database and supply them as an argument for the addItem() method along with the contents of the $_POST variable. The addItem() method creates the product on eBay. If the call is successful, we create a prepared statement for adding the details of the product in the database. Once that’s done we flash a message into the session saying that the product was created. If the call is not successful then we pass the response returned from the API along with a message that the product was not created.

如果验证通过,我们将从数据库中检索商店设置,并将其作为addItem()方法的参数以及$_POST变量的内容提供。 addItem()方法在eBay上创建产品。 如果调用成功,我们将创建一条准备好的语句,以将产品的详细信息添加到数据库中。 完成后,我们会向会话中闪现一条消息,说明该产品已创建。 如果调用失败,那么我们将传递从API返回的响应以及未创建产品的消息。

$store_settings_result = $this->app->db->query("SELECT payment_profile, return_profile, shipping_profile, out_of_stock_control, get_it_fast, category_prefill,
category_mapping, condition_type, country_code_type, currency_code, dispatch_time, optimal_picturesize,
listing_duration, listing_type, item_location, postal_code, store_name, county,
street, ebay_website, shippingservice_priority, shipping_service, shippingservice_cost, shippingservice_additionalcost
FROM store_settings WHERE id = 1");
$store_settings = $store_settings_result->fetch_object();
$response = $this->app->ebay->addItem($store_settings, $_POST);
if($response->Ack == 'Success'){
if($query = $this->app->db->prepare("INSERT INTO products SET title = ?, category_id = ?, price = ?, qty = ?, brand = ?, description = ?")){
$title = $_POST['title'];
$category_id = $_POST['category_id'];
$price = $_POST['price'];
$qty = $_POST['quantity'];
$brand = $_POST['brand'];
$description = $_POST['description'];
$query->bind_param("ssdiss", $title, $category_id, $price, $qty, $brand, $description);
$query->execute();
}
$this->app->flash('message', array('type' => 'success', 'text' => 'Product was created!'));
}else{
$this->app->flash('message', array('type' => 'danger', 'response' => $response, 'text' => 'Product was not created!'));
}
$this->app->redirect('/tester/ebay_trading_api/products/new');

Next, we’ll define the addItem method in the Ebay class. Define 2 parameters: $store_settings and $item_data. Inside the method declare a variable called $boolean_value. This allows us to convert the integer value 0 to a string false and the integer value 1 to a string true. We need this because the API only accepts either true or false for boolean parameters.

接下来,我们将在Ebay类中定义addItem方法。 定义2个参数: $store_settings$item_data 。 在方法内部声明一个名为$boolean_value的变量。 这使我们能够将整数0转换为字符串false ,并将整数1转换为字符串true 。 我们需要这样做,因为API仅接受布尔参数为truefalse

Next, assign the uploads session item to a variable. If you remember from earlier, this session item is where we pushed the filenames of the images that the user uploaded. Next is the $baseupload_url, this contains the base URL in which all uploaded images can be found. We need this because the UploadSiteHostedPictures API method only accepts a URL for uploading to ebay. This also means that you need to have an actual server that’s accessible via public internet. The UploadSiteHostedPictures method only accepts a single URL at a time so we have to loop through all the images and supply the actual URL as the value for the ExternalPictureURL field. If the request is successful we just append the new image URL that’s returned to the $picture_details variable. This will be used as one of the arguments passed to the call for actually creating the product on eBay.

接下来,将上uploads会话项分配给变量。 如果您还记得以前的版本,则此会话项是我们推送用户上传图像的文件名的地方。 接下来是$baseupload_url ,它包含可以在其中找到所有上载图像的基本URL。 我们需UploadSiteHostedPictures是因为UploadSiteHostedPictures API方法仅接受用于上传到ebay的URL。 这也意味着您需要有一台可以通过公共互联网访问的实际服务器。 UploadSiteHostedPictures方法一次只接受一个URL,因此我们必须遍历所有图像并提供实际URL作为ExternalPictureURL字段的值。 如果请求成功,我们只需将返回的新图像URL附加到$picture_details变量中即可。 这将用作传递给在eBay上实际创建产品的调用的参数之一。

Next, we make the request for adding the product to eBay. This can be done via either the AddItem method or the VerifyAddItem method. The AddItem method is the one that you would want in production, since it adds the product to ebay. If there are any fees, those are also applied. VerifyAddItem on the other hand acts like a sandbox method, it doesn’t actually add the item on ebay. You can use it if you want to test the AddItem call. No fees are applied when you call it, but it lets you know how much of a fee will be applied or if the request would actually be successful. Note that you don’t need to use the sandbox version of the API in order to call the VerifyAddItem method. You can use it even on the live version of the API.

接下来,我们请求将产品添加到eBay。 可以通过AddItem方法或VerifyAddItem方法来完成。 AddItem方法是您要在生产中使用的方法,因为它将产品添加到ebay。 如果有任何费用,这些费用也将适用。 另一方面, VerifyAddItem的作用类似于沙盒方法,实际上并没有在ebay上添加该项目。 如果要测试AddItem调用,可以使用它。 调用时不收取任何费用,但是它可以让您知道要收取多少费用或请求是否实际成功。 请注意,您无需使用API​​的沙盒版本即可调用VerifyAddItem方法。 您甚至可以在实时版本的API上使用它。

public function addItem($store_settings, $item_data){
$boolean_value = array('false', 'true');
$product_images = $_SESSION['uploads'];
$baseupload_url = 'http://somewhere.com/uploads/';
$picture_details = '';
if(!empty($product_images)){
foreach($product_images as $img){
$requestBody = '<?xml version="1.0" encoding="utf-8"?>
<UploadSiteHostedPicturesRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<RequesterCredentials>
<eBayAuthToken>' . $this->user_token . '</eBayAuthToken>
</RequesterCredentials>
<ExternalPictureURL>' . $baseupload_url . '' . $img . '</ExternalPictureURL>
</UploadSiteHostedPicturesRequest>';
$response = $this->request('UploadSiteHostedPictures', $requestBody);
if(!empty($response->Ack) && $response->Ack != 'Failure'){
$uploaded_img = json_decode(json_encode($response->SiteHostedPictureDetails->PictureSetMember[3]->MemberURL), true);
$picture_details .= '<PictureURL>' . $uploaded_img[0] . '</PictureURL>';
}
}
}
$requestBody = '<?xml version="1.0" encoding="utf-8"?>
<AddItemRequest xmlns="urn:ebay:apis:eBLBaseComponents">
<RequesterCredentials>
<eBayAuthToken>' . $this->user_token . '</eBayAuthToken>
</RequesterCredentials>
<Item>
<SellerProfiles>
<SellerPaymentProfile>
<PaymentProfileID>' . $store_settings->payment_profile . '</PaymentProfileID>
</SellerPaymentProfile>
<SellerReturnProfile>
<ReturnProfileID>' . $store_settings->return_profile . '</ReturnProfileID>
</SellerReturnProfile>
<SellerShippingProfile>
<ShippingProfileID>' . $store_settings->shipping_profile . '</ShippingProfileID>
</SellerShippingProfile>
</SellerProfiles>
<OutOfStockControl>' . $store_settings->out_of_stock_control . '</OutOfStockControl>
<GetItFast>' . $boolean_value[$store_settings->get_it_fast] . '</GetItFast>
<CategoryBasedAttributesPrefill>' . $boolean_value[$store_settings->category_prefill] . '</CategoryBasedAttributesPrefill>
<CategoryMappingAllowed>' . $boolean_value[$store_settings->category_mapping] . '</CategoryMappingAllowed>
<ConditionID>' . $store_settings->condition_type . '</ConditionID>
<Country>' . $store_settings->country_code_type . '</Country>
<Currency>' . $store_settings->currency_code . '</Currency>
<Description>' . $item_data['description'] . '</Description>
<DispatchTimeMax>' . $store_settings->dispatch_time . '</DispatchTimeMax>
<ListingDesigner>
<OptimalPictureSize>' . $boolean_value[$store_settings->optimal_picturesize] . '</OptimalPictureSize>
</ListingDesigner>
<ListingDuration>' . $store_settings->listing_duration . '</ListingDuration>
<ListingType>' . $store_settings->listing_type . '</ListingType>
<Location>' . $store_settings->item_location . '</Location>
<PictureDetails>'
. $picture_details .
'</PictureDetails>
<PostalCode>' . $store_settings->postal_code . '</PostalCode>
<PrimaryCategory>
<CategoryID>' . $item_data['category_id'] . '</CategoryID>
</PrimaryCategory>
<Quantity>' . $item_data['quantity'] . '</Quantity>
<SellerContactDetails>
<CompanyName>' . $store_settings->store_name . '</CompanyName>
<County>' . $store_settings->county . '</County>
<Street>' . $store_settings->street . '</Street>
</SellerContactDetails>
<Site>' . $store_settings->ebay_website . '</Site>
<StartPrice currencyID="' . $store_settings->currency_code . '">' . $item_data['price'] . '</StartPrice>
<Title>' . $item_data['title'] . '</Title>
<ShippingDetails>
<ShippingServiceOptions>
<ShippingServicePriority>' . $store_settings->shippingservice_priority . '</ShippingServicePriority>
<ShippingService>' . $store_settings->shipping_service . '</ShippingService>
<ShippingServiceCost currencyID="' . $store_settings->currency_code . '">' . $store_settings->shippingservice_cost . '</ShippingServiceCost>
<ShippingServiceAdditionalCost currencyID="' . $store_settings->currency_code . '">' . $store_settings->shippingservice_additionalcost . '</ShippingServiceAdditionalCost>
</ShippingServiceOptions>
</ShippingDetails>
</Item>
</AddItemRequest>';
$response = $this->request('AddItem', $requestBody);
return $response;
}

To make things clearer, here’s a breakdown of the parameters we passed to the AddItem request. Here we’re passing in the seller profiles. The only requirement for each seller profile is the profile ID. We already got those earlier when we fetched the store settings, so we simply get them from the database.

为了使事情更清楚,这是我们传递给AddItem请求的参数的细分。 在这里,我们传递了卖方资料。 每个卖家资料的唯一要求是资料ID。 在获取商店设置时,我们早已获得了这些设置,因此我们只需从数据库中获取它们即可。

<SellerProfiles>
<SellerPaymentProfile>
<PaymentProfileID>' . $store_settings->payment_profile . '</PaymentProfileID>
</SellerPaymentProfile>
<SellerReturnProfile>
<ReturnProfileID>' . $store_settings->return_profile . '</ReturnProfileID>
</SellerReturnProfile>
<SellerShippingProfile>
<ShippingProfileID>' . $store_settings->shipping_profile . '</ShippingProfileID>
</SellerShippingProfile>
</SellerProfiles>

OutOfStockControl is a boolean value for specifying whether to keep the listing alive after it reaches a quantity of 0. Setting this to true excludes the listing from search results and from being viewed.

OutOfStockControl是一个布尔值,用于指定在数量达到0后是否使列表保持活动。将其设置为true会将列表从搜索结果和查看中排除。

<OutOfStockControl>' . $store_settings->out_of_stock_control . '</OutOfStockControl>

GetItFast is a boolean value for specifying whether the “get it fast” shipping is enabled or not.

GetItFast是一个布尔值,用于指定是否启用“快速获取”传送。

<GetItFast>' . $boolean_value[$store_settings->get_it_fast] . '</GetItFast>

CategoryBasedAttributesPrefill is a boolean value for specifying whether to prefill some of the item data based on the selected category.

CategoryBasedAttributesPrefill是一个布尔值,用于指定是否根据所选类别预填充某些项目数据。

<CategoryBasedAttributesPrefill>' . $boolean_value[$store_settings->category_prefill] . '</CategoryBasedAttributesPrefill>

CategoryMappingAllowed is a boolean value for specifying whether eBay will look up the current category ID that is mapped to the same category and use the new Category ID for the listing or not.

CategoryMappingAllowed是一个布尔值,用于指定eBay是否将查找映射到相同类别的当前类别ID,并将新的类别ID用于列表。

<CategoryMappingAllowed>' . $boolean_value[$store_settings->category_mapping] . '</CategoryMappingAllowed>

ConditionID allows you to specify the item condition. eBay has assigned numeric values to every possible item condition. Check the table on this page.

ConditionID允许您指定项目条件。 eBay已为每种可能的商品条件分配了数值。 检查此表上的表格。

<ConditionID>' . $store_settings->condition_type . '</ConditionID>

Country allows you to specify the country in which the item is located. You can check out a list of country codes and their corresponding country from this page.

Country允许您指定项目所在的国家。 您可以从此页面签出国家代码及其对应国家的列表。

<Country>' . $store_settings->country_code_type . '</Country>

Currency allows you to specify the currency in which the price of the product is expressed.

Currency允许您指定表示产品价格的货币。

<Currency>' . $store_settings->currency_code . '</Currency>

Description is the description of the item. You can also pass in HTML to this field.

Description是项目的描述。 您也可以将HTML传递给此字段。

<Description>' . $item_data['description'] . '</Description>

DispatchTimeMax is the max number of days in which the item will be dispatched or mailed to the customer. Specifying 0 means that the item is mailed to the customer as soon as the order is received.

DispatchTimeMax是将项目分派或邮寄给客户的最大天数。 指定0表示该商品在收到订单后立即邮寄给客户。

<DispatchTimeMax>' . $store_settings->dispatch_time . '</DispatchTimeMax>

OptimalPictureSize is a boolean value for specifying whether the the product image will be enlarged to fit the description of the item or not.

OptimalPictureSize是一个布尔值,用于指定是否将产品图像放大以适合商品说明。

<ListingDesigner>
<OptimalPictureSize>' . $boolean_value[$store_settings->optimal_picturesize] . '</OptimalPictureSize>
</ListingDesigner>

ListingDuration allows you to specify the number of days you want the listing to be active. Valid values can be found on this page.

ListingDuration允许您指定要激活的天数。 有效值可在此页面上找到。

<ListingDuration>' . $store_settings->listing_duration . '</ListingDuration>

ListingType allows you to specify the type of listing. Valid values can be found on this page. The usual value for this field is either Auction or FixedPriceItem.

ListingType允许您指定列表的类型。 有效值可在此页面上找到。 该字段的通常值为AuctionFixedPriceItem

<ListingType>' . $store_settings->listing_type . '</ListingType>

Location is the location of the item. This is a conditional field; if you don’t know the value for the PostalCode then you can just specify the value for this field.

Location是项目的位置。 这是一个条件字段; 如果您不知道PostalCode的值,则只需为此字段指定值。

<Location>' . $store_settings->item_location . '</Location>

PictureDetails is where we put in the URL’s of the product images that we have uploaded to eBay.

PictureDetails是我们放入已上传到eBay的产品图像的URL的地方。

<PictureDetails>'
. $picture_details .
'</PictureDetails>

PostalCode is the postal code of the area where the item is located. You can use the Location or this field to specify the location of the item.

PostalCode是该商品所在地区的邮政编码。 您可以使用Location或此字段来指定项目的位置。

<PostalCode>' . $store_settings->postal_code . '</PostalCode>

CategoryID is the ID of the main category of the item.

CategoryID是项目主要类别的ID。

<PrimaryCategory>
<CategoryID>' . $item_data['category_id'] . '</CategoryID>
</PrimaryCategory>

Quantity is an integer value of how many units of a specific item you have on your inventory.

Quantity是库存中特定项目的多少个单位的整数值。

<Quantity>' . $item_data['quantity'] . '</Quantity>

SellerContactDetails is where you specify the contact details of the seller. This is an optional field, it uses the seller information by default. But you can use this to override the settings.

SellerContactDetails可以在SellerContactDetails中指定卖家的联系方式。 这是一个可选字段,默认情况下使用卖方信息。 但是您可以使用它来覆盖设置。

<SellerContactDetails>
<CompanyName>' . $store_settings->store_name . '</CompanyName>
<County>' . $store_settings->county . '</County>
<Street>' . $store_settings->street . '</Street>
</SellerContactDetails>

Site is the ID of the eBay website where the product is listed. Examples include US for United States, and UK for United Kingdom. A list of valid values for this field can be found on this page.

Site是列出产品的eBay网站的ID。 示例包括美国(美国)和英国(英国)。 可以在此页面上找到此字段的有效值列表。

<Site>' . $store_settings->ebay_website . '</Site>

StartPrice is the starting price of the item when it is listed for the first time, or when revised or relisted.

StartPrice是项目首次列出,修订或重新列出时的起始价格。

<StartPrice currencyID="' . $store_settings->currency_code . '">' . $item_data['price'] . '</StartPrice>

Title is the title of the product.

Title是产品的标题。

<Title>' . $item_data['title'] . '</Title>

ShippingDetails is where you specify the shipping details for the product, such as the shipping service to be used, and additional costs if any.

您可以在ShippingDetails中指定产品的运输详细信息,例如要使用的运输服务以及其他费用(如果有)。

<ShippingDetails>
<ShippingServiceOptions>
<ShippingServicePriority>' . $store_settings->shippingservice_priority . '</ShippingServicePriority>
<ShippingService>' . $store_settings->shipping_service . '</ShippingService>
<ShippingServiceCost currencyID="' . $store_settings->currency_code . '">' . $store_settings->shippingservice_cost . '</ShippingServiceCost>
<ShippingServiceAdditionalCost currencyID="' . $store_settings->currency_code . '">' . $store_settings->shippingservice_additionalcost . '</ShippingServiceAdditionalCost>
</ShippingServiceOptions>
</ShippingDetails>

结论 (Conclusion)

That’s it! In this tutorial we went through eBay’s Trading API. We have learned that we can talk to their API by acquiring a token for the user. We also walk through fetching the user settings, uploading images and adding products using the API. But that’s not all you can do with Ebay’s Trading API. It’s a pretty huge API and almost anything that you can think of that you can do with eBay with regards to selling products, you can also do with the API. So be sure to check the docs if you’re curious. You can check out the source code of the project we’ve built in this github repository.

而已! 在本教程中,我们介绍了eBay的Trading API。 我们了解到,我们可以通过为用户获取令牌来与他们的API对话。 我们还将逐步介绍如何使用API​​获取用户设置,上传图片和添加产品。 但这不是您使用Ebay的Trading API所能做的全部。 这是一个非常庞大的API,您可以想到的几乎所有可以在eBay上进行销售的产品,也可以使用该API。 因此,如果您感到好奇,请务必检查文档 。 您可以检出我们在github存储库中构建的项目的源代码。

Feedback appreciated!

反馈表示赞赏!

翻译自: https://www.sitepoint.com/adding-products-ebay-store-trading-api/

使用交易API将产品添加到您的eBay商店相关推荐

  1. Python量化交易平台开发教程系列1-类CTP交易API的工作原理

    原创文章,转载请注明出处:用Python的交易员 类CTP交易API简介 国内程序化交易技术的爆发式发展几乎就是起源于上期技术公司基于CTP柜台推出了交易API,使得用户可以随意开发自己的交易软件直接 ...

  2. 如何使用a股量化交易api接口?

    在进行量化交易的需要的时候,可以考虑使用a股量化交易api接口作为分析工具. 如何使用a股量化交易api接口? 一是进行自主研发,不过这种办法费时费力,而且对技术也有一定要求. 第二种办法就是选择一个 ...

  3. 如何学习调用股票量化交易API接口的方法?

    对于股票量化交易API接口学习调用的方法,主要是从数字看点平台有丰富的API接口,它让应用程序可以轻松地使用另一个应用程序的数据和资源,把通用的.共性的应用功能进行模块化处理,让开发变的简单又快捷,即 ...

  4. 萤石开放平台——怎么通过API接口远程添加摄像头?

    高科技摄像头特别是海康萤石摄像头,已经不再只局限于简单的视频功能,特别是智能AI的普及,摄像头也华丽变身成了一个个独立的智能个体,可以实现人脸抓拍,人形检测,客流统计等店铺值守场景,也可以实现安全帽识 ...

  5. 常见的交易API接口介绍

    考虑到很多用户初次使用时对于各API接口的功能和获取方式存在较多的疑问,这里进行专门介绍. CTP 模块:vn.ctp 经纪商:期货公司.兴业证券 产品:期货.期货期权 特点:国内最早的针对程序化交易 ...

  6. 如何申请GRS交易证TC产品贴标?

    如何申请GRS交易证TC产品贴标? 1.产品被考核合格使用标识 1.1对某个具体产品,在上一个B2B交易中,必须提供TC 1.2产品GRS材料占比>=50% 1.3只被认证过的组织被允许在产品上 ...

  7. 《React后台管理系统实战:五》产品管理(二):产品添加页面及验证等、富文本编辑器、提交商品

    一.产品添加基础部分 1 home.jsx点添加按钮动作跳转到添加商品页 点击:onClick={() => this.props.history.push('/product/add-upda ...

  8. 如何使用 SAP API Portal Policy Editor 给 SAP API 调用自动添加认证信息

    打开 API portal,找到要编辑的 API,点击打开,进入明细页面: 点击 Policies: 在策略编辑器的右侧,您可以看到开箱即用的策略,可帮助您为您的用例选择策略.所有安全策略都分组在安全 ...

  9. Magento给产品添加“new”或者折扣数量标签 magento new label. discount label

    文章最底部有效果图. 给新产品添加"new"的标签.给折扣产品,显示出折扣的数量. 这个可以自己写一段代码加在到模板文件夹下面的catalog/product/list.phtml ...

最新文章

  1. Spring JdbcTemplate的queryForList(String sql , Class<T> elementType)返回非映射实体类的解决方法
  2. hadoop元数据mysql中表字段_Hive 元数据表结构详解
  3. pycharm提示 Method 'xxx' may be 'static'(类方法与静态方法)
  4. 【远程操控】Pycharm远程连接服务器之本地显示独立的plot窗口
  5. docker --- mysql的部署
  6. 带你利用一句话完成转场动画
  7. 从竞品数据搜集切入,NiucoData要做商业情报追踪分析工具
  8. 荣耀Magic3相机界面公布:提供专业“电影”功能
  9. JAVA美发门店管理系统计算机毕业设计Mybatis+系统+数据库+调试部署
  10. 西威变频器使用说明书_西威变频器调试说明.doc
  11. Milton 1.5.1发布,开源服务器端类库
  12. C语言编程猜谜语,简单的一字谜语合集
  13. html如何防止内部撑开,父div没有被撑开,该怎么解决?_html/css_WEB-ITnose
  14. 文艺爱好---英文单词
  15. 递归与回溯4:一文彻底理解回溯
  16. 题目:请写一段将正整数转化为四进制字符串的函数(十进制正整数转四进制字符串)
  17. mysql面试-01
  18. Linux_centos版初学(基础命令)
  19. sketchup 计算机配置,流畅运行SU草图大师软件的最低电脑配置要求
  20. excel拆分工资条

热门文章

  1. SQL宝典(中文版) 高清PDF版下载
  2. PCB设计之阻抗不连续性,如何解决?
  3. 徐锋-用例和面向方面软件开发-UMLChina讲座-音频和幻灯
  4. 02 | 论文中的「题目、目录、摘要和结论」应该怎么写?
  5. 第1关:Series数据选择
  6. 统计学知识大梳理(附框架图公式)
  7. Traffic Jams in the Land(线段树好题)
  8. 使用JTAG Flash Programmer烧写Flash
  9. 7-3 找零钱***分数 20作者 李祥单位 湖北经济学院
  10. OpenGL学习笔记:光照贴图