@@ -127,6 +127,121 @@ protected static function get_client() {
127
127
return self ::$ amazonpay_client ;
128
128
}
129
129
130
+ /**
131
+ * Location type detection.
132
+ *
133
+ * @param object $location Location to check.
134
+ * @return boolean
135
+ */
136
+ private static function location_is_continent ( $ location ) {
137
+ return 'continent ' === $ location ->type ;
138
+ }
139
+
140
+ /**
141
+ * Location type detection.
142
+ *
143
+ * @param object $location Location to check.
144
+ * @return boolean
145
+ */
146
+ private static function location_is_country ( $ location ) {
147
+ return 'country ' === $ location ->type ;
148
+ }
149
+
150
+ /**
151
+ * Location type detection.
152
+ *
153
+ * @param object $location Location to check.
154
+ * @return boolean
155
+ */
156
+ private static function location_is_state ( $ location ) {
157
+ return 'state ' === $ location ->type ;
158
+ }
159
+
160
+ /**
161
+ * Location type detection.
162
+ *
163
+ * @param object $location Location to check.
164
+ * @return boolean
165
+ */
166
+ private static function location_is_postcode ( $ location ) {
167
+ return 'postcode ' === $ location ->type ;
168
+ }
169
+
170
+ protected static function get_shipping_restrictions () {
171
+ $ data_store = WC_Data_Store::load ( 'shipping-zone ' );
172
+ $ raw_zones = $ data_store ->get_zones ();
173
+ $ zones = array ();
174
+
175
+ $ all_continents = WC ()->countries ->get_continents ();
176
+ $ all_countries = WC ()->countries ->get_countries ();
177
+ $ all_states = WC ()->countries ->get_states ();
178
+
179
+ $ row_zone = new WC_Shipping_Zone ( 0 );
180
+ $ methods = $ row_zone ->get_shipping_methods ( true , 'json ' );
181
+ if ( ! empty ( $ methods ) ) {
182
+ // Rest of the World has shipping methods, so we can assume we can ship to all shipping countries
183
+ // Skip the whole thing
184
+ $ countries = WC ()->countries ->get_shipping_countries ();
185
+ if ( count ( $ countries ) !== count ( $ all_countries ) ) {
186
+ foreach ( $ countries as $ country => $ name ) {
187
+ $ zones [ $ country ] = new stdClass (); // If we use an empty array it'll be treated as an array in JSON
188
+ }
189
+ return $ zones ;
190
+ } else {
191
+ return false ; // No restrictions
192
+ }
193
+ }
194
+
195
+ foreach ( $ raw_zones as $ raw_zone ) {
196
+ $ zone = new WC_Shipping_Zone ( $ raw_zone );
197
+ $ methods = $ zone ->get_shipping_methods ( true , 'json ' );
198
+ if ( empty ( $ methods ) ) {
199
+ continue ; // If no shipping methods, we assume no support on this region
200
+ }
201
+
202
+ $ locations = $ zone ->get_zone_locations ( 'json ' );
203
+ $ continents = array_filter ( $ locations , array ( __CLASS__ , 'location_is_continent ' ) );
204
+ $ countries = array_filter ( $ locations , array ( __CLASS__ , 'location_is_country ' ) );
205
+ $ states = array_filter ( $ locations , array ( __CLASS__ , 'location_is_state ' ) );
206
+ $ postcodes = array_filter ( $ locations , array ( __CLASS__ , 'location_is_postcode ' ) ); // HARD TODO: Postcode wildcards can't be implemented afaik
207
+
208
+ foreach ( $ continents as $ location ) {
209
+ foreach ( $ all_continents [ $ location ->code ]['countries ' ] as $ country ) {
210
+ if ( ! isset ( $ zones [ $ country ] ) ) {
211
+ $ zones [ $ country ] = new stdClass (); // If we use an empty array it'll be treated as an array in JSON
212
+ }
213
+ }
214
+ }
215
+
216
+ foreach ( $ countries as $ location ) {
217
+ $ country = $ location ->code ;
218
+ if ( ! isset ( $ zones [ $ country ] ) ) {
219
+ $ zones [ $ country ] = new stdClass (); // If we use an empty array it'll be treated as an array in JSON
220
+ }
221
+ }
222
+
223
+ foreach ( $ states as $ location ) {
224
+ $ location_codes = explode ( ': ' , $ location ->code );
225
+ $ country = strtoupper ( $ location_codes [0 ] );
226
+ $ state = $ location_codes [1 ];
227
+ if ( ! isset ( $ zones [ $ country ] ) ) {
228
+ $ zones [ $ country ] = new stdClass (); // If we use an empty array it'll be treated as an array in JSON
229
+ }
230
+
231
+ if ( ! isset ( $ zones [ $ country ]->statesOrRegions ) ) {
232
+ $ zones [ $ country ]->statesOrRegions = array ();
233
+ }
234
+
235
+ $ zones [ $ country ]->statesOrRegions [] = $ state ;
236
+ if ( 'US ' !== $ country ) {
237
+ $ zones [ $ country ]->statesOrRegions [] = $ all_states [ $ country ][ $ state ];
238
+ }
239
+ }
240
+ }
241
+
242
+ return $ zones ;
243
+ }
244
+
130
245
protected static function create_checkout_session_params ( $ redirect_url = null ) {
131
246
132
247
$ settings = self ::get_settings ();
@@ -142,7 +257,17 @@ protected static function create_checkout_session_params( $redirect_url = null )
142
257
),
143
258
);
144
259
145
- $ payload = wp_json_encode ( $ payload , JSON_UNESCAPED_SLASHES );
260
+ $ restrictions = self ::get_shipping_restrictions ();
261
+ if ( $ restrictions ) {
262
+ $ payload ['deliverySpecifications ' ] = array (
263
+ 'addressRestrictions ' => array (
264
+ 'type ' => 'Allowed ' ,
265
+ 'restrictions ' => $ restrictions ,
266
+ ),
267
+ );
268
+ }
269
+
270
+ $ payload = wp_json_encode ( $ payload , JSON_UNESCAPED_SLASHES | JSON_UNESCAPED_UNICODE );
146
271
147
272
return $ payload ;
148
273
0 commit comments