paymentmanager

package module
v0.4.48 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Nov 11, 2026 License: MIT Imports: 13 Imported by: 0

README

Payment Manager

Módulo de dominio para registrar pagos de mesón (efectivo, débito, crédito, transferencia) y pagos online (Webpay Plus, vía una pasarela inyectada). Maneja devoluciones y la conciliación con la pasarela. Diseño: docs/ARCHITECTURE.md; flujos y ramas probadas: docs/diagrams/flows.md.

Inicio rápido

En la raíz del repo, abre la demo (pantalla Pagos y un paso de cobro de mesón, con la pasarela en memoria sandbox):

webtyp

Operaciones

Op Descripción Requiere
get_charge Consulta el valor a pagar y su moneda payment_online, Read
create_counter_payment Registra un pago de mesón (genera un número de recibo secuencial) payment, Create
start_online_payment Inicia flujo webpay payment_online, Create
get_payment_status Estado actual de un pago payment_online, Read
get_payment Obtiene un pago (limpio de token) payment, Read
list_payments_by_reference Pagos de una reserva/referencia payment, Read
list_payments Lista pagos payment, Read
refund_payment Realiza una devolución parcial o total refund, Create
list_refunds Devoluciones de un pago refund, Read
start_terminal_payment Inicia cobro en máquina payment, Create
refresh_terminal_payment Refresca el estado en la máquina payment, Update
reconcile_payments Cierra pagos online y de máquina pendientes payment, Update

Estados

Estado Descripción
PENDING Pago online iniciado, esperando respuesta de pasarela
PAID Pago completado y acreditado
FAILED Pago rechazado por la pasarela
CANCELLED El cliente abortó o canceló el flujo webpay, o cancelado en la máquina
EXPIRED El pago webpay no fue completado a tiempo
PARTIALLY_REFUNDED Se devolvió parte del monto, pero queda saldo
REFUNDED Devolución total del monto

Cableado en una app

gw, _ := transbank.Open(env.Get(transbank.EnvWebpay)) // github.com/veltylabs/transbank
pos := tuu.NewTerminal()
pm, err := paymentmanager.New(db, paymentmanager.Deps{
	Publisher: broker,
	Gateway:   gw,
	Terminal:  pos,
	Charges:   []paymentmanager.ChargeSource{{Module: "appointment_booking", Reader: bookingModule, Device: "POS-12345"}},
})
  • El esquema lo crea migrate.Migrate(conn, compiler) desde el cmd/migrate de la app.
  • La app corre reconcile_payments cada minuto.
  • ui.PaymentStep es el paso de cobro que incrustan otras pantallas; ui.Browser es la pantalla Pagos; ui.TakeReturn lee la vuelta de la pasarela.

Economic facts

Este módulo publica hechos económicos (money.Fact) usando la dependencia webtyp.com/money. Cuando un pago es completado exitosamente o una devolución es registrada, se publican hechos Charged y Refunded (respectivamente) sobre el events.Publisher configurado en Deps.Publisher. El Scope corresponde al módulo que pidió el cobro (ReferenceModule). La contabilidad y seguimiento de caja quedan fuera de payment_manager y se realizan en otro lado suscribiéndose a estos hechos (money.Subscribe).

Archivos clave

Archivo Qué contiene
model.go / model_orm.go Modelos (model_orm.go lo genera ormc; no editar)
fsm.go Máquina de estados del pago
ports.go Puertos Gateway y ChargeReader
module.go / repository.go Servicio y consultas
ops.go Operaciones, recursos RBAC y códigos HTTP
view.go Presenter de la lista de pagos
amount.go FormatAmount
sandbox/ Pasarela en memoria para pruebas y demo
migrate/ Esquema (payment, refund)
ui/ Paso de pago, pantalla Pagos, vuelta de la pasarela
seed/, web/ Datos y demo
  • Errores: los errores se envían por rpc.WriteError y usan constantes fuertemente tipadas de model.NotFound, model.Conflict y model.Invalid.
  • Permisos: permisos por tabla configurados con model.ResourceOf.
  • Modelo: claves foráneas declaradas con la estructura Ref.

Documentation

Index

Constants

View Source
const (
	StatusStarted    = "started"
	ReconcilePending = "pending"
	ReconcileDone    = "done"
)
View Source
const (
	QueryPayment = "payment"
	QueryStatus  = "status"
)

QueryPayment y QueryStatus son los parámetros de la query con que la ruta de retorno de la pasarela devuelve al cliente a la app.

View Source
const (
	ChannelCounter  = "counter"
	ChannelOnline   = "online"
	ChannelTerminal = "terminal" // cobro en caja empujado a la máquina de tarjeta
)
View Source
const (
	MethodCash     = "cash"
	MethodDebit    = "debit"
	MethodCredit   = "credit"
	MethodTransfer = "transfer"
	MethodCard     = "card" // pago en línea con tarjeta, cualquiera sea el procesador
)
View Source
const (
	CurrencyCLP = "CLP"
	CurrencyUSD = "USD"
)
View Source
const (
	StatusPending           = "PENDING"
	StatusPaid              = "PAID"
	StatusFailed            = "FAILED"
	StatusCancelled         = "CANCELLED" // el cliente abandonó el pago online
	StatusExpired           = "EXPIRED"   // venció sin respuesta de la pasarela
	StatusPartiallyRefunded = "PARTIALLY_REFUNDED"
	StatusRefunded          = "REFUNDED"
)
View Source
const (
	RefundKindReversed  = "REVERSED"  // pasarela: reversa total
	RefundKindNullified = "NULLIFIED" // pasarela: anulación total o parcial
	RefundKindManual    = "MANUAL"    // mesón: devolución registrada por el cajero
)
View Source
const (
	PendingTimeout      = 600       // un pago PENDING (online o máquina) más viejo que esto se concilia
	GatewayStatusWindow = 7 * 86400 // la pasarela guarda el estado 7 días
)

Tiempos (segundos).

View Source
const (
	SourcePayment    = "payment"
	SourcePaymentFee = "payment_fee"
	SourceRefund     = "refund"
)

Origen de los hechos.

View Source
const (
	EventPay           = "PAY"
	EventFail          = "FAIL"
	EventCancel        = "CANCEL"
	EventExpire        = "EXPIRE"
	EventRefundPartial = "REFUND_PARTIAL"
	EventRefundTotal   = "REFUND_TOTAL"
)

Eventos de la máquina de estados del pago.

View Source
const (
	EventPaymentPaid     = "payment.paid"
	EventPaymentFailed   = "payment.failed"
	EventPaymentRefunded = "payment.refunded"
)

Eventos publicados después de cada mutación exitosa. Payload: *Payment, o *Refund en EventPaymentRefunded.

View Source
const (
	OutcomePending    = "pending"
	OutcomeAuthorized = "authorized"
	OutcomeRejected   = "rejected"
	OutcomeCancelled  = "cancelled"
	OutcomeExpired    = "expired"
)
View Source
const (
	DefaultTerminalPushSeconds      = 5  // the machine must accept the charge or the cashier is told «no connection»
	DefaultTerminalPayWindowSeconds = 30 // how long the customer has to pass the card before the payment is offered for manual confirmation
	DefaultOnlineStartSeconds       = 10 // the gateway must answer with the payment link
	TerminalPushCapSeconds          = 10 // Definition caps: Timeouts above them are refused by New
	OnlineStartCapSeconds           = 15
)
View Source
const ErrCannotRead = model.Invalid("payment_manager: cannot read the request")
View Source
const ListWindowSeconds = 30 * time.Day

