Added payment update action
This commit is contained in:
1 parent
b6203d8a03
commit
fe6f3b6672
12 files changed
+420
-105
No files matched your search
+102
-16
@@ -9,6 +9,7 @@ import (
|
||||
"github.com/gin-gonic/gin"
|
||||
"github.com/google/uuid"
|
||||
"io"
|
||||
"log"
|
||||
"net/http"
|
||||
"payment-poc/database"
|
||||
"payment-poc/state"
|
||||
@@ -16,22 +17,67 @@ import (
|
||||
)
|
||||
|
||||
type Service struct {
|
||||
Provider *database.PaymentEntryProvider
|
||||
ShopId string
|
||||
ShopSecret string
|
||||
BackendUrl string
|
||||
}
|
||||
|
||||
func (s *Service) CreatePaymentUrl(amount int64) (string, error) {
|
||||
entry, err := s.Provider.CreateEntry(database.PaymentEntry{
|
||||
Gateway: state.GatewayWsPay,
|
||||
State: state.StateInitialized,
|
||||
TotalAmount: amount,
|
||||
})
|
||||
if err != nil {
|
||||
return "", err
|
||||
func (s *Service) UpdatePayment(entry database.PaymentEntry) (updatedEntry database.PaymentEntry, err error) {
|
||||
var request = StatusCheckRequest{
|
||||
Version: "2.0",
|
||||
ShopId: s.ShopId,
|
||||
ShoppingCartId: entry.Id.String(),
|
||||
Signature: CalculateStatusCheckSignature(s.ShopId, s.ShopSecret, entry.Id.String()),
|
||||
}
|
||||
return "/wspay/initialize/" + entry.Id.String(), nil
|
||||
|
||||
httpResponse, err := createRequest(
|
||||
"POST",
|
||||
"https://test.wspay.biz/api/services/statusCheck",
|
||||
map[string]string{"content-type": "application/json"},
|
||||
toJson(request),
|
||||
)
|
||||
if err != nil {
|
||||
return database.PaymentEntry{}, err
|
||||
}
|
||||
|
||||
var response StatusCheckResponse
|
||||
err = readResponse(httpResponse, &response)
|
||||
if err != nil {
|
||||
return database.PaymentEntry{}, err
|
||||
}
|
||||
|
||||
if CompareStatusCheckReturnSignature(response.Signature, s.ShopId, s.ShopSecret, response.ActionSuccess, response.ApprovalCode, entry.Id.String()) != nil {
|
||||
entry.Amount = &response.Amount
|
||||
newState := determineState(response)
|
||||
|
||||
if entry.State != newState && newState != "" {
|
||||
log.Printf("Updated state for %s: %s -> %s", entry.Id.String(), entry.State, newState)
|
||||
entry.State = newState
|
||||
}
|
||||
|
||||
entry.State = state.StateCompleted
|
||||
} else {
|
||||
return database.PaymentEntry{}, errors.New("invalid signature")
|
||||
}
|
||||
return entry, nil
|
||||
}
|
||||
|
||||
func determineState(response StatusCheckResponse) state.PaymentState {
|
||||
if response.Completed == "1" {
|
||||
return state.StateCompleted
|
||||
} else if response.Voided == "1" {
|
||||
return state.StateVoided
|
||||
} else if response.Refunded == "1" {
|
||||
return state.StateVoided
|
||||
} else if response.Authorized == "1" {
|
||||
return state.StateAccepted
|
||||
} else {
|
||||
return state.StateInitialized
|
||||
}
|
||||
}
|
||||
|
||||
func (s *Service) CreatePaymentUrl(entry database.PaymentEntry) (database.PaymentEntry, string, error) {
|
||||
return entry, "/wspay/initialize/" + entry.Id.String(), nil
|
||||
}
|
||||
|
||||
func (s *Service) CompleteTransaction(entry database.PaymentEntry, amount int64) (database.PaymentEntry, error) {
|
||||
@@ -127,12 +173,12 @@ func (s *Service) InitializePayment(entry database.PaymentEntry) Form {
|
||||
return form
|
||||
}
|
||||
|
||||
func (s *Service) HandleSuccessResponse(c *gin.Context) (string, error) {
|
||||
func (s *Service) HandleSuccessResponse(c *gin.Context, provider *database.PaymentEntryProvider) (string, error) {
|
||||
response := FormReturn{}
|
||||
if err := c.ShouldBind(&response); err != nil {
|
||||
return "", err
|
||||
}
|
||||
entry, err := s.Provider.FetchById(uuid.MustParse(response.ShoppingCartID))
|
||||
entry, err := provider.FetchById(uuid.MustParse(response.ShoppingCartID))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -148,19 +194,19 @@ func (s *Service) HandleSuccessResponse(c *gin.Context) (string, error) {
|
||||
entry.ApprovalCode = &response.ApprovalCode
|
||||
entry.State = state.StateAccepted
|
||||
|
||||
if _, err := s.Provider.UpdateEntry(entry); err != nil {
|
||||
if _, err := provider.UpdateEntry(entry); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return "/entries/" + entry.Id.String(), nil
|
||||
}
|
||||
|
||||
func (s *Service) HandleErrorResponse(c *gin.Context, paymentState state.PaymentState) (string, error) {
|
||||
func (s *Service) HandleErrorResponse(c *gin.Context, provider *database.PaymentEntryProvider, paymentState state.PaymentState) (string, error) {
|
||||
response := FormError{}
|
||||
if err := c.ShouldBind(&response); err != nil {
|
||||
return "", err
|
||||
}
|
||||
entry, err := s.Provider.FetchById(uuid.MustParse(response.ShoppingCartID))
|
||||
entry, err := provider.FetchById(uuid.MustParse(response.ShoppingCartID))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -176,7 +222,7 @@ func (s *Service) HandleErrorResponse(c *gin.Context, paymentState state.Payment
|
||||
entry.Error = &response.ErrorMessage
|
||||
entry.State = paymentState
|
||||
|
||||
if _, err := s.Provider.UpdateEntry(entry); err != nil {
|
||||
if _, err := provider.UpdateEntry(entry); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -268,6 +314,46 @@ func CompareCompletionReturnSignature(signature string, shopId string, secret st
|
||||
}
|
||||
}
|
||||
|
||||
func CompareStatusCheckReturnSignature(signature string, shopId string, secret string, actionSuccess string, approvalCode string, cartId string) error {
|
||||
/**
|
||||
Represents a signature created from string formatted from following values in a following order using
|
||||
SHA512 algorithm:
|
||||
ShopID
|
||||
SecretKey
|
||||
ActionSuccess
|
||||
ApprovalCode
|
||||
SecretKey
|
||||
ShopID
|
||||
ApprovalCode
|
||||
WsPayOrderId
|
||||
*/
|
||||
calculatedSignature := shopId + secret + actionSuccess + approvalCode + secret + shopId + approvalCode + cartId
|
||||
hash := sha512.New()
|
||||
hash.Write([]byte(calculatedSignature))
|
||||
if hex.EncodeToString(hash.Sum(nil)) == signature {
|
||||
return nil
|
||||
} else {
|
||||
return errors.New("signature mismatch")
|
||||
}
|
||||
}
|
||||
|
||||
func CalculateStatusCheckSignature(shopId string, secret string, cartId string) string {
|
||||
/**
|
||||
Represents a signature created from string formatted from following values in a following order using
|
||||
SHA512 algorithm:
|
||||
ShopID
|
||||
SecretKey
|
||||
ShoppingCartID
|
||||
SecretKey
|
||||
ShopID
|
||||
ShoppingCartID
|
||||
*/
|
||||
signature := shopId + secret + cartId + secret + shopId + cartId
|
||||
hash := sha512.New()
|
||||
hash.Write([]byte(signature))
|
||||
return hex.EncodeToString(hash.Sum(nil))
|
||||
}
|
||||
|
||||
func readResponse[T any](httpResponse *http.Response, response T) error {
|
||||
if httpResponse.StatusCode == http.StatusOK {
|
||||
content, err := io.ReadAll(httpResponse.Body)
|
||||
|
||||
+6
-6
@@ -130,14 +130,14 @@ type StatusCheckResponse struct {
|
||||
ApprovalCode string
|
||||
ShopID string
|
||||
ShoppingCartID string
|
||||
Amount string
|
||||
Amount int64
|
||||
CurrencyCode string
|
||||
ActionSuccess string
|
||||
Success string // deprecated
|
||||
Authorized int
|
||||
Completed int
|
||||
Voided int
|
||||
Refunded int
|
||||
Authorized string
|
||||
Completed string
|
||||
Voided string
|
||||
Refunded string
|
||||
PaymentPlan string
|
||||
Partner string
|
||||
OnSite int
|
||||
@@ -151,7 +151,7 @@ type StatusCheckResponse struct {
|
||||
CustomerCountry string
|
||||
CustomerPhone string
|
||||
CustomerEmail string
|
||||
TransactionDateTime string //yyyymmddHHMMss
|
||||
TransactionDateTime string // yyyymmddHHMMss
|
||||
IsLessThan30DaysFromTransaction bool
|
||||
CanBeCompleted bool
|
||||
CanBeVoided bool
|
||||
|
||||
Reference in new issue
Block a user