|
|
|
@ -79,6 +79,11 @@ func (p *Provider) CreateInvoice(ctx context.Context, req map[string]string) (st
|
|
|
|
|
p.logger.Error("failed to create payment yandex receipt by parse map", zap.Error(err))
|
|
|
|
|
return "", errors.NewWithMessage("failed to parse input request by parse map", errors.ErrInvalidArgs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if request.Recurrent {
|
|
|
|
|
return p.CreateRecurrentPayment(ctx, request)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
idempotenceKey := uuid.New().String()
|
|
|
|
|
|
|
|
|
|
yandexPayment, err := p.httpClient.R().
|
|
|
|
@ -250,3 +255,77 @@ func (p *Provider) handleWebhook(ctx *fiber.Ctx) error {
|
|
|
|
|
|
|
|
|
|
return ctx.SendStatus(http.StatusOK)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func (p *Provider) CreateRecurrentPayment(ctx context.Context, request *models.CreatePayment[yandex.Receipt]) (string, errors.Error) {
|
|
|
|
|
methods, err := p.paymentMethodRepository.GetByUserID(ctx, request.UserID)
|
|
|
|
|
if err != nil {
|
|
|
|
|
p.logger.Error("failed to get payment methods", zap.Error(err), zap.String("userId", request.UserID))
|
|
|
|
|
return "", errors.NewWithError(err, errors.ErrInternalError)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if len(methods) == 0 {
|
|
|
|
|
p.logger.Warn("no saved payment methods found", zap.String("userId", request.UserID))
|
|
|
|
|
return "", errors.NewWithMessage("no saved payment methods found", errors.ErrInvalidArgs)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for _, method := range methods {
|
|
|
|
|
idempotenceKey := uuid.New().String()
|
|
|
|
|
|
|
|
|
|
yandexPayment, err := p.httpClient.R().
|
|
|
|
|
SetContext(ctx).
|
|
|
|
|
SetHeader("Content-Type", "application/json").
|
|
|
|
|
SetHeader("Idempotence-Key", idempotenceKey).
|
|
|
|
|
SetHeader("Authorization", utils.ConvertYoomoneySercetsToAuth("Basic", p.config.StoreID, p.config.SecretKey)).
|
|
|
|
|
SetBody(&yandex.CreateRecurrentPayment{
|
|
|
|
|
Amount: yandex.Amount{
|
|
|
|
|
Value: utils.ConvertAmountToStringFloat(request.Amount),
|
|
|
|
|
Currency: request.Currency,
|
|
|
|
|
},
|
|
|
|
|
PaymentMethodID: method.MethodID,
|
|
|
|
|
Capture: true,
|
|
|
|
|
}).
|
|
|
|
|
Post(p.config.PaymentsURL)
|
|
|
|
|
|
|
|
|
|
if err != nil {
|
|
|
|
|
p.logger.Error("failed to create recurrent payment", zap.Error(err), zap.String("userId", request.UserID))
|
|
|
|
|
return "", errors.NewWithError(fmt.Errorf("failed to create recurrent payment"), errors.ErrInternalError)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if yandexPayment.StatusCode() != http.StatusOK {
|
|
|
|
|
p.logger.Error("unexpected status code from yandex", zap.Int("statusCode", yandexPayment.StatusCode()), zap.String("userId", request.UserID))
|
|
|
|
|
return "", errors.NewWithError(fmt.Errorf("unexpected status code: %d", yandexPayment.StatusCode()), errors.ErrInternalError)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var payment yandex.Payment
|
|
|
|
|
if err := json.Unmarshal(yandexPayment.Body(), &payment); err != nil {
|
|
|
|
|
p.logger.Error("failed to unmarshal payment response", zap.Error(err), zap.String("userId", request.UserID), zap.String("methodId", method.MethodID))
|
|
|
|
|
return "", errors.NewWithError(err, errors.ErrInternalError)
|
|
|
|
|
}
|
|
|
|
|
if payment.Status != yandex.PaymentStatusSuccessfully {
|
|
|
|
|
p.logger.Error("payment not succeeded", zap.String("userId", request.UserID), zap.String("status", string(payment.Status)))
|
|
|
|
|
continue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
_, err = p.repository.Insert(ctx, &models.Payment{
|
|
|
|
|
UserID: request.UserID,
|
|
|
|
|
PaymentID: payment.ID,
|
|
|
|
|
IdempotencePaymentID: idempotenceKey,
|
|
|
|
|
ClientIP: request.ClientIP,
|
|
|
|
|
Currency: request.Currency,
|
|
|
|
|
Amount: request.Amount,
|
|
|
|
|
Type: request.Type,
|
|
|
|
|
Status: models.PaymentStatusMap[string(payment.Status)],
|
|
|
|
|
Completed: false,
|
|
|
|
|
RawPaymentBody: payment,
|
|
|
|
|
CallbackHostGRPC: request.CallbackHostGRPC,
|
|
|
|
|
})
|
|
|
|
|
if err != nil {
|
|
|
|
|
p.logger.Error("failed to save payment to database", zap.Error(err))
|
|
|
|
|
return "", errors.NewWithError(fmt.Errorf("failed to save payment to database: %w", err), errors.ErrInternalError)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return payment.ID, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return "", errors.NewWithMessage("failed to create recurrent payment with any saved method", errors.ErrInternalError)
|
|
|
|
|
}
|
|
|
|
|