ListWindowSeconds es cuánto hacia atrás muestra la lista de pagos: 30 días.

View Source
const ModelName = "payment_manager"

ModelName is the module identity: Definition.Name.

Variables

View Source
var (
	ErrNotFound            = model.NotFound("payment not found")
	ErrRefundNotFound      = model.NotFound("refund not found")
	ErrMissingArgs         = model.Invalid("missing required arguments")
	ErrUnknownReference    = model.Invalid("no charge reader for this reference module")
	ErrNotPayable          = model.Invalid("the reference has nothing to pay")
	ErrUnsupportedCurrency = model.Invalid("unsupported currency")
	ErrInvalidMethod       = model.Invalid("invalid payment method for this channel")
	ErrInvalidTransition   = model.Invalid("invalid payment status transition")
	ErrRefundExceeds       = model.Invalid("refund amount exceeds what is left to refund")
	ErrIdTaken             = model.Conflict("id already used by another operation")
	ErrAlreadyPaid         = model.Conflict("the reference is already paid")
	ErrNotPaid             = model.Conflict("payment is not paid")
	ErrConflict            = model.Conflict("payment changed concurrently")
	ErrGatewayUnavailable  = model.Invalid("online payments are not configured")
	ErrGatewayFailed       = model.Invalid("payment gateway call failed")
	ErrAmountMismatch      = model.Invalid("gateway amount differs from the payment amount")
	ErrTerminalUnavailable = model.Invalid("card terminal payments are not configured")
	ErrNoTerminalDevice    = model.Invalid("no card terminal device for this reference module")
	ErrTerminalFailed      = model.Invalid("card terminal call failed")
	ErrTerminalRequired    = model.Invalid("card payments for this reference go through the card terminal")
	ErrNotTerminal         = model.Invalid("payment is not a card terminal payment")
	ErrTokenMismatch       = model.Invalid("the return's token is not this payment's; nothing was changed")
)
View Source
var (
	ErrTimeoutOutOfRange   = fmt.Err("a wait is negative or longer than the module allows, so the module did not start; use a value between 1 and the limit documented in Timeouts")
	ErrTerminalUnreachable = fmt.Err("the card machine did not answer, so nothing was charged by this module; charge it on the machine and press «pago realizado correctamente»")
	ErrPaymentNotPending   = fmt.Err("this payment is no longer pending, so it cannot be confirmed")
	ErrStillPending        = fmt.Err("the machine has not finished yet; asking again shortly")
)
View Source
var ChargeResultModel = model.Definition{
	Name: "charge_result",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text(), NotNull: true},
		{Name: "reference_module", Type: model.Text(), NotNull: true},
		{Name: "reference_id", Type: model.Text(), NotNull: true},
		{Name: "amount", Type: model.Int()},
		{Name: "currency", Type: model.Text()},
		{Name: "payable", Type: model.Bool()},
		{Name: "terminal", Type: model.Bool()},
	},
	Allow: model.Read,
	Rules: model.Rules{
		Read: model.AddMyBusinessRule,
	},
}
View Source
var OnlinePaymentRequestModel = model.Definition{
	Name: "payment_online_request",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}, NotNull: true, Permitted: model.Permitted{Letters: true, Numbers: true, Extra: []rune{'.', '-', '_'}, Minimum: 1, Maximum: 26}},
		{Name: "tenant_id", Type: model.Text(), NotNull: true, ServerOnly: true},
		{Name: "reference_module", Type: model.Text(), NotNull: true},
		{Name: "reference_id", Type: model.Text(), NotNull: true},
		{Name: "return_url", Type: input.Text()},
		{Name: "payment_id", Type: model.Text(), ServerOnly: true},
		{Name: "redirect_url", Type: model.Text(), ServerOnly: true},
		{Name: "status", Type: model.Text(), ServerOnly: true},
		{Name: "failure", Type: model.Text(), ServerOnly: true},
		{Name: "created_at", Type: model.UnixTime(), ServerOnly: true},
		{Name: "payer_name", Type: model.Text()},
		{Name: "payer_email", Type: model.Text()},
		{Name: "payer_phone", Type: model.Text()},
		{Name: "token", Type: model.Text(), ServerOnly: true},
		{Name: "token_field", Type: model.Text(), ServerOnly: true},
	},
	Allow: model.Create | model.Read,
	Rules: model.Rules{
		Create: model.AddMyBusinessRule,
		Read:   model.HaveNoBusinessRule,
	},
	ExternalCalls: []model.ExternalCallDefinition{
		{Name: "GatewayStart", Mode: model.WaitForReply, MaxWaitSeconds: 15},
	},
}
View Source
var OnlinePaymentRequest_ = struct {
	Id              string
	TenantId        string
	ReferenceModule string
	ReferenceId     string
	ReturnUrl       string
	PaymentId       string
	RedirectUrl     string
	Status          string
	Failure         string
	CreatedAt       string
	PayerName       string
	PayerEmail      string
	PayerPhone      string
	Token           string
	TokenField      string
}{
	Id:              "id",
	TenantId:        "tenant_id",
	ReferenceModule: "reference_module",
	ReferenceId:     "reference_id",
	ReturnUrl:       "return_url",
	PaymentId:       "payment_id",
	RedirectUrl:     "redirect_url",
	Status:          "status",
	Failure:         "failure",
	CreatedAt:       "created_at",
	PayerName:       "payer_name",
	PayerEmail:      "payer_email",
	PayerPhone:      "payer_phone",
	Token:           "token",
	TokenField:      "token_field",
}
View Source
var PaymentCounterModel = model.Definition{
	Name: "payment_counter",
	Fields: model.Fields{
		{Name: "tenant_id", Type: model.Text(), DB: &model.FieldDB{PK: true}, NotNull: true},
		{Name: "next_number", Type: model.Int(), NotNull: true},
	},
}
View Source
var PaymentCounter_ = struct {
	TenantId   string
	NextNumber string
}{
	TenantId:   "tenant_id",
	NextNumber: "next_number",
}
View Source
var PaymentManualConfirmationModel = model.Definition{
	Name: "payment_manual_confirmation",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}, NotNull: true, Permitted: model.Permitted{Letters: true, Numbers: true, Extra: []rune{'.', '-', '_'}, Minimum: 1, Maximum: 26}},
		{Name: "tenant_id", Type: model.Text(), NotNull: true, ServerOnly: true},
		{Name: "payment_id", Type: model.Text(), NotNull: true},
		{Name: "note", Type: input.Text(), NotNull: true},
		{Name: "actor_id", Type: model.Text(), ServerOnly: true},
		{Name: "created_at", Type: model.UnixTime(), ServerOnly: true},
	},
	Allow: model.Create | model.Read,
	Rules: model.Rules{
		Create: model.AddMyBusinessRule,
		Read:   model.HaveNoBusinessRule,
	},
	ExternalCalls: []model.ExternalCallDefinition{
		{Name: "Confirm", Mode: model.WaitForReply, MaxWaitSeconds: 10},
	},
}
View Source
var PaymentManualConfirmation_ = struct {
	Id        string
	TenantId  string
	PaymentId string
	Note      string
	ActorId   string
	CreatedAt string
}{
	Id:        "id",
	TenantId:  "tenant_id",
	PaymentId: "payment_id",
	Note:      "note",
	ActorId:   "actor_id",
	CreatedAt: "created_at",
}
View Source
var PaymentModel = model.Definition{
	Name: "payment",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}, NotNull: true, Permitted: model.Permitted{Letters: true, Numbers: true, Extra: []rune{'.', '-', '_'}, Minimum: 1, Maximum: 26}},
		{Name: "tenant_id", Type: model.Text(), NotNull: true, ServerOnly: true},
		{Name: "reference_module", Type: model.Text(), NotNull: true, Item: model.ItemDescription, Permitted: model.Permitted{Maximum: 60}},
		{Name: "reference_id", Type: model.Text(), NotNull: true, Item: model.ItemDescription, Permitted: model.Permitted{Maximum: 64}},
		{Name: "channel", Type: model.Text(), NotNull: true},
		{Name: "method", Type: model.Text(), NotNull: true, Item: model.ItemDescription},
		{Name: "amount", Type: model.Int(), NotNull: true, Item: model.ItemLabel, ServerOnly: true},
		{Name: "currency", Type: model.Text(), NotNull: true, Item: model.ItemDescription, Permitted: model.Permitted{Letters: true, Minimum: 3, Maximum: 3}},
		{Name: "status", Type: model.Text(), NotNull: true, Item: model.ItemDescription, ServerOnly: true},
		{Name: "refunded_amount", Type: model.Int()},
		{Name: "provider_token", Type: model.Text(), OmitEmpty: true, ServerOnly: true},
		{Name: "provider", Type: model.Text(), OmitEmpty: true, Permitted: model.Permitted{Letters: true, Numbers: true, Extra: []rune{'_', '-'}, Maximum: 30}, ServerOnly: true},

		{Name: "authorization_code", Type: model.Text(), OmitEmpty: true, Permitted: model.Permitted{Letters: true, Numbers: true, Maximum: 6}},
		{Name: "payment_type_code", Type: model.Text(), OmitEmpty: true, Permitted: model.Permitted{Letters: true, Maximum: 2}},
		{Name: "installments", Type: model.Int(), OmitEmpty: true},
		{Name: "card_last4", Type: model.Text(), OmitEmpty: true, Permitted: model.Permitted{Numbers: true, Maximum: 4}},
		{Name: "receipt_number", Type: model.Text(), OmitEmpty: true, Permitted: model.Permitted{Maximum: 40}},
		{Name: "return_to", Type: model.Text(), OmitEmpty: true, Permitted: model.Permitted{Letters: true, Numbers: true, Extra: []rune{'_', '-'}, Maximum: 60}},
		{Name: "created_by", Type: model.Text(), OmitEmpty: true},
		{Name: "created_at", Type: model.UnixTime(), ServerOnly: true},
		{Name: "paid_at", Type: model.UnixTime(), OmitEmpty: true},
		{Name: "updated_at", Type: model.UnixTime(), ServerOnly: true},
		{Name: "revision", Type: model.Int()},
	},
	Allow: model.Create | model.Read,
	Rules: model.Rules{
		Create: model.AddMyBusinessRule,
		Read:   model.HaveNoBusinessRule,
	},
	ExternalCalls: []model.ExternalCallDefinition{
		{Name: "TerminalPush", Mode: model.WaitForReply, MaxWaitSeconds: 10},
		{Name: "TerminalStatus", Mode: model.RetryInBackground, MaxAttempts: 20},
	},
}
View Source
var PaymentReconciliationModel = model.Definition{
	Name: "payment_reconciliation",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}, NotNull: true, Permitted: model.Permitted{Letters: true, Numbers: true, Extra: []rune{'.', '-', '_'}, Minimum: 1, Maximum: 26}},
		{Name: "tenant_id", Type: model.Text(), NotNull: true, ServerOnly: true},
		{Name: "status", Type: model.Text(), ServerOnly: true},
		{Name: "failure", Type: model.Text(), ServerOnly: true},
		{Name: "reconciled", Type: model.Int(), ServerOnly: true},
		{Name: "actor_id", Type: model.Text(), ServerOnly: true},
		{Name: "created_at", Type: model.UnixTime(), ServerOnly: true},
	},
	Allow: model.Create | model.Read,
	Rules: model.Rules{
		Create: model.AddMyBusinessRule,
		Read:   model.HaveNoBusinessRule,
	},
	ExternalCalls: []model.ExternalCallDefinition{
		{Name: "Reconcile", Mode: model.RetryInBackground, MaxAttempts: 3},
	},
}
View Source
var PaymentReconciliation_ = struct {
	Id         string
	TenantId   string
	Status     string
	Failure    string
	Reconciled string
	ActorId    string
	CreatedAt  string
}{
	Id:         "id",
	TenantId:   "tenant_id",
	Status:     "status",
	Failure:    "failure",
	Reconciled: "reconciled",
	ActorId:    "actor_id",
	CreatedAt:  "created_at",
}
View Source
var PaymentStatusResultModel = model.Definition{
	Name: "payment_status_result",
	Fields: model.Fields{
		{Name: "id", Type: model.Text()},
		{Name: "tenant_id", Type: model.Text(), NotNull: true},
		{Name: "status", Type: model.Text()},
	},
	Allow: model.Read,
	Rules: model.Rules{
		Read: model.AddMyBusinessRule,
	},
}
View Source
var Payment_ = struct {
	Id                string
	TenantId          string
	ReferenceModule   string
	ReferenceId       string
	Channel           string
	Method            string
	Amount            string
	Currency          string
	Status            string
	RefundedAmount    string
	ProviderToken     string
	Provider          string
	AuthorizationCode string
	PaymentTypeCode   string
	Installments      string
	CardLast4         string
	ReceiptNumber     string
	ReturnTo          string
	CreatedBy         string
	CreatedAt         string
	PaidAt            string
	UpdatedAt         string
	Revision          string
}{
	Id:                "id",
	TenantId:          "tenant_id",
	ReferenceModule:   "reference_module",
	ReferenceId:       "reference_id",
	Channel:           "channel",
	Method:            "method",
	Amount:            "amount",
	Currency:          "currency",
	Status:            "status",
	RefundedAmount:    "refunded_amount",
	ProviderToken:     "provider_token",
	Provider:          "provider",
	AuthorizationCode: "authorization_code",
	PaymentTypeCode:   "payment_type_code",
	Installments:      "installments",
	CardLast4:         "card_last4",
	ReceiptNumber:     "receipt_number",
	ReturnTo:          "return_to",
	CreatedBy:         "created_by",
	CreatedAt:         "created_at",
	PaidAt:            "paid_at",
	UpdatedAt:         "updated_at",
	Revision:          "revision",
}
View Source
var RefundModel = model.Definition{
	Name: "refund",
	Fields: model.Fields{
		{Name: "id", Type: model.Text(), DB: &model.FieldDB{PK: true}, NotNull: true, Permitted: model.Permitted{Letters: true, Numbers: true, Extra: []rune{'.', '-', '_'}, Minimum: 1, Maximum: 26}},
		{Name: "tenant_id", Type: model.Text(), NotNull: true, ServerOnly: true},
		{Name: "payment_id", Type: model.Text(), Ref: &PaymentModel, DB: &model.FieldDB{RefColumn: "id"}, NotNull: true},
		{Name: "amount", Type: model.Int(), NotNull: true, Item: model.ItemLabel, ServerOnly: true},
		{Name: "kind", Type: model.Text(), NotNull: true},
		{Name: "method", Type: model.Text(), OmitEmpty: true},
		{Name: "reason", Type: input.Textarea(), NotNull: true, Permitted: model.Permitted{Maximum: 255}},
		{Name: "authorization_code", Type: model.Text(), OmitEmpty: true},
		{Name: "created_by", Type: model.Text(), OmitEmpty: true},
		{Name: "created_at", Type: model.UnixTime(), ServerOnly: true},
	},
	Allow: model.Create | model.Read,
	Rules: model.Rules{
		Create: model.AddMyBusinessRule,
		Read:   model.HaveNoBusinessRule,
	},
	ExternalCalls: []model.ExternalCallDefinition{
		{Name: "GatewayRefund", Mode: model.WaitForReply, MaxWaitSeconds: 15},
	},
}
View Source
var Refund_ = struct {
	Id                string
	TenantId          string
	PaymentId         string
	Amount            string
	Kind              string
	Method            string
	Reason            string
	AuthorizationCode string
	CreatedBy         string
	CreatedAt         string
}{
	Id:                "id",
	TenantId:          "tenant_id",
	PaymentId:         "payment_id",
	Amount:            "amount",
	Kind:              "kind",
	Method:            "method",
	Reason:            "reason",
	AuthorizationCode: "authorization_code",
	CreatedBy:         "created_by",
	CreatedAt:         "created_at",
}

