Example #1
0
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
}
Example #2
0
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})
}
Example #3
0
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})
}
Example #4
0
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})
}