refactored payment orchestration
This commit is contained in:
@@ -0,0 +1,77 @@
|
||||
package gateway
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
"github.com/tech/sendico/gateway/chain/storage/model"
|
||||
paymentgateway "github.com/tech/sendico/pkg/messaging/notifications/paymentgateway"
|
||||
pmodel "github.com/tech/sendico/pkg/model"
|
||||
"github.com/tech/sendico/pkg/mservice"
|
||||
"github.com/tech/sendico/pkg/payments/rail"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func isFinalStatus(t *model.Transfer) bool {
|
||||
switch t.Status {
|
||||
case model.TransferStatusFailed, model.TransferStatusSuccess, model.TransferStatusCancelled:
|
||||
return true
|
||||
default:
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
func toOpStatus(t *model.Transfer) rail.OperationResult {
|
||||
switch t.Status {
|
||||
case model.TransferStatusFailed:
|
||||
return rail.OperationResultFailed
|
||||
case model.TransferStatusSuccess:
|
||||
return rail.OperationResultSuccess
|
||||
case model.TransferStatusCancelled:
|
||||
return rail.OperationResultCancelled
|
||||
default:
|
||||
panic(fmt.Sprintf("toOpStatus: unexpected transfer status: %s", t.Status))
|
||||
}
|
||||
}
|
||||
|
||||
func toError(t *model.Transfer) string {
|
||||
if t == nil {
|
||||
return ""
|
||||
}
|
||||
if t.Status == model.TransferStatusSuccess {
|
||||
return ""
|
||||
}
|
||||
return t.FailureReason
|
||||
}
|
||||
|
||||
func (s *Service) updateTransferStatus(ctx context.Context, transferRef string, status model.TransferStatus, failureReason, txHash string) (*model.Transfer, error) {
|
||||
transfer, err := s.storage.Transfers().UpdateStatus(ctx, transferRef, status, failureReason, txHash)
|
||||
if err != nil {
|
||||
s.logger.Warn("Failed to update transfer status", zap.String("transfer_ref", transferRef), zap.String("status", string(status)), zap.Error(err))
|
||||
}
|
||||
if isFinalStatus(transfer) {
|
||||
s.emitTransferStatusEvent(transfer)
|
||||
}
|
||||
return transfer, err
|
||||
}
|
||||
|
||||
func (s *Service) emitTransferStatusEvent(transfer *model.Transfer) {
|
||||
if s == nil || s.producer == nil || transfer == nil {
|
||||
return
|
||||
}
|
||||
|
||||
exec := pmodel.PaymentGatewayExecution{
|
||||
PaymentIntentID: transfer.IntentRef,
|
||||
IdempotencyKey: transfer.IdempotencyKey,
|
||||
ExecutedMoney: transfer.NetAmount,
|
||||
PaymentRef: transfer.PaymentRef,
|
||||
Status: toOpStatus(transfer),
|
||||
OperationRef: transfer.OperationRef,
|
||||
Error: toError(transfer),
|
||||
TransferRef: transfer.TransferRef,
|
||||
}
|
||||
env := paymentgateway.PaymentGatewayExecution(mservice.ChainGateway, &exec)
|
||||
if err := s.producer.SendMessage(env); err != nil {
|
||||
s.logger.Warn("Failed to publish transfer status event", zap.Error(err), zap.String("transfer_ref", transfer.TransferRef))
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user