Functions

func FormatAmount added in v0.1.0

func FormatAmount(amount int64, currency string) string

func NewView added in v0.1.0

func NewView(caller router.Caller, opts ...view.Option) view.Presenter

func Transition added in v0.1.0

func Transition(current, event string) (string, error)

Transition devuelve el estado al que lleva event desde current, o ErrInvalidTransition.

Types

type BankDays added in v0.4.0

type BankDays interface {
	BankDayAfter(from time.Unix, days int) (time.Unix, error)
}

BankDays convierte días hábiles bancarios en fecha. Lo cumple business_calendar.(*Module).BankDayAfter. Ejemplo: deps.BankDays = calendario

type ChargeReader added in v0.1.0

type ChargeReader interface {
	Charge(tenantId, referenceId string) (amount int64, currency string, payable bool, err error)
}

type ChargeResult added in v0.1.0

type ChargeResult struct {
	TenantId        string
	ReferenceModule string
	ReferenceId     string
	Amount          int64
	Currency        string
	Payable         bool
	Terminal        bool
}

func (*ChargeResult) Allow added in v0.4.47

func (*ChargeResult) Allow() model.Action

func (*ChargeResult) DecodeFields added in v0.1.0

func (m *ChargeResult) DecodeFields(r model.FieldReader)

