start of preauth
This commit is contained in:
parent
bb526a248d
commit
56d33b167a
@ -43,6 +43,7 @@ func (app *App) RegisterRoutes(mux *http.ServeMux) {
|
||||
mux.HandleFunc("/issuedoorcard", app.issueDoorCard)
|
||||
mux.HandleFunc("/printroomticket", app.printRoomTicket)
|
||||
mux.HandleFunc("/starttransaction", app.startTransaction)
|
||||
mux.HandleFunc("/startandconfirmtransaction", app.startAndConfirmTransaction)
|
||||
}
|
||||
|
||||
func (app *App) startTransaction(w http.ResponseWriter, r *http.Request) {
|
||||
@ -95,7 +96,106 @@ func (app *App) startTransaction(w http.ResponseWriter, r *http.Request) {
|
||||
writeTransactionResult(w, http.StatusBadRequest, theResponse)
|
||||
return
|
||||
}
|
||||
log.Printf("Start trnasaction payload: Amount=%s, Type=%s", theRequest.AmountMinorUnits, theRequest.TransactionType)
|
||||
log.Printf("Transaction payload: Amount=%s, Type=%s", theRequest.AmountMinorUnits, theRequest.TransactionType)
|
||||
|
||||
client := &http.Client{Timeout: 300 * time.Second}
|
||||
response, err := client.Post(transactionUrl, "text/xml", bytes.NewBuffer(body))
|
||||
if err != nil {
|
||||
logging.Error(serviceName, err.Error(), "Payment processing error", string(op), "", "", 0)
|
||||
theResponse.Data = payment.BuildFailureURL(payment.ResultError, "No response from payment processor")
|
||||
writeTransactionResult(w, http.StatusBadGateway, theResponse)
|
||||
return
|
||||
}
|
||||
defer response.Body.Close()
|
||||
|
||||
body, err = io.ReadAll(response.Body)
|
||||
if err != nil {
|
||||
logging.Error(serviceName, err.Error(), "Read response body error", string(op), "", "", 0)
|
||||
theResponse.Data = payment.BuildFailureURL(payment.ResultError, "Failed to read response body")
|
||||
writeTransactionResult(w, http.StatusInternalServerError, theResponse)
|
||||
return
|
||||
}
|
||||
|
||||
if err := trResult.ParseTransactionResult(body); err != nil {
|
||||
logging.Error(serviceName, err.Error(), "Parse transaction result error", string(op), "", "", 0)
|
||||
}
|
||||
|
||||
// Compose JSON from responseEntries
|
||||
result := make(map[string]string)
|
||||
for _, e := range trResult.Entries {
|
||||
switch e.Key {
|
||||
case payment.ReceiptData, payment.ReceiptDataMerchant:
|
||||
// ignore these
|
||||
case payment.ReceiptDataCardholder:
|
||||
cardholderReceipt = e.Value
|
||||
case payment.TransactionResult:
|
||||
theResponse.Status.Message = e.Value
|
||||
theResponse.Status.Code = http.StatusOK
|
||||
result[e.Key] = e.Value
|
||||
default:
|
||||
result[e.Key] = e.Value
|
||||
}
|
||||
}
|
||||
|
||||
if err := printer.PrintCardholderReceipt(cardholderReceipt); err != nil {
|
||||
log.Errorf("PrintCardholderReceipt error: %v", err)
|
||||
}
|
||||
|
||||
theResponse.Data = payment.BuildPaymentRedirectURL(result)
|
||||
writeTransactionResult(w, http.StatusOK, theResponse)
|
||||
}
|
||||
|
||||
func (app *App) startAndConfirmTransaction(w http.ResponseWriter, r *http.Request) {
|
||||
const op = logging.Op("startAndConfirmTransaction")
|
||||
var (
|
||||
theResponse cmstypes.ResponseRec
|
||||
cardholderReceipt string
|
||||
theRequest cmstypes.TransactionRec
|
||||
trResult payment.TransactionResultXML
|
||||
)
|
||||
|
||||
theResponse.Status.Code = http.StatusInternalServerError
|
||||
theResponse.Status.Message = "500 Internal server error"
|
||||
|
||||
w.Header().Set("Access-Control-Allow-Origin", "*")
|
||||
w.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS")
|
||||
w.Header().Set("Access-Control-Allow-Headers", "Content-Type")
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
|
||||
if !app.isPayment {
|
||||
theResponse.Data = payment.BuildFailureURL(payment.ResultError, "Payment processing is disabled")
|
||||
writeTransactionResult(w, http.StatusServiceUnavailable, theResponse)
|
||||
return
|
||||
}
|
||||
|
||||
if r.Method == http.MethodOptions {
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
return
|
||||
}
|
||||
|
||||
log.Println("startAndConfirmTransaction called")
|
||||
if r.Method != http.MethodPost {
|
||||
theResponse.Data = payment.BuildFailureURL(payment.ResultError, "Method not allowed; use POST")
|
||||
writeTransactionResult(w, http.StatusMethodNotAllowed, theResponse)
|
||||
return
|
||||
}
|
||||
defer r.Body.Close()
|
||||
|
||||
if ct := r.Header.Get("Content-Type"); ct != "text/xml" {
|
||||
theResponse.Data = payment.BuildFailureURL(payment.ResultError, "Content-Type must be text/xml")
|
||||
writeTransactionResult(w, http.StatusUnsupportedMediaType, theResponse)
|
||||
return
|
||||
}
|
||||
|
||||
body, _ := io.ReadAll(r.Body)
|
||||
err := xml.Unmarshal(body, &theRequest)
|
||||
if err != nil {
|
||||
logging.Error(serviceName, err.Error(), "ReadXML", string(op), "", "", 0)
|
||||
theResponse.Data = payment.BuildFailureURL(payment.ResultError, "Invalid XML payload")
|
||||
writeTransactionResult(w, http.StatusBadRequest, theResponse)
|
||||
return
|
||||
}
|
||||
log.Printf("Transaction payload: Amount=%s, Type=%s", theRequest.AmountMinorUnits, theRequest.TransactionType)
|
||||
|
||||
client := &http.Client{Timeout: 300 * time.Second}
|
||||
response, err := client.Post(transactionUrl, "text/xml", bytes.NewBuffer(body))
|
||||
|
||||
@ -248,7 +248,7 @@ func nullableFloatArg(nf sql.NullFloat64) interface{} {
|
||||
}
|
||||
|
||||
// BuildRedirectURL builds the redirect URL to send the guest to after payment.
|
||||
func BuildRedirectURL(result map[string]string) string {
|
||||
func BuildPaymentRedirectURL(result map[string]string) string {
|
||||
res := result[TransactionResult]
|
||||
tType := result[TransactionType]
|
||||
|
||||
@ -284,6 +284,34 @@ func BuildRedirectURL(result map[string]string) string {
|
||||
return BuildFailureURL(res, result[Errors])
|
||||
}
|
||||
|
||||
func BuildPreauthRedirectURL(result map[string]string) string {
|
||||
res := result[TransactionResult]
|
||||
tType := result[TransactionType]
|
||||
|
||||
// Transaction approved?
|
||||
if strings.EqualFold(res, ResultApproved) {
|
||||
switch {
|
||||
// Transaction type AccountVerification?
|
||||
case strings.EqualFold(tType, AccountVerificationType):
|
||||
log.WithField(LogResult, result[TransactionResult]).
|
||||
Info("Account verification approved")
|
||||
|
||||
return buildSuccessURL(result)
|
||||
|
||||
// Transaction type Sale?
|
||||
case strings.EqualFold(tType, SaleTransactionType):
|
||||
// Transaction confirmed?
|
||||
log.WithField(LogResult, result[ConfirmResult]).
|
||||
Info("Transaction approved and confirmed")
|
||||
|
||||
return buildSuccessURL(result)
|
||||
}
|
||||
}
|
||||
|
||||
// Not approved
|
||||
return BuildFailureURL(res, result[Errors])
|
||||
}
|
||||
|
||||
func buildSuccessURL(result map[string]string) string {
|
||||
q := url.Values{}
|
||||
q.Set("TxnReference", result[Reference])
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user