peddler 5.3.1 → 5.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +74 -11
  3. data/lib/peddler/api.rb +30 -6
  4. data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09/order_attribute.rb +20 -0
  5. data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09/outbound_execution_error.rb +24 -0
  6. data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09/outbound_listing.rb +24 -0
  7. data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09/outbound_order.rb +60 -0
  8. data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09/outbound_order_creation_data.rb +23 -0
  9. data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09/outbound_order_reference.rb +18 -0
  10. data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09/outbound_shipment.rb +43 -0
  11. data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09/shipment_label_page_types.rb +20 -0
  12. data/lib/peddler/apis/amazon_warehousing_and_distribution_2024_05_09.rb +100 -0
  13. data/lib/peddler/apis/external_fulfillment_shipments_2024_09_11/address.rb +4 -1
  14. data/lib/peddler/apis/external_fulfillment_shipments_2024_09_11/distance.rb +20 -0
  15. data/lib/peddler/apis/external_fulfillment_shipments_2024_09_11/geocodes.rb +23 -0
  16. data/lib/peddler/apis/external_fulfillment_shipments_2024_09_11/handover_location.rb +23 -0
  17. data/lib/peddler/apis/external_fulfillment_shipments_2024_09_11/ship_label_metadata.rb +4 -0
  18. data/lib/peddler/apis/external_fulfillment_shipments_2024_09_11/shipment_info.rb +3 -0
  19. data/lib/peddler/apis/external_fulfillment_shipments_2024_09_11/shipping_options.rb +4 -0
  20. data/lib/peddler/apis/external_fulfillment_shipments_2024_09_11.rb +1 -1
  21. data/lib/peddler/apis/feeds_2021_06_30.rb +8 -2
  22. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/amount.rb +2 -2
  23. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/delivery_document.rb +2 -2
  24. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/delivery_information.rb +2 -1
  25. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/delivery_preferences.rb +1 -1
  26. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/delivery_window.rb +3 -4
  27. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/drop_off_location.rb +9 -7
  28. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/feature_settings.rb +5 -1
  29. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/feature_sku.rb +1 -1
  30. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/fulfillment_order.rb +2 -2
  31. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/fulfillment_preview_shipment.rb +6 -6
  32. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/fulfillment_shipment_package.rb +3 -4
  33. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/get_feature_inventory_response.rb +1 -1
  34. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/get_feature_sku_result.rb +12 -3
  35. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/origin.rb +2 -1
  36. data/lib/peddler/apis/fulfillment_outbound_2020_07_01/tracking_event.rb +1 -2
  37. data/lib/peddler/apis/listings_restrictions_2021_08_01/restriction_list.rb +1 -1
  38. data/lib/peddler/apis/listings_restrictions_2021_08_01.rb +4 -1
  39. data/lib/peddler/apis/notifications_v1/aggregation_filter.rb +2 -2
  40. data/lib/peddler/apis/notifications_v1/destination.rb +1 -1
  41. data/lib/peddler/apis/notifications_v1/event_bridge_resource.rb +2 -2
  42. data/lib/peddler/apis/notifications_v1/event_filter.rb +6 -6
  43. data/lib/peddler/apis/notifications_v1/marketplace_filter.rb +1 -1
  44. data/lib/peddler/apis/notifications_v1/marketplace_ids.rb +2 -2
  45. data/lib/peddler/apis/notifications_v1/order_change_type_filter.rb +2 -1
  46. data/lib/peddler/apis/notifications_v1/order_change_types.rb +2 -2
  47. data/lib/peddler/apis/notifications_v1/processing_directive.rb +18 -7
  48. data/lib/peddler/apis/notifications_v1/send_test_notification_request.rb +20 -0
  49. data/lib/peddler/apis/notifications_v1/send_test_notification_response.rb +20 -0
  50. data/lib/peddler/apis/notifications_v1/test_notification.rb +22 -0
  51. data/lib/peddler/apis/notifications_v1.rb +45 -17
  52. data/lib/peddler/apis/orders_2026_01_01/associated_order_item.rb +27 -0
  53. data/lib/peddler/apis/orders_2026_01_01/fulfillment_order.rb +19 -0
  54. data/lib/peddler/apis/orders_2026_01_01/item_packing.rb +3 -0
  55. data/lib/peddler/apis/orders_2026_01_01/item_picking.rb +1 -1
  56. data/lib/peddler/apis/orders_2026_01_01/item_proceeds_breakdown.rb +5 -5
  57. data/lib/peddler/apis/orders_2026_01_01/item_proceeds_detailed_breakdown.rb +1 -1
  58. data/lib/peddler/apis/orders_2026_01_01/item_tax.rb +20 -0
  59. data/lib/peddler/apis/orders_2026_01_01/item_tax_calculation_breakdown.rb +21 -0
  60. data/lib/peddler/apis/orders_2026_01_01/item_tax_collection.rb +24 -0
  61. data/lib/peddler/apis/orders_2026_01_01/order.rb +13 -1
  62. data/lib/peddler/apis/orders_2026_01_01/order_item.rb +7 -0
  63. data/lib/peddler/apis/orders_2026_01_01/order_payment.rb +17 -0
  64. data/lib/peddler/apis/orders_2026_01_01/order_proceeds.rb +5 -0
  65. data/lib/peddler/apis/orders_2026_01_01/order_proceeds_breakdown.rb +30 -0
  66. data/lib/peddler/apis/orders_2026_01_01/order_tax.rb +20 -0
  67. data/lib/peddler/apis/orders_2026_01_01/order_tax_invoicing.rb +34 -0
  68. data/lib/peddler/apis/orders_2026_01_01/order_tax_registration.rb +39 -0
  69. data/lib/peddler/apis/orders_2026_01_01/package_status.rb +4 -3
  70. data/lib/peddler/apis/orders_2026_01_01/pagination.rb +5 -5
  71. data/lib/peddler/apis/orders_2026_01_01/payment_execution.rb +39 -0
  72. data/lib/peddler/apis/orders_2026_01_01/search_orders_response.rb +10 -11
  73. data/lib/peddler/apis/orders_2026_01_01/serial_number_requirement.rb +19 -0
  74. data/lib/peddler/apis/orders_2026_01_01/tax_registration_attribute.rb +22 -0
  75. data/lib/peddler/apis/orders_2026_01_01.rb +15 -13
  76. data/lib/peddler/apis/orders_v0/address.rb +3 -3
  77. data/lib/peddler/apis/orders_v0/address_extended_fields.rb +9 -2
  78. data/lib/peddler/apis/orders_v0/approved_alternative_details.rb +20 -0
  79. data/lib/peddler/apis/orders_v0/approved_attribute.rb +23 -0
  80. data/lib/peddler/apis/orders_v0/buyer_info.rb +3 -0
  81. data/lib/peddler/apis/orders_v0/geo_coordinates.rb +20 -0
  82. data/lib/peddler/apis/orders_v0/interim_status_detail.rb +24 -0
  83. data/lib/peddler/apis/orders_v0/order_buyer_info.rb +3 -0
  84. data/lib/peddler/apis/orders_v0/regulated_order_verification_status.rb +5 -0
  85. data/lib/peddler/apis/orders_v0/valid_interim_status_code.rb +21 -0
  86. data/lib/peddler/apis/orders_v0/valid_verification_detail.rb +2 -1
  87. data/lib/peddler/apis/orders_v0/verification_details.rb +8 -0
  88. data/lib/peddler/apis/orders_v0.rb +6 -2
  89. data/lib/peddler/apis/product_pricing_2022_05_01/competitive_summary_response_body.rb +3 -0
  90. data/lib/peddler/apis/product_pricing_2022_05_01/item.rb +17 -0
  91. data/lib/peddler/apis/product_pricing_2022_05_01/points.rb +1 -1
  92. data/lib/peddler/apis/product_pricing_2022_05_01/similar_items.rb +17 -0
  93. data/lib/peddler/apis/product_type_definitions_2020_09_01/error_list.rb +1 -1
  94. data/lib/peddler/apis/product_type_definitions_2020_09_01/product_type.rb +1 -1
  95. data/lib/peddler/apis/product_type_definitions_2020_09_01/product_type_list.rb +1 -1
  96. data/lib/peddler/apis/product_type_definitions_2020_09_01/schema_link.rb +2 -1
  97. data/lib/peddler/apis/product_type_definitions_2020_09_01.rb +12 -8
  98. data/lib/peddler/apis/replenishment_2022_11_07/deliveries_condition.rb +22 -0
  99. data/lib/peddler/apis/replenishment_2022_11_07/forecast_deliveries.rb +26 -0
  100. data/lib/peddler/apis/replenishment_2022_11_07/get_selling_partner_metrics_request.rb +8 -3
  101. data/lib/peddler/apis/replenishment_2022_11_07/get_selling_partner_metrics_request_filters.rb +48 -0
  102. data/lib/peddler/apis/replenishment_2022_11_07/get_selling_partner_metrics_response_metric.rb +14 -10
  103. data/lib/peddler/apis/replenishment_2022_11_07/list_offer_metrics_request.rb +2 -2
  104. data/lib/peddler/apis/replenishment_2022_11_07/list_offer_metrics_request_filters.rb +17 -4
  105. data/lib/peddler/apis/replenishment_2022_11_07/list_offer_metrics_response_offer.rb +37 -23
  106. data/lib/peddler/apis/replenishment_2022_11_07/list_offers_request.rb +2 -2
  107. data/lib/peddler/apis/replenishment_2022_11_07/list_offers_request_filters.rb +7 -3
  108. data/lib/peddler/apis/replenishment_2022_11_07/list_offers_response_offer.rb +27 -1
  109. data/lib/peddler/apis/replenishment_2022_11_07/offer_program_configuration.rb +1 -1
  110. data/lib/peddler/apis/replenishment_2022_11_07/time_interval.rb +10 -6
  111. data/lib/peddler/apis/reports_2021_06_30.rb +8 -2
  112. data/lib/peddler/apis/seller_wallet_2024_03_01/balance.rb +6 -6
  113. data/lib/peddler/apis/seller_wallet_2024_03_01/balance_listing.rb +2 -2
  114. data/lib/peddler/apis/seller_wallet_2024_03_01/bank_account.rb +5 -5
  115. data/lib/peddler/apis/seller_wallet_2024_03_01/bank_account_listing.rb +2 -2
  116. data/lib/peddler/apis/seller_wallet_2024_03_01/delete_transfer_schedule.rb +3 -2
  117. data/lib/peddler/apis/seller_wallet_2024_03_01/fee.rb +4 -7
  118. data/lib/peddler/apis/seller_wallet_2024_03_01/fx_rate_details.rb +6 -6
  119. data/lib/peddler/apis/seller_wallet_2024_03_01/payee_contact_information.rb +5 -5
  120. data/lib/peddler/apis/seller_wallet_2024_03_01/payment_preference.rb +2 -3
  121. data/lib/peddler/apis/seller_wallet_2024_03_01/schedule_expression.rb +4 -5
  122. data/lib/peddler/apis/seller_wallet_2024_03_01/transaction.rb +13 -14
  123. data/lib/peddler/apis/seller_wallet_2024_03_01/transaction_account.rb +8 -8
  124. data/lib/peddler/apis/seller_wallet_2024_03_01/transaction_initiation_request.rb +8 -7
  125. data/lib/peddler/apis/seller_wallet_2024_03_01/transaction_instrument_details.rb +6 -7
  126. data/lib/peddler/apis/seller_wallet_2024_03_01/transaction_listing.rb +6 -5
  127. data/lib/peddler/apis/seller_wallet_2024_03_01/transfer_rate_preview.rb +4 -3
  128. data/lib/peddler/apis/seller_wallet_2024_03_01/transfer_schedule.rb +11 -12
  129. data/lib/peddler/apis/seller_wallet_2024_03_01/transfer_schedule_failures.rb +3 -3
  130. data/lib/peddler/apis/seller_wallet_2024_03_01/transfer_schedule_information.rb +5 -6
  131. data/lib/peddler/apis/seller_wallet_2024_03_01/transfer_schedule_listing.rb +6 -5
  132. data/lib/peddler/apis/seller_wallet_2024_03_01/transfer_schedule_request.rb +11 -13
  133. data/lib/peddler/apis/seller_wallet_2024_03_01.rb +30 -28
  134. data/lib/peddler/apis/services_v1/associated_item.rb +3 -0
  135. data/lib/peddler/apis/services_v1/linked_asset.rb +24 -0
  136. data/lib/peddler/apis/services_v1/money_amount.rb +20 -0
  137. data/lib/peddler/apis/services_v1/payment.rb +20 -0
  138. data/lib/peddler/apis/services_v1/service_job.rb +9 -0
  139. data/lib/peddler/apis/services_v1.rb +11 -5
  140. data/lib/peddler/apis/shipment_invoicing_v0/payment_information.rb +6 -6
  141. data/lib/peddler/apis/shipment_invoicing_v0/payment_information_list.rb +1 -1
  142. data/lib/peddler/apis/uploads_2020_11_01.rb +1 -1
  143. data/lib/peddler/data_kiosk/economics20240315.json +6 -6
  144. data/lib/peddler/data_kiosk/sales_and_traffic20231115.json +6 -6
  145. data/lib/peddler/data_kiosk/sales_and_traffic20240424.json +6 -6
  146. data/lib/peddler/data_kiosk/vendor_analytics20240930.json +6 -6
  147. data/lib/peddler/errors.rb +1 -0
  148. data/lib/peddler/notifications/order_change/notification.rb +4 -3
  149. data/lib/peddler/notifications/order_change/order_change_notification.rb +2 -2
  150. data/lib/peddler/notifications/order_change/order_change_trigger.rb +4 -4
  151. data/lib/peddler/notifications/order_change/order_item.rb +7 -7
  152. data/lib/peddler/notifications/order_change/summary.rb +17 -17
  153. data/lib/peddler/version.rb +1 -1
  154. data/sig/peddler/api.rbs +3 -1
  155. data/sig/peddler/apis/amazon_warehousing_and_distribution_2024_05_09.rbs +167 -0
  156. data/sig/peddler/apis/external_fulfillment_shipments_2024_09_11.rbs +85 -28
  157. data/sig/peddler/apis/feeds_2021_06_30.rbs +1 -1
  158. data/sig/peddler/apis/fulfillment_outbound_2020_07_01.rbs +11 -8
  159. data/sig/peddler/apis/listings_restrictions_2021_08_01.rbs +1 -1
  160. data/sig/peddler/apis/notifications_v1.rbs +61 -7
  161. data/sig/peddler/apis/orders_2026_01_01.rbs +272 -39
  162. data/sig/peddler/apis/orders_v0.rbs +115 -36
  163. data/sig/peddler/apis/product_pricing_2022_05_01.rbs +40 -7
  164. data/sig/peddler/apis/product_type_definitions_2020_09_01.rbs +1 -1
  165. data/sig/peddler/apis/replenishment_2022_11_07.rbs +117 -42
  166. data/sig/peddler/apis/reports_2021_06_30.rbs +1 -1
  167. data/sig/peddler/apis/services_v1.rbs +71 -15
  168. data/sig/peddler/errors.rbs +3 -0
  169. metadata +51 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 39a668305211189b981586a66d71362c7f641c50f6ccacf3a28172a4abb8e696
