Add shipment endpoints and payment webhook split handling
This commit is contained in:
parent
94c27ec7dc
commit
ce825fd1d5
5 changed files with 295 additions and 26 deletions
|
|
@ -87,14 +87,15 @@ type InventoryAdjustment struct {
|
|||
|
||||
// Order captures the status lifecycle and payment intent.
|
||||
type Order struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
BuyerID uuid.UUID `db:"buyer_id" json:"buyer_id"`
|
||||
SellerID uuid.UUID `db:"seller_id" json:"seller_id"`
|
||||
Status OrderStatus `db:"status" json:"status"`
|
||||
TotalCents int64 `db:"total_cents" json:"total_cents"`
|
||||
Items []OrderItem `json:"items"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
BuyerID uuid.UUID `db:"buyer_id" json:"buyer_id"`
|
||||
SellerID uuid.UUID `db:"seller_id" json:"seller_id"`
|
||||
Status OrderStatus `db:"status" json:"status"`
|
||||
TotalCents int64 `db:"total_cents" json:"total_cents"`
|
||||
Items []OrderItem `json:"items"`
|
||||
Shipping ShippingAddress `json:"shipping"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
// OrderItem stores SKU-level batch tracking.
|
||||
|
|
@ -118,6 +119,51 @@ type PaymentPreference struct {
|
|||
PaymentURL string `json:"payment_url"`
|
||||
}
|
||||
|
||||
// PaymentWebhookEvent represents Mercado Pago notifications with split amounts.
|
||||
type PaymentWebhookEvent struct {
|
||||
PaymentID string `json:"payment_id"`
|
||||
OrderID uuid.UUID `json:"order_id"`
|
||||
Status string `json:"status"`
|
||||
MarketplaceFee int64 `json:"marketplace_fee"`
|
||||
SellerAmount int64 `json:"seller_amount"`
|
||||
TotalPaidAmount int64 `json:"total_paid_amount"`
|
||||
}
|
||||
|
||||
// PaymentSplitResult echoes the amounts distributed between actors.
|
||||
type PaymentSplitResult struct {
|
||||
OrderID uuid.UUID `json:"order_id"`
|
||||
PaymentID string `json:"payment_id"`
|
||||
Status string `json:"status"`
|
||||
MarketplaceFee int64 `json:"marketplace_fee"`
|
||||
SellerReceivable int64 `json:"seller_receivable"`
|
||||
TotalPaidAmount int64 `json:"total_paid_amount"`
|
||||
}
|
||||
|
||||
// ShippingAddress captures delivery details at order time.
|
||||
type ShippingAddress struct {
|
||||
RecipientName string `json:"recipient_name" db:"shipping_recipient_name"`
|
||||
Street string `json:"street" db:"shipping_street"`
|
||||
Number string `json:"number" db:"shipping_number"`
|
||||
Complement string `json:"complement,omitempty" db:"shipping_complement"`
|
||||
District string `json:"district" db:"shipping_district"`
|
||||
City string `json:"city" db:"shipping_city"`
|
||||
State string `json:"state" db:"shipping_state"`
|
||||
ZipCode string `json:"zip_code" db:"shipping_zip_code"`
|
||||
Country string `json:"country" db:"shipping_country"`
|
||||
}
|
||||
|
||||
// Shipment stores freight label data and tracking linkage.
|
||||
type Shipment struct {
|
||||
ID uuid.UUID `db:"id" json:"id"`
|
||||
OrderID uuid.UUID `db:"order_id" json:"order_id"`
|
||||
Carrier string `db:"carrier" json:"carrier"`
|
||||
TrackingCode string `db:"tracking_code" json:"tracking_code"`
|
||||
ExternalTracking string `db:"external_tracking" json:"external_tracking"`
|
||||
Status string `db:"status" json:"status"`
|
||||
CreatedAt time.Time `db:"created_at" json:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at" json:"updated_at"`
|
||||
}
|
||||
|
||||
// OrderStatus enumerates supported transitions.
|
||||
type OrderStatus string
|
||||
|
||||
|
|
|
|||
|
|
@ -290,6 +290,7 @@ func (h *Handler) CreateOrder(w http.ResponseWriter, r *http.Request) {
|
|||
BuyerID: req.BuyerID,
|
||||
SellerID: req.SellerID,
|
||||
Items: req.Items,
|
||||
Shipping: req.Shipping,
|
||||
}
|
||||
|
||||
var total int64
|
||||
|
|
@ -454,6 +455,83 @@ func (h *Handler) CreatePaymentPreference(w http.ResponseWriter, r *http.Request
|
|||
writeJSON(w, http.StatusCreated, pref)
|
||||
}
|
||||
|
||||
// CreateShipment godoc
|
||||
// @Summary Gera guia de postagem/transporte
|
||||
// @Tags Logistica
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param shipment body createShipmentRequest true "Dados de envio"
|
||||
// @Success 201 {object} domain.Shipment
|
||||
// @Router /api/v1/shipments [post]
|
||||
func (h *Handler) CreateShipment(w http.ResponseWriter, r *http.Request) {
|
||||
var req createShipmentRequest
|
||||
if err := decodeJSON(r.Context(), r, &req); err != nil {
|
||||
writeError(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
shipment := &domain.Shipment{
|
||||
OrderID: req.OrderID,
|
||||
Carrier: req.Carrier,
|
||||
TrackingCode: req.TrackingCode,
|
||||
ExternalTracking: req.ExternalTracking,
|
||||
}
|
||||
|
||||
if err := h.svc.CreateShipment(r.Context(), shipment); err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusCreated, shipment)
|
||||
}
|
||||
|
||||
// GetShipmentByOrderID godoc
|
||||
// @Summary Rastreia entrega
|
||||
// @Tags Logistica
|
||||
// @Produce json
|
||||
// @Param order_id path string true "Order ID"
|
||||
// @Success 200 {object} domain.Shipment
|
||||
// @Router /api/v1/shipments/{order_id} [get]
|
||||
func (h *Handler) GetShipmentByOrderID(w http.ResponseWriter, r *http.Request) {
|
||||
orderID, err := parseUUIDFromPath(r.URL.Path)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
shipment, err := h.svc.GetShipmentByOrderID(r.Context(), orderID)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusNotFound, err)
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, shipment)
|
||||
}
|
||||
|
||||
// HandlePaymentWebhook godoc
|
||||
// @Summary Recebe notificações do Mercado Pago
|
||||
// @Tags Pagamentos
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param notification body domain.PaymentWebhookEvent true "Evento do gateway"
|
||||
// @Success 200 {object} domain.PaymentSplitResult
|
||||
// @Router /api/v1/payments/webhook [post]
|
||||
func (h *Handler) HandlePaymentWebhook(w http.ResponseWriter, r *http.Request) {
|
||||
var event domain.PaymentWebhookEvent
|
||||
if err := decodeJSON(r.Context(), r, &event); err != nil {
|
||||
writeError(w, http.StatusBadRequest, err)
|
||||
return
|
||||
}
|
||||
|
||||
summary, err := h.svc.HandlePaymentWebhook(r.Context(), event)
|
||||
if err != nil {
|
||||
writeError(w, http.StatusInternalServerError, err)
|
||||
return
|
||||
}
|
||||
|
||||
writeJSON(w, http.StatusOK, summary)
|
||||
}
|
||||
|
||||
// CreateUser handles the creation of platform users.
|
||||
func (h *Handler) CreateUser(w http.ResponseWriter, r *http.Request) {
|
||||
requester, err := getRequester(r)
|
||||
|
|
@ -772,9 +850,17 @@ type registerProductRequest struct {
|
|||
}
|
||||
|
||||
type createOrderRequest struct {
|
||||
BuyerID uuid.UUID `json:"buyer_id"`
|
||||
SellerID uuid.UUID `json:"seller_id"`
|
||||
Items []domain.OrderItem `json:"items"`
|
||||
BuyerID uuid.UUID `json:"buyer_id"`
|
||||
SellerID uuid.UUID `json:"seller_id"`
|
||||
Items []domain.OrderItem `json:"items"`
|
||||
Shipping domain.ShippingAddress `json:"shipping"`
|
||||
}
|
||||
|
||||
type createShipmentRequest struct {
|
||||
OrderID uuid.UUID `json:"order_id"`
|
||||
Carrier string `json:"carrier"`
|
||||
TrackingCode string `json:"tracking_code"`
|
||||
ExternalTracking string `json:"external_tracking"`
|
||||
}
|
||||
|
||||
type updateStatusRequest struct {
|
||||
|
|
|
|||
|
|
@ -114,9 +114,9 @@ func (r *Repository) CreateOrder(ctx context.Context, order *domain.Order) error
|
|||
return err
|
||||
}
|
||||
|
||||
orderQuery := `INSERT INTO orders (id, buyer_id, seller_id, status, total_cents, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7)`
|
||||
if _, err := tx.ExecContext(ctx, orderQuery, order.ID, order.BuyerID, order.SellerID, order.Status, order.TotalCents, order.CreatedAt, order.UpdatedAt); err != nil {
|
||||
orderQuery := `INSERT INTO orders (id, buyer_id, seller_id, status, total_cents, shipping_recipient_name, shipping_street, shipping_number, shipping_complement, shipping_district, shipping_city, shipping_state, shipping_zip_code, shipping_country, created_at, updated_at)
|
||||
VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15, $16)`
|
||||
if _, err := tx.ExecContext(ctx, orderQuery, order.ID, order.BuyerID, order.SellerID, order.Status, order.TotalCents, order.Shipping.RecipientName, order.Shipping.Street, order.Shipping.Number, order.Shipping.Complement, order.Shipping.District, order.Shipping.City, order.Shipping.State, order.Shipping.ZipCode, order.Shipping.Country, order.CreatedAt, order.UpdatedAt); err != nil {
|
||||
_ = tx.Rollback()
|
||||
return err
|
||||
}
|
||||
|
|
@ -136,9 +136,26 @@ VALUES ($1, $2, $3, $4, $5, $6, $7)`
|
|||
}
|
||||
|
||||
func (r *Repository) GetOrder(ctx context.Context, id uuid.UUID) (*domain.Order, error) {
|
||||
var order domain.Order
|
||||
orderQuery := `SELECT id, buyer_id, seller_id, status, total_cents, created_at, updated_at FROM orders WHERE id = $1`
|
||||
if err := r.db.GetContext(ctx, &order, orderQuery, id); err != nil {
|
||||
var row struct {
|
||||
ID uuid.UUID `db:"id"`
|
||||
BuyerID uuid.UUID `db:"buyer_id"`
|
||||
SellerID uuid.UUID `db:"seller_id"`
|
||||
Status domain.OrderStatus `db:"status"`
|
||||
TotalCents int64 `db:"total_cents"`
|
||||
ShippingRecipientName string `db:"shipping_recipient_name"`
|
||||
ShippingStreet string `db:"shipping_street"`
|
||||
ShippingNumber string `db:"shipping_number"`
|
||||
ShippingComplement string `db:"shipping_complement"`
|
||||
ShippingDistrict string `db:"shipping_district"`
|
||||
ShippingCity string `db:"shipping_city"`
|
||||
ShippingState string `db:"shipping_state"`
|
||||
ShippingZipCode string `db:"shipping_zip_code"`
|
||||
ShippingCountry string `db:"shipping_country"`
|
||||
CreatedAt time.Time `db:"created_at"`
|
||||
UpdatedAt time.Time `db:"updated_at"`
|
||||
}
|
||||
orderQuery := `SELECT id, buyer_id, seller_id, status, total_cents, shipping_recipient_name, shipping_street, shipping_number, shipping_complement, shipping_district, shipping_city, shipping_state, shipping_zip_code, shipping_country, created_at, updated_at FROM orders WHERE id = $1`
|
||||
if err := r.db.GetContext(ctx, &row, orderQuery, id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
|
|
@ -147,8 +164,28 @@ func (r *Repository) GetOrder(ctx context.Context, id uuid.UUID) (*domain.Order,
|
|||
if err := r.db.SelectContext(ctx, &items, itemQuery, id); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
order.Items = items
|
||||
return &order, nil
|
||||
order := &domain.Order{
|
||||
ID: row.ID,
|
||||
BuyerID: row.BuyerID,
|
||||
SellerID: row.SellerID,
|
||||
Status: row.Status,
|
||||
TotalCents: row.TotalCents,
|
||||
Items: items,
|
||||
Shipping: domain.ShippingAddress{
|
||||
RecipientName: row.ShippingRecipientName,
|
||||
Street: row.ShippingStreet,
|
||||
Number: row.ShippingNumber,
|
||||
Complement: row.ShippingComplement,
|
||||
District: row.ShippingDistrict,
|
||||
City: row.ShippingCity,
|
||||
State: row.ShippingState,
|
||||
ZipCode: row.ShippingZipCode,
|
||||
Country: row.ShippingCountry,
|
||||
},
|
||||
CreatedAt: row.CreatedAt,
|
||||
UpdatedAt: row.UpdatedAt,
|
||||
}
|
||||
return order, nil
|
||||
}
|
||||
|
||||
func (r *Repository) UpdateOrderStatus(ctx context.Context, id uuid.UUID, status domain.OrderStatus) error {
|
||||
|
|
@ -167,6 +204,27 @@ func (r *Repository) UpdateOrderStatus(ctx context.Context, id uuid.UUID, status
|
|||
return nil
|
||||
}
|
||||
|
||||
func (r *Repository) CreateShipment(ctx context.Context, shipment *domain.Shipment) error {
|
||||
now := time.Now().UTC()
|
||||
shipment.CreatedAt = now
|
||||
shipment.UpdatedAt = now
|
||||
|
||||
query := `INSERT INTO shipments (id, order_id, carrier, tracking_code, external_tracking, status, created_at, updated_at)
|
||||
VALUES (:id, :order_id, :carrier, :tracking_code, :external_tracking, :status, :created_at, :updated_at)`
|
||||
|
||||
_, err := r.db.NamedExecContext(ctx, query, shipment)
|
||||
return err
|
||||
}
|
||||
|
||||
func (r *Repository) GetShipmentByOrderID(ctx context.Context, orderID uuid.UUID) (*domain.Shipment, error) {
|
||||
var shipment domain.Shipment
|
||||
query := `SELECT id, order_id, carrier, tracking_code, external_tracking, status, created_at, updated_at FROM shipments WHERE order_id = $1`
|
||||
if err := r.db.GetContext(ctx, &shipment, query, orderID); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &shipment, nil
|
||||
}
|
||||
|
||||
func (r *Repository) AdjustInventory(ctx context.Context, productID uuid.UUID, delta int64, reason string) (*domain.InventoryItem, error) {
|
||||
tx, err := r.db.BeginTxx(ctx, nil)
|
||||
if err != nil {
|
||||
|
|
@ -452,6 +510,15 @@ CREATE TABLE IF NOT EXISTS orders (
|
|||
seller_id UUID NOT NULL REFERENCES companies(id),
|
||||
status TEXT NOT NULL,
|
||||
total_cents BIGINT NOT NULL,
|
||||
shipping_recipient_name TEXT,
|
||||
shipping_street TEXT,
|
||||
shipping_number TEXT,
|
||||
shipping_complement TEXT,
|
||||
shipping_district TEXT,
|
||||
shipping_city TEXT,
|
||||
shipping_state TEXT,
|
||||
shipping_zip_code TEXT,
|
||||
shipping_country TEXT,
|
||||
created_at TIMESTAMPTZ NOT NULL,
|
||||
updated_at TIMESTAMPTZ NOT NULL
|
||||
);
|
||||
|
|
@ -478,6 +545,17 @@ CREATE TABLE IF NOT EXISTS cart_items (
|
|||
updated_at TIMESTAMPTZ NOT NULL,
|
||||
UNIQUE (buyer_id, product_id)
|
||||
);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS shipments (
|
||||
id UUID PRIMARY KEY,
|
||||
order_id UUID NOT NULL UNIQUE REFERENCES orders(id),
|
||||
carrier TEXT NOT NULL,
|
||||
tracking_code TEXT,
|
||||
external_tracking TEXT,
|
||||
status TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL,
|
||||
updated_at TIMESTAMPTZ NOT NULL
|
||||
);
|
||||
`
|
||||
|
||||
if _, err := r.db.ExecContext(ctx, schema); err != nil {
|
||||
|
|
|
|||
|
|
@ -37,7 +37,7 @@ func New(cfg config.Config) (*Server, error) {
|
|||
|
||||
repo := postgres.New(db)
|
||||
gateway := payments.NewMercadoPagoGateway(cfg.MercadoPagoBaseURL, cfg.MarketplaceCommission)
|
||||
svc := usecase.NewService(repo, gateway, cfg.JWTSecret, cfg.JWTExpiresIn)
|
||||
svc := usecase.NewService(repo, gateway, cfg.MarketplaceCommission, cfg.JWTSecret, cfg.JWTExpiresIn)
|
||||
h := handler.New(svc)
|
||||
|
||||
mux := http.NewServeMux()
|
||||
|
|
@ -78,6 +78,11 @@ func New(cfg config.Config) (*Server, error) {
|
|||
mux.Handle("PATCH /api/orders/", chain(http.HandlerFunc(h.UpdateOrderStatus), middleware.Logger, middleware.Gzip, auth))
|
||||
mux.Handle("POST /api/orders/", chain(http.HandlerFunc(h.CreatePaymentPreference), middleware.Logger, middleware.Gzip, auth))
|
||||
|
||||
mux.Handle("POST /api/v1/shipments", chain(http.HandlerFunc(h.CreateShipment), middleware.Logger, middleware.Gzip, auth))
|
||||
mux.Handle("GET /api/v1/shipments/", chain(http.HandlerFunc(h.GetShipmentByOrderID), middleware.Logger, middleware.Gzip, auth))
|
||||
|
||||
mux.Handle("POST /api/v1/payments/webhook", chain(http.HandlerFunc(h.HandlePaymentWebhook), middleware.Logger, middleware.Gzip))
|
||||
|
||||
mux.Handle("POST /api/v1/auth/register", chain(http.HandlerFunc(h.Register), middleware.Logger, middleware.Gzip))
|
||||
mux.Handle("POST /api/v1/auth/login", chain(http.HandlerFunc(h.Login), middleware.Logger, middleware.Gzip))
|
||||
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ package usecase
|
|||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/golang-jwt/jwt/v5"
|
||||
|
|
@ -29,6 +30,8 @@ type Repository interface {
|
|||
CreateOrder(ctx context.Context, order *domain.Order) error
|
||||
GetOrder(ctx context.Context, id uuid.UUID) (*domain.Order, error)
|
||||
UpdateOrderStatus(ctx context.Context, id uuid.UUID, status domain.OrderStatus) error
|
||||
CreateShipment(ctx context.Context, shipment *domain.Shipment) error
|
||||
GetShipmentByOrderID(ctx context.Context, orderID uuid.UUID) (*domain.Shipment, error)
|
||||
|
||||
CreateUser(ctx context.Context, user *domain.User) error
|
||||
ListUsers(ctx context.Context, filter domain.UserFilter) ([]domain.User, int64, error)
|
||||
|
|
@ -48,15 +51,16 @@ type PaymentGateway interface {
|
|||
}
|
||||
|
||||
type Service struct {
|
||||
repo Repository
|
||||
pay PaymentGateway
|
||||
jwtSecret []byte
|
||||
tokenTTL time.Duration
|
||||
repo Repository
|
||||
pay PaymentGateway
|
||||
jwtSecret []byte
|
||||
tokenTTL time.Duration
|
||||
marketplaceCommission float64
|
||||
}
|
||||
|
||||
// NewService wires use cases together.
|
||||
func NewService(repo Repository, pay PaymentGateway, jwtSecret string, tokenTTL time.Duration) *Service {
|
||||
return &Service{repo: repo, pay: pay, jwtSecret: []byte(jwtSecret), tokenTTL: tokenTTL}
|
||||
func NewService(repo Repository, pay PaymentGateway, commissionPct float64, jwtSecret string, tokenTTL time.Duration) *Service {
|
||||
return &Service{repo: repo, pay: pay, jwtSecret: []byte(jwtSecret), tokenTTL: tokenTTL, marketplaceCommission: commissionPct}
|
||||
}
|
||||
|
||||
func (s *Service) RegisterCompany(ctx context.Context, company *domain.Company) error {
|
||||
|
|
@ -103,6 +107,22 @@ func (s *Service) UpdateOrderStatus(ctx context.Context, id uuid.UUID, status do
|
|||
return s.repo.UpdateOrderStatus(ctx, id, status)
|
||||
}
|
||||
|
||||
// CreateShipment persists a freight label for an order if not already present.
|
||||
func (s *Service) CreateShipment(ctx context.Context, shipment *domain.Shipment) error {
|
||||
if _, err := s.repo.GetOrder(ctx, shipment.OrderID); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
shipment.ID = uuid.Must(uuid.NewV7())
|
||||
shipment.Status = "Label gerada"
|
||||
return s.repo.CreateShipment(ctx, shipment)
|
||||
}
|
||||
|
||||
// GetShipmentByOrderID returns freight details for an order.
|
||||
func (s *Service) GetShipmentByOrderID(ctx context.Context, orderID uuid.UUID) (*domain.Shipment, error) {
|
||||
return s.repo.GetShipmentByOrderID(ctx, orderID)
|
||||
}
|
||||
|
||||
func (s *Service) CreatePaymentPreference(ctx context.Context, id uuid.UUID) (*domain.PaymentPreference, error) {
|
||||
order, err := s.repo.GetOrder(ctx, id)
|
||||
if err != nil {
|
||||
|
|
@ -111,6 +131,40 @@ func (s *Service) CreatePaymentPreference(ctx context.Context, id uuid.UUID) (*d
|
|||
return s.pay.CreatePreference(ctx, order)
|
||||
}
|
||||
|
||||
// HandlePaymentWebhook processes Mercado Pago notifications ensuring split consistency.
|
||||
func (s *Service) HandlePaymentWebhook(ctx context.Context, event domain.PaymentWebhookEvent) (*domain.PaymentSplitResult, error) {
|
||||
order, err := s.repo.GetOrder(ctx, event.OrderID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
expectedMarketplaceFee := int64(float64(order.TotalCents) * (s.marketplaceCommission / 100))
|
||||
marketplaceFee := event.MarketplaceFee
|
||||
if marketplaceFee == 0 {
|
||||
marketplaceFee = expectedMarketplaceFee
|
||||
}
|
||||
|
||||
sellerReceivable := order.TotalCents - marketplaceFee
|
||||
if event.SellerAmount > 0 {
|
||||
sellerReceivable = event.SellerAmount
|
||||
}
|
||||
|
||||
if strings.EqualFold(event.Status, "approved") || strings.EqualFold(event.Status, "paid") {
|
||||
if err := s.repo.UpdateOrderStatus(ctx, order.ID, domain.OrderStatusPaid); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return &domain.PaymentSplitResult{
|
||||
OrderID: order.ID,
|
||||
PaymentID: event.PaymentID,
|
||||
Status: event.Status,
|
||||
MarketplaceFee: marketplaceFee,
|
||||
SellerReceivable: sellerReceivable,
|
||||
TotalPaidAmount: event.TotalPaidAmount,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (s *Service) CreateUser(ctx context.Context, user *domain.User, password string) error {
|
||||
hashed, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Reference in a new issue