func (*ChargeResult) EncodeFields added in v0.1.0

func (m *ChargeResult) EncodeFields(w model.FieldWriter)

func (*ChargeResult) IsNil added in v0.1.0

func (m *ChargeResult) IsNil() bool

func (*ChargeResult) ModelName added in v0.1.0

func (m *ChargeResult) ModelName() string

func (*ChargeResult) Pointers added in v0.1.0

func (m *ChargeResult) Pointers() []any

func (*ChargeResult) Read added in v0.4.47

func (*ChargeResult) Schema added in v0.1.0

func (m *ChargeResult) Schema() []model.Field

func (*ChargeResult) Validate added in v0.1.0

func (m *ChargeResult) Validate(action byte) error

type ChargeResultList added in v0.1.0

type ChargeResultList []*ChargeResult

func (*ChargeResultList) Allow added in v0.4.47

func (*ChargeResultList) Allow() model.Action

func (*ChargeResultList) Append added in v0.1.0

func (s *ChargeResultList) Append() model.Fielder

func (*ChargeResultList) At added in v0.1.0

func (s *ChargeResultList) At(i int) model.Fielder

func (*ChargeResultList) DecodeFields added in v0.1.0

func (s *ChargeResultList) DecodeFields(_ model.FieldReader)

func (*ChargeResultList) EncodeFields added in v0.1.0

func (s *ChargeResultList) EncodeFields(_ model.FieldWriter)

func (*ChargeResultList) IsNil added in v0.1.0

func (s *ChargeResultList) IsNil() bool

func (*ChargeResultList) Len added in v0.1.0

func (s *ChargeResultList) Len() int

type ChargeSource added in v0.1.0

type ChargeSource struct {
	Module string
	Reader ChargeReader
	Device string // id de la máquina de la caja que cobra las referencias de este módulo; "" = sin máquina
}

type Deps added in v0.1.0

type Deps struct {
	IDs       model.IDGenerator
	Timeouts  Timeouts
	TenantID  string           // requerido: el tenant al que sirve esta instancia
	Publisher events.Publisher // opcional — nil desactiva la publicación
	Gateway   Gateway          // opcional — nil: el canal online responde ErrGatewayUnavailable
	Charges   []ChargeSource   // requerido: quién responde el monto de cada módulo de referencia
	Terminal  Terminal         // opcional — nil: el cobro con máquina responde ErrTerminalUnavailable
	BankDays  BankDays         // requerido si el Terminal o el Gateway implementan PayoutTerms
}

Deps son las dependencias que inyecta la raíz de composición.

type Gateway added in v0.1.0

type Gateway interface {
	Provider() string
	Start(req GatewayStart) (GatewayStarted, error)
	Status(token string) (GatewayResult, error)
	// Confirm finaliza la transacción cuando el proveedor lo exige y devuelve su estado real; idempotente.
	Confirm(token string) (GatewayResult, error)
	Refund(token string, amount int64) (GatewayRefund, error)
}

Gateway es la pasarela de pago en línea. La implementación (github.com/veltylabs/transbank, github.com/veltylabs/tuu) la inyecta la app; verifica sola lo que le devuelve su procesador y llama a CompleteOnlinePayment con el resultado ya verificado. Sus llamadas son síncronas y solo corren en el servidor.

type GatewayRefund added in v0.1.0

type GatewayRefund struct {
	Kind              string
	AuthorizationCode string
	Amount            int64
}

type GatewayResult added in v0.1.0

type GatewayResult struct {
	Outcome           string
	Amount            int64
	AuthorizationCode string
	PaymentTypeCode   string
	Installments      int64
	CardLast4         string
}

type GatewayStart added in v0.1.0

type GatewayStart struct {
	PaymentId   string // nuestro id (Webpay: buy_order y session_id; TUU: x_reference)
	Amount      int64
	Currency    string
	Description string // texto corto para el pagador; puede ir vacío
	Payer       Payer  // lo exige TUU; Webpay lo ignora
	WaitSeconds int64
}

type GatewayStarted added in v0.1.0

