//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)) }
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 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) }
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}) }