Code cleanup

This commit is contained in:
Borna Rajković 2023-07-30 12:14:05 +02:00
parent dcc9754d43
commit 1307c7bc6e
18 changed files with 129 additions and 459 deletions

View File

@ -31,7 +31,7 @@ type PaymentEntry struct {
PaymentIntentId *string `db:"payment_intent_id"`
// wspay field
ShoppingCardID *string `db:"shopping_card_it"`
ShoppingCardID *string `db:"shopping_card_id"`
STAN *string `db:"stan"`
Success *int `db:"success"`
ApprovalCode *string `db:"approval_code"`

View File

@ -16,7 +16,7 @@ func (p *PaymentEntryProvider) CreateEntry(entry PaymentEntry) (PaymentEntry, er
}
entry.Created = time.Now()
_, err := p.DB.Exec(`INSERT INTO "payment_entry" ("id", "created", "gateway", "state", "lang", "error", "amount", "total_amount", "eci", "payment_intent_id", "shopping_card_id", "stan", "success", "approval_code", "order_id", "transaction_id", "event_id")`,
_, err := p.DB.Exec(`INSERT INTO "payment_entry" ("id", "created", "gateway", "state", "lang", "error", "amount", "total_amount", "eci", "payment_intent_id", "shopping_card_id", "stan", "success", "approval_code", "order_id", "transaction_id", "event_id") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16, $17)`,
&entry.Id, &entry.Created, &entry.Gateway, &entry.State, &entry.Lang, &entry.Error, &entry.Amount, &entry.TotalAmount, &entry.ECI, &entry.PaymentIntentId, &entry.ShoppingCardID, &entry.STAN, &entry.Success, &entry.ApprovalCode, &entry.OrderId, &entry.TransactionId, &entry.EventId,
)
if err != nil {

View File

@ -1,65 +1,30 @@
CREATE TABLE IF NOT EXISTS "wspay"
CREATE TABLE IF NOT EXISTS "payment_entry"
(
"id" uuid NOT NULL,
"shop_id" varchar(128) NOT NULL,
"shopping_card_id" varchar(128) NOT NULL,
"created" timestamp NOT NULL,
"modified" timestamp DEFAULT NULL,
"gateway" varchar(255) NOT NULL,
"state" varchar(255) NOT NULL,
"lang" varchar(16) DEFAULT NULL,
"error" varchar(255) DEFAULT NULL,
"amount" int DEFAULT NULL,
"total_amount" int NOT NULL,
"lang" varchar(128) DEFAULT '',
"eci" varchar(255) DEFAULT NULL,
"customer_first_name" varchar(128) DEFAULT '',
"customer_last_name" varchar(128) DEFAULT '',
"customer_address" varchar(128) DEFAULT '',
"customer_city" varchar(128) DEFAULT '',
"customer_zip" varchar(128) DEFAULT '',
"customer_country" varchar(128) DEFAULT '',
"customer_phone" varchar(128) DEFAULT '',
"payment_intent_id" varchar(255) DEFAULT NULL,
"payment_plan" varchar(128) DEFAULT '',
"credit_card_name" varchar(128) DEFAULT '',
"credit_card_number" varchar(128) DEFAULT '',
"payment_method" varchar(128) DEFAULT '',
"currency_code" int DEFAULT 0,
"shopping_card_id" varchar(255) DEFAULT NULL,
"stan" varchar(255) DEFAULT NULL,
"success" int DEFAULT NULL,
"approval_code" varchar(255) DEFAULT NULL,
"date_time" timestamp DEFAULT current_timestamp,
"eci" varchar(256) DEFAULT '',
"stan" varchar(256) DEFAULT '',
"success" int DEFAULT 0,
"approval_code" varchar(256) DEFAULT '',
"error_message" varchar(256) DEFAULT '',
"error_codes" varchar(256) DEFAULT '',
"payment_state" varchar(256) DEFAULT '',
PRIMARY KEY (id),
CONSTRAINT unique_id UNIQUE ("shopping_card_id")
);
CREATE TABLE IF NOT EXISTS "stripe"
(
"id" uuid NOT NULL,
"total_amount" int NOT NULL,
"lang" varchar(128) DEFAULT '',
"payment_intent_id" varchar(256) DEFAULT '',
"payment_state" varchar(256) DEFAULT '',
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS "viva"
(
"id" uuid NOT NULL,
"order_id" varchar(24) DEFAULT '',
"order_id" varchar(255) DEFAULT NULL,
"transaction_id" uuid DEFAULT NULL,
"total_amount" int NOT NULL,
"event_id" varchar(128) DEFAULT '',
"eci" varchar(128) DEFAULT '',
"payment_state" varchar(256) DEFAULT '',
"event_id" varchar(255) DEFAULT NULL,
PRIMARY KEY (id)
);

View File

@ -1,65 +0,0 @@
CREATE TABLE IF NOT EXISTS "wspay"
(
"id" uuid NOT NULL,
"shop_id" varchar(128) NOT NULL,
"shopping_card_id" varchar(128) NOT NULL,
"total_amount" int NOT NULL,
"lang" varchar(128) DEFAULT '',
"customer_first_name" varchar(128) DEFAULT '',
"customer_last_name" varchar(128) DEFAULT '',
"customer_address" varchar(128) DEFAULT '',
"customer_city" varchar(128) DEFAULT '',
"customer_zip" varchar(128) DEFAULT '',
"customer_country" varchar(128) DEFAULT '',
"customer_phone" varchar(128) DEFAULT '',
"payment_plan" varchar(128) DEFAULT '',
"credit_card_name" varchar(128) DEFAULT '',
"credit_card_number" varchar(128) DEFAULT '',
"payment_method" varchar(128) DEFAULT '',
"currency_code" int DEFAULT 0,
"date_time" timestamp DEFAULT current_timestamp,
"eci" varchar(256) DEFAULT '',
"stan" varchar(256) DEFAULT '',
"success" int DEFAULT 0,
"approval_code" varchar(256) DEFAULT '',
"error_message" varchar(256) DEFAULT '',
"error_codes" varchar(256) DEFAULT '',
"payment_state" varchar(256) DEFAULT '',
PRIMARY KEY (id),
CONSTRAINT unique_id UNIQUE ("shopping_card_id")
);
CREATE TABLE IF NOT EXISTS "stripe"
(
"id" uuid NOT NULL,
"total_amount" int NOT NULL,
"lang" varchar(128) DEFAULT '',
"payment_intent_id" varchar(256) DEFAULT '',
"payment_state" varchar(256) DEFAULT '',
PRIMARY KEY (id)
);
CREATE TABLE IF NOT EXISTS "viva"
(
"id" uuid NOT NULL,
"order_id" varchar(24) DEFAULT '',
"transaction_id" uuid DEFAULT NULL,
"total_amount" int NOT NULL,
"event_id" varchar(128) DEFAULT '',
"eci" varchar(128) DEFAULT '',
"payment_state" varchar(256) DEFAULT '',
PRIMARY KEY (id)
);

39
main.go
View File

@ -18,6 +18,7 @@ import (
stripe2 "payment-poc/stripe"
"payment-poc/viva"
"payment-poc/wspay"
"sort"
"strconv"
"strings"
"time"
@ -121,6 +122,9 @@ func main() {
for key := range paymentGateways {
gateways = append(gateways, key)
}
sort.Slice(gateways, func(i, j int) bool {
return string(gateways[i]) < string(gateways[j])
})
c.HTML(200, "methods.gohtml", gin.H{"Amount": amount, "Gateways": gateways})
})
g.GET("/:gateway", func(c *gin.Context) {
@ -146,6 +150,15 @@ func main() {
return
}
})
g.GET("/entries/:id", func(c *gin.Context) {
id := uuid.MustParse(c.Param("id"))
entry, err := entryProvider.FetchById(id)
if err != nil {
c.AbortWithError(http.StatusBadRequest, err)
return
}
c.HTML(200, "info.gohtml", gin.H{"Entry": entry})
})
g.POST("/entries/:id/complete", func(c *gin.Context) {
id := uuid.MustParse(c.Param("id"))
entry, err := entryProvider.FetchById(id)
@ -160,7 +173,7 @@ func main() {
return
}
entry, err = paymentGateway.CompleteTransaction(entry, amount)
if err != nil {
if err == nil {
entryProvider.UpdateEntry(entry)
c.Redirect(http.StatusSeeOther, "/entries/"+id.String())
} else {
@ -183,7 +196,7 @@ func main() {
}
if paymentGateway, ok := paymentGateways[entry.Gateway]; ok {
entry, err = paymentGateway.CancelTransaction(entry)
if err != nil {
if err == nil {
entryProvider.UpdateEntry(entry)
c.Redirect(http.StatusSeeOther, "/entries/"+id.String())
} else {
@ -218,14 +231,6 @@ func getAccounts() gin.Accounts {
return gin.Accounts{auth[0]: auth[1]}
}
func parseDateTime(dateTime string) time.Time {
t, err := time.Parse("20060102150405", dateTime)
if err != nil {
log.Printf("couldn't parse response time %s: %v", dateTime, err)
}
return t
}
func fetchAmount(amount string) (int64, error) {
if amount, err := strconv.ParseFloat(amount, 64); err == nil {
return int64(amount * 100), nil
@ -329,19 +334,21 @@ func hasProfile(profile string) bool {
func formatState(stt state.PaymentState) string {
switch stt {
case state.StateCanceled:
return "Otkazano"
return "Otkazana"
case state.StateVoided:
return "Otkazano sa strane administratora"
return "Otkazana sa strane administratora"
case state.StateAccepted:
return "Prihvačeno"
return "Predautorizirana"
case state.StateError:
return "Greška"
case state.StatePreinitialized:
return "Predinicijalizirana"
case state.StateInitialized:
return "Inicijalna izrada"
return "Inicijalizirana"
case state.StateCanceledInitialization:
return "Otkazano tijekom izrade"
return "Otkazana tijekom izrade"
case state.StateCompleted:
return "Završeno"
return "Autorizirana"
}
return "nepoznato stanje '" + string(stt) + "'"
}

View File

@ -3,6 +3,8 @@ package state
type PaymentState string
const (
// initial state
StatePreinitialized PaymentState = "preinitialized"
// initial state
StateInitialized PaymentState = "initialized"

View File

@ -1,16 +0,0 @@
package stripe
import (
"github.com/google/uuid"
"payment-poc/state"
)
type StripeDb struct {
Id uuid.UUID `db:"id"`
TotalAmount int64 `db:"total_amount"`
Lang string `db:"lang"`
PaymentIntentId string `db:"payment_intent_id"`
State state.PaymentState `db:"payment_state"`
}

View File

@ -19,7 +19,7 @@ type Service struct {
func (s *Service) CreatePaymentUrl(amount int64) (url string, err error) {
entry, err := s.Provider.CreateEntry(database.PaymentEntry{
Gateway: state.GatewayVivaWallet,
Gateway: state.GatewayStripe,
State: state.StateInitialized,
TotalAmount: amount,
})
@ -83,7 +83,7 @@ func (s *Service) CompleteTransaction(entry database.PaymentEntry, amount int64)
}
log.Printf("received state on completion: %v", pi.Status)
if pi.Status == stripe.PaymentIntentStatusSucceeded || pi.Status == stripe.PaymentIntentStatusProcessing {
entry.TotalAmount = pi.Amount
entry.Amount = &pi.AmountReceived
entry.State = state.StateCompleted
}
return entry, nil

View File

@ -1,35 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Obrada odgovora</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
<style>
th {text-align: left}
h2 {
margin-top: 16px;
}
</style>
</head>
<body class="container">
<p>Obrada odgovora...</p>
<div id="error"></div>
<script>
window.onload = () => {
setTimeout(() => {
window?.top?.postMessage(JSON.stringify({"success": true}), {targetOrigin: "*"});
if(window?.top) {
document.querySelector("#error").innerHTML = `<p>Izgleda da je došlo do greške, jer stranica nije otvorena u iframe-u</p><a href="/">Stisnite ovdje da se vratite na naslovnicu</a>`;
}
}, 2000);
}
</script>
</body>
</html>

View File

@ -10,10 +10,10 @@
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
<style>
th {text-align: left}
tr > td:nth-child(2) {
tr > td:nth-child(3) {
text-align: right;
}
tr > th:nth-child(2) {
tr > th:nth-child(3) {
text-align: right;
}
td, th {
@ -25,70 +25,32 @@
</style>
</head>
<body class="container">
<h2>Novo plačanje</h2>
<h2>Novo plaćanje</h2>
<form method="get" action="/methods">
<div class="mb-3">
<label class="form-label" for="amount">Vrijednost</label>
<input class="form-control" id="amount" required name="amount" type="number" step="0.01" min="0">
</div>
<button class="btn btn-primary" type="submit">Izradi novo plačanje</button>
<button class="btn btn-primary" type="submit">Izradi novo plaćanje</button>
</form>
<div>
<h2>WsPay</h2>
<h2>Entries</h2>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Gateway</th>
<th>Vrijednost</th>
<th>Stanje</th>
</tr>
</thead>
<tbody>
{{range .WsPay}}
{{range .Entries}}
<tr>
<td><a class="link-primary" href="/wspay/info/{{.Id}}">{{.Id}}</a></td>
<td>{{formatCurrency .TotalAmount}}</td>
<td>{{formatState .State}}</td>
</tr>
{{end}}
</tbody>
</table>
<h2>Stripe</h2>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Vrijednost</th>
<th>Stanje</th>
</tr>
</thead>
<tbody>
{{range .Stripe}}
<tr>
<td><a class="link-primary" href="/stripe/info/{{.Id}}">{{.Id}}</a></td>
<td>{{formatCurrency .TotalAmount}}</td>
<td>{{formatState .State}}</td>
</tr>
{{end}}
</tbody>
</table>
<h2>Viva</h2>
<table class="table">
<thead>
<tr>
<th>Id</th>
<th>Vrijednost</th>
<th>Stanje</th>
</tr>
</thead>
<tbody>
{{range .Viva}}
<tr>
<td><a class="link-primary" href="/viva/info/{{.Id}}">{{.Id}}</a></td>
<td><a class="link-primary" href="/entries/{{.Id}}">{{.Id}}</a></td>
<td>{{.Gateway}}</td>
<td>{{formatCurrency .TotalAmount}}</td>
<td>{{formatState .State}}</td>
</tr>

65
templates/info.gohtml Normal file
View File

@ -0,0 +1,65 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Index</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
<style>
th {text-align: left}
h2 {
margin-top: 16px;
}
</style>
</head>
<body class="container">
<h2>Plaćanje {{.Entry.Id}}</h2>
<table class="table">
<tr><th>Id: </th><td>{{.Entry.Id}}</td></tr>
<tr><th>Datum izrade: </th><td>{{.Entry.Created.Format "Jan 02, 2006 15:04:05 UTC"}}</td></tr>
<tr><th>Zadnja izmjena: </th><td>{{or (.Entry.Modified.Format "Jan 02, 2006 15:04:05 UTC") .Entry.Created.Format "Jan 02, 2006 15:04:05 UTC"}}</td></tr>
<tr><th>Gateway: </th><td>{{.Entry.Gateway}}</td></tr>
<tr><th>Naplaćena vrijednost: </th><td>{{or .Entry.Amount "-"}}</td></tr>
<tr><th>Ukupna vrijednost: </th><td>{{formatCurrency .Entry.TotalAmount}}</td></tr>
<tr><th>Jezik: </th><td>{{or .Entry.Lang "-"}}</td></tr>
<tr><th>Greške: </th><td>{{or .Entry.Error "-"}}</td></tr>
<tr><th>Stanje: </th><td>{{formatState .Entry.State}}</td></tr>
{{if eq .Entry.Gateway "wspay"}}
<tr><th>WsPay</th><td></td></tr>
<tr><th>Shopping cart ID: </th><td>{{or .Entry.ShoppingCartID "-"}}</td></tr>
<tr><th>Success: </th><td>{{or .Entry.Success "-"}}</td></tr>
{{end}}
{{if eq .Entry.Gateway "stripe"}}
<tr><th>Stripe</th><td></td></tr>
<tr><th>Payment intent ID: </th><td>{{or .Entry.PaymentIntentId "-"}}</td></tr>
{{end}}
{{if eq .Entry.Gateway "viva-wallet"}}
<tr><th>Viva wallet</th><td></td></tr>
<tr><th>Order ID: </th><td>{{or .Entry.OrderId "-"}}</td></tr>
<tr><th>Transaction ID: </th><td>{{or .Entry.TransactionId "-"}}</td></tr>
<tr><th>Event ID: </th><td>{{or .Entry.EventId "-"}}</td></tr>
{{end}}
</table>
{{if eq .Entry.State "accepted"}}
<form class="mb-3" method="post" action="/entries/{{.Entry.Id}}/complete">
<div class="mb-3">
<label class="form-label" for="amount">Završi plaćanje</label>
<input class="form-control" id="amount" required name="amount" type="number" value="{{decimalCurrency .Entry.TotalAmount}}" step="0.01" min="0.01" max="{{decimalCurrency .Entry.TotalAmount}}">
</div>
<button class="btn btn-primary" type="submit">Završi plaćanje</button>
</form>
<form method="post" action="/entries/{{.Entry.Id}}/cancel">
<button class="btn btn-primary" type="submit">Otkaži plaćanje</button>
</form>
{{end}}
</body>
</html>

View File

@ -22,9 +22,9 @@
</style>
</head>
<body class="container">
<h2>Izaberi metodu plačanja</h2>
<a class="btn btn-success" href="/wspay?amount={{.Amount}}">WsPay</a>
<a class="btn btn-success" href="/stripe?amount={{.Amount}}">Stripe</a>
<a class="btn btn-success" href="/viva?amount={{.Amount}}">Viva</a>
<h2>Izaberi metodu plaćanja</h2>
{{range .Gateways}}
<a class="btn btn-success" href="/{{.}}?amount={{$.Amount}}">{{.}}</a>
{{end}}
</body>
</html>

View File

@ -1,42 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Info</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
<style>
th {text-align: left}
h2 {
margin-top: 16px;
}
</style>
</head>
<body class="container">
<h2>Plačanje {{.Entry.Id}}</h2>
<table class="table">
<tr><th>Id: </th><td>{{.Entry.Id}}</td></tr>
<tr><th>Ukupna vrijednost: </th><td>{{formatCurrency .Entry.TotalAmount}}</td></tr>
<tr><th>Jezik: </th><td>{{omitempty .Entry.Lang}}</td></tr>
<tr><th>Stanje: </th><td>{{formatState .Entry.State}}</td></tr>
</table>
{{if eq .Entry.State "accepted"}}
<form class="mb-3" method="post" action="/stripe/complete/{{.Entry.Id}}">
<div class="mb-3">
<label class="form-label" for="amount">Završi transakciju</label>
<input class="form-control" id="amount" required name="amount" type="number" value="{{decimalCurrency .Entry.TotalAmount}}" step="0.01" min="0.01" max="{{decimalCurrency .Entry.TotalAmount}}">
</div>
<button class="btn btn-primary" type="submit">Završi transakciju</button>
</form>
<form method="post" action="/stripe/cancel/{{.Entry.Id}}">
<button class="btn btn-primary" type="submit">Otkaži transakciju</button>
</form>
{{end}}
</body>
</html>

View File

@ -1,44 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Info</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
<style>
th {text-align: left}
h2 {
margin-top: 16px;
}
</style>
</head>
<body class="container">
<h2>Plačanje {{.Entry.Id}}</h2>
<table class="table">
<tr><th>Id: </th><td>{{.Entry.Id}}</td></tr>
<tr><th>Order id: </th><td>{{.Entry.OrderId}}</td></tr>
<tr><th>Transaction id: </th><td>{{.Entry.TransactionId.String}}</td></tr>
<tr><th>Ukupna vrijednost: </th><td>{{formatCurrency .Entry.TotalAmount}}</td></tr>
<tr><th>Jezik: </th><td>{{omitempty .Entry.Lang}}</td></tr>
<tr><th>Događaj: </th><td>{{.Entry.EventId}}</td></tr>
<tr><th>Stanje: </th><td>{{formatState .Entry.State}}</td></tr>
</table>
{{if eq .Entry.State "accepted"}}
<form class="mb-3" method="post" action="/viva/complete/{{.Entry.Id}}">
<div class="mb-3">
<label class="form-label" for="amount">Završi transakciju</label>
<input class="form-control" id="amount" required name="amount" type="number" value="{{decimalCurrency .Entry.TotalAmount}}" step="0.01" min="0.01" max="{{decimalCurrency .Entry.TotalAmount}}">
</div>
<button class="btn btn-primary" type="submit">Završi transakciju</button>
</form>
<form method="post" action="/viva/cancel/{{.Entry.Id}}">
<button class="btn btn-primary" type="submit">Otkaži transakciju</button>
</form>
{{end}}
</body>
</html>

View File

@ -17,7 +17,7 @@
<body class="container" style="margin-top: 32px">
<h2>Započni proces plačanja</h2>
<form action="{{.Action}}" method="POST">
<form id="wspay-form" action="{{.Action}}" method="POST">
<input type="hidden" name="ShopID" value="{{.Form.ShopID}}">
<input type="hidden" name="ShoppingCartID" value="{{.Form.ShoppingCartID}}">
<input type="hidden" name="Version" value="{{.Form.Version}}">
@ -26,36 +26,10 @@
<input type="hidden" name="ReturnURL" value="{{.Form.ReturnURL}}">
<input type="hidden" name="CancelURL" value="{{.Form.CancelURL}}">
<input type="hidden" name="ReturnErrorURL" value="{{.Form.ReturnErrorURL}}">
<input type="submit" class="btn btn-primary" value="Koristi normalni redirect">
</form>
<h2>Započni normalni proces u iframe-u</h2>
<form target="payment-frame" name="pay" action="{{.Action}}" method="POST">
<input type="hidden" name="Iframe" value="True">
<input type="hidden" name="IframeResponseTarget" value="SELF">
<input type="hidden" name="ShopID" value="{{.Form.ShopID}}">
<input type="hidden" name="ShoppingCartID" value="{{.Form.ShoppingCartID}}">
<input type="hidden" name="Version" value="{{.Form.Version}}">
<input type="hidden" name="TotalAmount" value="{{formatCurrency .Form.TotalAmount}}">
<input type="hidden" name="Signature" value="{{.Form.Signature}}">
<input type="hidden" name="ReturnURL" value="{{.Form.ReturnURL}}?iframe=true">
<input type="hidden" name="CancelURL" value="{{.Form.CancelURL}}?iframe=true">
<input type="hidden" name="ReturnErrorURL" value="{{.Form.ReturnErrorURL}}?iframe=true">
<input type="submit" class="btn btn-primary" value="Koristi navigaciju u iframe-u">
</form>
<iframe id="payment-frame" name="payment-frame" style="width: 100%; min-height: 600px"></iframe>
<script>
window.addEventListener(
"message",
(event) => {
console.log("received response")
window.location.href = "/";
},
false
);
document.querySelector("#wspay-form").submit();
</script>
</body>
</html>

View File

@ -1,62 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Info</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-9ndCyUaIbzAi2FUVXJi0CjmCapSmO7SnpJef0486qhLnuZ2cdeRhO02iuK6FUUVM" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.3.0/dist/js/bootstrap.bundle.min.js" integrity="sha384-geWF76RCwLtnZ8qwWowPQNguL3RmwHVBC9FhGdlKrxdiJJigb/j/68SIy3Te4Bkz" crossorigin="anonymous"></script>
<style>
th {text-align: left}
h2 {
margin-top: 16px;
}
</style>
</head>
<body class="container">
<h2>Plačanje {{.Entry.Id}}</h2>
<table class="table">
<tr><th>CartId: </th><td>{{.Entry.ShoppingCartID}}</td></tr>
<tr><th>Ukupna vrijednost: </th><td>{{formatCurrency .Entry.TotalAmount}}</td></tr>
<tr><th>Jezik: </th><td>{{omitempty .Entry.Lang}}</td></tr>
<tr><th>Ime: </th><td>{{omitempty .Entry.CustomerFirstName}}</td></tr>
<tr><th>Prezime: </th><td>{{omitempty .Entry.CustomerLastName}}</td></tr>
<tr><th>Adresa: </th><td>{{omitempty .Entry.CustomerAddress}}</td></tr>
<tr><th>Grad: </th><td>{{omitempty .Entry.CustomerCity}}</td></tr>
<tr><th>ZIP: </th><td>{{omitempty .Entry.CustomerZIP}}</td></tr>
<tr><th>Zemlja: </th><td>{{omitempty .Entry.CustomerCountry}}</td></tr>
<tr><th>Broj telefona: </th><td>{{omitempty .Entry.CustomerPhone}}</td></tr>
<tr><th>Plan plačanja: </th><td>{{omitempty .Entry.PaymentPlan}}</td></tr>
<tr><th>Ime kartice: </th><td>{{omitempty .Entry.CreditCardName}}</td></tr>
<tr><th>Broj kartice: </th><td>{{omitempty .Entry.CreditCardNumber}}</td></tr>
<tr><th>Metoda plačanja: </th><td>{{omitempty .Entry.PaymentMethod}}</td></tr>
<tr><th>Oznaka valute: </th><td>{{.Entry.CurrencyCode}}</td></tr>
<tr><th>Datum i vrijeme: </th><td>{{.Entry.DateTime.Format "Jan 02, 2006 15:04:05 UTC"}}</td></tr>
<tr><th>Uspjeh: </th> <td>{{.Entry.Success}}</td></tr>
<tr><th>Kod: </th> <td>{{omitempty .Entry.ApprovalCode}}</td></tr>
<tr><th>Poruka greške: </th> <td>{{omitempty .Entry.ErrorMessage}}</td></tr>
<tr><th>Kodovi greške: </th> <td>{{omitempty .Entry.ErrorCodes}}</td></tr>
<tr><th>Stanje: </th><td>{{formatState .Entry.State}}</td></tr>
</table>
{{if eq .Entry.State "accepted"}}
<form class="mb-3" method="post" action="/wspay/complete/{{.Entry.Id}}">
<div class="mb-3">
<label class="form-label" for="amount">Završi transakciju</label>
<input class="form-control" id="amount" required name="amount" type="number" value="{{decimalCurrency .Entry.TotalAmount}}" step="0.01" min="0.01" max="{{decimalCurrency .Entry.TotalAmount}}">
</div>
<button class="btn btn-primary" type="submit">Završi transakciju</button>
</form>
<form method="post" action="/wspay/cancel/{{.Entry.Id}}">
<button class="btn btn-primary" type="submit">Otkaži transakciju</button>
</form>
{{end}}
</body>
</html>

View File

@ -1,41 +0,0 @@
package wspay
import (
"github.com/google/uuid"
"payment-poc/state"
"time"
)
type WsPayDb struct {
Id uuid.UUID `db:"id"`
ShopID string `db:"shop_id"`
ShoppingCartID string `db:"shopping_card_id"`
TotalAmount int64 `db:"total_amount"`
Lang string `db:"lang"`
CustomerFirstName string `db:"customer_first_name"`
CustomerLastName string `db:"customer_last_name"`
CustomerAddress string `db:"customer_address"`
CustomerCity string `db:"customer_city"`
CustomerZIP string `db:"customer_zip"`
CustomerCountry string `db:"customer_country"`
CustomerPhone string `db:"customer_phone"`
PaymentPlan string `db:"payment_plan"`
CreditCardName string `db:"credit_card_name"`
CreditCardNumber string `db:"credit_card_number"`
PaymentMethod string `db:"payment_method"`
CurrencyCode int `db:"currency_code"`
DateTime time.Time `db:"date_time"`
ECI string `db:"eci"`
STAN string `db:"stan"`
Success int `db:"success"`
ApprovalCode string `db:"approval_code"`
ErrorMessage string `db:"error_message"`
ErrorCodes string `db:"error_codes"`
State state.PaymentState `db:"payment_state"`
}

View File

@ -24,7 +24,7 @@ type Service struct {
func (s *Service) CreatePaymentUrl(amount int64) (string, error) {
entry, err := s.Provider.CreateEntry(database.PaymentEntry{
Gateway: state.GatewayVivaWallet,
Gateway: state.GatewayWsPay,
State: state.StateInitialized,
TotalAmount: amount,
})