abo payment logic

This commit is contained in:
Joerg Lehmann 2020-01-17 15:31:00 +01:00
parent 7975741c8a
commit ee61c4c9c0
6 changed files with 118 additions and 6 deletions

34
mail.go
View File

@ -42,3 +42,37 @@ mini-beieli.ch`
log.Fatal(err) log.Fatal(err)
} }
} }
func sendPaymentConfirmationEmail(username,charge_data string, amount int64) {
c, err := smtp.Dial("127.0.0.1:25")
if err != nil {
log.Fatal(err)
}
defer c.Close()
// Set the sender and recipient.
c.Mail("info@mini-beieli.ch")
c.Rcpt(username)
// Send the email body.
wc, err := c.Data()
if err != nil {
log.Fatal(err)
}
defer wc.Close()
mail_message := "To: " + username + `
Subject: Zahlungsbestaetigung mini-beieli.ch
Lieber Benutzer von mini-beieli.ch
Sie haben soeben erfolgreich folgende Abo-Verlaengerungen bezahlt:
` + charge_data + `
Mit freundlichen Grüssen
--
mini-beieli.ch`
buf := bytes.NewBufferString(mail_message)
if _, err = buf.WriteTo(wc); err != nil {
log.Fatal(err)
}
}

View File

@ -59,6 +59,12 @@ func metricsHandler(response http.ResponseWriter, request *http.Request) {
return return
} }
if AboExpired(mydeveui) {
log.Println("specified 'deveui' has an expired abo")
fmt.Fprintf(response, "{ \"msg\": \"specified deveui has an expired abo\" }")
return
}
log.Println("Url Param 'deveui' is: " + string(mydeveui)) log.Println("Url Param 'deveui' is: " + string(mydeveui))
// Format of start and stop: YYYY-MM-DDTHH:MI:SSZ // Format of start and stop: YYYY-MM-DDTHH:MI:SSZ
@ -258,7 +264,7 @@ func lastmetricsHandler(response http.ResponseWriter, request *http.Request) {
func CalcDaysUntil(mydate string) int { func CalcDaysUntil(mydate string) int {
var days int var days int
layout := "01.01.2006" layout := "02.01.2006"
t, err := time.Parse(layout, mydate) t, err := time.Parse(layout, mydate)
if err != nil { if err != nil {

View File

@ -228,6 +228,15 @@ func getActiveUntil(deveui string) string {
return res return res
} }
func AboExpired(deveui string) bool {
active_until := getActiveUntil(deveui);
layout := "02.01.2006"
t, _ := time.Parse(layout, active_until)
return t.Before(time.Now())
}
func prolongActivation(deveui string, years int) (string, error) { func prolongActivation(deveui string, years int) (string, error) {
conn := globalPool.Get() conn := globalPool.Get()
defer conn.Close() defer conn.Close()

View File

@ -206,6 +206,14 @@ function drawGraph(deveui, alias, property, start, stop, create_graph) {
} }
$.getJSON('https://mini-beieli.ch/metrics?deveui=' + deveui + '&alias=' + alias + '&property=' + property + range, function(mydata) { $.getJSON('https://mini-beieli.ch/metrics?deveui=' + deveui + '&alias=' + alias + '&property=' + property + range, function(mydata) {
if ("msg" in mydata) {
$('#chart').html(`<article class="message is-danger">
<div class="message-body">
Abo ist abgelaufen!
</div>
</article>`);
return;
}
var options = { var options = {
chart: { chart: {
type: 'line', type: 'line',

View File

@ -3,7 +3,6 @@
{{end}} {{end}}
{{define "body_content"}} {{define "body_content"}}
{{ if ne .UserName "" }} {{ if ne .UserName "" }}
<div id="modal" class="modal"> <div id="modal" class="modal">
<div class="modal-background"></div> <div class="modal-background"></div>
<div class="modal-card"> <div class="modal-card">
@ -83,6 +82,28 @@ Device ID: <span id="deveui"></span>
</div> </div>
</div> </div>
<div id="payment_notifier" class="modal">
<div class="modal-background"></div>
<div class="modal-card">
<header class="modal-card-head">
<p class="modal-card-title">Info: Bezahlung durchgef&uuml;hrt</p>
</header>
<section class="modal-card-body">
<article class="message is-info">
<div class="message-body">
Sie haben eine Abo Verlaengerung bezahlt, besten Dank!
Sie erhalten eine Mail, sobald die Zahlung erfolgreich abgeschlossen ist.
</div>
</article>
</section>
<footer class="modal-card-foot">
<button id="payment_notifier_close" class="button is-success">Schliessen</button>
</footer>
</div>
</div>
{{range .LastMetrics}} {{range .LastMetrics}}
<div class="column waage is-full notification is-warning"> <div class="column waage is-full notification is-warning">
<p class="is-size-2 is-size-5-mobile has-text-centered has-text-weight-bold" ><span class="alias" id="alias_{{.Deveui}}">{{.Alias}}</span><a class="show-modal" class="block-link"><span style="float:right;" class="icon is-size-4 is-size-5-mobile"><i class="fa fa-cog"></i></span></a></p> <p class="is-size-2 is-size-5-mobile has-text-centered has-text-weight-bold" ><span class="alias" id="alias_{{.Deveui}}">{{.Alias}}</span><a class="show-modal" class="block-link"><span style="float:right;" class="icon is-size-4 is-size-5-mobile"><i class="fa fa-cog"></i></span></a></p>
@ -108,6 +129,14 @@ Device ID: <span id="deveui"></span>
</div> </div>
</a> </a>
</div> </div>
{{ if (lt .DaysUntilDeactivated 0) }}
<div class="level-item has-text-centered">
<div>
<p class="icon"><i class="fa fa-balance-scale"></i></p>
<p id="weight_{{.Deveui}}" class="title is-size-2 has-text-weight-bold has-text-danger">Abo ist abgelaufen</p>
</div>
</div>
{{ else }}
<div class="level-item has-text-centered"> <div class="level-item has-text-centered">
<a class="block-link" href="/graph.html?deveui={{.Deveui}}&alias={{.Alias}}&property=w"> <a class="block-link" href="/graph.html?deveui={{.Deveui}}&alias={{.Alias}}&property=w">
<div> <div>
@ -116,6 +145,7 @@ Device ID: <span id="deveui"></span>
</div> </div>
</a> </a>
</div> </div>
{{ end }}
<div class="level-item has-text-centered"> <div class="level-item has-text-centered">
<a class="block-link" href="/graph.html?deveui={{.Deveui}}&alias={{.Alias}}&property=p"> <a class="block-link" href="/graph.html?deveui={{.Deveui}}&alias={{.Alias}}&property=p">
<div> <div>
@ -135,7 +165,7 @@ Device ID: <span id="deveui"></span>
</nav> </nav>
</div> </div>
<div class="has-text-centered"> <div class="has-text-centered">
<span class="is-size-6 has-text-centered">aktiv bis</span> <span class="is-size-6 has-text-centered">Abo aktiv bis</span>
<span class="paid_until is-size-6 has-text-centered">{{.ActiveUntil}}</span> <span class="paid_until is-size-6 has-text-centered">{{.ActiveUntil}}</span>
</div> </div>
{{ if (lt .DaysUntilDeactivated 1095) }} {{ if (lt .DaysUntilDeactivated 1095) }}
@ -205,6 +235,11 @@ $("#cart-close").click(function() {
$("#cart").removeClass("is-active"); $("#cart").removeClass("is-active");
}); });
$("#payment_notifier_close").click(function() {
$("#payment_notifier").removeClass("is-active");
location.reload(true);
});
$(".abo_plus").click(function() { $(".abo_plus").click(function() {
console.log("abo_plus"); console.log("abo_plus");
el = $(this).parent().find(".abo_add_years"); el = $(this).parent().find(".abo_add_years");
@ -255,7 +290,12 @@ $(".abo_pay").click(function() {
this_count = Number($( this ).find(".abo_add_years").html()); this_count = Number($( this ).find(".abo_add_years").html());
if (this_count > 0) { if (this_count > 0) {
counter += this_count; counter += this_count;
this_date = $( this ).find(".paid_until").html(); paid_until = $( this ).find(".paid_until").html();
if (moment(paid_until,'DD.MM.YYYY') < moment()) {
this_date = moment().format('DD.MM.YYYY');
} else {
this_date = paid_until;
}
abo_table += '<tr><td>' + $( this ).find('.alias').html() + '</td><td>' + moment(this_date,'DD.MM.YYYY').add('years', this_count).format('DD.MM.YYYY') + '</td><td class="has-text-right">' + (this_count * 24).toFixed(2) + '</td></tr>'; abo_table += '<tr><td>' + $( this ).find('.alias').html() + '</td><td>' + moment(this_date,'DD.MM.YYYY').add('years', this_count).format('DD.MM.YYYY') + '</td><td class="has-text-right">' + (this_count * 24).toFixed(2) + '</td></tr>';
if (charge_data == '') { if (charge_data == '') {
charge_data = $( this ).find("div").first().attr('id') + ":" + this_count; charge_data = $( this ).find("div").first().attr('id') + ":" + this_count;
@ -366,7 +406,6 @@ var card = elements.create("card", { style: style });
card.mount("#card-element"); card.mount("#card-element");
$("#card-errors-article").hide(); $("#card-errors-article").hide();
card.addEventListener('change', ({error}) => { card.addEventListener('change', ({error}) => {
if (error) { if (error) {
$("#card-errors").text(error.message); $("#card-errors").text(error.message);
@ -406,6 +445,7 @@ function ConfirmPayment(clientSecret) {
$('#card-errors-article').hide(); $('#card-errors-article').hide();
$("#cart").removeClass("is-active"); $("#cart").removeClass("is-active");
EndPaymentProgress(); EndPaymentProgress();
$('#payment_notifier').addClass('is-active');
} }
} }
}); });

View File

@ -64,6 +64,20 @@ func getstripepaymentintentHandler(response http.ResponseWriter, request *http.R
} }
} }
func HandlePayment(user string, charge_data string, amount int64) {
fmt.Printf("HandlePayment for %s (charge_data: %s, amount: %d)!\n", user, charge_data, amount)
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)
}
}
sendPaymentConfirmationEmail(user,charge_data,amount)
}
func stripeWebhookHandler(w http.ResponseWriter, req *http.Request) { func stripeWebhookHandler(w http.ResponseWriter, req *http.Request) {
const MaxBodyBytes = int64(65536) const MaxBodyBytes = int64(65536)
req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes) req.Body = http.MaxBytesReader(w, req.Body, MaxBodyBytes)
@ -93,6 +107,7 @@ func stripeWebhookHandler(w http.ResponseWriter, req *http.Request) {
return return
} }
fmt.Printf("PaymentIntent was successful (charge_data: %s, amount: %d)!\n", paymentIntent.Metadata["charge_data"], paymentIntent.Amount) 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 // ... handle other event types
default: default:
fmt.Fprintf(os.Stderr, "Unexpected event type: %s\n", event.Type) fmt.Fprintf(os.Stderr, "Unexpected event type: %s\n", event.Type)