//createAppendingeStripeClient creates an httpclient on a per-request basis for use in making api calls to Stripe
//stripe's api is accessed via http requests, need a way to make these requests
//urlfetch is the appengine way of making http requests
//this func returns an httpclient *per request* aka per request to this app
//otherwise one request could use another requests httpclient
//this is for app engine only since the golang http.DefaultClient is unavailable
func createAppengineStripeClient(c context.Context) *client.API {
	//create http client
	httpClient := urlfetch.Client(c)

	//returns "sc" stripe client
	return client.New(stripePrivateKey, stripe.NewBackends(httpClient))
}
Beispiel #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})
}
Beispiel #3
0
func OrdersHandler(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	sc := client.New(config.Get(c, "STRIPE_KEY"), stripe.NewBackends(urlfetch.Client(c)))

	lastKey := "or_17fQDrKpn8lOrcLslDTTOnWv"

	r.ParseForm()

	before := r.Form.Get("before")
	if before != "" {
		lastKey = before
	}

	params := &stripe.OrderListParams{
		ListParams: stripe.ListParams{
			Single: true,
			End:    lastKey,
		},
	}

	status := r.Form.Get("status")
	if status != "" && status != "all" {
		params = &stripe.OrderListParams{
			Status: stripe.OrderStatus(status),
			ListParams: stripe.ListParams{
				Single: true,
				End:    lastKey,
			},
		}
	}

	iter := sc.Orders.List(params)

	var response OrdersResponse
	response.Orders = []*ShortOrder{}

	for iter.Next() {
		if iter.Order().Status != stripe.StatusCanceled {
			o := iter.Order()
			response.Orders = append(response.Orders, &ShortOrder{
				ID:       o.ID,
				Created:  o.Created,
				Status:   o.Status,
				Shipping: o.Shipping,
				Customer: o.Customer,
				Meta:     o.Meta,
			})
		}
	}

	web.SendJSON(c, w, response)
}
Beispiel #4
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})
}
Beispiel #5
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})
}