基本思路:
1. 拉取sdk
2. createFeedDocument -> uploadFeedDocument -> createFeed
3. getOrder查看订单状态
实现过程:
1.github找到一个比较好用的sdk
进入项目目录,运行
composer require double-break/spapi-php
2. 执行流程,createFeedDocument -> uploadFeedDocument -> createFeed
直接上代码:
public static function shipped($get, $post) {
$brushData = empty($post['data']) ? array() : json_decode(stripslashes($post['data']), true);
$token = empty($brushData['token']) ? [] : $brushData['token'];
$xml = empty($brushData['xml']) ? '' : $brushData['xml'];
$host = empty($brushData['host']) ? '' : $brushData['host'];
if (empty($token)) {
$result = array(
'state' => '301',
'info' => '缺少必要参数,token'
);
}
if (empty($brushData['platformOrder'])) {
$result = array(
'state' => '302',
'info' => '缺少必要参数,platformOrder'
);
}
if (empty($host)) {
$result = array(
'state' => '303',
'info' => '缺少必要参数,host'
);
}
if (empty($token['spRefreshToken']) || empty($token['spClientId']) || empty($token['spClientSecret']) ||
empty($token['spAccessKeyId']) || empty($token['spSecretKey']) || empty($token['spRoleArn']) || empty($token['spRegion'])) {
$result = array(
'state' => '304',
'info' => 'token缺少必要参数,spRefreshToken/spClientId/spClientSecret/spAccessKeyId/spSecretKey/spRoleArn/spRegion'
);
}
if (empty($xml)) {
$result = array(
'state' => '305',
'info' => '标记内容为空'
);
}
if (!empty($result)) return $result;
include ROOT_DIR . '/vendor/autoload.php';
/** The Setup **/
$config = [
'http' => [
'verify' => true,
'debug' => false
],
'refresh_token' => $token['spRefreshToken'],
'client_id' => $token['spClientId'],
'client_secret' => $token['spClientSecret'],
//STS: Keys of the IAM role which are needed to generate Secure Session
// (a.k.a Secure token) for accessing and assuming the IAM role
'access_key' => $token['spAccessKeyId'],
'secret_key' => $token['spSecretKey'],
'role_arn' => $token['spRoleArn'] ,
//API: Actual configuration related to the SP API :)
'region' => $token['spRegion'],
'host' => $host
];
//Create token storage which will store the temporary tokens
$tokenStorage = new DoubleBreak\Spapi\SimpleTokenStorage('./aws-tokens');
//Create the request signer which will be automatically used to sign all of the
//requests to the API
$signer = new DoubleBreak\Spapi\Signer();
//Create Credentials service and call getCredentials() to obtain
//all the tokens needed under the hood
$credentials = new DoubleBreak\Spapi\Credentials($tokenStorage, $signer, $config, $token['account']);
$cred = $credentials->getCredentials();
// content type of the feed data to be uploaded.
$contentType = 'text/xml; charset=UTF-8';
// create feed document
$feedClient = new \DoubleBreak\Spapi\Api\Feeds($cred, $config);
$response = $feedClient->createFeedDocument(["contentType" => $contentType]);
$payload = $response;
$result = (new \DoubleBreak\Spapi\Helper\Feeder())->uploadFeedDocument($payload,$contentType,$xml);
if ($result === 'Done') {
$body = [
'feedType' => 'POST_ORDER_FULFILLMENT_DATA',
"marketplaceIds" => [
$token['marketplace_id']
],
"inputFeedDocumentId" => $payload['feedDocumentId']
];
$res = $feedClient->createFeed($body);
if (!empty($res['feedId'])) {
return array('state' => 200, 'info' => $res);
}
} else {
return array('state' => 30, 'info' => 'xml文件上传失败');
}
}
3. 下一次标记时查询订单状态,若订单状态已经变成Shipped,则表示上一次标记成功,不再进行标记,否则重试。
查询订单方法:
public static function getOrder($get, $post) {
$brushData = empty($post['data']) ? array() : json_decode(stripslashes($post['data']), true);
$token = empty($brushData['token']) ? [] : $brushData['token'];
$host = empty($brushData['host']) ? '' : $brushData['host'];
if (empty($token)) {
$result = array(
'state' => '301',
'info' => '缺少必要参数,token'
);
}
if (empty($brushData['platformOrder'])) {
$result = array(
'state' => '302',
'info' => '缺少必要参数,platformOrder'
);
}
if (empty($host)) {
$result = array(
'state' => '303',
'info' => '缺少必要参数,host'
);
}
if (empty($token['spRefreshToken']) || empty($token['spClientId']) || empty($token['spClientSecret']) ||
empty($token['spAccessKeyId']) || empty($token['spSecretKey']) || empty($token['spRoleArn']) || empty($token['spRegion'])) {
$result = array(
'state' => '304',
'info' => 'token缺少必要参数,spRefreshToken/spClientId/spClientSecret/spAccessKeyId/spSecretKey/spRoleArn/spRegion'
);
}
if (!empty($result)) return $result;
include ROOT_DIR . '/vendor/autoload.php';
/** The Setup **/
$config = [
'http' => [
'verify' => true,
'debug' => false
],
'refresh_token' => $token['spRefreshToken'],
'client_id' => $token['spClientId'],
'client_secret' => $token['spClientSecret'],
//STS: Keys of the IAM role which are needed to generate Secure Session
// (a.k.a Secure token) for accessing and assuming the IAM role
'access_key' => $token['spAccessKeyId'],
'secret_key' => $token['spSecretKey'],
'role_arn' => $token['spRoleArn'] ,
//API: Actual configuration related to the SP API :)
'region' => $token['spRegion'],
'host' => $host
];
//Create token storage which will store the temporary tokens
$tokenStorage = new DoubleBreak\Spapi\SimpleTokenStorage('./aws-tokens');
//Create the request signer which will be automatically used to sign all of the
//requests to the API
$signer = new DoubleBreak\Spapi\Signer();
//Create Credentials service and call getCredentials() to obtain
//all the tokens needed under the hood
$credentials = new DoubleBreak\Spapi\Credentials($tokenStorage, $signer, $config, $token['account']);
$cred = $credentials->getCredentials();
$orderClient = new DoubleBreak\Spapi\Api\Orders($cred, $config);
$res = $orderClient->getOrder($brushData['platformOrder']);
$result = [
'state' => 200,
'info' => $res
];
return $result;
}
实现过程就是这么简单,希望能帮到有需要的人。
附加参数格式:
1. shipped方法传参的token参数:
{
"account":"xxx",
"merchant_id":"xxx",
"marketplace_id":"xxx",
"shorthand_code":"DE",
"accountId":"xxx",
"authorizeState":1,
"expireState":null,
"spAccessKeyId":"xxx",
"spClientId":"xxx",
"spClientSecret":"a9059aff31f3fab2a96ed4fb851a0f9bfb04e859d2483266ca01c7781659b84f",
"spRefreshToken":"xxx",
"spRegion":"eu-west-1",
"spRoleArn":"arn:aws:iam::429211419775:role\/PlsSellingPartnerAPIRole",
"spSecretKey":"xxx"
}
2. xml模版:
<?xml version="1.0" encoding="UTF-8"?>
<AmazonEnvelope><Header>
<DocumentVersion>1.02</DocumentVersion>
<MerchantIdentifier></MerchantIdentifier>
</Header>
<MessageType>OrderFulfillment</MessageType>
<PurgeAndReplace>true</PurgeAndReplace><Message>
<MessageID>1</MessageID>
<OrderFulfillment>
<AmazonOrderID>305-0942001-3129934</AmazonOrderID>
<FulfillmentDate>2022-08-29T03:15:59.000Z</FulfillmentDate>
<FulfillmentData>
<CarrierName>GLS</CarrierName>
<ShippingMethod></ShippingMethod>
<ShipperTrackingNumber>103389001671</ShipperTrackingNumber>
</FulfillmentData><Item><AmazonOrderItemCode>33520471730635</AmazonOrderItemCode>
<Quantity>1</Quantity>
</Item></OrderFulfillment></Message></AmazonEnvelope>
3. 官方文档的流程 Feeds API v2021-06-30 Use Case Guide
4. sdk需要修改或替换的地方:
4.1》vendor/guzzlehttp/guzzle/src/functions.php 默认linux系统,可以改下同时支持window和linux运行
function debug_resource($value = null)
{
if (is_resource($value)) {
return $value;
} elseif (defined('STDOUT')) {
return STDOUT;
}
$agent = $_SERVER['HTTP_USER_AGENT'];
if (strpos($agent, "Window") === false) {
return fopen('php://output', 'w');
} else {
return fopen('php://stdout','w');
}
}
4.2> vendor/double-break/spapi-php/src/Credentials.php
vendor/double-break/spapi-php/src/SimpleTokenStorage.php
两个文件适当修改以便支持多账号使用(原SDK只使用单独一个帐号使用), 我的方式是将写入和读取aws-tokens文件写成多维数组,用账号名为key值。
附加api返回格式:
1. createFeed请求的数据:
{"feedType":"POST_ORDER_FULFILLMENT_DATA","marketplaceIds":["ATVPDKIKX0DER"],"inputFeedDocumentId":"amzn1.tortuga.3.d1dbeb92-b475-46d4-946c-491f46724dc0.TJG1LXE67GBUR"}
2. createFeed返回的数据:
Array ( [feedId] => 204332019186 )
3. getFeed返回的结果:
Array ( [processingEndTime] => 2022-07-13T10:26:53+00:00 [processingStatus] => DONE [marketplaceIds] => Array ( [0] => ATVPDKIKX0DER ) [feedId] => 204332019186 [feedType] => POST_ORDER_FULFILLMENT_DATA [createdTime] => 2022-07-13T10:26:13+00:00 [processingStartTime] => 2022-07-13T10:26:28+00:00 [resultFeedDocumentId] => amzn1.tortuga.3.9f6c8425-58a5-4031-851c-65142aaafa75.T3JQMGCAVP75PJ )
4. getFeedDocument返回:
Array ( [feedDocumentId] => amzn1.tortuga.3.21b9cb2c-f796-4d59-b37a-2b7b60121f23.TFG3R55E0799T [url] => https://tortuga-prod-na.s3-external-1.amazonaws.com/%2FNinetyDays/amzn1.tortuga.3.2e5b624c-93ee-475b-baee-5754483f3a5c.T2YQZUNM2Y0QBM?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20220713T102852Z&X-Amz-SignedHeaders=host&X-Amz-Expires=300&X-Amz-Credential=AKIA5U6MO6RAJ4ZS7WYA%2F20220713%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=4e978cd0907b625e21c6b05c1b53cb3d912d3ed34244561d8fd73991147ce84a )
附加站点节点url配置:
array(
'CA' => array('region' => 'us-east-1','marketplace_id' => 'A2EUQ1WTGCTBG2','service_url_report' => 'https://sellingpartnerapi-na.amazon.com'), //加拿大
'US' => array('region' => 'us-east-1','marketplace_id' => 'ATVPDKIKX0DER','service_url_report' => 'https://sellingpartnerapi-na.amazon.com'), //美国
'MX' => array('region' => 'us-east-1','marketplace_id' => 'A1AM78C64UM0Y8','service_url_report' => 'https://sellingpartnerapi-na.amazon.com'), //墨西哥
'BR' => array('region' => 'us-east-1','marketplace_id' => 'A2Q3Y263D00KWC','service_url_report' => 'https://sellingpartnerapi-na.amazon.com'), //巴西
'ES' => array('region' => 'eu-west-1','marketplace_id' => 'A1RKKUPIHCS9HS','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //西班牙
'UK' => array('region' => 'eu-west-1','marketplace_id' => 'A1F83G8C2ARO7P','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //英国
'GB' => array('region' => 'eu-west-1','marketplace_id' => 'A1F83G8C2ARO7P','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //英国
'FR' => array('region' => 'eu-west-1','marketplace_id' => 'A13V1IB3VIYZZH','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //法国
'NL' => array('region' => 'eu-west-1','marketplace_id' => 'A1805IZSGTT6HS','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //荷兰
'DE' => array('region' => 'eu-west-1','marketplace_id' => 'A1PA6795UKMFR9','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //德国
'IT' => array('region' => 'eu-west-1','marketplace_id' => 'APJ6JRA9NG5V4','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //意大利
'SE' => array('region' => 'eu-west-1','marketplace_id' => 'A2NODRKZP88ZB9','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //瑞典
'PL' => array('region' => 'eu-west-1','marketplace_id' => 'A1C3SOZRARQ6R3','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //波兰
'EG' => array('region' => 'eu-west-1','marketplace_id' => 'ARBP9OOSHTCHU','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //埃及
'TR' => array('region' => 'eu-west-1','marketplace_id' => 'A33AVAJ2PDY3EV','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //土耳其
'SA' => array('region' => 'eu-west-1','marketplace_id' => 'A17E79C6D8DWNP','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //沙特阿拉伯
'AE' => array('region' => 'eu-west-1','marketplace_id' => 'A2VIGQ35RCS4UG','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //阿拉伯联合酋长国
'IN' => array('region' => 'eu-west-1','marketplace_id' => 'A21TJRUUN4KGV','service_url_report' => 'https://sellingpartnerapi-eu.amazon.com'), //印度
'SG' => array('region' => 'us-west-2','marketplace_id' => 'A19VAU5U5O7RUS','service_url_report' => 'https://sellingpartnerapi-fe.amazon.com'), //新加坡
'AU' => array('region' => 'us-west-2','marketplace_id' => 'A39IBJ37TRP1C6','service_url_report' => 'https://sellingpartnerapi-fe.amazon.com'), //澳大利亚
'JP' => array('region' => 'us-west-2','marketplace_id' => 'A1VC38T7YXB528','service_url_report' => 'https://sellingpartnerapi-fe.amazon.com') //日本
),