type GatewayStarted struct {
	Token       string // id del cobro en el procesador; se guarda en Payment.ProviderToken
	RedirectURL string
	TokenField  string // no vacío: el navegador envía Token por POST en este campo (Webpay: "token_ws"); vacío: GET a RedirectURL
}

type Module added in v0.1.0

type Module struct {
	// contains filtered or unexported fields
}

Module registra, confirma y devuelve pagos.

func New

func New(db *orm.DB, deps Deps) (*Module, error)

New conecta el módulo a un *orm.DB ya migrado (ver el subpaquete migrate).

func (*Module) Charge added in v0.1.0

func (m *Module) Charge(tenantId, referenceModule, referenceId string) (amount int64, currency string, payable bool, err error)

Charge pregunta al módulo dueño de la referencia cuánto se cobra. El monto nunca viene del cliente.

func (*Module) CompleteOnlinePayment added in v0.1.0

func (m *Module) CompleteOnlinePayment(ret OnlineReturn) (Payment, error)

CompleteOnlinePayment cierra un pago online cuando el cliente vuelve de la pasarela. La vuelta solo IDENTIFICA el pago (OnlineReturn no trae resultado): lo que pasó lo pregunta el módulo a la pasarela con el token guardado, nunca con el de la petición, así que nadie puede cancelar ni vencer un pago ajeno con una dirección armada a mano. Un pago que ya no está pendiente se devuelve igual (idempotente); un resultado aún pendiente lo deja pendiente (la conciliación lo vence).

Ejemplo: p, err := m.CompleteOnlinePayment(paymentmanager.OnlineReturn{PaymentId: "p1", Token: tokenDeLaVuelta})

func (*Module) Definition added in v0.4.47

func (m *Module) Definition() model.ModuleDefinition

Definition is the module's declaration (definition.go); crud.Mount compares it with what MountOperations mounted.

func (*Module) Due added in v0.2.0

func (m *Module) Due(tenantId, referenceModule, referenceId string) (amount int64, currency string, err error)

Due devuelve lo que falta cobrar de una referencia: el monto que informa su ChargeReader menos el bruto de los pagos PAID y PARTIALLY_REFUNDED de esa referencia. Un pago PENDING, FAILED, CANCELLED, EXPIRED o REFUNDED no cuenta. El monto nunca viene del cliente.

func (*Module) GetPayment added in v0.1.0

func (m *Module) GetPayment(tenantId, id string) (Payment, error)

GetPayment lee un pago del tenant.

func (*Module) ListPayments added in v0.1.0

func (m *Module) ListPayments(tenantId string, from, to time.Unix) ([]Payment, error)

ListPayments lista los pagos creados en [from, to) (segundos).

func (*Module) ListPaymentsByReference added in v0.1.0

func (m *Module) ListPaymentsByReference(tenantId, referenceModule, referenceId string) ([]Payment, error)

ListPaymentsByReference lista los pagos de una referencia.

func (*Module) ListRefunds added in v0.1.0

func (m *Module) ListRefunds(tenantId, paymentId string) ([]Refund, error)

ListRefunds lista las devoluciones de un pago.

func (*Module) ModelName added in v0.1.0

func (m *Module) ModelName() string

func (*Module) MountOperations added in v0.1.0

func (m *Module) MountOperations(reg crud.Registry)

MountOperations offers every entity of the module: the actions its model allows, with crud's validation and the rules written in rule_*.go.

func (*Module) NextReceiptNumber added in v0.1.21

func (m *Module) NextReceiptNumber(tenantId string) (string, error)

NextReceiptNumber returns this tenant's next sequential receipt number, formatted "R-000001" (zero-padded to 6 digits; grows past it without truncating). It must be gap-free per tenant.

func (*Module) PaidAmount added in v0.1.0

func (m *Module) PaidAmount(tenantId, paymentId, referenceModule, referenceId string) (amount int64, currency string, err error)

PaidAmount verifica un pago para el módulo dueño de la referencia: devuelve el monto neto (pagado menos devuelto) solo si el pago es de esa referencia y está pagado.

func (*Module) ReconcilePayments added in v0.2.0

func (m *Module) ReconcilePayments(tenantId string, now time.Unix) (int, error)

RefundPayment devuelve amount de un pago pagado. En online lo pide a la pasarela; en mesón registra la devolución con su medio.

func (*Module) StoreOnlinePaymentRequest added in v0.4.47

func (m *Module) StoreOnlinePaymentRequest() crud.Store

StoreOnlinePaymentRequest is the store of payment_online_request.

func (*Module) StorePayment added in v0.4.47

func (m *Module) StorePayment() crud.Store

StorePayment is the store of payment.

func (*Module) StorePaymentManualConfirmation added in v0.4.47

func (m *Module) StorePaymentManualConfirmation() crud.Store

StorePaymentManualConfirmation is the store of payment_manual_confirmation.

func (*Module) StorePaymentReconciliation added in v0.4.47

func (m *Module) StorePaymentReconciliation() crud.Store

StorePaymentReconciliation is the store of payment_reconciliation.

func (*Module) StoreRefund added in v0.4.47

func (m *Module) StoreRefund() crud.Store

StoreRefund is the store of refund.

type OnlinePaymentRequest added in v0.4.47

type OnlinePaymentRequest struct {
	Id              string
	TenantId        string
	ReferenceModule string
	ReferenceId     string
	ReturnUrl       string
	PaymentId       string
	RedirectUrl     string
	Status          string
	Failure         string
	CreatedAt       time.Unix
	PayerName       string
	PayerEmail      string
	PayerPhone      string
	Token           string
	TokenField      string
}

func ReadOneOnlinePaymentRequest added in v0.4.47

func ReadOneOnlinePaymentRequest(qb *orm.QB, model *OnlinePaymentRequest) (*OnlinePaymentRequest, error)

func (*OnlinePaymentRequest) Allow added in v0.4.47

func (*OnlinePaymentRequest) Create added in v0.4.47

func (*OnlinePaymentRequest) DecodeFields added in v0.4.47

func (m *OnlinePaymentRequest) DecodeFields(r model.FieldReader)

func (*OnlinePaymentRequest) EncodeFields added in v0.4.47

func (m *OnlinePaymentRequest) EncodeFields(w model.FieldWriter)

func (*OnlinePaymentRequest) GatewayStart added in v0.4.47

call_online_payment_request_gateway_start.go — WaitForReply; the create's response carries what is set here

func (*OnlinePaymentRequest) IsNil added in v0.4.47

func (m *OnlinePaymentRequest) IsNil() bool

func (*OnlinePaymentRequest) ModelName added in v0.4.47

func (m *OnlinePaymentRequest) ModelName() string

func (*OnlinePaymentRequest) Pointers added in v0.4.47

func (m *OnlinePaymentRequest) Pointers() []any

func (*OnlinePaymentRequest) Schema added in v0.4.47

func (m *OnlinePaymentRequest) Schema() []model.Field

func (*OnlinePaymentRequest) Validate added in v0.4.47

func (m *OnlinePaymentRequest) Validate(action byte) error

type OnlinePaymentRequestGatewayStart added in v0.4.47

type OnlinePaymentRequestGatewayStart struct{}