4
- data.tar.gz: 68366d3f5f419c79062854e75d00ac37dfcb82098fa5660d17f56a60ebb893d2
3
+ metadata.gz: dfaa728f0b1fe2e6c63402f3bc188b58f9b6d2d35177666a48f2dcf36420e353
4
+ data.tar.gz: 80d2163af9c60fdd65feaa9d4b9d24d3c5e4babc4d6386228ed03f8ac9851bcf
5
5
  SHA512:
6
- metadata.gz: dec0fa29e3b3a30a23ba120145c5baa6c98ef90b105727fba91daab9ae621393d3ab9f15aa515b2e25ed4f4c332c503b3429781d5ba1e7d0c6f425416318ce8b
7
- data.tar.gz: f729c59ad31e1cc10fdb782cdccc1c749e7f7ad62b587d4beb31054569517bb185329f0d0e2f46d604543fe7e4436c5ed81bea931dec53e7d7d2acc34696f2d9
6
+ metadata.gz: 73ecd6efcc89cf60e4565e5d13e39c96240a8bf1e2a08e7f88eeb1ed5f72f65ed63c18a7d2f300727c09adb430a05cea4b110b22ad0e98fd73c20cb4404d4a9e
7
+ data.tar.gz: d1c8d6b7d388b26110edc1326fa1907e7ad696d79d8f9a7acfea37d7df739fbc6ddd6908933496e7734dded1725553fcc417be22491ed8bace4b887463169567
data/README.md CHANGED
@@ -1,29 +1,31 @@
1
1
  # Peddler
