/* * SPDX-FileCopyrightText: 2023 jordi fita mas * SPDX-License-Identifier: AGPL-3.0-only */ package redsys import ( "context" "fmt" "github.com/jackc/pgtype" "golang.org/x/text/language" "dev.tandem.ws/tandem/camper/pkg/auth" "dev.tandem.ws/tandem/camper/pkg/database" ) type TransactionType int const ( TransactionTypeCharge TransactionType = 0 TransactionTypeRefund TransactionType = 3 TransactionTypePreauth TransactionType = 1 TransactionTypePreauthConfirm TransactionType = 2 TransactionTypePreauthVoid TransactionType = 9 TransactionTypeSplitAuth TransactionType = 7 TransactionTypeSplitConfirm TransactionType = 8 ) type Request struct { TransactionType TransactionType Amount string OrderNumber string Product string CardHolder string SuccessURL string FailureURL string NotificationURL string ConsumerLanguage language.Tag } type SignedRequest struct { MerchantParameters string Signature string SignatureVersion string } func SignRequest(ctx context.Context, conn *database.Conn, company *auth.Company, req *Request) (*SignedRequest, error) { row := conn.QueryRow(ctx, "select redsys_sign_request($1, $2)", company.ID, req) signed := &SignedRequest{} if err := row.Scan(&signed); err != nil { return nil, err } return signed, nil } func (src Request) EncodeText(ci *pgtype.ConnInfo, dst []byte) ([]byte, error) { typeName := database.RedsysRequestTypeName dt, ok := ci.DataTypeForName(typeName) if !ok { return nil, fmt.Errorf("unable to find oid for type name %v", typeName) } values := []interface{}{ src.TransactionType, src.Amount, src.OrderNumber, src.Product, src.CardHolder, src.SuccessURL, src.FailureURL, src.NotificationURL, src.ConsumerLanguage, } ct := pgtype.NewValue(dt.Value).(*pgtype.CompositeType) if err := ct.Set(values); err != nil { return nil, err } return ct.EncodeText(ci, dst) } func (dst *SignedRequest) DecodeText(ci *pgtype.ConnInfo, src []byte) error { typeName := database.RedsysSignedRequestTypeName dt, ok := ci.DataTypeForName(typeName) if !ok { return fmt.Errorf("unable to find oid for type name %v", typeName) } ct := pgtype.NewValue(dt.Value).(*pgtype.CompositeType) if err := ct.DecodeText(ci, src); err != nil { return err } return ct.AssignTo(dst) }