refactor payment process - first step

This commit is contained in:
Joerg Lehmann 2020-01-02 10:35:00 +01:00
parent 274c5dc9e7
commit bf9485087d
5 changed files with 255 additions and 22 deletions

View File

@ -89,6 +89,7 @@ func main() {
http.HandleFunc("/lastmetrics", lastmetricsHandler) http.HandleFunc("/lastmetrics", lastmetricsHandler)
http.HandleFunc("/save_scale_settings", save_scale_settingsHandler) http.HandleFunc("/save_scale_settings", save_scale_settingsHandler)
http.HandleFunc("/getstripesession", getstripesessionHandler) http.HandleFunc("/getstripesession", getstripesessionHandler)
http.HandleFunc("/getstripepaymentintent", getstripepaymentintentHandler)
http.HandleFunc("/stripewebhook", stripeWebhookHandler) http.HandleFunc("/stripewebhook", stripeWebhookHandler)
logit("Starting Web Application...") logit("Starting Web Application...")

102
snippets/checkout.html Normal file
View File

@ -0,0 +1,102 @@
{{define "header_additions"}}
<script src="https://js.stripe.com/v3/"></script>
{{end}}
{{define "body_content"}}
<p class="title is-4">Checkout</p>
<p id="charge_data" hidden>0002CC01000003F7:2</p>
<div id="card-element">
<!-- Elements will create input elements here -->
</div>
<!-- We'll put the error messages in this element -->
<div id="card-errors" role="alert"></div>
<button id="submit">Pay</button>
<script type="text/javascript">
// Set your publishable key: remember to change this to your live publishable key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
var stripe = Stripe('pk_test_YkSGqH3Tk9WKK9HrlY63GhAg');
var elements = stripe.elements();
// Set up Stripe.js and Elements to use in checkout form
var style = {
base: {
color: "#32325d",
}
};
var card = elements.create("card", { style: style });
card.mount("#card-element");
card.addEventListener('change', ({error}) => {
const displayError = document.getElementById('card-errors');
if (error) {
displayError.textContent = error.message;
} else {
displayError.textContent = '';
}
});
var submitButton = document.getElementById('submit');
function GetClientSecret() {
var result = "";
$.ajax({
async: false,
url: "getstripepaymentintent",
type: "get", //send it through get method
dataType: "json",
data: {
charge_data: $("#charge_data").html()
},
success: function(response) {
console.log('pay success');
console.log(response.stripesessionid);
console.log('rc: '+response.rc);
if (response.rc == 0) {
result = response.stripeclientsecret;
}
},
error: function(xhr) {
console.log('getstripepaymentintent error');
//Do Something to handle error
}
});
return result;
}
submitButton.addEventListener('click', function(ev) {
var clientSecret = GetClientSecret();
stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: card,
billing_details: {
name: 'Jenny Rosen'
}
}
}).then(function(result) {
if (result.error) {
// Show error to your customer (e.g., insufficient funds)
console.log(result.error.message);
} else {
// The payment has been processed!
if (result.paymentIntent.status === 'succeeded') {
// Show a success message to your customer
// There's a risk of the customer closing the window before callback
// execution. Set up a webhook or plugin to listen for the
// payment_intent.succeeded event that handles any business critical
// post-payment actions.
alert("Payment succeeded!!!");
}
}
});
});
</script>
{{end}}

View File

