Browse Source

fix: correct OAuth 1.0a signature generation for WooCommerce API #24

- Include URL query parameters in OAuth signature calculation
- Separate base URL from query params before signature generation
- Combine oauth params and query params for signature
- Fixes 'Invalid signature' error (401) from WooCommerce REST API
Claude 5 months ago
parent
commit
f24d0c11ff
1 changed files with 19 additions and 5 deletions
  1. 19 5
      supabase/functions/_shared/woocommerce-client.ts

+ 19 - 5
supabase/functions/_shared/woocommerce-client.ts

@@ -147,8 +147,18 @@ export async function wooCommerceApiRequest(
     throw new Error('WooCommerce credentials not found')
   }
 
-  // Build API URL
-  const apiUrl = `${store.store_url}/wp-json/wc/v3${endpoint}`
+  // Build full API URL with query parameters
+  const fullApiUrl = `${store.store_url}/wp-json/wc/v3${endpoint}`
+
+  // Parse URL to separate base URL and query parameters
+  const urlObj = new URL(fullApiUrl)
+  const baseUrl = `${urlObj.origin}${urlObj.pathname}`
+
+  // Extract query parameters from URL
+  const queryParams: Record<string, string> = {}
+  urlObj.searchParams.forEach((value, key) => {
+    queryParams[key] = value
+  })
 
   // Generate OAuth parameters
   const oauthParams: Record<string, string> = {
@@ -158,8 +168,11 @@ export async function wooCommerceApiRequest(
     oauth_signature_method: 'HMAC-SHA256'
   }
 
-  // Generate signature
-  const signature = generateOAuthSignature(method, apiUrl, oauthParams, store.api_secret)
+  // Combine OAuth params and query params for signature generation
+  const allParams = { ...oauthParams, ...queryParams }
+
+  // Generate signature using base URL (without query params) and all parameters
+  const signature = generateOAuthSignature(method, baseUrl, allParams, store.api_secret)
   oauthParams.oauth_signature = signature
 
   // Build authorization header
@@ -182,7 +195,8 @@ export async function wooCommerceApiRequest(
   }
 
   try {
-    const response = await fetch(apiUrl, options)
+    // Use the full URL with query parameters
+    const response = await fetch(fullApiUrl, options)
 
     if (!response.ok) {
       const errorText = await response.text()