diff --git a/customer-spa/src/pages/Checkout/index.tsx b/customer-spa/src/pages/Checkout/index.tsx
index 59a6ace..0f5e103 100644
--- a/customer-spa/src/pages/Checkout/index.tsx
+++ b/customer-spa/src/pages/Checkout/index.tsx
@@ -628,18 +628,27 @@ export default function Checkout() {
value={billingData.country}
onChange={(v) => setBillingData({ ...billingData, country: v })}
placeholder="Select country"
- disabled={countries.length <= 1}
+ disabled={countries.length === 1}
/>
- setBillingData({ ...billingData, state: v })}
- placeholder={billingStateOptions.length ? "Select state" : "N/A"}
- disabled={!billingStateOptions.length}
- />
+ {billingStateOptions.length > 0 ? (
+ setBillingData({ ...billingData, state: v })}
+ placeholder="Select state"
+ />
+ ) : (
+ setBillingData({ ...billingData, state: e.target.value })}
+ placeholder="Enter state/province"
+ className="w-full border rounded-lg px-4 py-2"
+ />
+ )}
@@ -801,18 +810,27 @@ export default function Checkout() {
value={shippingData.country}
onChange={(v) => setShippingData({ ...shippingData, country: v })}
placeholder="Select country"
- disabled={countries.length <= 1}
+ disabled={countries.length === 1}
/>
- setShippingData({ ...shippingData, state: v })}
- placeholder={shippingStateOptions.length ? "Select state" : "N/A"}
- disabled={!shippingStateOptions.length}
- />
+ {shippingStateOptions.length > 0 ? (
+ setShippingData({ ...shippingData, state: v })}
+ placeholder="Select state"
+ />
+ ) : (
+ setShippingData({ ...shippingData, state: e.target.value })}
+ placeholder="Enter state/province"
+ className="w-full border rounded-lg px-4 py-2"
+ />
+ )}
diff --git a/includes/Api/CheckoutController.php b/includes/Api/CheckoutController.php
index 77e0fc8..dfa71ea 100644
--- a/includes/Api/CheckoutController.php
+++ b/includes/Api/CheckoutController.php
@@ -32,6 +32,12 @@ class CheckoutController {
'callback' => [ new self(), 'get_fields' ],
'permission_callback' => [ \WooNooW\Api\Permissions::class, 'anon_or_wp_nonce' ],
]);
+ // Public countries endpoint for customer checkout form
+ register_rest_route($namespace, '/countries', [
+ 'methods' => 'GET',
+ 'callback' => [ new self(), 'get_countries' ],
+ 'permission_callback' => '__return_true', // Public - needed for checkout
+ ]);
// Public order view endpoint for thank you page
register_rest_route($namespace, '/checkout/order/(?P\d+)', [
'methods' => 'GET',
@@ -729,4 +735,42 @@ class CheckoutController {
}
return null;
}
+
+ /**
+ * Get countries and states for checkout form
+ * Public endpoint - no authentication required
+ */
+ public function get_countries(): array {
+ $wc_countries = WC()->countries;
+
+ // Get allowed selling countries
+ $allowed = $wc_countries->get_allowed_countries();
+
+ // Format for frontend
+ $countries = [];
+ foreach ($allowed as $code => $name) {
+ $countries[] = [
+ 'code' => $code,
+ 'name' => $name,
+ ];
+ }
+
+ // Get states for all allowed countries
+ $states = [];
+ foreach (array_keys($allowed) as $country_code) {
+ $country_states = $wc_countries->get_states($country_code);
+ if (!empty($country_states) && is_array($country_states)) {
+ $states[$country_code] = $country_states;
+ }
+ }
+
+ // Get default country
+ $default_country = $wc_countries->get_base_country();
+
+ return [
+ 'countries' => $countries,
+ 'states' => $states,
+ 'default_country' => $default_country,
+ ];
+ }
}
\ No newline at end of file