@ -1,3 +1,6 @@
{{define "header_additions"}}
<script src="https://js.stripe.com/v3/"></script>
{{end}}
{{define "body_content"}} {{define "body_content"}}
{{ if ne .UserName "" }} {{ if ne .UserName "" }}
@ -56,10 +59,21 @@ Device ID: <span id="deveui"></span>
<p class="modal-card-title">Abo verl&auml;ngern</p> <p class="modal-card-title">Abo verl&auml;ngern</p>
</header> </header>
<p id="charge_data" hidden>0</p> <p id="charge_data" hidden>0</p>
<section class="modal-card-body" id="abos_verlaengern"> <section class="modal-card-body">
<!-- Content ... --> <div id="abos_verlaengern">
<!-- Content ... -->
</div>
<div>
<div class="has-margin-top-20" id="card-element">
<!-- Elements will create input elements here -->
</div>
<!-- We'll put the error messages in this element -->
<div id="card-errors" role="alert"></div>
</div>
</section> </section>
<footer class="modal-card-foot"> <footer class="modal-card-foot">
<button id="cart-pay" class="button is-success">Bezahlen</button> <button id="cart-pay" class="button is-success">Bezahlen</button>
<button id="cart-close" class="button">Cancel</button> <button id="cart-close" class="button">Cancel</button>
</footer> </footer>
@ -185,7 +199,6 @@ $(".show-modal").click(function() {
}); });
$("#cart-close").click(function() { $("#cart-close").click(function() {
console.log("blabla");
$("#cart").removeClass("is-active"); $("#cart").removeClass("is-active");
}); });
@ -334,20 +347,37 @@ $("#modal-save").click(function() {
}); });
</script> // Set your publishable key: remember to change this to your live publishable key in production
// See your keys here: https://dashboard.stripe.com/account/apikeys
<script src="https://js.stripe.com/v3/"></script>
<script>
var stripe = Stripe('pk_test_YkSGqH3Tk9WKK9HrlY63GhAg'); var stripe = Stripe('pk_test_YkSGqH3Tk9WKK9HrlY63GhAg');
var elements = stripe.elements();
$("#cart-pay").click(function() { // Set up Stripe.js and Elements to use in checkout form
console.log("hoopla"); var style = {
$("#cart").removeClass("is-active"); base: {
color: "#32325d",
}
};
var card = elements.create("card", { style: style });
card.mount("#card-element");
card.addEventListener('change', ({error}) => {
const displayError = document.getElementById('card-errors');
if (error) {
displayError.textContent = error.message;
} else {
displayError.textContent = '';
}
});
function GetClientSecret() {
var result = "";
$.ajax({ $.ajax({
url: "getstripesession", async: false,
url: "getstripepaymentintent",
type: "get", //send it through get method type: "get", //send it through get method
dataType: "json", dataType: "json",
data: { data: {
@ -358,23 +388,44 @@ $("#cart-pay").click(function() {
console.log(response.stripesessionid); console.log(response.stripesessionid);
console.log('rc: '+response.rc); console.log('rc: '+response.rc);
if (response.rc == 0) { if (response.rc == 0) {
console.log('redirectToCheckout'); result = response.stripeclientsecret;
stripe.redirectToCheckout({
sessionId: response.stripesessionid
}).then(function (result) {
// If `redirectToCheckout` fails due to a browser or network
// error, display the localized error message to your customer
// using `result.error.message`.
});
} }
}, },
error: function(xhr) { error: function(xhr) {
console.log('getstripesession error'); console.log('getstripepaymentintent error');
//Do Something to handle error //Do Something to handle error
} }
}); });
return result;
}
$('#cart-pay').on('click', function(ev) {
var clientSecret = GetClientSecret();
stripe.confirmCardPayment(clientSecret, {
payment_method: {
card: card,
billing_details: {
name: '{{ .UserName }}'
}
}
}).then(function(result) {
if (result.error) {
// Show error to your customer (e.g., insufficient funds)
console.log(result.error.message);
} else {
// The payment has been processed!
if (result.paymentIntent.status === 'succeeded') {
// Show a success message to your customer
// There's a risk of the customer closing the window before callback
// execution. Set up a webhook or plugin to listen for the
// payment_intent.succeeded event that handles any business critical
// post-payment actions.
console.log("Payment succeeded!!!");
$("#cart").removeClass("is-active");
}
}
});
}); });
</script> </script>

View File

@ -41,3 +41,35 @@ hr {
.apexcharts-legend { .apexcharts-legend {
font-family: "Rubik", sans-serif; font-family: "Rubik", sans-serif;
} }
/**
* * The CSS shown here will not be introduced in the Quickstart guide, but
* * shows how you can use CSS to style your Element's container.
* */
input,
.StripeElement {
height: 40px;
padding: 10px 12px;
color: #32325d;
background-color: white;
border: 1px solid transparent;
border-radius: 4px;
box-shadow: 0 1px 3px 0 #e6ebf1;
-webkit-transition: box-shadow 150ms ease;
transition: box-shadow 150ms ease;
}
input:focus,
.StripeElement--focus {
box-shadow: 0 1px 3px 0 #cfd7df;
}
.StripeElement--invalid {
border-color: #fa755a;
}
.StripeElement--webkit-autofill {
background-color: #fefde5 !important;
}

View File

@ -11,6 +11,7 @@ import (
"strconv" "strconv"
"github.com/stripe/stripe-go" "github.com/stripe/stripe-go"
"github.com/stripe/stripe-go/checkout/session" "github.com/stripe/stripe-go/checkout/session"
"github.com/stripe/stripe-go/paymentintent"
"github.com/stripe/stripe-go/webhook" "github.com/stripe/stripe-go/webhook"
) )
@ -18,6 +19,52 @@ func getStripeKey() string {
return "sk_test_GJbXPD0IAFNvvGpNEpaeDfhl" 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),
}
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 getstripesessionHandler(response http.ResponseWriter, request *http.Request) { func getstripesessionHandler(response http.ResponseWriter, request *http.Request) {
name := getUserName(request) name := getUserName(request)
if name != "" { if name != "" {