OnlinePaymentRequestGatewayStart is the ExternalCall type for payment_online_request.GatewayStart.

func (OnlinePaymentRequestGatewayStart) ModelName added in v0.4.47

type OnlinePaymentRequestList added in v0.4.47

type OnlinePaymentRequestList []*OnlinePaymentRequest

func ReadAllOnlinePaymentRequest added in v0.4.47

func ReadAllOnlinePaymentRequest(qb *orm.QB) (OnlinePaymentRequestList, error)

func (*OnlinePaymentRequestList) Allow added in v0.4.47

func (*OnlinePaymentRequestList) Append added in v0.4.47

func (*OnlinePaymentRequestList) At added in v0.4.47

func (*OnlinePaymentRequestList) DecodeFields added in v0.4.47

func (s *OnlinePaymentRequestList) DecodeFields(_ model.FieldReader)

func (*OnlinePaymentRequestList) EncodeFields added in v0.4.47

func (s *OnlinePaymentRequestList) EncodeFields(_ model.FieldWriter)

func (*OnlinePaymentRequestList) IsNil added in v0.4.47

func (s *OnlinePaymentRequestList) IsNil() bool

func (*OnlinePaymentRequestList) Len added in v0.4.47

func (s *OnlinePaymentRequestList) Len() int

type OnlineReturn added in v0.1.0

type OnlineReturn struct {
	PaymentId string // the buy order the provider echoes, when it sends one
	Token     string // the provider token of the transaction, when it sends one
}

OnlineReturn identifies the payment a provider's return refers to. It carries no outcome: the module asks the gateway.

type Payer added in v0.3.0

type Payer struct {
	Name  string
	Email string
	Phone string
}

Payer es quien paga en línea. Los campos pueden ir vacíos; un adaptador que los exige responde error.

type Payment added in v0.1.0

type Payment struct {
	Id                string
	TenantId          string
	ReferenceModule   string
	ReferenceId       string
	Channel           string
	Method            string
	Amount            int64
	Currency          string
	Status            string
	RefundedAmount    int64
	ProviderToken     string
	Provider          string
	AuthorizationCode string
	PaymentTypeCode   string
	Installments      int64
	CardLast4         string
	ReceiptNumber     string
	ReturnTo          string
	CreatedBy         string
	CreatedAt         time.Unix
	PaidAt            time.Unix
	UpdatedAt         time.Unix
	Revision          int64
}

func ReadOnePayment added in v0.1.0

func ReadOnePayment(qb *orm.QB, model *Payment) (*Payment, error)

func (*Payment) Allow added in v0.4.47

func (*Payment) Allow() model.Action

func (*Payment) Create added in v0.4.47

func (p *Payment) Create(a crud.CurrentUser, tx crud.Tx, m *Module) (crud.RuleAnswer, error)

func (*Payment) DecodeFields added in v0.1.0

func (m *Payment) DecodeFields(r model.FieldReader)

func (*Payment) EncodeFields added in v0.1.0

func (m *Payment) EncodeFields(w model.FieldWriter)

func (*Payment) IsNil added in v0.1.0

func (m *Payment) IsNil() bool

func (*Payment) Item added in v0.1.0

func (m *Payment) Item() model.Item

func (*Payment) ModelName added in v0.1.0

func (m *Payment) ModelName() string

func (*Payment) Pointers added in v0.1.0

func (m *Payment) Pointers() []any

func (*Payment) Schema added in v0.1.0

func (m *Payment) Schema() []model.Field

func (*Payment) TerminalPush added in v0.4.47

func (p *Payment) TerminalPush(a crud.CurrentUser, m *Module, key crud.IdempotencyKey) (crud.FieldsToSave, error)

call_payment_terminal_push.go — WaitForReply

func (*Payment) TerminalStatus added in v0.4.47

func (p *Payment) TerminalStatus(a crud.CurrentUser, m *Module, key crud.IdempotencyKey) (crud.FieldsToSave, error)

call_payment_terminal_status.go — RetryInBackground: polls until the machine answers or the window ends

func (*Payment) Validate added in v0.1.0

func (m *Payment) Validate(action byte) error

type PaymentCounter added in v0.1.21

type PaymentCounter struct {
	TenantId   string
	NextNumber int64
}

func ReadOnePaymentCounter added in v0.1.21

func ReadOnePaymentCounter(qb *orm.QB, model *PaymentCounter) (*PaymentCounter, error)

func (*PaymentCounter) Allow added in v0.4.47

func (*PaymentCounter) Allow() model.Action

func (*PaymentCounter) DecodeFields added in v0.1.21

func (m *PaymentCounter) DecodeFields(r model.FieldReader)

func (*PaymentCounter) EncodeFields added in v0.1.21

func (m *PaymentCounter) EncodeFields(w model.FieldWriter)

func (*PaymentCounter) IsNil added in v0.1.21

func (m *PaymentCounter) IsNil() bool

func (*PaymentCounter) ModelName added in v0.1.21

func (m *PaymentCounter) ModelName() string

func (*PaymentCounter) Pointers added in v0.1.21

func (m *PaymentCounter) Pointers() []any

func (*PaymentCounter) Schema added in v0.1.21

func (m *PaymentCounter) Schema() []model.Field

func (*PaymentCounter) Validate added in v0.1.21

func (m *PaymentCounter) Validate(action byte) error

type PaymentCounterList added in v0.1.21

type PaymentCounterList []*PaymentCounter

func ReadAllPaymentCounter added in v0.1.21

func ReadAllPaymentCounter(qb *orm.QB) (PaymentCounterList, error)

func (*PaymentCounterList) Allow added in v0.4.47

func (*PaymentCounterList) Allow() model.Action

func (*PaymentCounterList) Append added in v0.1.21

func (s *PaymentCounterList) Append() model.Fielder

func (*PaymentCounterList) At added in v0.1.21

func (*PaymentCounterList) DecodeFields added in v0.1.21

func (s *PaymentCounterList) DecodeFields(_ model.FieldReader)

func (*PaymentCounterList) EncodeFields added in v0.1.21

func (s *PaymentCounterList) EncodeFields(_ model.FieldWriter)

func (*PaymentCounterList) IsNil added in v0.1.21

func (s *PaymentCounterList) IsNil() bool

func (*PaymentCounterList) Len added in v0.1.21

func (s *PaymentCounterList) Len() int

type PaymentList added in v0.1.0

type PaymentList []*Payment

func ReadAllPayment added in v0.1.0

func ReadAllPayment(qb *orm.QB) (PaymentList, error)

func (*PaymentList) Allow added in v0.4.47

func (*PaymentList) Allow() model.Action

func (*PaymentList) Append added in v0.1.0

func (s *PaymentList) Append() model.Fielder

func (*PaymentList) At added in v0.1.0

func (s *PaymentList) At(i int) model.Fielder

func (*PaymentList) DecodeFields added in v0.1.0

func (s *PaymentList) DecodeFields(_ model.FieldReader)

func (*PaymentList) EncodeFields added in v0.1.0

func (s *PaymentList) EncodeFields(_ model.FieldWriter)

func (*PaymentList) IsNil added in v0.1.0

func (s *PaymentList) IsNil() bool

func (*PaymentList) Len added in v0.1.0

