fixed issue in creditcall payment processing where error description was not properly set

This commit is contained in:
yurii 2025-08-26 16:13:21 +01:00
parent 251afd6aeb
commit bb8cdb1d84
3 changed files with 47 additions and 62 deletions

View File

@ -29,7 +29,7 @@ import (
) )
const ( const (
buildVersion = "1.0.13" buildVersion = "1.0.14"
serviceName = "hardlink" serviceName = "hardlink"
customLayout = "2006-01-02 15:04:05 -0700" customLayout = "2006-01-02 15:04:05 -0700"
transactionUrl = "http://127.0.0.1:18181/start-transaction/" transactionUrl = "http://127.0.0.1:18181/start-transaction/"
@ -259,7 +259,7 @@ func (app *App) startTransaction(w http.ResponseWriter, r *http.Request) {
return return
} }
client := &http.Client{Timeout: 90 * time.Second} client := &http.Client{Timeout: 300 * time.Second}
response, err := client.Post(transactionUrl, "text/xml", r.Body) response, err := client.Post(transactionUrl, "text/xml", r.Body)
if err != nil { if err != nil {
logging.Error(serviceName, err.Error(), "Payment processing error", string(op), "", "", 0) logging.Error(serviceName, err.Error(), "Payment processing error", string(op), "", "", 0)

View File

@ -218,63 +218,45 @@ func nullableFloatArg(nf sql.NullFloat64) interface{} {
} }
func BuildRedirectURL(result map[string]string) string { func BuildRedirectURL(result map[string]string) string {
// 1) normalize the result code var msgType, description string
q := url.Values{}
res := strings.ToLower(result["TRANSACTION_RESULT"]) res := strings.ToLower(result["TRANSACTION_RESULT"])
// 2) pick base path and optional error params if res == ResultApproved {
var basePath string q.Set("TxnReference", result["REFERENCE"])
var msgType, description string q.Set("CardHash", hex.EncodeToString([]byte(result["CARD_HASH"])))
q.Set("CardReference", hex.EncodeToString([]byte(result["CARD_REFERENCE"])))
switch res { u := url.URL{
case ResultApproved: Path: CheckinSuccessfulEndpoint,
basePath = CheckinSuccessfulEndpoint RawQuery: q.Encode(),
}
case ResultDeclined: return u.String()
basePath = CheckinUnsuccessfulEndpoint
msgType = "declined"
description = "payment declined"
case ResultCancelled:
basePath = CheckinUnsuccessfulEndpoint
msgType = "cancelled"
description = "payment cancelled by customer"
case ResultPending:
// you could choose to treat pending as unsuccessful or special-case it
basePath = CheckinUnsuccessfulEndpoint
msgType = "pending"
description = "payment pending"
case ResultError:
basePath = CheckinUnsuccessfulEndpoint
msgType = "error"
description = result["ERROR"]
default:
basePath = CheckinUnsuccessfulEndpoint
msgType = "error"
description = "unknown transaction result"
} }
if msgType != "" { msgType = ResultError
log.Warnf("Transaction %s: %s - %s", res, msgType, description) if res != "" {
msgType = res
} }
// 3) build query params errors, ok := result["ERRORS"]
q := url.Values{} if ok && errors != "" {
q.Set("TxnReference", result["REFERENCE"]) description = errors
q.Set("CardHash", hex.EncodeToString([]byte(result["CARD_HASH"]))) }
q.Set("CardReference", hex.EncodeToString([]byte(result["CARD_REFERENCE"]))) errors, ok = result["ERROR"]
if ok && errors != "" {
// only append these when non-approved description += " " + errors
if msgType != "" { }
q.Set("MsgType", msgType) if description == "" {
q.Set("Description", description) description = "Transaction failed"
} }
// 4) assemble final URL log.Errorf("Transaction %s: %s", msgType, description)
// note: url.URL automatically escapes values in RawQuery
q.Set("MsgType", msgType)
q.Set("Description", description)
u := url.URL{ u := url.URL{
Path: basePath, Path: CheckinUnsuccessfulEndpoint,
RawQuery: q.Encode(), RawQuery: q.Encode(),
} }
return u.String() return u.String()

View File

@ -2,44 +2,47 @@
builtVersion is a const in main.go builtVersion is a const in main.go
#### 1.0.14 - 21 August 2025
fixed issue in creditcall payment processing where error description was not properly set
#### 1.0.13 - 21 August 2025 #### 1.0.13 - 21 August 2025
TCP/IP connection to the lock server is now established before encoding the keycard and closedafter the encoding is done. TCP/IP connection to the lock server is now established before encoding the keycard and closedafter the encoding is done.
#### 1.0.12 - 11 August 2024 #### 1.0.12 - 11 August 2025
added delay before checking dispenser status added delay before checking dispenser status
#### 1.0.11 - 11 August 2024 #### 1.0.11 - 11 August 2025
updated Salto key encoding workflow updated Salto key encoding workflow
#### 1.0.10 - 08 August 2024 #### 1.0.10 - 08 August 2025
updated logging for TLJ locks updated logging for TLJ locks
#### 1.0.9 - 08 August 2024 #### 1.0.9 - 08 August 2025
added TLJ lock server and implemented workflow for TLJ locks added TLJ lock server and implemented workflow for TLJ locks
#### 1.0.8 - 01 August 2024 #### 1.0.8 - 01 August 2025
improved error handling and logging in Salto improved error handling and logging in Salto
#### 1.0.7 - 25 July 2024 #### 1.0.7 - 25 July 2025
added check if the room exists added check if the room exists
#### 1.0.6 - 25 July 2024 #### 1.0.6 - 25 July 2025
updated workflow for Salto locks updated workflow for Salto locks
#### 1.0.5 - 24 July 2024 #### 1.0.5 - 24 July 2025
added encoding keycard copy for Salto locks added encoding keycard copy for Salto locks
#### 1.0.4 - 22 July 2024 #### 1.0.4 - 22 July 2025
added salto lock server and implemented workflow for Salto added salto lock server and implemented workflow for Salto
#### 1.0.0 - 30 June 2024 #### 1.0.0 - 30 June 2025
added creditcall payment method added creditcall payment method
`/starttransaction` - API payment endpoint to start a transaction `/starttransaction` - API payment endpoint to start a transaction
#### 0.9.1 - 22 May 2024 #### 0.9.1 - 22 May 2025
added lockserver interface and implemented workflow for Omnitec added lockserver interface and implemented workflow for Omnitec
#### 0.9.0 - 22 May 2024 #### 0.9.0 - 22 May 2025
The new API has two new endpoints: The new API has two new endpoints:
- `/issuedoorcard` - encoding the door card for the room. - `/issuedoorcard` - encoding the door card for the room.
- `/printroomticket` - printing the room ticket. - `/printroomticket` - printing the room ticket.