2
2
 
3
- [![Build](https://github.com/lineofflight/peddler/actions/workflows/ci.yml/badge.svg)][build]
4
-
5
3
  Peddler is a Ruby interface to the [Amazon Selling Partner API (SP-API)][api-docs]. The SP-API enables Amazon sellers and vendors to programmatically access their data on orders, shipments, payments, and more.
6
4
 
7
- Peddler is automatically generated from the latest Open API models provided by Amazon.
5
+ Peddler is automatically generated from the latest Open API models provided by Amazon. A nightly job tracks Amazon's spec changes, so new endpoints and fields land shortly after Amazon publishes them. Model changes are not considered breaking and don't trigger a major version bump.
8
6
 
9
7
  Peddler covers all SP-API endpoints, reports, notifications, and feeds. It's also lightweight: thanks to Zeitwerk, only the code you use gets loaded.
10
8
 
11
- To begin using the Amazon SP-API, you must [register as a developer][register-as-developer] and [register your application][register-application]. Once registered, [obtain your Login with Amazon (LWA) credentials][view-credentials] to access your own or other selling partners' data.
12
-
13
- - [API docs][api-docs]
14
- - [OpenAPI models][openapi-models]
15
- - [API samples][api-samples]
16
-
17
9
  <img src="https://github.com/hakanensari/peddler/blob/main/images/peddler.jpg?raw=true" alt="Peddler" style="max-width: 830px" />
18
10
 
19
11
  ## Installation
20
12
 
21
13
  Add to your Gemfile.
22
14
 
15
+ ### Agent skill
16
+
17
+ If you use an agent, install the SP-API skill:
18
+
19
+ ```shell
20
+ npx skills add lineofflight/peddler
21
+ ```
22
+
23
23
  ## Usage
24
24
 
25
25
  ### Authorization
26
26
 
27
+ Before using Peddler, you must [register as a developer][register-as-developer], [register your application][register-application], and [obtain your Login with Amazon (LWA) credentials][view-credentials]; Amazon's [official SP-API code samples][api-samples] can help you get started.
28
+
27
29
  Set your LWA credentials in your environment.
28
30
 
29
31
  ```shell
@@ -85,6 +87,48 @@ class Seller
85
87
  end
86
88
  ```
87
89
 
90
+ ### Restricted Data Tokens (RDT) and PII
91
+
92
+ Some operations are restricted because they return Personally Identifiable Information (PII), such as a buyer's name and shipping address. To call one, exchange your access token for a Restricted Data Token (RDT) scoped to the specific resources you need, then pass the RDT in place of the access token.
93
+
94
+ ```ruby
95
+ api = Peddler.tokens.new(aws_region, access_token)
96
+ response = api.create_restricted_data_token({
97
+ "restrictedResources" => [
98
+ {
99
+ "method" => "GET",
100
+ "path" => "/orders/v0/orders/123-1234567-1234567/address",
101
+ },
102
+ ],
103
+ })
104
+ restricted_data_token = response.parse.restricted_data_token
105
+ ```
106
+
107
+ Use the RDT exactly where you would normally pass the access token.
108
+
109
+ ```ruby
110
+ api = Peddler.orders.new(aws_region, restricted_data_token)
111
+ address = api.get_order_address("123-1234567-1234567").parse.payload.shipping_address
112
+ ```
113
+
114
+ For the Orders API, also specify which `dataElements` you need (`buyerInfo`, `shippingAddress`, or `buyerTaxInformation`).
115
+
116
+ ```ruby
117
+ api = Peddler.tokens.new(aws_region, access_token)
118
+ response = api.create_restricted_data_token({
119
+ "restrictedResources" => [
120
+ {
121
+ "method" => "GET",
122
+ "path" => "/orders/v0/orders",
123
+ "dataElements" => ["buyerInfo", "shippingAddress"],
124
+ },
125
+ ],
126
+ })
127
+ restricted_data_token = response.parse.restricted_data_token
128
+ ```
129
+
130
+ An RDT is valid for one hour. Like access tokens, cache and reuse it across calls. See the [Tokens API Use Case Guide][tokens-guide] for the full list of restricted operations.
131
+
88
132
  ### Rate limiting
89
133
 
90
134
  Amazon's SP-API imposes [rate limits][rate-limits] on operations. Override the default value by passing a `:rate_limit` parameter when calling an operation.
@@ -153,6 +197,21 @@ rescue Peddler::Error => e
153
197
  end
154
198
  ```
155
199
 
200
+ #### Rescuing Specific Errors
201
+
202
+ Peddler raises specific pre-defined subclasses for common Amazon error codes (e.g., `Peddler::Errors::QuotaExceeded`, `Peddler::Errors::NotFound`, `Peddler::Errors::InvalidInput`).
203
+
204
+ If Amazon returns an undocumented or newly introduced error code, Peddler dynamically instantiates a matching subclass under the `Peddler::Errors` namespace at runtime. To rescue a new specific subclass without causing a boot-time `NameError` in your application, define the class beforehand in an initializer:
205
+
206
+ ```ruby
207
+ # config/initializers/peddler_errors.rb
208
+ module Peddler
209
+ module Errors
210
+ class NewAmazonErrorCode < Error; end
211
+ end
212
+ end
213
+ ```
214
+
156
215
  ### Available APIs
157
216
 
158
217
  Peddler provides Ruby interfaces to all Amazon SP-API endpoints. Each API is available in its respective version. Access APIs by calling methods on the Peddler module:
@@ -290,6 +349,10 @@ For complete method signatures, see [sig/peddler/apis/](sig/peddler/apis/)
290
349
 
291
350
  For a complete list of available APIs and their detailed documentation, refer to the [API models repository][openapi-models].
292
351
 
352
+ ## Best practices
353
+
354
+ Writing efficient SP-API code? See the [best-practices checklist](skills/sp-api-ruby/best-practices.md) bundled with the agent skill: cutting call volume, batching, caching, API versions, reports, and per-API quirks.
355
+
293
356
  ## Development
294
357
 
295
358
  ```bash
@@ -309,8 +372,7 @@ bundle exec rake generate
309
372
  # Type check with Steep
310
373
  bundle exec steep check --severity-level=hint
311
374
  ```
312
- [build]: https://github.com/lineofflight/peddler/actions
313
- [api-docs]: https://developer.amazonservices.com/sp-api-docs/overview
375
+ [api-docs]: https://developer-docs.amazon.com/sp-api/docs/welcome
314
376
  [register-as-developer]: https://developer-docs.amazon.com/sp-api/docs/registering-as-a-developer
315
377
  [register-application]: https://developer-docs.amazon.com/sp-api/docs/registering-your-application
316
378
  [openapi-models]: https://github.com/amzn/selling-partner-api-models
@@ -318,4 +380,5 @@ bundle exec steep check --severity-level=hint
318
380
  [view-credentials]: https://developer-docs.amazon.com/sp-api/docs/viewing-your-application-information-and-credentials
319
381
  [authorization]: https://developer-docs.amazon.com/sp-api/docs/authorizing-selling-partner-api-applications
320
382
  [rate-limits]: https://developer-docs.amazon.com/sp-api/docs/usage-plans-and-rate-limits
383
+ [tokens-guide]: https://developer-docs.amazon.com/sp-api/docs/tokens-api-use-case-guide
321
384
  [httprb]: https://github.com/httprb/http
data/lib/peddler/api.rb CHANGED
@@ -9,6 +9,8 @@ module Peddler
9
9
  class CannotSandbox < StandardError; end
10
10
  class MustSandbox < StandardError; end
11
11
 
12
+ TRANSIENT_STATUSES = [429, 500, 502, 503, 504].freeze
13
+
12
14
  # @return [Peddler::Endpoint]
13
15
  attr_reader :endpoint
14
16
 
@@ -24,7 +26,7 @@ module Peddler
24
26
  # @param [String] access_token The access token for authentication
25
27
  # @param [Integer] retries The number of retries if throttled (default: 0)
26
28
  # @param [HTTP::Client] http HTTP client
27
- def initialize(aws_region, access_token, retries: 0, http: HTTP)
29
+ def initialize(aws_region, access_token, retries: 0, http: HTTP::Client.new)
28
30
  @endpoint = Endpoint.find(aws_region)
29
31
  @access_token = access_token
30
32
  @retries = retries
@@ -53,7 +55,7 @@ module Peddler
53
55
 
54
56
  # @see https://developer-docs.amazon.com/sp-api/docs/include-a-user-agent-header-in-all-requests
55
57
  # @see https://developer-docs.amazon.com/amazon-shipping/docs/connecting-to-the-selling-partner-api#step-3-add-headers-to-the-uri
56
- # @return [HTTP::Client]
58
+ # @return [HTTP::Session]
57
59
  def http(rate_limit: nil)
58
60
  client = @http.headers(
59
61
  "Host" => endpoint_uri.host,
@@ -62,10 +64,32 @@ module Peddler
62
64
  "X-Amz-Date" => timestamp,
63
65
  )
64
66
 
65
- return client if retries.zero? || rate_limit.nil?
66
-
67
- delay = sandbox? ? 0.2 : 1.0 / rate_limit
68
- client.retriable(delay:, tries: retries + 1, retry_statuses: [429]) # steep:ignore NoMethod
67
+ return client if retries.zero?
68
+
69
+ on_retry = ->(_req, _err, res) {
70
+ Thread.current[:peddler_last_retry_status] = res&.status
71
+ }
72
+
73
+ delay = ->(iteration) {
74
+ last_status = Thread.current[:peddler_last_retry_status]
75
+
76
+ if last_status == 429 && rate_limit
77
+ # Rate-limit-aware exponential backoff with jitter if throttled
78
+ # @see https://aws.amazon.com/blogs/architecture/exponential-backoff-and-jitter/
79
+ initial_delay = sandbox? ? 0.2 : 1.0 / rate_limit
80
+ (initial_delay * (2.0**(iteration - 1))) + (rand * 0.1)
81
+ else
82
+ # Standard backoff for network errors and 5xx
83
+ (2.0**(iteration - 1)) - 1 + rand
84
+ end
85
+ }
86
+
87
+ client.retriable(
88
+ tries: retries + 1,
89
+ delay: delay,
90
+ on_retry: on_retry,
91
+ retry_statuses: TRANSIENT_STATUSES,
92
+ )
69
93
  end
70
94
 
71
95
  private
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+
7
+ module Peddler
8
+ module APIs
9
+ class AmazonWarehousingAndDistribution20240509
10
+ # Consists of the order preference and corresponding preference value.
11
+ OrderAttribute = Structure.new do
12
+ # @return [String] Preference for the distribution order.
13
+ attribute(:order_preference, String, null: false, from: "orderPreference")
14
+
15
+ # @return [String] Value for the order preference.
16
+ attribute(:order_preference_value, String, null: false, from: "orderPreferenceValue")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+
7
+ module Peddler
8
+ module APIs
9
+ class AmazonWarehousingAndDistribution20240509
10
+ # Execution errors associated with the outbound order. This field will be populated if the order failed
11
+ # validation.
12
+ OutboundExecutionError = Structure.new do
13
+ # @return [String] Failure code details for the error.
14
+ attribute(:failure_code, String, null: false, from: "failureCode")
15
+
16
+ # @return [Array<String>] Failure reasons for the error.
17
+ attribute(:failure_reasons, [String], null: false, from: "failureReasons")
18
+
19
+ # @return [String] MSKU associated with the error.
20
+ attribute?(:sku, String)
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,24 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+
7
+ module Peddler
8
+ module APIs
9
+ class AmazonWarehousingAndDistribution20240509
10
+ # A list of paginated outbound orders filtered by the attributes passed in the request.
11
+ OutboundListing = Structure.new do
12
+ # @return [String] TA token that is used to retrieve the next page of results. The response includes `nextToken`
13
+ # when the number of results exceeds the specified `maxResults` value. To get the next page of results, call
14
+ # the operation with this token and include the same arguments as the call that produced the token. To get a
15
+ # complete list, call this operation until `nextToken` is null. Note that this operation can return empty
16
+ # pages.
17
+ attribute?(:next_token, String, from: "nextToken")
18
+
19
+ # @return [Array<OutboundOrder>] List of outbound orders.
20
+ attribute?(:outbound_orders, [OutboundOrder], from: "outboundOrders")
21
+ end
22
+ end
23
+ end
24
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+ require "time"
7
+
8
+ module Peddler
9
+ module APIs
10
+ class AmazonWarehousingAndDistribution20240509
11
+ # Represents an AWD outbound order.
12
+ OutboundOrder = Structure.new do
13
+ # @return [String] Order ID for the outbound order.
14
+ attribute(:order_id, String, null: false, from: "orderId")
15
+
16
+ # @return [String] Status for the outbound order.
17
+ attribute(:order_status, String, null: false, from: "orderStatus")
18
+
19
+ # @return [Array<OutboundShipment>] List of outbound shipments that are part of this order.
20
+ attribute(:outbound_shipments, [OutboundShipment], null: false, from: "outboundShipments")
21
+
22
+ # @return [Time] Date on which this outbound order was confirmed.
23
+ attribute?(:confirmed_on, Time, from: "confirmedOn")
24
+
25
+ # @return [Time] Date on which this outbound order was created.
26
+ attribute?(:created_at, Time, from: "createdAt")
27
+
28
+ # @return [Array<DistributionPackageQuantity>] List of packages that are eligible for outbound.
29
+ attribute?(:eligible_packages_to_outbound, [DistributionPackageQuantity], from: "eligiblePackagesToOutbound")
30
+
31
+ # @return [Array<ProductQuantity>] List of product units that are eligible for outbound.
32
+ attribute?(:eligible_products_to_outbound, [ProductQuantity], from: "eligibleProductsToOutbound")
33
+
34
+ # @return [Array<OutboundExecutionError>] Execution errors associated with the outbound order. This field will
35
+ # be populated if the order failed validation.
36
+ attribute?(:execution_errors, [OutboundExecutionError], from: "executionErrors")
37
+
38
+ # @return [Array<OrderAttribute>] Order preferences for this outbound order.
39
+ attribute?(:order_preferences, [OrderAttribute], from: "orderPreferences")
40
+
41
+ # @return [Array<DistributionPackageQuantity>] List of packages to be outbound.
42
+ attribute?(:packages_to_outbound, [DistributionPackageQuantity], from: "packagesToOutbound")
43
+
44
+ # @return [Array<ProductQuantity>] List of product units to be outbound.
45
+ attribute?(:products_to_outbound, [ProductQuantity], from: "productsToOutbound")
46
+
47
+ # @return [Array<DistributionPackageQuantity>] Outbound packages that are shipped after the execution has
48
+ # completed post confirmation.
49
+ attribute?(:shipped_outbound_packages, [DistributionPackageQuantity], from: "shippedOutboundPackages")
50
+
51
+ # @return [Array<ProductQuantity>] Outbound product units that are shipped after the execution has completed
52
+ # post confirmation.
53
+ attribute?(:shipped_outbound_products, [ProductQuantity], from: "shippedOutboundProducts")
54
+
55
+ # @return [Time] Date on which this outbound order was last updated.
56
+ attribute?(:updated_at, Time, from: "updatedAt")
57
+ end
58
+ end
59
+ end
60
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+
7
+ module Peddler
8
+ module APIs
9
+ class AmazonWarehousingAndDistribution20240509
10
+ # Payload for creating an outbound order.
11
+ OutboundOrderCreationData = Structure.new do
12
+ # @return [Array<OrderAttribute>] Order preferences for the outbound order.
13
+ attribute?(:order_preferences, [OrderAttribute], from: "orderPreferences")
14
+
15
+ # @return [Array<DistributionPackageQuantity>] List of packages to be outbound.
16
+ attribute?(:packages_to_outbound, [DistributionPackageQuantity], from: "packagesToOutbound")
17
+
18
+ # @return [Array<ProductQuantity>] List of product units to be outbound.
19
+ attribute?(:products_to_outbound, [ProductQuantity], from: "productsToOutbound")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,18 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+
7
+ module Peddler
8
+ module APIs
9
+ class AmazonWarehousingAndDistribution20240509
10
+ # A response that contains the reference identifier for the newly created or updated outbound order. This includes
11
+ # an order ID.
12
+ OutboundOrderReference = Structure.new do
13
+ # @return [String] outbound order ID.
14
+ attribute(:order_id, String, null: false, from: "orderId")
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,43 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+ require "time"
7
+
8
+ module Peddler
9
+ module APIs
10
+ class AmazonWarehousingAndDistribution20240509
11
+ # Represents an AWD outbound shipment.
12
+ OutboundShipment = Structure.new do
13
+ # @return [Address] Destination address for this shipment.
14
+ attribute(:destination_address, Address, null: false, from: "destinationAddress")
15
+
16
+ # @return [String] Outbound order ID this outbound shipment belongs to.
17
+ attribute(:order_id, String, null: false, from: "orderId")
18
+
19
+ # @return [Address] Origin address for this shipment.
20
+ attribute(:origin_address, Address, null: false, from: "originAddress")
21
+
22
+ # @return [String] Unique shipment ID.
23
+ attribute(:shipment_id, String, null: false, from: "shipmentId")
24
+
25
+ # @return [String] Current status of this shipment.
26
+ attribute(:shipment_status, String, null: false, from: "shipmentStatus")
27
+
28
+ # @return [Time] Timestamp when the shipment was created.
29
+ attribute?(:created_at, Time, from: "createdAt")
30
+
31
+ # @return [Array<DistributionPackageQuantity>] Specific distribution packages that are included in the context
32
+ # of this shipment.
33
+ attribute?(:shipment_package_quantities, [DistributionPackageQuantity], from: "shipmentPackageQuantities")
34
+
35
+ # @return [Array<ProductQuantity>] Specific product units that are included in the context of this shipment.
36
+ attribute?(:shipment_product_quantities, [ProductQuantity], from: "shipmentProductQuantities")
37
+
38
+ # @return [Time] Timestamp when the shipment was updated.
39
+ attribute?(:updated_at, Time, from: "updatedAt")
40
+ end
41
+ end
42
+ end
43
+ end
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+
7
+ module Peddler
8
+ module APIs
9
+ class AmazonWarehousingAndDistribution20240509
10
+ # Shipment label page types.
11
+ ShipmentLabelPageTypes = Structure.new do
12
+ # @return [String] Status of label page types.
13
+ attribute(:label_status, String, null: false, from: "labelStatus")
14
+
15
+ # @return [Array<PageType>] List of available page types.
16
+ attribute?(:page_types, Array, from: "pageTypes")
17
+ end
18
+ end
19
+ end
20
+ end
@@ -108,6 +108,19 @@ module Peddler
108
108
  get(path, params:, rate_limit:, parser:)
109
109
  end
110
110
 
111
+ # Retrieves the available label page types for a shipment ID that you specify. This is an asynchronous operation.
112
+ # If the label status is `GENERATED`, then the pageTypes are available.
113
+ #
114
+ # @note This operation can make a static sandbox call.
115
+ # @param shipment_id [String] ID for the shipment.
116
+ # @param rate_limit [Float] Requests per second
117
+ # @return [Peddler::Response] The API response
118
+ def get_label_page_types(shipment_id, rate_limit: 1.0)
119
+ path = "/awd/2024-05-09/inboundShipments/#{percent_encode(shipment_id)}/labelPageTypes"
120
+ parser = -> { ShipmentLabelPageTypes }
121
+ get(path, rate_limit:, parser:)
122
+ end
123
+
111
124
  # Updates transport details for an AWD shipment.
112
125
  #
113
126
  # @note This operation can make a static sandbox call.
@@ -197,6 +210,93 @@ module Peddler
197
210
  get(path, params:, rate_limit:, parser:)
198
211
  end
199
212
 
213
+ # Retrieves all outbound AWD orders (with optional filters) that pertain to a merchant. By default, orders are
214
+ # sorted by the `updatedAt` attribute in descending order.
215
+ #
216
+ # @note This operation can make a static sandbox call.
217
+ # @param updated_after [String] Get the outbound orders updated after a certain time (inclusive). The date must be
218
+ # in {https://developer-docs.amazon.com/sp-api/docs/iso-8601 ISO 8601} format.
219
+ # @param updated_before [String] Get the outbound orders updated before a certain time (inclusive). The date must
220
+ # be in {https://developer-docs.amazon.com/sp-api/docs/iso-8601 ISO 8601} format.
221
+ # @param sort_order [String] Sort the response in `ASCENDING` or `DESCENDING` order.
222
+ # @param max_results [Integer] Maximum number of results to return.
223
+ # @param next_token [String] A token that is used to retrieve the next page of results. The response includes
224
+ # `nextToken` when the number of results exceeds the specified `maxResults` value. To get the next page of
225
+ # results, call the operation with this token and include the same arguments as the call that produced the
226
+ # token. To get a complete list, call this operation until `nextToken` is null. Note that this operation can
227
+ # return empty pages.
228
+ # @param rate_limit [Float] Requests per second
229
+ # @return [Peddler::Response] The API response
230
+ def list_outbounds(updated_after: nil, updated_before: nil, sort_order: nil, max_results: 25, next_token: nil,
231
+ rate_limit: 1.0)
232
+ path = "/awd/2024-05-09/outboundOrders"
233
+ params = {
234
+ "updatedAfter" => updated_after,
235
+ "updatedBefore" => updated_before,
236
+ "sortOrder" => sort_order,
237
+ "maxResults" => max_results,
238
+ "nextToken" => next_token,
239
+ }.compact
240
+ parser = -> { OutboundListing }
241
+ get(path, params:, rate_limit:, parser:)
242
+ end
243
+
244
+ # Creates a draft AWD outbound order with the specified products. The API returns the order ID for the newly
245
+ # created order and starts an async validation check on the outbound products. After the validation check, the
246
+ # order status transitions from `VALIDATING` to `ELIGIBLE/INELIGIBLE`.
247
+ #
248
+ # @note This operation can make a static sandbox call.
249
+ # @param body [Hash] Payload for creating an outbound order.
250
+ # @param rate_limit [Float] Requests per second
251
+ # @return [Peddler::Response] The API response
252
+ def create_outbound(body, rate_limit: 1.0)
253
+ path = "/awd/2024-05-09/outboundOrders"
254
+ parser = -> { OutboundOrderReference }
255
+ post(path, body:, rate_limit:, parser:)
256
+ end
257
+
258
+ # Retrieves an AWD outbound order with a set of shipments that contain items that are outbound into a destination
259
+ # channel. If the order is not eligible, the validation errors field is included in the order response. The API
260
+ # returns the order ID for the newly created order and starts an async validation check on the outbound products.
261
+ # After the validation check, the order status transitions from `VALIDATING` to `ELIGIBLE/INELIGIBLE`.
262
+ #
263
+ # @note This operation can make a static sandbox call.
264
+ # @param order_id [String] ID for the outbound order to be retrieved.
265
+ # @param rate_limit [Float] Requests per second
266
+ # @return [Peddler::Response] The API response
267
+ def get_outbound(order_id, rate_limit: 1.0)
268
+ path = "/awd/2024-05-09/outboundOrders/#{percent_encode(order_id)}"
269
+ parser = -> { OutboundOrder }
270
+ get(path, rate_limit:, parser:)
271
+ end
272
+
273
+ # Updates an AWD outbound order that is in `DRAFT`, `ELIGIBLE`, or `INELIGIBLE` status. This API allows updates on
274
+ # `productsToOutbound` and `orderPreferences` attributes only. Any updates will restart the outbound order
275
+ # validation.
276
+ #
277
+ # @note This operation can make a static sandbox call.
278
+ # @param order_id [String] ID for the outbound order to be updated.
279
+ # @param body [Hash] Represents an AWD outbound order.
280
+ # @param rate_limit [Float] Requests per second
281
+ # @return [Peddler::Response] The API response
282
+ def update_outbound(order_id, body, rate_limit: 1.0)
283
+ path = "/awd/2024-05-09/outboundOrders/#{percent_encode(order_id)}"
284
+ parser = -> { OutboundOrderReference }
285
+ put(path, body:, rate_limit:, parser:)
286
+ end
287
+
288
+ # Confirms an AWD outbound order for a set of shipments that contain items that must be outbound to a destination
289
+ # node. You can confirm the order only if it's in an`ELIGIBLE` state.
290
+ #
291
+ # @note This operation can make a static sandbox call.
292
+ # @param order_id [String] ID for the outbound order you want to confirm.
293
+ # @param rate_limit [Float] Requests per second
294
+ # @return [Peddler::Response] The API response
295
+ def confirm_outbound(order_id, rate_limit: 1.0)
296
+ path = "/awd/2024-05-09/outboundOrders/#{percent_encode(order_id)}/confirmation"
297
+ post(path, rate_limit:)
298
+ end
299
+
200
300
  # Retrieves all the AWD replenishment orders pertaining to a merchant with optional filters.
201
301
  # API by default will sort orders by updatedAt attribute in descending order.
202
302
  #
@@ -40,7 +40,10 @@ module Peddler
40
40
  # @return [String] The email address of the contact associated with the address.
41
41
  attribute?(:email, String)
42
42
 
43
- # @return [String] The municiplaity where the person, business, or institution is located.
43
+ # @return [Geocodes] The geographic coordinates of the address.
44
+ attribute?(:geocodes, Geocodes)
45
+
46
+ # @return [String] The municipality where the person, business, or institution is located.
44
47
  attribute?(:municipality, String)
45
48
 
46
49
  # @return [String] The name of the person, business or institution at that address.
@@ -0,0 +1,20 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+
7
+ module Peddler
8
+ module APIs
9
+ class ExternalFulfillmentShipments20240911
10
+ # A distance measurement.
11
+ Distance = Structure.new do
12
+ # @return [String] The unit of measurement of the distance.
13
+ attribute(:distance_unit, String, null: false, from: "distanceUnit")
14
+
15
+ # @return [String] The numerical value of the distance.
16
+ attribute(:value, String, null: false)
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+
7
+ module Peddler
8
+ module APIs
9
+ class ExternalFulfillmentShipments20240911
10
+ # Geographic coordinates.
11
+ Geocodes = Structure.new do
12
+ # @return [String] The latitude coordinate.
13
+ attribute(:latitude, String, null: false)
14
+
15
+ # @return [String] The longitude coordinate.
16
+ attribute(:longitude, String, null: false)
17
+
18
+ # @return [String] The elevation in meters.
19
+ attribute?(:elevation, String)
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ # frozen_string_literal: true
2
+
3
+ # This file is generated. Do not edit.
4
+
5
+ require "structure"
6
+
7
+ module Peddler
8
+ module APIs
9
+ class ExternalFulfillmentShipments20240911
10
+ # The drop-off location details for package handover.
11
+ HandoverLocation = Structure.new do
12
+ # @return [Address] The address of the drop-off location.
13
+ attribute?(:address, Address)
14
+
15
+ # @return [Distance] The distance from the seller's location to the drop-off point.
16
+ attribute?(:distance, Distance)
17
+
18
+ # @return [String] URL to the map that shows the drop-off location.
19
+ attribute?(:map_url, String, from: "mapUrl")
20
+ end
21
+ end
22
+ end
23
+ end
@@ -16,6 +16,10 @@ module Peddler
16
16
  # @return [String] The tracking number of the package.
17
17
  attribute(:tracking_id, String, null: false, from: "trackingId")
18
18
 
19
+ # @return [HandoverLocation] The drop-off location details. This value is populated when `handoverMethod` is
20
+ # `DROPOFF`.
21
+ attribute?(:handover_location, HandoverLocation, from: "handoverLocation")
22
+
19
23
  # @return [TimeWindow] The time window during which the package was picked up.
20
24
  attribute?(:pickup_window, TimeWindow, from: "pickupWindow")
21
25