draft
This commit is contained in:
144
internal/modules/payments/handler.go
Normal file
144
internal/modules/payments/handler.go
Normal file
@@ -0,0 +1,144 @@
|
||||
package payments
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"strings"
|
||||
|
||||
"google.golang.org/grpc"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/metadata"
|
||||
"google.golang.org/grpc/status"
|
||||
appv1 "stream.api/internal/gen/proto/app/v1"
|
||||
"stream.api/internal/modules/common"
|
||||
)
|
||||
|
||||
type Handler struct {
|
||||
appv1.UnimplementedPaymentsServiceServer
|
||||
module *Module
|
||||
}
|
||||
|
||||
var _ appv1.PaymentsServiceServer = (*Handler)(nil)
|
||||
|
||||
func NewHandler(module *Module) *Handler { return &Handler{module: module} }
|
||||
|
||||
func (h *Handler) CreatePayment(ctx context.Context, req *appv1.CreatePaymentRequest) (*appv1.CreatePaymentResponse, error) {
|
||||
authResult, err := h.module.runtime.Authenticate(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
planID := strings.TrimSpace(req.GetPlanId())
|
||||
if planID == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "Plan ID is required")
|
||||
}
|
||||
if !common.IsAllowedTermMonths(req.GetTermMonths()) {
|
||||
return nil, status.Error(codes.InvalidArgument, "Term months must be one of 1, 3, 6, or 12")
|
||||
}
|
||||
paymentMethod := common.NormalizePaymentMethod(req.GetPaymentMethod())
|
||||
if paymentMethod == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "Payment method must be wallet or topup")
|
||||
}
|
||||
result, err := h.module.CreatePayment(ctx, CreatePaymentCommand{UserID: authResult.UserID, PlanID: planID, TermMonths: req.GetTermMonths(), PaymentMethod: paymentMethod, TopupAmount: req.TopupAmount})
|
||||
if err != nil {
|
||||
return nil, h.handleError(ctx, err, "Failed to create payment")
|
||||
}
|
||||
return presentCreatePaymentResponse(result), nil
|
||||
}
|
||||
|
||||
func (h *Handler) ListPaymentHistory(ctx context.Context, req *appv1.ListPaymentHistoryRequest) (*appv1.ListPaymentHistoryResponse, error) {
|
||||
authResult, err := h.module.runtime.Authenticate(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := h.module.ListPaymentHistory(ctx, PaymentHistoryQuery{UserID: authResult.UserID, Page: req.GetPage(), Limit: req.GetLimit()})
|
||||
if err != nil {
|
||||
return nil, h.handleError(ctx, err, "Failed to fetch payment history")
|
||||
}
|
||||
return presentPaymentHistoryResponse(result), nil
|
||||
}
|
||||
|
||||
func (h *Handler) TopupWallet(ctx context.Context, req *appv1.TopupWalletRequest) (*appv1.TopupWalletResponse, error) {
|
||||
authResult, err := h.module.runtime.Authenticate(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := h.module.TopupWallet(ctx, TopupWalletCommand{UserID: authResult.UserID, Amount: req.GetAmount()})
|
||||
if err != nil {
|
||||
return nil, h.handleError(ctx, err, "Failed to top up wallet")
|
||||
}
|
||||
return presentTopupWalletResponse(result), nil
|
||||
}
|
||||
|
||||
func (h *Handler) DownloadInvoice(ctx context.Context, req *appv1.DownloadInvoiceRequest) (*appv1.DownloadInvoiceResponse, error) {
|
||||
authResult, err := h.module.runtime.Authenticate(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
result, err := h.module.DownloadInvoice(ctx, DownloadInvoiceQuery{UserID: authResult.UserID, ID: strings.TrimSpace(req.GetId())})
|
||||
if err != nil {
|
||||
return nil, h.handleError(ctx, err, "Failed to download invoice")
|
||||
}
|
||||
return presentDownloadInvoiceResponse(result), nil
|
||||
}
|
||||
|
||||
func (h *Handler) ListAdminPayments(ctx context.Context, req *appv1.ListAdminPaymentsRequest) (*appv1.ListAdminPaymentsResponse, error) {
|
||||
result, err := h.module.ListAdminPayments(ctx, ListAdminPaymentsQuery{Page: req.GetPage(), Limit: req.GetLimit(), UserID: strings.TrimSpace(req.GetUserId()), StatusFilter: strings.TrimSpace(req.GetStatus())})
|
||||
if err != nil {
|
||||
return nil, h.handleError(ctx, err, "Failed to list payments")
|
||||
}
|
||||
return presentListAdminPaymentsResponse(result), nil
|
||||
}
|
||||
|
||||
func (h *Handler) GetAdminPayment(ctx context.Context, req *appv1.GetAdminPaymentRequest) (*appv1.GetAdminPaymentResponse, error) {
|
||||
result, err := h.module.GetAdminPayment(ctx, GetAdminPaymentQuery{ID: strings.TrimSpace(req.GetId())})
|
||||
if err != nil {
|
||||
return nil, h.handleError(ctx, err, "Failed to get payment")
|
||||
}
|
||||
return presentGetAdminPaymentResponse(*result), nil
|
||||
}
|
||||
|
||||
func (h *Handler) CreateAdminPayment(ctx context.Context, req *appv1.CreateAdminPaymentRequest) (*appv1.CreateAdminPaymentResponse, error) {
|
||||
userID := strings.TrimSpace(req.GetUserId())
|
||||
planID := strings.TrimSpace(req.GetPlanId())
|
||||
if userID == "" || planID == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "User ID and plan ID are required")
|
||||
}
|
||||
if !common.IsAllowedTermMonths(req.GetTermMonths()) {
|
||||
return nil, status.Error(codes.InvalidArgument, "Term months must be one of 1, 3, 6, or 12")
|
||||
}
|
||||
paymentMethod := common.NormalizePaymentMethod(req.GetPaymentMethod())
|
||||
if paymentMethod == "" {
|
||||
return nil, status.Error(codes.InvalidArgument, "Payment method must be wallet or topup")
|
||||
}
|
||||
result, err := h.module.CreateAdminPayment(ctx, CreateAdminPaymentCommand{UserID: userID, PlanID: planID, TermMonths: req.GetTermMonths(), PaymentMethod: paymentMethod, TopupAmount: req.TopupAmount})
|
||||
if err != nil {
|
||||
return nil, h.handleError(ctx, err, "Failed to create payment")
|
||||
}
|
||||
return presentCreateAdminPaymentResponse(result), nil
|
||||
}
|
||||
|
||||
func (h *Handler) UpdateAdminPayment(ctx context.Context, req *appv1.UpdateAdminPaymentRequest) (*appv1.UpdateAdminPaymentResponse, error) {
|
||||
result, err := h.module.UpdateAdminPayment(ctx, UpdateAdminPaymentCommand{ID: strings.TrimSpace(req.GetId()), NewStatus: req.GetStatus()})
|
||||
if err != nil {
|
||||
return nil, h.handleError(ctx, err, "Failed to update payment")
|
||||
}
|
||||
return presentUpdateAdminPaymentResponse(*result), nil
|
||||
}
|
||||
|
||||
func (h *Handler) handleError(ctx context.Context, err error, fallback string) error {
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if validationErr, ok := err.(*PaymentValidationError); ok {
|
||||
body := validationErr.apiBody()
|
||||
if encoded, marshalErr := json.Marshal(body); marshalErr == nil {
|
||||
_ = grpc.SetTrailer(ctx, metadata.Pairs("x-error-body", string(encoded)))
|
||||
}
|
||||
return status.Error(codes.Code(validationErr.GRPCCode), validationErr.Message)
|
||||
}
|
||||
if _, ok := status.FromError(err); ok {
|
||||
return err
|
||||
}
|
||||
h.module.runtime.Logger().Error(fallback, "error", err)
|
||||
return status.Error(codes.Internal, fallback)
|
||||
}
|
||||
Reference in New Issue
Block a user