PHP 接口:
有看不懂的可以回复或联系@me
<?php
/**
* Created by PhpStorm.
* User: Administrator
* Date: 2021/5/19
* Time: 10:52
*/
namespace app\shopify;
class Shopify
{
private $max_time;
public function __construct()
{
$this->max_time = date('Y-m-d', strtotime('+3 days')) . 'T11:00:00-05:00';
}
/**
* 检索位置列表
* @param $username
* @param $password
* @param $shop
* @param $u_id
* @return mixed|string
*/
public function getThisLocations($username, $password, $shop, $u_id)
{
$url = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/admin/api/2021-07/locations.json';
$result = $this->requestHandle($url, $data = [], $method = 'GET');
if (isset($result['locations']) && is_array($result['locations'])) {
foreach ($result['locations'] as $k => $node) {
$data = [
'location_id' => $node['id'],
'u_id' => $u_id,
'shop' => $shop,
'name' => $node['name'],
'address1' => $node['address1'],
'address2' => $node['address2'],
'city' => $node['city'],
'zip' => $node['zip'],
'province' => $node['province'],
'country' => $node['country'],
'phone' => $node['phone'],
'country_code' => $node['country_code'],
'country_name' => $node['country_name'],
'province_code' => $node['province_code'],
'active' => $node['active'],
'localized_country_name' => $node['localized_country_name'],
'localized_province_name' => $node['localized_province_name'],
];
if (db('shop_locations')->where('location_id', $node['id'])->where('u_id', $u_id)->value('id')) {
db('shop_locations')->where('location_id', $node['id'])->where('u_id', $u_id)->update($data);
} else {
db('shop_locations')->insertGetId($data);
}
}
}
return $result;
}
/**
* 获得订单信息
* @param $username
* @param $password
* @param $shop
* @param $time
* @return mixed|string
* https://shopify.dev/api/admin-rest/2021-10/resources/order#[get]/admin/api/2021-10/orders.json
*/
public function getShopifyOrderLists($username, $password, $shop, $time)
{
if (!$time) {
$time = $this->max_time;
}
$url = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/admin/api/2021-07/orders.json';
$data = [
'financial_status' => 'paid',
'limit' => 50,
'created_at_max' => $time
];
$result = $this->requestHandle($url, $data, $method = 'GET');
return $result;
}
/**
* 检索订单计数
* @param $shop
* @param $username
* @param $password
* @param $time
* @return array|string
*/
public function getOrderCount($shop, $username, $password, $time)
{
if (!$time) {
$time = $this->max_time;
}
$url = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/admin/api/2021-07/orders/count.json';
$data = [
'financial_status' => 'paid',
'created_at_max' => $time
];
$result = $this->requestHandle($url, $data, $method = 'GET');
return $result;
}
/**
* 获取店铺产品列表
* @param array $opt
* @return mixed
*/
public function getShopProductList($shop, $opt = [])
{
$shop_stroe_list = db('shop_store')->where('url', $shop)->find();
$username = $shop_stroe_list['username'];
$password = $shop_stroe_list['password'];
$data = [
'status' => 'active'
];
$data = array_merge($data, $opt);
$query = http_build_query($data);
$url = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/admin/api/2021-07/products.json?' . $query;
$product = $this->GetCurlRequest($url);
$result = JD($product)['products'];
return $result;
}
/**
* 创建履行
* @param $shop
* @param $username
* @param $password
* @param $order_id
* @param $tracking_number
* @param $tracking_company
* @param $fulfillment_id
* @return array|string
* https://shopify.dev/api/admin-rest/2021-10/resources/fulfillment#[post]/admin/api/2021-10/orders/{order_id}/fulfillments.json
*/
public function createFulfillments($shop, $username, $password, $order_id, $tracking_number, $tracking_company, $fulfillment_id)
{
$result = [];
if ($fulfillment_id != 1) {
if ($fulfillment_id) {
$this->cancelFulfillments($shop, $username, $password, $fulfillment_id, $order_id);
}
$url = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/admin/api/2021-07/orders/' . $order_id .
'/fulfillments.json';
$data = [
'fulfillment' => [
"location_id" => '66207809762',#美国:66207809762 中国:66393768162
"notify_customer" => true,
"tracking_number" => $tracking_number,
"tracking_company" => $tracking_company,
"tracking_urls" => ["https://t.17track.net/en#nums=" . $tracking_number]
]
];
$result = $this->requestHandle($url, $data, 'POST');
return $result;
}
return $result;
}
/**
* 取消履行
* @param $shop
* @param $username
* @param $password
* @param $fulfillment_id
* @param $order_id
* @return array|string
*/
public function cancelFulfillments($shop, $username, $password, $fulfillment_id, $order_id)
{
$url = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/admin/api/2021-07/orders/' . $order_id .
'/fulfillments/' . $fulfillment_id . '/cancel.json';
$result = $this->requestHandle($url, $data = [], $method = 'GET');
return $result;
}
/**
* 获取店铺产品总数量
* 参考:https://shopify.dev/api/admin/rest/reference/products/product#count-2021-07
* @return bool|string
*/
public function getShopProductCount($shop)
{
$shop_stroe_list = db('shop_store')->where('url', $shop)->find();
$username = $shop_stroe_list['username'];
$password = $shop_stroe_list['password'];
$url = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/admin/api/2021-07/products/count.json?published_status=published';
$count = $this->GetCurlRequest($url);
$count = JD($count)['count'];
return $count;
}
/**
* @param $shop
* @param $product_id
* @param $image_id
* @param $data
* @return array|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
public function modifyImage($shop, $product_id, $image_id, $data)
{
$url = 'admin/api/2021-04/products/' . $product_id . '/images/' . $image_id . '.json';
$shop_stroe_list = db('shop_store')->where('url', $shop)->find();
$username = $shop_stroe_list['username'];
$password = $shop_stroe_list['password'];
$url = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/' . $url;
$opt = $data;
$result = $this->requestHandle($url, $opt, 'PUT');
if (!$result['image']) {
d($result);
}
$result = $result['image'];
return $result;
}
/**
* 获取商品图片信息
* @param $shop
* @param $product_id
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function getImagesInfo($shop, $product_id)
{
$url = 'admin/api/2021-04/products/' . $product_id . '/images.json';
$shop_stroe_list = db('shop_store')->where('url', $shop)->find();
$username = $shop_stroe_list['username'];
$password = $shop_stroe_list['password'];
$url = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/' . $url;
$result = $this->requestHandle($url, [], 'GET');
return $result['images'];
}
/**
* 添加图片、位置调整
*/
public function updateProducts()
{
$url = '/admin/api/2021-04/products/6745942098102.json';
$token = $this->getToken();
$shop = 'hemingliang';
$data = [
'product' => [
'id' => 6745942098102,
'images' => [
[
'id' => 28843460329654,
// 'position'=>1
],
[
'id' => 28843460264118,
// 'position'=>2
],
[
'src' => 'http://img.321.design/goods_imgs/20987311521622117386.jpg'
]
],
]
];
$product = $this->shopify_call($token, $shop, $url, $data, 'PUT', array(0 => 'Content-Type: application/json'));
return $product;
}
/**
* 创建产品
* @param $shop
* @param array $opt
* @return mixed
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
*/
public function writeProducts($shop, $opt = [])
{
if (!$opt) {
$opt = array(
"product" => array(
"title" => ' ahml ' . 11 . ' test Super Soft ',
"body_html" => "<p>✦ Super Soft & Durable - Durable Enough To Provide You With Long Term Use. Machine Wash Cold On Gentle Cycle.Avoid Bleaching.Do Not Iron, Avoid Exposure To The Sun.</p>
<p>✦ Take It Anywhere - Warmqin Blankets Are Delicate And Breathable, Extra Softer And Warmer, Suit For All Seasons. Ideal For Keeping You Warm And Cozy From Head To Toe While Watching Tv, Lounging On The Sofa/Bed Working Gaming Reading A Book Napping Or
Studying.</p>
<p>✦ Makes A Great Gift - A Great Gift For Someone Who Likes To Be Cozy! Prefect For Familys Friends & Students On Mother’s Day Father’s Day Christmas Easter Valentine’s Day Thanksgiving New Year’s Eve Birthdays Anniversaries, Back To School, Graduation
Gift.</p>
<p>✦ Available In 3 Sizes - 50x40 Inches(Small Size), 60x50 Inches(Medium Size), 80x60 Inches(Large Size), Small Size Fits Most Kids, Medium Size Fits Most Teen, Large Size Fits Most Adults, Choosing One That Is More Suitable For Yourself, So You Can Stay
Warm From Head To Toe No More Cold Feet.</p>
<p>✦ 24 Hours Customer Service - We Believe In Quality Rather Than Quantity! Our Soft, Durable And Stylish Blankets Can Help You Spend A Beautiful And Comfortable Night To Solve Sleep Problems.</p>",
"vendor" => "amituo",
"product_type" => "blanket",
"published_at" => strval(date('Y-m-d', time()) . 'T' . date('H:i:s', time() + 5 - 3600 * 8)),
"published_scope" => "global",
"options" => [
array(
'name' => 'Product',
'values' => [
"第一个",
"第二个",
]
),
array(
'name' => 'Color',
'values' => [
"Black"
]
),
array(
'name' => 'Size',
'values' => [
'50*40',
'60*50',
]
),
],
"variants" => array(
array(
"sku" => "31315465454",
"price" => 29.99,
"compare_at_price" => 49.00,
"grams" => 1000,
'option1' => '第一个',
'option2' => 'Black',
'option3' => '40*50',
"taxable" => false,
"inventory_quantity" => 11,
"inventory_management" => 'shopify',
),
array(
"sku" => "31315465454",
"price" => 39.99,
"compare_at_price" => 79.00,
"grams" => 1000,
'option1' => '第一个',
'option2' => 'Black',
'option3' => '50*60',
"taxable" => false,
"inventory_quantity" => 11,
"inventory_management" => 'shopify'
),
#第二个
array(
"sku" => "31315465454",
"price" => 29.99,
"compare_at_price" => 39.00,
"grams" => 1000,
'option1' => '第二个',
'option2' => 'Black',
'option3' => '40*50',
"taxable" => false,
"inventory_quantity" => 11,
"inventory_management" => 'shopify',
),
array(
"sku" => "31315465454",
"price" => 39.99,
"compare_at_price" => 59.00,
"grams" => 1000,
'option1' => '第二个',
'option2' => 'Black',
'option3' => '50*60',
"taxable" => false,
"inventory_quantity" => 11,
"inventory_management" => 'shopify'
),
),
"images" => array(
array(
"src" => db('goods_imgs')->where(['goods_id' => rand(100, 146019)
, 'sort_order' => 0])->value('path'),
),
array(
"src" => db('goods_imgs')->where(['goods_id' => rand(100, 146019)
, 'sort_order' => 1])->value('path'),
),
array(
"src" => db('goods_imgs')->where(['goods_id' => rand(100, 146019)
, 'sort_order' => 2])->value('path'),
)
),
)
);
}
$shop_stroe_list = db('shop_store')->where('url', $shop)->find();
$username = $shop_stroe_list['username'];
$password = $shop_stroe_list['password'];
$url = 'https://' . $username . ':' . $password . '@' . $shop . '.myshopify.com/admin/api/2021-07/products.json';
$product = $this->postCurlRequest($url, $opt);
if (!isset(JD($product)['product'])) {
d($product);
}
$result = JD($product)['product'];
return $result;
}
/**
* 获取店铺授权
* @return string
*/
public function getStoreScopes()
{
$scopes = "read_locations,read_content,write_content,read_themes,write_themes,read_products,write_products,read_product_listings,read_collection_listings,read_customers,write_customers,read_orders,write_orders,read_draft_orders,write_draft_orders,read_script_tags,write_script_tags,read_fulfillments,write_fulfillments,read_shipping,write_shipping,read_analytics,read_checkouts,write_checkouts,read_reports,write_reports,read_price_rules,write_price_rules,read_marketing_events,write_marketing_events,read_resource_feedbacks,write_resource_feedbacks,read_locations,read_inventory,write_inventory";
return $scopes;
}
/**
* 获取token
* @param $shop
* @return mixed|string
* @throws \think\Exception
* @throws \think\db\exception\DataNotFoundException
* @throws \think\db\exception\ModelNotFoundException
* @throws \think\exception\DbException
* @throws \think\exception\PDOException
*/
protected function getToken($shop)
{
$token = db('shop_store')->where('url', $shop)->value('token');
if (!$token) {
$shopify_info = db('shop_shopify')->where('id', 1)->find();
$code = db('shop_store')->where('url', $shop)->value('code');
$request_headers = array(
"Content-type" => "application/json",
"client_id" => $shopify_info['client_id'],
"client_secret" => $shopify_info['client_secret'],
"code" => $code
);
$shopify_response = $this->shopify_call(NULL, $shop, "/admin/oauth/access_token", $request_headers, 'POST', $request_headers);
$shopify_response = json_decode($shopify_response['response'], TRUE);
$token = $shopify_response['access_token'];
db('shop_store')->where('url', $shop)->update(['token' => $token]);
}
return $token;
}
/**
* @param $token token
* @param $shop shop
* @param $api_endpoint 接口路径
* @param array $query 接口参数
* @param string $method 访问方式
* @param array $request_headers 头部信息
* @return array|string
*/
public function shopify_call($token, $shop, $api_endpoint, $query = array(), $method = 'GET', $request_headers = array())
{
$url = "https://" . $shop . ".myshopify.com" . $api_endpoint;
if (!is_null($query) && in_array($method, array('GET', 'DELETE'))) $url = $url . "?" . http_build_query($query);
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($curl, CURLOPT_MAXREDIRS, 3);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_USERAGENT, 'My New Shopify App v.1');
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
$request_headers[] = "";
if (!is_null($token)) $request_headers[] = "X-Shopify-Access-Token: " . $token;
curl_setopt($curl, CURLOPT_HTTPHEADER, $request_headers);
if ($method != 'GET' && in_array($method, array('POST', 'PUT'))) {
if (is_array($query)) {
$fquery = http_build_query($query);
if ($request_headers[0] == 'Content-Type: application/json')
$fquery = json_encode($query);
}
curl_setopt($curl, CURLOPT_POSTFIELDS, $fquery);
}
$response = curl_exec($curl);
$response = str_replace("HTTP/1.1 100 Continue\r\r", '', $response);
$response = str_replace("HTTP/1.1 100 Continue\r\n\r\n", '', $response);
$response = str_replace("HTTP/1.1 100 Continue\n\n", '', $response);
$error_number = curl_errno($curl);
$error_message = curl_error($curl);
curl_close($curl);
if ($error_number) {
return $error_message;
} else {
$response = preg_split("/\r\n\r\n|\n\n|\r\r/", $response, 2);
$headers = array();
$header_data = explode("\n", $response[0]);
$headers['status'] = $header_data[0];
array_shift($header_data);
foreach ($header_data as $part) {
$h = explode(":", $part);
$headers[trim($h[0])] = trim($h[1]);
}
return array('response' => JD($response[1]), 'headers' => $headers);
}
}
/**
* curl 请求
* @param $url
* @param array $data
* @param string $method
* @return mixed|string
*/
protected function requestHandle($url, $data = [], $method = 'GET')
{
if (in_array($method, array('GET', 'DELETE'))) {
if ($data) {
$url = $url . "?" . http_build_query($data);
}
}
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_HEADER, TRUE);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($curl, CURLOPT_MAXREDIRS, 3);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
if (in_array($method, array('POST', 'PUT'))) {
if (is_array($data)) {
$data = json_encode($data);
}
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
$response = curl_exec($curl);
$response = str_replace("HTTP/1.1 100 Continue\r\r", '', $response);
$response = str_replace("HTTP/1.1 100 Continue\r\n\r\n", '', $response);
$response = str_replace("HTTP/1.1 100 Continue\n\n", '', $response);
$error_number = curl_errno($curl);
$error_message = curl_error($curl);
curl_close($curl);
if ($error_number) {
return $error_message;
} else {
$response = preg_split("/\r\n\r\n|\n\n|\r\r/", $response, 2);
$headers = array();
$header_data = explode("\n", $response[0]);
$headers['status'] = $header_data[0];
array_shift($header_data);
foreach ($header_data as $part) {
$h = explode(":", $part);
$headers[trim($h[0])] = trim($h[1]);
}
return JD($response[1]);
}
}
/**
* post 请求
* @param $remote_server
* @param $post_string
* @return bool|string
*/
protected function postCurlRequest($remote_server, $data)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $remote_server);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json'));
if (is_array($data)) {
$data = json_encode($data);
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
/**
* get 请求
* @param $url
* @return bool|string
*/
protected function GetCurlRequest($url)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//关闭ssl验证
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_HEADER, 0);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
}
