Skip to content

Commit f08367c

Browse files
committed
implemented ShippingOptions function
1 parent d25bea7 commit f08367c

File tree

2 files changed

+127
-3
lines changed

2 files changed

+127
-3
lines changed

shopify/shopify.go

Lines changed: 107 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,14 @@ package shopify
33
import (
44
"bytes"
55
"encoding/json"
6+
"errors"
67
"fmt"
78
"log"
89
"net/http"
10+
"net/http/cookiejar"
11+
"net/url"
912
"strconv"
13+
"strings"
1014
"time"
1115
)
1216

@@ -117,9 +121,108 @@ func (shopifyClient *Shopify) PlaceOrder(order OrderResponse) Order {
117121
return shopifyResponse.SingleOrder
118122
}
119123

124+
// ShippingOptions returns shipping options and rates for a given shipping address
125+
func (shopifyClient *Shopify) ShippingOptions(order Order) ([]ShippingRate, error) {
126+
127+
var itemsInfo []string
128+
129+
cartURLStr := "cart/"
130+
131+
// Create CART
132+
for _, itemObj := range order.Items {
133+
itemsInfo = append(itemsInfo, fmt.Sprintf("%d:%d", itemObj.VariantID, itemObj.Quantity))
134+
}
135+
136+
itemsInCartURLStr := cartURLStr + strings.Join(itemsInfo, ",")
137+
138+
completeURL := fmt.Sprintf("https://%s%s%s", shopifyClient.shopifyDomain, baseURLString, itemsInCartURLStr)
139+
log.Printf("[ShippingOptions] - Request URL: %s", completeURL)
140+
cookieJar, _ := cookiejar.New(nil)
141+
142+
client := &http.Client{
143+
Jar: cookieJar,
144+
}
145+
146+
r, err := http.NewRequest("GET", completeURL, nil)
147+
resp, err := client.Do(r)
148+
149+
defer resp.Body.Close()
150+
151+
if resp.StatusCode == http.StatusNotFound {
152+
fmt.Printf("[ShippingOptions] - 404 on executing request: %s", completeURL)
153+
} else if resp.StatusCode == 429 {
154+
fmt.Printf("[ShippingOptions] - Rate limited!")
155+
}
156+
if err != nil {
157+
fmt.Printf("[ShippingOptions] - Error executing request : %s", err)
158+
}
159+
160+
// GET shipping Options given the cart (cookies used)
161+
address := order.ShippingAddress
162+
163+
urlStr := cartURLStr + "shipping_rates.json?"
164+
165+
v := url.Values{}
166+
v.Set("shipping_address[zip]", address.PostalCode)
167+
v.Add("shipping_address[country]", address.CountryCode)
168+
v.Add("shipping_address[province]", address.State)
169+
v.Encode()
170+
171+
urlStr = urlStr + v.Encode()
172+
173+
completeURL = fmt.Sprintf("https://%s%s%s", shopifyClient.shopifyDomain, baseURLString, urlStr)
174+
log.Printf("\n\n[ShippingOptions] - Request URL: %s", completeURL)
175+
176+
r, err = http.NewRequest("GET", completeURL, nil)
177+
178+
resp, err = client.Do(r)
179+
180+
defer resp.Body.Close()
181+
182+
if resp.StatusCode == http.StatusNotFound {
183+
fmt.Printf("[ShippingOptions] - 404 on executing request: %s", completeURL)
184+
} else if resp.StatusCode == 429 {
185+
fmt.Printf("[ShippingOptions] - Rate limited!")
186+
}
187+
if err != nil {
188+
fmt.Printf("[ShippingOptions] - Error executing request : %s", err)
189+
}
190+
191+
//bodyResp, _ := ioutil.ReadAll(resp.Body)
192+
//fmt.Printf("\n\n *****RESPONSE: %#v\n", string(bodyResp))
193+
var shopifyResponse = new(ShippingRatesResponse)
194+
err = json.NewDecoder(resp.Body).Decode(shopifyResponse)
195+
196+
if err != nil {
197+
fmt.Printf("\n[ShippingOptions] - Decoding error: %#v", err)
198+
fmt.Printf("\n[ShippingOptions] - Response: %#v", resp.Body)
199+
}
200+
201+
// Address not supported error handling
202+
if shopifyResponse.Country != nil || shopifyResponse.Zip != nil || shopifyResponse.Province != nil {
203+
var errorsArray []string
204+
errorMessageStr := "Address Not supported: "
205+
206+
if shopifyResponse.Country != nil {
207+
errorsArray = append(errorsArray, address.CountryCode+" "+shopifyResponse.Country[0])
208+
}
209+
if shopifyResponse.Zip != nil {
210+
errorsArray = append(errorsArray, address.PostalCode+" "+shopifyResponse.Zip[0])
211+
}
212+
if shopifyResponse.Province != nil {
213+
errorsArray = append(errorsArray, address.State+" "+shopifyResponse.Province[0])
214+
}
215+
errorMessageStr = errorMessageStr + strings.Join(errorsArray, ", ")
216+
addressNotSupported := errors.New(errorMessageStr)
217+
return shopifyResponse.ShippingRates, addressNotSupported
218+
}
219+
220+
return shopifyResponse.ShippingRates, nil
221+
}
222+
120223
func (shopifyClient *Shopify) makeRequest(method string, urlStr string, body interface{}, payload string) {
121224
url := fmt.Sprintf("https://%s%s%s", shopifyClient.shopifyDomain, baseURLString, urlStr)
122-
log.Printf("[makeRequest] - Request URL: %s", url)
225+
log.Printf("\n\n[makeRequest] - Request URL: %s", url)
123226
client := &http.Client{}
124227
buf := new(bytes.Buffer)
125228

@@ -133,6 +236,7 @@ func (shopifyClient *Shopify) makeRequest(method string, urlStr string, body int
133236
r.Header.Add("X-Shopify-Access-Token", shopifyClient.shopifySecretToken)
134237

135238
resp, err := client.Do(r)
239+
136240
defer resp.Body.Close()
137241
if resp.StatusCode == http.StatusNotFound {
138242
fmt.Printf("[makeRequest] - 404 on executing request: %s", url)
@@ -143,8 +247,8 @@ func (shopifyClient *Shopify) makeRequest(method string, urlStr string, body int
143247
fmt.Printf("[makeRequest] - Error executing request : %s", err)
144248
}
145249

146-
// bodyResp, _ := ioutil.ReadAll(resp.Body)
147-
// fmt.Printf("\n\nRESPONSE BODY: %#v", string(bodyResp))
250+
//bodyResp, _ := ioutil.ReadAll(resp.Body)
251+
//fmt.Printf("\n\n *****RESPONSE: %#v\n", string(bodyResp))
148252

149253
err = json.NewDecoder(resp.Body).Decode(body)
150254

shopify/shopifyorder.go

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -272,3 +272,23 @@ type Order struct {
272272
type OrderResponse struct {
273273
SingleOrder Order `json:"order"`
274274
}
275+
276+
// ShippingRate models the shopify ShippingRate object
277+
type ShippingRate struct {
278+
Name string `json:"name"`
279+
Code string `json:"code"`
280+
Price string `json:"price"`
281+
Source string `json:"source"`
282+
DeliveryDate string `json:"delivery_date"`
283+
DeliveryRange []string `json:"delivery_range"`
284+
DeliveryDays []int `json:"delivery_days"`
285+
}
286+
287+
// ShippingRatesResponse models the shopify ShippingRates array
288+
type ShippingRatesResponse struct {
289+
ShippingRates []ShippingRate `json:"shipping_rates"`
290+
// Fields For Error cases responses:
291+
Zip []string `json:"zip,omitempty"`
292+
Province []string `json:"province,omitempty"`
293+
Country []string `json:"country,omitempty"`
294+
}

0 commit comments

Comments
 (0)