camper/pkg/redsys/client.go

94 lines
2.3 KiB
Go

/*
* SPDX-FileCopyrightText: 2023 jordi fita mas <jfita@peritasoft.com>
* 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)
}