mini-beieli-web/stripe.go

126 lines
4.0 KiB
Go

package main
import (
"encoding/json"
"fmt"
"github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/paymentintent"
"io/ioutil"
"log"
"net/http"
"os"
"strconv"
"strings"
)
func getStripeKey() string {
return "sk_test_GJbXPD0IAFNvvGpNEpaeDfhl"
}
func getstripepaymentintentHandler(response http.ResponseWriter, request *http.Request) {
name := getUserName(request)
if name != "" {
charge_data, ok := request.URL.Query()["charge_data"]
if !ok || len(charge_data[0]) < 1 {
log.Println("Url Param 'charge_data' is missing")
fmt.Fprintf(response, "{ \"rc\": 1, \"msg\": \"charge_data must be specified in URL\" }")
return
}
scales := strings.Split(charge_data[0], ",")
var abo_years = 0
var items []string
for _, scale := range scales {
items = strings.Split(scale, ":")
if len(items) == 2 {
abo_count, err := strconv.Atoi(items[1])
if err == nil {
abo_years += abo_count
}
}
}
abo_amount := int64(abo_years * 2400)
stripe.Key = getStripeKey()
params := &stripe.PaymentIntentParams{
Amount: stripe.Int64(abo_amount),
Currency: stripe.String(string(stripe.CurrencyCHF)),
ReceiptEmail: stripe.String(name),
}
params.AddMetadata("charge_data", charge_data[0])
paymentintent, err := paymentintent.New(params)
if err != nil {
fmt.Fprintf(response, "{ \"rc\": 5, \"stripeclientsecret\": \"%s\" }\n", err)
} else {
fmt.Fprintf(response, "{ \"rc\": 0, \"stripeclientsecret\": \"%s\" }\n", paymentintent.ClientSecret)
}
} else {
fmt.Fprintf(response, "{ \"rc\": 6, \"msg\": \"Only available for logged in users\" }")
}
}
func HandlePayment(user string, charge_data string, amount int64) {
fmt.Printf("HandlePayment for %s (charge_data: %s, amount: %d)!\n", user, charge_data, amount)
charge_data_email_text := fmt.Sprintf("%-30s %20s %10s\n", "Alias", "verlängern bis", "Betrag")
charge_data_email_text = charge_data_email_text + strings.Repeat("-", 62) + "\n"
for _, token := range strings.Split(charge_data, ",") {
res := strings.Split(token, ":")
if (len(res)) == 2 {
deveui := res[0]
years, _ := strconv.Atoi(res[1])
fmt.Printf("prolongActivation %s: %d\n", deveui, years)
prolongActivation(deveui, years)
line := fmt.Sprintf("%-30s %20s %10.2f\n", getDevAlias(deveui), getActiveUntil(deveui), float64(24*years))
charge_data_email_text = charge_data_email_text + line
}
}
charge_data_email_text = charge_data_email_text + strings.Repeat("-", 62) + "\n"
charge_data_email_text = charge_data_email_text + fmt.Sprintf("%-30s %20s %10.2f\n", "Total CHF", "", float64(amount/100))
sendPaymentConfirmationEmail(user, charge_data_email_text, amount)
}
func stripeWebhookHandler(w http.ResponseWriter, req *http.Request) {
const MaxBodyBytes = int64(65536)
req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes)
payload, err := ioutil.ReadAll(req.Body)
if err != nil {
fmt.Fprintf(os.Stderr, "Error reading request body: %v\n", err)
w.WriteHeader(http.StatusServiceUnavailable)
return
}
event := stripe.Event{}
if err := json.Unmarshal(payload, &event); err != nil {
fmt.Fprintf(os.Stderr, "Failed to parse webhook body json: %v\n", err.Error())
w.WriteHeader(http.StatusBadRequest)
return
}
// Unmarshal the event data into an appropriate struct depending on its Type
switch event.Type {
case "payment_intent.succeeded":
var paymentIntent stripe.PaymentIntent
err := json.Unmarshal(event.Data.Raw, &paymentIntent)
if err != nil {
fmt.Fprintf(os.Stderr, "Error parsing webhook JSON: %v\n", err)
w.WriteHeader(http.StatusBadRequest)
return
}
fmt.Printf("PaymentIntent was successful (charge_data: %s, amount: %d)!\n", paymentIntent.Metadata["charge_data"], paymentIntent.Amount)
HandlePayment(paymentIntent.ReceiptEmail, paymentIntent.Metadata["charge_data"], paymentIntent.Amount)
// ... handle other event types
default:
fmt.Fprintf(os.Stderr, "Unexpected event type: %s\n", event.Type)
w.WriteHeader(http.StatusBadRequest)
return
}
w.WriteHeader(http.StatusOK)
}