Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 70 additions & 35 deletions example/checkout/main.go
Original file line number Diff line number Diff line change
@@ -1,50 +1,85 @@
package main

import (
"context"
"embed"
"fmt"
"html/template"
"log"
"net/http"
"os"
"strconv"

gonanoid "github.com/matoous/go-nanoid/v2"

"github.com/sumup/sumup-go"
"github.com/sumup/sumup-go/checkouts"
)

var (
//go:embed templates
templatesFs embed.FS
templates *template.Template
)

func init() {
templates = template.Must(template.ParseFS(templatesFs, "templates/*.html"))
}

func main() {
ctx := context.Background()
merchantCode := os.Getenv("SUMUP_MERCHANT_CODE")
client := sumup.NewClient()

checkout, err := client.Checkouts.Create(ctx, checkouts.CreateCheckoutBody{
Amount: 123,
CheckoutReference: "TX000001",
Currency: "EUR",
MerchantCode: "MK0001",
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
templates.ExecuteTemplate(w, "index.html", nil)
})
http.HandleFunc("/create-checkout", func(w http.ResponseWriter, r *http.Request) {
if r.Method != http.MethodPost {
http.Redirect(w, r, "/", http.StatusSeeOther)
return
}

rawAmount := r.FormValue("amount")
amount, err := strconv.ParseFloat(rawAmount, 64)
if err != nil {
http.Error(w, fmt.Sprintf("Invalid amount %q: %v.", rawAmount, err), http.StatusBadRequest)
return
}

checkoutReference := gonanoid.Must()
description := "Test Payment"
checkout, err := client.Checkouts.Create(r.Context(), checkouts.CreateCheckoutBody{
Amount: amount,
CheckoutReference: checkoutReference,
Currency: "EUR",
MerchantCode: merchantCode,
Description: &description,
})
if err != nil {
http.Error(w, fmt.Sprintf("Failed to create checkout: %v.", err), http.StatusInternalServerError)
return
}

data := struct {
CheckoutID string
}{
CheckoutID: *checkout.Id,
}

templates.ExecuteTemplate(w, "checkout.html", data)
})
if err != nil {
log.Printf("[ERROR] create checkout: %v", err)
return
}

log.Printf("[INFO] checkout created: id=%q, amount=%v, currency=%q", *checkout.Id, *checkout.Amount, string(*checkout.Currency))

checkoutSuccess, err := client.Checkouts.Process(ctx, *checkout.Id, checkouts.ProcessCheckoutBody{
Card: &checkouts.Card{
Cvv: "123",
ExpiryMonth: "12",
ExpiryYear: "2023",
Name: "Boaty McBoatface",
Number: "4200000000000042",
},
PaymentType: checkouts.ProcessCheckoutBodyPaymentTypeCard,
http.HandleFunc("/payment-result", func(w http.ResponseWriter, r *http.Request) {
status := r.URL.Query().Get("status")
message := r.URL.Query().Get("message")

templates.ExecuteTemplate(w, "result.html", struct {
Status string
Message string
}{
Status: status,
Message: message,
})
})
if err != nil {
log.Printf("[ERROR] process checkout: %v", err)
return
}

if accepted, ok := checkoutSuccess.AsCheckoutSuccess(); ok {
log.Printf("[INFO] checkout success: id=%q, transaction_id=%q", *accepted.Id, *(*accepted.Transactions)[0].Id)
}

if accepted, ok := checkoutSuccess.AsCheckoutAccepted(); ok {
log.Printf("[INFO] checkout accepted: redirect_to=%q", *accepted.NextStep.RedirectUrl)
}

fmt.Println("Server started at http://localhost:8080")
log.Fatal(http.ListenAndServe(":8080", nil))
}
27 changes: 27 additions & 0 deletions example/checkout/templates/checkout.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<!DOCTYPE html>
<html>

<head>
<title>Complete Payment</title>
<script src="https://gateway.sumup.com/gateway/ecom/card/v2/sdk.js"></script>
</head>

<body>
<h1>Complete Your Payment</h1>
<div id="sumup-card"></div>
<script>
SumUpCard.mount({
id: 'sumup-card',
checkoutId: '{{.CheckoutID}}',
onResponse: function (type, body) {
if (type === 'success') {
window.location.href = '/payment-result?status=success&message=Payment successful';
} else {
window.location.href = '/payment-result?status=error&message=' + encodeURIComponent(body.message || 'Payment failed');
}
}
});
</script>
</body>

</html>
16 changes: 16 additions & 0 deletions example/checkout/templates/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<!DOCTYPE html>
<html>

<head>
<title>SumUp Payment</title>
</head>

<body>
<h1>Enter Amount</h1>
<form action="/create-checkout" method="post">
<input type="number" name="amount" step="0.01" required>
<button type="submit">Pay</button>
</form>
</body>

</html>
14 changes: 14 additions & 0 deletions example/checkout/templates/result.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>

<head>
<title>Payment Result</title>
</head>

<body>
<h1>Payment {{.Status}}</h1>
<p>{{.Message}}</p>
<a href="/">Make another payment</a>
</body>

</html>
5 changes: 4 additions & 1 deletion example/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ replace github.com/sumup/sumup-go => ../

require github.com/sumup/sumup-go v0.0.0-20230919081147-7283f347e1b5

require golang.org/x/oauth2 v0.26.0 // indirect
require (
github.com/matoous/go-nanoid/v2 v2.1.0 // indirect
golang.org/x/oauth2 v0.26.0 // indirect
)
2 changes: 2 additions & 0 deletions example/go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
github.com/matoous/go-nanoid/v2 v2.1.0 h1:P64+dmq21hhWdtvZfEAofnvJULaRR1Yib0+PnU669bE=
github.com/matoous/go-nanoid/v2 v2.1.0/go.mod h1:KlbGNQ+FhrUNIHUxZdL63t7tl4LaPkZNpUULS8H4uVM=
golang.org/x/oauth2 v0.26.0 h1:afQXWNNaeC4nvZ0Ed9XvCCzXM6UHJG7iCg0W4fPqSBE=
golang.org/x/oauth2 v0.26.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI=