示例#1
0
func (sp *StripePayment) handle(w http.ResponseWriter, r *http.Request, session *lobster.Session, frameParams lobster.FrameParams) {
	if !lobster.AntifloodCheck(lobster.ExtractIP(r.RemoteAddr), "payment_stripe_handle", 5) {
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormattedError("try_again_later"))
		return
	}
	lobster.AntifloodAction(lobster.ExtractIP(r.RemoteAddr), "payment_stripe_handle")

	stripeToken := r.PostFormValue("stripeToken")
	amount, amountErr := strconv.Atoi(r.PostFormValue("amount"))
	currency := r.PostFormValue("currency")

	if stripeToken == "" || amount <= 0 || amountErr != nil || currency == "" {
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormatError(fmt.Errorf("credit card payment failed due to form submission error")))
		return
	}

	// duplicate amount range check here since user might tamper with the amount in the form
	cfg := lobster.GetConfig()
	if amount < int(cfg.Billing.DepositMinimum*100) || amount > int(cfg.Billing.DepositMaximum*100) {
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormattedErrorf("amount_between", cfg.Billing.DepositMinimum, cfg.Billing.DepositMaximum))
		return
	}

	chargeParams := &stripe.ChargeParams{
		Amount:   uint64(amount),
		Currency: stripe.Currency(currency),
		Source:   &stripe.SourceParams{Token: stripeToken},
		Desc:     "Lobster credit",
	}
	charge, err := sp.client.Charges.New(chargeParams)

	if err != nil {
		emailParams := StripeErrorEmail{
			fmt.Sprintf("error creating charge for user %d", session.UserId),
			err,
		}
		lobster.MailWrap(-1, "stripeError", emailParams, false)
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormatError(fmt.Errorf("credit card payment error; make sure that you have entered your credit card details correctly")))
		return
	} else if !charge.Paid {
		emailParams := StripeErrorEmail{
			fmt.Sprintf("created charge for user %d but paid is false", session.UserId),
			nil,
		}
		lobster.MailWrap(-1, "stripeError", emailParams, false)
		lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.FormatError(fmt.Errorf("credit card payment error; make sure that you have entered your credit card details correctly")))
		return
	}

	transaction := charge.Tx
	lobster.TransactionAdd(
		session.UserId,
		"stripe",
		charge.ID,
		"Stripe payment: "+charge.ID,
		int64(charge.Amount)*lobster.BILLING_PRECISION/100,
		transaction.Fee*lobster.BILLING_PRECISION/100,
	)
	lobster.RedirectMessage(w, r, "/panel/billing", lobster.L.Success("payment_made"))
}
示例#2
0
func ticketOpen(userId int, name string, message string, staff bool) (int, error) {
	if name == "" || message == "" {
		return 0, L.Error("subject_message_empty")
	} else if len(message) > 16384 {
		return 0, L.Errorf("message_too_long", "15,000")
	}

	user := lobster.UserDetails(userId)
	if !staff && (user == nil || user.Status == "new") {
		return 0, L.Errorf("ticket_for_support", cfg.Default.AdminEmail)
	}

	result := db.Exec("INSERT INTO tickets (user_id, name, status, modify_time) VALUES (?, ?, 'open', NOW())", userId, name)
	ticketId := result.LastInsertId()
	db.Exec("INSERT INTO ticket_messages (ticket_id, staff, message) VALUES (?, ?, ?)", ticketId, staff, message)
	if staff {
		lobster.MailWrap(userId, "ticketOpen", TicketUpdateEmail{Id: ticketId, Subject: name, Message: message}, false)
	} else {
		lobster.MailWrap(-1, "ticketOpen", TicketUpdateEmail{Id: ticketId, Subject: name, Message: message}, false)
	}
	log.Printf("Ticket opened for user %d: %s", userId, name)
	return ticketId, nil
}
示例#3
0
func ticketReply(userId int, ticketId int, message string, staff bool) error {
	if message == "" {
		return L.Error("message_empty")
	}

	ticket := TicketDetails(userId, ticketId, staff)
	if ticket == nil {
		return L.Error("invalid_ticket")
	}

	db.Exec("INSERT INTO ticket_messages (ticket_id, staff, message) VALUES (?, ?, ?)", ticketId, staff, message)

	// update ticket status
	newStatus := "open"
	if staff {
		newStatus = "answered"
		lobster.MailWrap(userId, "ticketReply", TicketUpdateEmail{Id: ticketId, Subject: ticket.Name, Message: message}, false)
	} else {
		lobster.MailWrap(-1, "ticketReply", TicketUpdateEmail{Id: ticketId, Subject: ticket.Name, Message: message}, false)
	}
	db.Exec("UPDATE tickets SET modify_time = NOW(), status = ? WHERE id = ?", newStatus, ticketId)
	log.Printf("Ticket reply for user %d on ticket #%d %s", userId, ticketId, ticket.Name)
	return nil
}
示例#4
0
func (this *CoinbasePayment) callback(w http.ResponseWriter, r *http.Request) {
	cfg := lobster.GetConfig()

	requestBytes, err := ioutil.ReadAll(r.Body)
	if err != nil {
		lobster.ReportError(err, "coinbase callback read error", fmt.Sprintf("ip: %s", r.RemoteAddr))
		w.WriteHeader(500)
		return
	}

	var data CoinbaseData
	err = json.Unmarshal(requestBytes, &data)
	if err != nil {
		lobster.ReportError(err, "coinbase callback decoding error", fmt.Sprintf("ip: %s; raw request: %s", r.RemoteAddr, requestBytes))
		w.WriteHeader(400)
		return
	}

	if data.Order.TotalNative.CurrencyIso != cfg.Billing.Currency {
		lobster.ReportError(fmt.Errorf("invalid currency %s", data.Order.TotalNative.CurrencyIso), "coinbase callback error", fmt.Sprintf("ip: %s; raw request: %s", r.RemoteAddr, requestBytes))
		w.WriteHeader(200)
		return
	} else if !strings.HasPrefix(data.Order.Custom, "lobster") {
		lobster.ReportError(fmt.Errorf("invalid payment with custom=%s", data.Order.Custom), "coinbase callback error", fmt.Sprintf("ip: %s; raw request: %s", r.RemoteAddr, requestBytes))
		w.WriteHeader(200)
		return
	}

	userIdStr := strings.Split(data.Order.Custom, "lobster")[1]
	userId, err := strconv.Atoi(userIdStr)
	if err != nil {
		lobster.ReportError(fmt.Errorf("invalid payment with custom=%s", data.Order.Custom), "coinbase callback error", fmt.Sprintf("ip: %s; raw request: %s", r.RemoteAddr, requestBytes))
		w.WriteHeader(200)
		return
	}

	if data.Order.Status == "completed" {
		lobster.TransactionAdd(userId, "coinbase", data.Order.Id, "Bitcoin transaction: "+data.Order.Transaction.Id, int64(data.Order.TotalNative.Cents)*lobster.BILLING_PRECISION/100, 0)
	} else if data.Order.Status == "mispaid" {
		lobster.MailWrap(-1, "coinbaseMispaid", CoinbaseMispaidEmail{OrderId: data.Order.Id}, false)
	}

	w.WriteHeader(200)
}