func (s *PaymentList) Len() int

type PaymentManualConfirmation added in v0.4.47

type PaymentManualConfirmation struct {
	Id        string
	TenantId  string
	PaymentId string
	Note      string
	ActorId   string
	CreatedAt time.Unix
}

func ReadOnePaymentManualConfirmation added in v0.4.47

func ReadOnePaymentManualConfirmation(qb *orm.QB, model *PaymentManualConfirmation) (*PaymentManualConfirmation, error)

func (*PaymentManualConfirmation) Allow added in v0.4.47

func (*PaymentManualConfirmation) Confirm added in v0.4.47

call_payment_manual_confirmation_confirm.go — WaitForReply

func (*PaymentManualConfirmation) Create added in v0.4.47

func (*PaymentManualConfirmation) DecodeFields added in v0.4.47

func (m *PaymentManualConfirmation) DecodeFields(r model.FieldReader)

func (*PaymentManualConfirmation) EncodeFields added in v0.4.47

func (m *PaymentManualConfirmation) EncodeFields(w model.FieldWriter)

func (*PaymentManualConfirmation) IsNil added in v0.4.47

func (m *PaymentManualConfirmation) IsNil() bool

func (*PaymentManualConfirmation) ModelName added in v0.4.47

func (m *PaymentManualConfirmation) ModelName() string

func (*PaymentManualConfirmation) Pointers added in v0.4.47

func (m *PaymentManualConfirmation) Pointers() []any

func (*PaymentManualConfirmation) Schema added in v0.4.47

func (m *PaymentManualConfirmation) Schema() []model.Field

func (*PaymentManualConfirmation) Validate added in v0.4.47

func (m *PaymentManualConfirmation) Validate(action byte) error

type PaymentManualConfirmationConfirm added in v0.4.47

type PaymentManualConfirmationConfirm struct{}

PaymentManualConfirmationConfirm is the ExternalCall type for payment_manual_confirmation.Confirm.

func (PaymentManualConfirmationConfirm) ModelName added in v0.4.47

type PaymentManualConfirmationList added in v0.4.47

type PaymentManualConfirmationList []*PaymentManualConfirmation

func ReadAllPaymentManualConfirmation added in v0.4.47

func ReadAllPaymentManualConfirmation(qb *orm.QB) (PaymentManualConfirmationList, error)

func (*PaymentManualConfirmationList) Allow added in v0.4.47

func (*PaymentManualConfirmationList) Append added in v0.4.47

func (*PaymentManualConfirmationList) At added in v0.4.47

func (*PaymentManualConfirmationList) DecodeFields added in v0.4.47

func (s *PaymentManualConfirmationList) DecodeFields(_ model.FieldReader)

func (*PaymentManualConfirmationList) EncodeFields added in v0.4.47

func (s *PaymentManualConfirmationList) EncodeFields(_ model.FieldWriter)

func (*PaymentManualConfirmationList) IsNil added in v0.4.47

func (*PaymentManualConfirmationList) Len added in v0.4.47

type PaymentReconciliation added in v0.4.47

type PaymentReconciliation struct {
	Id         string
	TenantId   string
	Status     string
	Failure    string
	Reconciled int64
	ActorId    string
	CreatedAt  time.Unix
}

func ReadOnePaymentReconciliation added in v0.4.47

func ReadOnePaymentReconciliation(qb *orm.QB, model *PaymentReconciliation) (*PaymentReconciliation, error)

func (*PaymentReconciliation) Allow added in v0.4.47

func (*PaymentReconciliation) Create added in v0.4.47

func (*PaymentReconciliation) DecodeFields added in v0.4.47

func (m *PaymentReconciliation) DecodeFields(r model.FieldReader)

func (*PaymentReconciliation) EncodeFields added in v0.4.47

func (m *PaymentReconciliation) EncodeFields(w model.FieldWriter)

func (*PaymentReconciliation) IsNil added in v0.4.47

func (m *PaymentReconciliation) IsNil() bool

func (*PaymentReconciliation) ModelName added in v0.4.47

func (m *PaymentReconciliation) ModelName() string

func (*PaymentReconciliation) Pointers added in v0.4.47

func (m *PaymentReconciliation) Pointers() []any

func (*PaymentReconciliation) Reconcile added in v0.4.47

func (*PaymentReconciliation) Schema added in v0.4.47

func (m *PaymentReconciliation) Schema() []model.Field

func (*PaymentReconciliation) Validate added in v0.4.47

func (m *PaymentReconciliation) Validate(action byte) error

type PaymentReconciliationList added in v0.4.47

type PaymentReconciliationList []*PaymentReconciliation

func ReadAllPaymentReconciliation added in v0.4.47

func ReadAllPaymentReconciliation(qb *orm.QB) (PaymentReconciliationList, error)

func (*PaymentReconciliationList) Allow added in v0.4.47

func (*PaymentReconciliationList) Append added in v0.4.47

func (*PaymentReconciliationList) At added in v0.4.47

func (*PaymentReconciliationList) DecodeFields added in v0.4.47

func (s *PaymentReconciliationList) DecodeFields(_ model.FieldReader)

func (*PaymentReconciliationList) EncodeFields added in v0.4.47

func (s *PaymentReconciliationList) EncodeFields(_ model.FieldWriter)

func (*PaymentReconciliationList) IsNil added in v0.4.47

func (s *PaymentReconciliationList) IsNil() bool

func (*PaymentReconciliationList) Len added in v0.4.47

func (s *PaymentReconciliationList) Len() int

type PaymentReconciliationReconcile added in v0.4.47

type PaymentReconciliationReconcile struct{}

PaymentReconciliationReconcile is the ExternalCall type for payment_reconciliation.Reconcile.

func (PaymentReconciliationReconcile) ModelName added in v0.4.47

type PaymentStatusResult added in v0.1.0

type PaymentStatusResult struct {
	Id       string
	TenantId string
	Status   string
}

func (*PaymentStatusResult) Allow added in v0.4.47

func (*PaymentStatusResult) Allow() model.Action

func (*PaymentStatusResult) DecodeFields added in v0.1.0

func (m *PaymentStatusResult) DecodeFields(r model.FieldReader)

func (*PaymentStatusResult) EncodeFields added in v0.1.0

func (m *PaymentStatusResult) EncodeFields(w model.FieldWriter)

func (*PaymentStatusResult) IsNil added in v0.1.0

func (m *PaymentStatusResult) IsNil() bool

func (*PaymentStatusResult) ModelName added in v0.1.0

func (m *PaymentStatusResult) ModelName() string

func (*PaymentStatusResult) Pointers added in v0.1.0

func (m *PaymentStatusResult) Pointers() []any

func (*PaymentStatusResult) Read added in v0.4.47

func (*PaymentStatusResult) Schema added in v0.1.0

func (m *PaymentStatusResult) Schema() []model.Field

func (*PaymentStatusResult) Validate added in v0.1.0

func (m *PaymentStatusResult) Validate(action byte) error

type PaymentStatusResultList added in v0.1.0

type PaymentStatusResultList []*PaymentStatusResult

func (*PaymentStatusResultList) Allow added in v0.4.47

func (*PaymentStatusResultList) Append added in v0.1.0

