|
@@ -0,0 +1,175 @@
|
|
|
|
+package com.hys.app.service.otherService.amazon;
|
|
|
|
+
|
|
|
|
+import com.amazon.spapi.api.FeedsApi;
|
|
|
|
+import com.amazon.spapi.api.OrdersV0Api;
|
|
|
|
+import com.amazon.spapi.client.ApiException;
|
|
|
|
+import com.amazon.spapi.model.feeds.CreateFeedDocumentResponse;
|
|
|
|
+import com.amazon.spapi.model.feeds.CreateFeedDocumentSpecification;
|
|
|
|
+import com.amazon.spapi.model.feeds.CreateFeedResponse;
|
|
|
|
+import com.amazon.spapi.model.feeds.CreateFeedSpecification;
|
|
|
|
+import com.amazon.spapi.model.orders.*;
|
|
|
|
+import com.amazon.spapi.SellingPartnerAPIAA.*;
|
|
|
|
+
|
|
|
|
+import java.io.IOException;
|
|
|
|
+import java.io.OutputStream;
|
|
|
|
+import java.net.HttpURLConnection;
|
|
|
|
+import java.net.URL;
|
|
|
|
+import java.nio.charset.StandardCharsets;
|
|
|
|
+import java.util.ArrayList;
|
|
|
|
+import java.util.Arrays;
|
|
|
|
+import java.util.List;
|
|
|
|
+import java.time.OffsetDateTime;
|
|
|
|
+
|
|
|
|
+public class OrderFulfillmentManager {
|
|
|
|
+ private OrdersV0Api ordersApi;
|
|
|
|
+ private FeedsApi feedsApi;
|
|
|
|
+
|
|
|
|
+ public OrderFulfillmentManager() {
|
|
|
|
+ // 初始化 OrdersV0Api
|
|
|
|
+ LWAAuthorizationCredentials lwaAuthorizationCredentials = LWAAuthorizationCredentials.builder()
|
|
|
|
+ .clientId("YOUR_CLIENT_ID")
|
|
|
|
+ .clientSecret("YOUR_CLIENT_SECRET")
|
|
|
|
+ .refreshToken("YOUR_REFRESH_TOKEN")
|
|
|
|
+ .endpoint("https://api.amazon.com/auth/o2/token")
|
|
|
|
+ .build();
|
|
|
|
+
|
|
|
|
+ AWSAuthenticationCredentials awsAuthenticationCredentials = AWSAuthenticationCredentials.builder()
|
|
|
|
+ .accessKeyId("YOUR_AWS_ACCESS_KEY")
|
|
|
|
+ .secretKey("YOUR_AWS_SECRET_KEY")
|
|
|
|
+ .region("YOUR_AWS_REGION")
|
|
|
|
+ .build();
|
|
|
|
+
|
|
|
|
+ this.ordersApi = new OrdersV0Api.Builder()
|
|
|
|
+ .lwaAuthorizationCredentials(lwaAuthorizationCredentials)
|
|
|
|
+ .awsAuthenticationCredentials(awsAuthenticationCredentials)
|
|
|
|
+ .endpoint("https://sellingpartnerapi-na.amazon.com")
|
|
|
|
+ .build();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public List<Order> getPendingOrders(String marketplaceId) throws ApiException {
|
|
|
|
+ GetOrdersResponse response = ordersApi.getOrders(
|
|
|
|
+ Arrays.asList(marketplaceId),
|
|
|
|
+ OffsetDateTime.now().minusDays(7).toString(), // 获取最近7天的订单
|
|
|
|
+ null, null, null,
|
|
|
|
+ Arrays.asList("Unshipped"), // 只获取未发货的订单
|
|
|
|
+ null, null,null,null, null, null, null, null, null, null, null
|
|
|
|
+ );
|
|
|
|
+ return response.getPayload().getOrders();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+
|
|
|
|
+ public void fulfillOrders(List<Order> orders, List<String> trackingNumbers, List<String> carrierCodes) throws ApiException, IOException {
|
|
|
|
+ if (orders.size() != trackingNumbers.size() || orders.size() != carrierCodes.size()) {
|
|
|
|
+ throw new IllegalArgumentException("订单数量与跟踪号和承运商代码数量不匹配");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ String xmlContent = createFulfillmentXml(orders, trackingNumbers, carrierCodes);
|
|
|
|
+
|
|
|
|
+ // 创建 feed 文档
|
|
|
|
+ CreateFeedDocumentSpecification feedDocSpec = new CreateFeedDocumentSpecification()
|
|
|
|
+ .contentType("text/xml; charset=UTF-8");
|
|
|
|
+ CreateFeedDocumentResponse feedDocResponse = feedsApi.createFeedDocument(feedDocSpec);
|
|
|
|
+
|
|
|
|
+ // 上传 feed 内容
|
|
|
|
+ uploadFeedDocument(feedDocResponse.getUrl(), xmlContent);
|
|
|
|
+
|
|
|
|
+ // 提交 feed
|
|
|
|
+ CreateFeedSpecification feedSpec = new CreateFeedSpecification()
|
|
|
|
+ .feedType("POST_ORDER_FULFILLMENT_DATA")
|
|
|
|
+ .marketplaceIds(Arrays.asList("YOUR_MARKETPLACE_ID"))
|
|
|
|
+ .inputFeedDocumentId(feedDocResponse.getFeedDocumentId());
|
|
|
|
+
|
|
|
|
+ CreateFeedResponse feedResponse = feedsApi.createFeed(feedSpec);
|
|
|
|
+
|
|
|
|
+ System.out.println("Feed submitted with id: " + feedResponse.getFeedId());
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String createFulfillmentXml(List<Order> orders, List<String> trackingNumbers, List<String> carrierCodes) {
|
|
|
|
+ StringBuilder xmlBuilder = new StringBuilder();
|
|
|
|
+ xmlBuilder.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n");
|
|
|
|
+ xmlBuilder.append("<AmazonEnvelope xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:noNamespaceSchemaLocation=\"amzn-envelope.xsd\">\n");
|
|
|
|
+ xmlBuilder.append(" <Header>\n");
|
|
|
|
+ xmlBuilder.append(" <DocumentVersion>1.01</DocumentVersion>\n");
|
|
|
|
+ xmlBuilder.append(" <MerchantIdentifier>YOUR_MERCHANT_ID</MerchantIdentifier>\n");
|
|
|
|
+ xmlBuilder.append(" </Header>\n");
|
|
|
|
+ xmlBuilder.append(" <MessageType>OrderFulfillment</MessageType>\n");
|
|
|
|
+
|
|
|
|
+ for (int i = 0; i < orders.size(); i++) {
|
|
|
|
+ Order order = orders.get(i);
|
|
|
|
+ String trackingNumber = trackingNumbers.get(i);
|
|
|
|
+ String carrierCode = carrierCodes.get(i);
|
|
|
|
+
|
|
|
|
+ xmlBuilder.append(" <Message>\n");
|
|
|
|
+ xmlBuilder.append(" <MessageID>").append(i + 1).append("</MessageID>\n");
|
|
|
|
+ xmlBuilder.append(" <OrderFulfillment>\n");
|
|
|
|
+ xmlBuilder.append(" <AmazonOrderID>").append(order.getAmazonOrderId()).append("</AmazonOrderID>\n");
|
|
|
|
+ xmlBuilder.append(" <FulfillmentDate>").append(OffsetDateTime.now()).append("</FulfillmentDate>\n");
|
|
|
|
+ xmlBuilder.append(" <FulfillmentData>\n");
|
|
|
|
+ xmlBuilder.append(" <CarrierCode>").append(carrierCode).append("</CarrierCode>\n");
|
|
|
|
+ xmlBuilder.append(" <ShippingMethod>Standard</ShippingMethod>\n");
|
|
|
|
+ xmlBuilder.append(" <ShipperTrackingNumber>").append(trackingNumber).append("</ShipperTrackingNumber>\n");
|
|
|
|
+ xmlBuilder.append(" </FulfillmentData>\n");
|
|
|
|
+ xmlBuilder.append(" </OrderFulfillment>\n");
|
|
|
|
+ xmlBuilder.append(" </Message>\n");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ xmlBuilder.append("</AmazonEnvelope>");
|
|
|
|
+ return xmlBuilder.toString();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void uploadFeedDocument(String presignedUrl, String content) throws IOException {
|
|
|
|
+ URL url = new URL(presignedUrl);
|
|
|
|
+ HttpURLConnection connection = (HttpURLConnection) url.openConnection();
|
|
|
|
+ connection.setDoOutput(true);
|
|
|
|
+ connection.setRequestMethod("PUT");
|
|
|
|
+ connection.setRequestProperty("Content-Type", "text/xml; charset=UTF-8");
|
|
|
|
+
|
|
|
|
+ try (OutputStream os = connection.getOutputStream()) {
|
|
|
|
+ byte[] input = content.getBytes(StandardCharsets.UTF_8);
|
|
|
|
+ os.write(input, 0, input.length);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ int responseCode = connection.getResponseCode();
|
|
|
|
+ if (responseCode != HttpURLConnection.HTTP_OK) {
|
|
|
|
+ throw new IOException("HTTP error code: " + responseCode);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public void processPendingOrders(String marketplaceId) {
|
|
|
|
+ try {
|
|
|
|
+ List<Order> pendingOrders = getPendingOrders(marketplaceId);
|
|
|
|
+ List<String> trackingNumbers = new ArrayList<>();
|
|
|
|
+ List<String> carrierCodes = new ArrayList<>();
|
|
|
|
+
|
|
|
|
+ for (Order order : pendingOrders) {
|
|
|
|
+ // 这里应该是从您的系统中获取实际的物流信息
|
|
|
|
+ trackingNumbers.add(generateTrackingNumber());
|
|
|
|
+ carrierCodes.add("UPS"); // 或其他承运商代码
|
|
|
|
+
|
|
|
|
+ // 在这里更新您本地系统中的订单状态
|
|
|
|
+ updateLocalOrderStatus(order.getAmazonOrderId(), "SHIPPED");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ fulfillOrders(pendingOrders, trackingNumbers, carrierCodes);
|
|
|
|
+ System.out.println(pendingOrders.size() + " orders have been fulfilled.");
|
|
|
|
+ } catch (ApiException | IOException e) {
|
|
|
|
+ e.printStackTrace();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private String generateTrackingNumber() {
|
|
|
|
+ // 生成或获取实际的跟踪号
|
|
|
|
+ return "TRACK-" + System.currentTimeMillis();
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ private void updateLocalOrderStatus(String orderId, String status) {
|
|
|
|
+ // 更新本地数据库中的订单状态
|
|
|
|
+ // 这里应该是您的本地数据库操作
|
|
|
|
+ System.out.println("Updating local order status: " + orderId + " to " + status);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ public static void main(String[] args) {
|
|
|
|
+ OrderFulfillmentManager manager = new OrderFulfillmentManager();
|
|
|
|
+ manager.processPendingOrders("YOUR_MARKETPLACE_ID");
|
|
|
|
+ }
|
|
|
|
+}
|