func getSoldCounter(c context.Context) int { var cachedCounter int _, err := memcache.JSON.Get(c, "sold", &cachedCounter) if err == nil { log.Infof(c, "[counter] Cache hit") return cachedCounter } if err != memcache.ErrCacheMiss { log.Infof(c, "[counter] Unexpected error") web.LogError(c, err, "Error accessing counter in memcache") } else { log.Infof(c, "[counter] Cache miss") } sold := new(Counter) key := datastore.NewKey(c, "Counter", "sold", 0, nil) err = datastore.Get(c, key, sold) if err != nil && err != datastore.ErrNoSuchEntity { web.LogError(c, err, "Error reading counter from datastore") return 0 } err = memcache.JSON.Set(c, &memcache.Item{ Key: "sold", Object: &sold.Value, }) if err != nil { web.LogError(c, err, "Error storing counter in memcache") } return sold.Value }
func ShipHandler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) sc := client.New(config.Get(c, "STRIPE_KEY"), stripe.NewBackends(urlfetch.Client(c))) r.ParseForm() orderID := r.Form.Get("orderID") trackingNumber := r.Form.Get("trackingNumber") order, err := sc.Orders.Update(orderID, &stripe.OrderUpdateParams{ Status: stripe.StatusFulfilled, Params: stripe.Params{ Meta: map[string]string{"tracking_number": trackingNumber}, }, }) if err != nil { web.SendError(c, w, err, 500, "Error marking order as fulfilled") return } customer, err := sc.Customers.Get(order.Customer.ID, nil) if err != nil { web.LogError(c, err, "Error fetching customer info for email") } else { err = email.SendShippingNotification(c, customer.Desc, customer.Email, order.Shipping, trackingNumber) if err != nil { web.LogError(c, err, "Error sending shipping notification") } } web.SendJSON(c, w, ChargeResponse{Success: true}) }
func PaymentHandler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) decoder := json.NewDecoder(r.Body) body := new(PaymentRequestBody) err := decoder.Decode(&body) if err != nil { web.SendError(c, w, err, 400, "Could not parse payment information") return } token := body.Token args := body.Args sc := client.New(config.Get(c, "STRIPE_KEY"), stripe.NewBackends(urlfetch.Client(c))) shipping := &stripe.ShippingParams{ Name: args.ShippingName, Address: &stripe.AddressParams{ Line1: args.ShippingAddressLine1, Line2: args.ShippingAddressLine2, City: args.ShippingAddressCity, State: args.ShippingAddressState, PostalCode: args.ShippingAddressZIP, Country: args.ShippingAddressCountry, }, } customer, err := sc.Customers.New(&stripe.CustomerParams{ Email: token.Email, Desc: args.BillingName, Source: &stripe.SourceParams{Token: token.ID}, }) if err != nil { web.SendError(c, w, err, 500, "Error saving customer to Stripe") return } order, err := sc.Orders.New(&stripe.OrderParams{ Currency: "usd", Customer: customer.ID, Shipping: shipping, Items: []*stripe.OrderItemParams{ &stripe.OrderItemParams{ Type: "sku", Parent: "book", }, }, }) if err != nil { web.SendError(c, w, err, 500, "Error saving order to Stripe") return } err = incrementSoldCounter(c) if err != nil { web.LogError(c, err, "Error incrementing sold counter") } err = email.SendReceipt(c, args.BillingName, token.Email, order.Shipping) if err != nil { web.LogError(c, err, "Error sending receipt") } web.SendJSON(c, w, PaymentResponse{Ok: true}) }
func ChargeHandler(w http.ResponseWriter, r *http.Request) { c := appengine.NewContext(r) sc := client.New(config.Get(c, "STRIPE_KEY"), stripe.NewBackends(urlfetch.Client(c))) r.ParseForm() orderID := r.Form.Get("orderID") customerID := r.Form.Get("customerID") _, err := sc.Orders.Pay(orderID, &stripe.OrderPayParams{ Customer: customerID, }) if err != nil { stripeErr := err.(*stripe.Error) web.LogError(c, err, "Error from Stripe") switch stripeErr.Code { case stripe.IncorrectNum: fallthrough case stripe.InvalidNum: fallthrough case stripe.InvalidExpM: fallthrough case stripe.InvalidExpY: fallthrough case stripe.InvalidCvc: fallthrough case stripe.ExpiredCard: fallthrough case stripe.IncorrectCvc: fallthrough case stripe.IncorrectZip: fallthrough case stripe.CardDeclined: customer, err := sc.Customers.Get(customerID, nil) if err != nil { web.SendError(c, w, err, 500, "Error getting customer") return } _, err = sc.Orders.Update(orderID, &stripe.OrderUpdateParams{ Status: stripe.StatusCanceled, }) if err != nil { web.SendError(c, w, err, 500, "Error marking order as cancelled") return } err = email.SendPaymentDeclinedNotification(c, customer.Desc, customer.Email) if err != nil { web.SendError(c, w, err, 500, "Error sending payment declined email") } web.SendJSON(c, w, ChargeResponse{Success: false}) return default: web.SendError(c, w, err, 500, "Error charging card") return } } web.SendJSON(c, w, ChargeResponse{Success: true}) }