func (*PaymentStatusResultList) At added in v0.1.0

func (*PaymentStatusResultList) DecodeFields added in v0.1.0

func (s *PaymentStatusResultList) DecodeFields(_ model.FieldReader)

func (*PaymentStatusResultList) EncodeFields added in v0.1.0

func (s *PaymentStatusResultList) EncodeFields(_ model.FieldWriter)

func (*PaymentStatusResultList) IsNil added in v0.1.0

func (s *PaymentStatusResultList) IsNil() bool

func (*PaymentStatusResultList) Len added in v0.1.0

func (s *PaymentStatusResultList) Len() int

type PaymentTerminalPush added in v0.4.47

type PaymentTerminalPush struct{}

PaymentTerminalPush is the ExternalCall type for payment.TerminalPush.

func (PaymentTerminalPush) ModelName added in v0.4.47

func (PaymentTerminalPush) ModelName() string

type PaymentTerminalStatus added in v0.4.47

type PaymentTerminalStatus struct{}

PaymentTerminalStatus is the ExternalCall type for payment.TerminalStatus.

func (PaymentTerminalStatus) ModelName added in v0.4.47

func (PaymentTerminalStatus) ModelName() string

type Payout added in v0.4.0

type Payout struct {
	Fee          int64
	FeeTax       int64
	BusinessDays int
}

Payout es lo que responde el adaptador: comisión, IVA de la comisión y días hábiles hasta el depósito. El neto depositado es Amount − Fee − FeeTax.

type PayoutCharge added in v0.4.0

type PayoutCharge struct {
	Amount   int64
	Currency string
	Method   string // MethodDebit, MethodCredit o MethodCard
	Channel  string // ChannelTerminal o ChannelOnline
}

PayoutCharge es el cobro del que se pregunta el abono.

type PayoutTerms added in v0.4.0

type PayoutTerms interface {
	Payout(c PayoutCharge) (Payout, error)
}

PayoutTerms es lo que un adaptador (Terminal o Gateway) sabe de su plan contratado: cuánto descuenta el procesador y en cuántos días hábiles bancarios deposita. Es opcional: el módulo lo detecta con una aserción de tipo; sin él, un cobro con tarjeta se registra sin fecha de depósito ni comisión. Ejemplo: terms, ok := gateway.(paymentmanager.PayoutTerms)

type Refund added in v0.1.0

type Refund struct {
	Id                string
	TenantId          string
	PaymentId         string
	Amount            int64
	Kind              string
	Method            string
	Reason            string
	AuthorizationCode string
	CreatedBy         string
	CreatedAt         time.Unix
}

func ReadOneRefund added in v0.1.0

func ReadOneRefund(qb *orm.QB, model *Refund) (*Refund, error)

func (*Refund) Allow added in v0.4.47

func (*Refund) Allow() model.Action

func (*Refund) Create added in v0.4.47

func (p *Refund) Create(a crud.CurrentUser, tx crud.Tx, m *Module) (crud.RuleAnswer, error)

func (*Refund) DecodeFields added in v0.1.0

func (m *Refund) DecodeFields(r model.FieldReader)

func (*Refund) EncodeFields added in v0.1.0

func (m *Refund) EncodeFields(w model.FieldWriter)

func (*Refund) GatewayRefund added in v0.4.47

func (p *Refund) GatewayRefund(a crud.CurrentUser, m *Module, key crud.IdempotencyKey) (crud.FieldsToSave, error)

func (*Refund) IsNil added in v0.1.0

func (m *Refund) IsNil() bool

func (*Refund) Item added in v0.4.17

func (m *Refund) Item() model.Item

func (*Refund) ModelName added in v0.1.0

func (m *Refund) ModelName() string

func (*Refund) Pointers added in v0.1.0

func (m *Refund) Pointers() []any

func (*Refund) Schema added in v0.1.0

func (m *Refund) Schema() []model.Field

func (*Refund) SchemaExt added in v0.1.0

func (m *Refund) SchemaExt() []model.FieldExt

func (*Refund) Validate added in v0.1.0

func (m *Refund) Validate(action byte) error

type RefundGatewayRefund added in v0.4.47

type RefundGatewayRefund struct{}

RefundGatewayRefund is the ExternalCall type for refund.GatewayRefund.

func (RefundGatewayRefund) ModelName added in v0.4.47

func (RefundGatewayRefund) ModelName() string

type RefundList added in v0.1.0

type RefundList []*Refund

func ReadAllRefund added in v0.1.0

func ReadAllRefund(qb *orm.QB) (RefundList, error)

func (*RefundList) Allow added in v0.4.47

func (*RefundList) Allow() model.Action

func (*RefundList) Append added in v0.1.0

func (s *RefundList) Append() model.Fielder

func (*RefundList) At added in v0.1.0

func (s *RefundList) At(i int) model.Fielder

func (*RefundList) DecodeFields added in v0.1.0

func (s *RefundList) DecodeFields(_ model.FieldReader)

func (*RefundList) EncodeFields added in v0.1.0

func (s *RefundList) EncodeFields(_ model.FieldWriter)

func (*RefundList) IsNil added in v0.1.0

func (s *RefundList) IsNil() bool

func (*RefundList) Len added in v0.1.0

func (s *RefundList) Len() int

type Terminal added in v0.2.0

type Terminal interface {
	Provider() string                              // nombre del procesador; se guarda en cada pago ("tuu")
	Push(req TerminalPush) (TerminalPushed, error) // envía el monto a la máquina; idempotente por RequestId
	Status(token string) (TerminalResult, error)   // estado del cobro en la máquina
}

Terminal es la máquina de cobro con tarjeta de una caja. La implementación concreta (por ejemplo github.com/veltylabs/tuu) la inyecta la app; sus llamadas son síncronas y solo corren en el servidor.

type TerminalPush added in v0.2.0

type TerminalPush struct {
	RequestId   string // = Payment.Id; la máquina lo usa como llave de idempotencia
	Device      string // id de la máquina en el procesador (TUU: número de serie)
	Amount      int64
	Currency    string
	Method      string // MethodDebit | MethodCredit
	WaitSeconds int64
	Description string // texto corto que muestra la máquina; puede ir vacío
}

type TerminalPushed added in v0.2.0

type TerminalPushed struct {
	Token string // id del cobro en el procesador; se guarda en Payment.ProviderToken
}

type TerminalResult added in v0.2.0

type TerminalResult struct {
	Outcome           string // OutcomePending | OutcomeAuthorized | OutcomeRejected | OutcomeCancelled
	Amount            int64
	AuthorizationCode string
	CardLast4         string
}

type Timeouts added in v0.4.47

type Timeouts struct {
	TerminalPushSeconds      int64
	TerminalPayWindowSeconds int64
	OnlineStartSeconds       int64
}

Timeouts are the waits of the module. A zero field takes its default. Example: Deps{Timeouts: Timeouts{TerminalPayWindowSeconds: 60}}

Directories

Path Synopsis
Package migrate crea y actualiza el esquema de payment_manager.
Package migrate crea y actualiza el esquema de payment_manager.
Package sandbox es una pasarela de pago en memoria que implementa paymentmanager.Gateway.
Package sandbox es una pasarela de pago en memoria que implementa paymentmanager.Gateway.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL