package handlers
import (
"encoding/json"
"errors"
"fmt"
"net/http"
"strconv"
"time"
"github.com/getsentry/sentry-go"
//"strconv"
aes "cf-capital/module_server/handlers/aes"
"cf-capital/module_server/handlers/auth"
eloquent "cf-capital/module_server/handlers/eloquent"
mail "cf-capital/module_server/handlers/email"
investment "cf-capital/module_server/handlers/investment/statement"
investmentV1 "cf-capital/module_server/handlers/investment/statement-v1"
lendbox "cf-capital/module_server/handlers/lendbox"
razorpay "cf-capital/module_server/handlers/razorpay"
slack "cf-capital/module_server/handlers/slack"
testUser "cf-capital/module_server/handlers/test/user"
server_handlers "cf-server/server/handlers"
"io/ioutil"
"os"
"text/template"
"github.com/go-playground/validator/v10"
log "github.com/rs/zerolog/log"
"github.com/speps/go-hashids/v2"
)
//var decoder = schema.NewDecoder()
type Context struct {
Title string
Name string
Fruits [3]string
}
type ApiError struct {
Status string `json:"status"`
Message string `json:"message"`
}
type responseBody struct {
Status string `json:"status"`
Message string `json:"message"`
Link string `json:"link,omitempty"`
Token string `json:"token,omitempty"`
Data string `json:"data,omitempty"`
}
type responseBodyPan struct {
Status string `json:"status"`
Message string `json:"message"`
Data eloquent.ValidatePANDataResult `json:"data"`
}
type responseBodyPincode struct {
Status string `json:"status"`
Message string `json:"message"`
Data eloquent.PincodeDetailsDataResult `json:"data"`
}
type responseBodyPassbook struct {
Status string `json:"status"`
Message string `json:"message"`
Data []investmentV1.PassbookData `json:"data"`
}
type responseBodyAccounts struct {
Status string `json:"status"`
Message string `json:"message"`
Data []investmentV1.AccountData `json:"data"`
}
type responseBodyScheme struct {
Status string `json:"status"`
Message string `json:"message"`
Data []investmentV1.SchemeData `json:"data"`
}
type responseBodyWithdrawal struct {
Status string `json:"status"`
Message string `json:"message"`
Data []investmentV1.WithdrawalList `json:"data"`
}
type responseProfile struct {
Status string `json:"status"`
Message string `json:"message"`
UserDetails eloquent.UserDetails `json:"data"`
}
type responseNominee struct {
Status string `json:"status"`
Message string `json:"message"`
Data eloquent.Nominee `json:"data"`
}
type responseBank struct {
Status string `json:"status"`
Message string `json:"message"`
Data []eloquent.BankData `json:"data"`
}
func GenerateOTP() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
log.Info().Msg("GenerateOTP called")
sentry.CaptureMessage("GenerateOTP called")
reqBody, _ := ioutil.ReadAll(req.Body)
var elo eloquent.OTPManagerTable
err := json.Unmarshal(reqBody, &elo.Data)
if err != nil {
log.Info().Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(elo.Data)
if err != nil {
log.Info().Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(errorValidation(err))
return
}
_, err = elo.GenerateOTP()
if err != nil {
log.Info().Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
log.Info().Msg("OTP sent successfully")
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "OTP sent successfully"})
}
}
func VerifyOTP() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var elo eloquent.OTPManagerTable
err := json.Unmarshal(reqBody, &elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(errorValidation(err))
return
}
res, err := elo.VerifyOTP()
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "OTP validate successfully", Token: res.Token})
}
}
func ValidatePAN() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var elo eloquent.ValidatePANDetails
elo.Auth.ID = auth.GetAuth(req)
err := json.Unmarshal(reqBody, &elo.Data)
log.Print("Auth", elo.Auth.ID)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(errorValidation(err))
return
}
if len(elo.Data.PAN) != 10 {
log.Print("Invalid PAN")
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Invalid PAN"})
return
}
resDataItem, errCheck, boolV := elo.ValidatePAN()
if errCheck != nil {
log.Print(errCheck.Error())
if boolV == true {
errMessage := errCheck.Error()
statusMessage := "OK"
statusCode := 200
if resDataItem.Status == "INVALID" {
errMessage = resDataItem.Status
statusMessage = "FAIL"
statusCode = 400
server_handlers.FormatResponse(w, statusCode)
_ = json.NewEncoder(w).Encode(responseBody{Status: statusMessage, Message: errMessage})
}
server_handlers.FormatResponse(w, statusCode)
_ = json.NewEncoder(w).Encode(responseBodyPan{Status: statusMessage, Message: errMessage, Data: resDataItem})
} else {
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
}
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBodyPan{Status: "OK", Message: "PAN validated successfully", Data: resDataItem})
}
}
func CreateUser() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var elo eloquent.User
elo.Auth.ID = auth.GetAuth(req)
err := json.Unmarshal(reqBody, &elo.Data)
elo.Data.Aadhaar = aes.EncryptData(elo.Data.Aadhaar)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
_, err = elo.CreateUser()
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
currentTime := time.Now()
dateTime := currentTime.Format("Mon 2006-01-2 15:04:05")
HtmlBody := "
" +
"
" +
"
" +
"
" +
"
" +
"" +
"| Name | " +
"" + elo.Data.FirstName + " " + elo.Data.MiddleName + " " + elo.Data.LastName + " | " +
"
" +
"" +
"| Email | " +
"" + elo.Data.Email + " | " +
"
" +
"
" +
"
"
log.Print("trigger email, new user registration")
_, err = mail.Email(HtmlBody, fmt.Sprint(elo.Data.FirstName, " ", elo.Data.MiddleName, " ", elo.Data.LastName, " New User Registration ", dateTime))
if err != nil {
log.Print("trigger email error")
log.Print(err.Error())
}
params := map[string]interface{}{
"Name": fmt.Sprint(elo.Data.FirstName, " ", elo.Data.MiddleName, " ", elo.Data.LastName),
"email": elo.Data.Email,
"Date": dateTime,
}
slack.SendSlack("New User Registration", params)
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "User successfully registered"})
}
}
func EsignAgreement() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var elo eloquent.UserSignAgreement
user := auth.GetUser(req)
elo.Auth.ID = user.ID
elo.Data.Name = user.Name
err := json.Unmarshal(reqBody, &elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
_, err = elo.EsignAgreement()
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "User Agreement signed successfully"})
}
}
func UploadDocument() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var elo eloquent.DocumentUpload
elo.Auth.ID = auth.GetAuth(req)
err := json.Unmarshal(reqBody, &elo.Data)
//log.Print(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
_, err = elo.UploadDocument()
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "Document uploaded successfully"})
}
}
func GetPincodeDetails() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
log.Print(reqBody)
log.Print(req.URL.Query()["pincode"])
for k, v := range req.URL.Query() {
fmt.Printf("%s: %s\n", k, v)
}
var elo eloquent.PincodeDetails
elo.Auth.ID = auth.GetAuth(req)
if len(req.URL.Query()["pincode"]) == 0 {
log.Print("Pincode is required")
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Pincode is required"})
return
}
elo.Data.Pincode = req.URL.Query()["pincode"][0]
validate := validator.New()
err := validate.Struct(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
res, errPincode := elo.GetPincodeDetails()
if errPincode != nil {
log.Print(errPincode.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errPincode.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBodyPincode{Status: "OK", Message: "Pincode detailed fetched successfully", Data: res})
}
}
func AddBank() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var elo eloquent.Bank
elo.Auth.ID = auth.GetAuth(req)
err := json.Unmarshal(reqBody, &elo.Data)
log.Print(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
_, err = elo.AddBank()
if err != nil {
if err.Error() != "Bank already updated" {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
}
var lend lendbox.BankDetails
lend.Auth.ID = elo.Auth.ID
lend, err = lend.GetLendboxBankDetails()
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
log.Print("calling lendbox bank")
_, err = lend.ShareBankDetails()
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
elo.UpdateBankDetailsLendboxFlag()
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "Bank added successfully"})
}
}
func UpdateAddress() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var elo eloquent.UpdateAddress
user := auth.GetUser(req)
if len(user.LbUserId) > 0 {
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Address already updated"})
return
}
elo.Auth.ID = user.ID
err := json.Unmarshal(reqBody, &elo.Data)
log.Print(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
_, err = elo.UpdateAddress()
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
var lend lendbox.InvestorRegistration
lend.Auth.ID = elo.Auth.ID
lend, err = lend.GetInvestorRegistrationDetails()
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
log.Print("RegisterInvestor : lend.RegisterInvestor()")
_, err = lend.RegisterInvestor()
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "Address updated successfully"})
}
}
func GetUser() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
var elo eloquent.UserDetails
ID := auth.GetAuth(req)
log.Print("USER")
log.Print(ID)
profile, err := elo.GetUser(ID)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseProfile{Status: "OK", Message: "Profile details fetched", UserDetails: profile})
}
}
func GetAgreementLink() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
w.Header().Add("Content Type", "text/html")
t, err := template.ParseFiles("module_server/handlers/templates/agreement.tmpl")
if err != nil {
log.Error().Err(err).Msg(err.Error())
}
t.Execute(w, auth.GetUser(req))
// schema := "https://"
// if req.TLS == nil {
// schema = "http://"
// }
//
// id, errChek := strconv.ParseInt(ID, 10, 64)
// if errChek != nil {
// fmt.Printf(errChek.Error())
// }
// link := schema + req.Host + "/agreement/" + getEncodedString(id)
// server_handlers.FormatResponse(w, 200)
// _ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "Agreement link fetched", Link: link})
}
}
// MakeTransaction
func MakeTransaction() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var elo eloquent.MakeTransaction
elo.Auth.ID = auth.GetAuth(req)
err := json.Unmarshal(reqBody, &elo.Data)
log.Print(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(elo.Data)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
_, err = elo.MakeTransaction()
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "Successfully sent the request for transaction"})
}
}
func InvestmentWebhookUpdate() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
log.Print(reqBody)
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "Payment Verified Successfully"})
return
}
}
func InvestmentWebhook() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
/*var investmentStruct investmentV1.InvestWebhook
log.Print(req.URL.Query())
err := decoder.Decode(&investmentStruct, req.URL.Query())
if err != nil {
log.Print("Error in GET parameters : ", err)
} else {
log.Print("GET parameters : ", investmentStruct)
}*/
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var investmentStruct investmentV1.InvestWebhook
err := json.Unmarshal(reqBody, &investmentStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
log.Print(investmentStruct)
if err != nil || investmentStruct.PaymentLinkStatus != "paid" {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Payment Verification Failed"})
return
}
params := map[string]interface{}{
"payment_link_id": investmentStruct.RazorpayPaymentLinkId,
"razorpay_payment_id": investmentStruct.PaymentPaymentId,
"payment_link_reference_id": investmentStruct.PaymentLinkReferenceId,
"payment_link_status": investmentStruct.PaymentLinkStatus,
"signature": investmentStruct.Signature,
}
investmentStruct.AccountId = investmentV1.GetAccountIDByReference(investmentStruct.PaymentLinkReferenceId)
status := razorpay.Verify(params)
if status && investmentStruct.AccountId > 0 {
var payments []investmentV1.PaymentConfirmation
var payment investmentV1.PaymentConfirmation
payment.TransactionID = investmentStruct.PaymentLinkReferenceId
payment.AccountId = investmentStruct.AccountId
payments = append(payments, payment)
investmentV1.UpdatePayment(payments)
/*var walletOrder []lendbox.WalletOrderData
var walletOrderData lendbox.WalletOrderData
var wallet lendbox.WalletOrderDataResult
for i := 0; i < len(payments); i++ {
walletOrderData, err = walletOrderData.GetTransactionDetails(payments[i].AccountId, payments[i].TransactionID)
if err != nil {
log.Print("lendbox GetTransactionDetails - error", err)
break
}
walletOrderData.TxType = "CREDIT"
}
walletOrder = append(walletOrder, walletOrderData)
wallet, err = lendbox.InitiateWalletOrder(walletOrder)
if err != nil {
log.Print("lendbox wallet order res - error", wallet)
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Payment Verification Failed"})
return
}
log.Print("lendbox wallet order res", wallet)*/
_, err := investmentV1.PaymentTransactionLogsUpdate(investmentStruct.PaymentLinkReferenceId, investmentStruct.PaymentPaymentId, "SUCCESS")
if err != nil {
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Payment Verification Failed"})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "Payment Verified Successfully"})
return
} else {
if status && investmentStruct.AccountId == 0 {
log.Print("Payment Already Verified - ", investmentStruct.PaymentLinkReferenceId)
} else {
investmentV1.PaymentTransactionLogsUpdate(investmentStruct.PaymentLinkReferenceId, investmentStruct.PaymentPaymentId, "FAILURE")
}
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Payment Verification Failed"})
return
}
}
}
func Invest() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var investmentStruct investmentV1.Invest
user := auth.GetUser(req)
investmentStruct.Auth.ID = user.ID
err := json.Unmarshal(reqBody, &investmentStruct)
log.Print(investmentStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
if investmentStruct.Amount < 10000 || investmentStruct.Amount > 5000000 {
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Amount should not be less than 10K and greater than 50L."})
return
}
validate := validator.New()
err = validate.Struct(investmentStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
investmentPayment, errPay := investmentStruct.Invest()
if errPay != nil {
log.Print(errPay)
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errPay.Error()})
return
}
payoutType := "Cumulative"
if investmentStruct.PayoutType == 1 {
payoutType = "Monthly"
}
paymentGateway := "Offline"
if investmentStruct.PaymentGateway == 1 {
paymentGateway = "Razorpay"
}
paymentMethod := "Online"
if investmentStruct.PaymentMethod == 2 {
paymentMethod = "Offline"
paymentGateway = "Offline"
}
currentTime := time.Now()
dateTime := currentTime.Format("Mon 2006-01-2 15:04:05")
schemeName := investmentStruct.GetSchemeDetails()
HtmlBody := "" +
"
" +
"
" +
"
" +
"
" +
"" +
"| LbUserId | " +
"" + user.LbUserId + " | " +
"
" +
"" +
"| Amount | " +
"" + fmt.Sprintf("%.2f", investmentStruct.Amount) + " | " +
"
" +
"" +
"| Scheme | " +
"" + schemeName + " | " +
"
" +
"" +
"| Gateway | " +
"" + paymentGateway + " | " +
"
" +
"" +
"| Payment Method | " +
"" + paymentMethod + " | " +
"
" +
"" +
"| PayoutType | " +
"" + payoutType + " | " +
"
" +
"| ReferenceCode | " +
"" + investmentPayment.ReferenceCode + " | " +
"
" +
"" +
"| Transaction Reference | " +
"" + investmentPayment.TransactionReference + " | " +
"
" +
"
" +
"
"
log.Print("trigger email")
_, err = mail.Email(HtmlBody, fmt.Sprint(user.LbUserId, " Request received for investment ", dateTime))
if err != nil {
log.Print("trigger email error")
log.Print(err.Error())
}
params := map[string]interface{}{
"lbUserId": user.LbUserId,
"investment_date": dateTime,
"ReferenceCode": investmentPayment.ReferenceCode,
"TransactionReference": investmentPayment.TransactionReference,
}
slack.SendSlack("New Investment", params)
if investmentStruct.PaymentMethod == 2 {
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "Invested"})
//_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "Payment link fetched", Link: "https://razorpay.com/payment-link/plink_K9mw6Fiqf3wtZ0/test"})
return
}
/* investmentPayment, errPay := investmentStruct.Invest()
if errPay != nil {
log.Print(errPay)
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errPay.Error()})
return
} */
log.Print("Preparing requestBody")
var api razorpay.Payment
api = getPaymentStruct(investmentStruct, investmentPayment, req)
output, errCheck := api.GetLink()
if errCheck != nil {
log.Print(errCheck)
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
outputRes := output.(map[string]interface{})
log.Print("outputRes")
b, errw := json.Marshal(outputRes)
if errw != nil {
log.Print(errw)
}
fmt.Println(string(b))
log.Print(outputRes["short_url"])
investmentStruct.PaymentTransactionLogs(investmentPayment)
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBody{Status: "OK", Message: "Payment link fetched", Link: outputRes["short_url"].(string)})
}
}
func getPaymentStruct(investmentStruct investmentV1.Invest, investmentPayment investmentV1.Invest, req *http.Request) razorpay.Payment {
var api razorpay.Payment
api.Amount = investmentStruct.Amount * 100
api.ReceiptId = investmentPayment.ReferenceCode
api.Notes1 = "cf-capital"
api.Description = fmt.Sprint("Payment for transaction id #", investmentPayment.ReferenceCode, ", ID#", auth.GetAuth(req))
api.Notes2 = fmt.Sprint("Payment for investment id #", investmentPayment.InvestmentPaymentID)
var customer razorpay.Customer
user := auth.GetUser(req)
customer.Name = user.Name
customer.Contact = user.Phone
customer.Email = user.Email
api.Customer = customer
var plan razorpay.Plan
plan.Name = fmt.Sprint("Flexi Plan # ", investmentStruct.MHP)
api.Plan = plan
return api
}
func Investment() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var investmentStruct investment.FlexiPlan
//elo.Auth.ID = auth.GetAuth(req)
err := json.Unmarshal(reqBody, &investmentStruct)
log.Print(investmentStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(investmentStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
payout, errCheck := investmentStruct.Flexi()
if errCheck != nil {
log.Print(errCheck.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(payout)
}
}
func AddNominee() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var nominee eloquent.Nominee
nominee.AuthID = auth.GetAuth(req)
err := json.Unmarshal(reqBody, &nominee)
log.Print(nominee)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(nominee)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
_, errCheck := nominee.AddNominee()
if errCheck != nil {
log.Print(errCheck.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
var response = map[string]string{"status": "OK", "message": "Nominee added!"}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(response)
}
}
func GetNominee() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
var nominee eloquent.Nominee
nominee.AuthID = auth.GetAuth(req)
nomineeData, errCheck := nominee.GetNominee()
if errCheck != nil {
log.Print(errCheck.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseNominee{Status: "OK", Message: "Nominee fetched", Data: nomineeData})
}
}
func GetBank() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
var bank eloquent.Bank
bank.Auth.ID = auth.GetAuth(req)
bankData, errCheck := bank.GetBank()
log.Print(bankData)
if errCheck != nil {
log.Print(errCheck.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBank{Status: "OK", Message: "Bank fetched", Data: bankData})
}
}
func Withdrawal() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var withdrawalStruct investmentV1.Withdrawal
user := auth.GetUser(req)
withdrawalStruct.Auth.ID = user.ID
err := json.Unmarshal(reqBody, &withdrawalStruct)
log.Print(withdrawalStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(withdrawalStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
withdrawal, errCheck := withdrawalStruct.Withdrawal()
if errCheck != nil {
log.Print(errCheck.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
currentTime := time.Now()
dateTime := currentTime.Format("Mon 2006-01-2 15:04:05")
schemeName := withdrawalStruct.GetSchemeDetailsByAccount()
HtmlBody := "" +
"
" +
"
" +
"
" +
"
" +
"" +
"| LbUserId | " +
"" + user.LbUserId + " | " +
"
" +
"" +
"| Amount | " +
"" + fmt.Sprintf("%.2f", withdrawalStruct.Amount) + " | " +
"
" +
"" +
"| Scheme | " +
"" + schemeName + " | " +
"
" +
"" +
"| Reason | " +
"" + withdrawalStruct.Reason + " | " +
"
" +
"" +
"| ReferenceCode | " +
"" + withdrawal.ReferenceCode + " | " +
"
" +
"
" +
"
"
log.Print("trigger email")
_, err = mail.Email(HtmlBody, fmt.Sprint(user.LbUserId, ": Request received for withdrawal ", dateTime))
if err != nil {
log.Print("trigger email error")
log.Print(err.Error())
}
params := map[string]interface{}{
"request": "Withdrawal",
"Name": user.Name,
"Withdrawal": dateTime,
"Amount": fmt.Sprintf("%.2f", withdrawalStruct.Amount),
}
slack.SendSlack("Withdrawal Request", params)
var response = map[string]string{"status": "OK", "message": "You have successfully made a withdrawal from your portfolio. The amount withdrawn will reflect in your selected Bank account within 24hours."}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(response)
//_, errCheck := withdrawalStruct.Withdrawal()
//if errCheck != nil {
// log.Print(errCheck.Error())
// server_handlers.FormatResponse(w, 400)
// _ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
// return
//}
//
//var response = map[string]string{"status": "OK", "message": "You have successfully made a withdrawal from your portfolio. The amount withdrawn will reflect in your selected Bank account within 24hours."}
//
//server_handlers.FormatResponse(w, 200)
//_ = json.NewEncoder(w).Encode(response)
}
}
func GetPassbook() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var passbookStruct investmentV1.Passbook
passbookStruct.Auth.ID = auth.GetAuth(req)
//passbookStruct.StartDate = req.URL.Query()["start_date"][0]
//passbookStruct.EndDate = req.URL.Query()["end_date"][0]
//passbookStruct.Auth.ID = auth.GetAuth(req)
//log.Print(passbookStruct)
//account_id, err := strconv.ParseInt(req.URL.Query()["account_id"][0], 10, 64)
//if err != nil {
// log.Error().Err(err).Msg(err.Error())
//}
//passbookStruct.AccountID = account_id
err := json.Unmarshal(reqBody, &passbookStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
log.Print(passbookStruct)
validate := validator.New()
err = validate.Struct(passbookStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
passbookItems, errCheck := passbookStruct.GetPassbook()
if errCheck != nil {
log.Print(errCheck.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBodyPassbook{Status: "OK", Message: "Passbook fetched", Data: passbookItems})
}
}
func GetAccounts() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
var accountStruct investmentV1.Accounts
//accountStruct.AccountID = req.URL.Query()["account_id"][0]
accountStruct.Auth.ID = auth.GetAuth(req)
var err error
var account_id int64
if req.URL.Query()["account_id"] != nil {
account_id, err = strconv.ParseInt(req.URL.Query()["account_id"][0], 10, 64)
}
if err != nil {
log.Error().Err(err).Msg(err.Error())
}
accountStruct.AccountID = account_id
validate := validator.New()
err = validate.Struct(accountStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
accountsItems, errCheck := accountStruct.GetAccounts()
if errCheck != nil {
log.Print(errCheck.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBodyAccounts{Status: "OK", Message: "Accounts fetched", Data: accountsItems})
}
}
func GetSchemes() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
var schemeStruct investmentV1.Schemes
//accountStruct.AccountID = req.URL.Query()["account_id"][0]
schemeStruct.Auth.ID = auth.GetAuth(req)
var err error
var scheme_id int64
var payout_id int64
if req.URL.Query()["scheme_id"] != nil {
scheme_id, err = strconv.ParseInt(req.URL.Query()["scheme_id"][0], 10, 64)
}
if req.URL.Query()["payout_id"] != nil {
payout_id, err = strconv.ParseInt(req.URL.Query()["payout_id"][0], 10, 64)
}
if err != nil {
log.Error().Err(err).Msg(err.Error())
}
schemeStruct.SchemeID = scheme_id
schemeStruct.PayoutID = payout_id
PolicyType := "C"
if schemeStruct.PayoutID == 1 {
PolicyType = "M"
}
schemeStruct.PayoutType = PolicyType
validate := validator.New()
err = validate.Struct(schemeStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
accountsItems, errCheck := schemeStruct.GetSchemes()
if errCheck != nil {
log.Print(errCheck.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBodyScheme{Status: "OK", Message: "Scheme fetched", Data: accountsItems})
}
}
func GetDashboard() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
var dashboard investmentV1.Dashboard
var investmentSummaryStruct investmentV1.InvestmentSummary
totalPortfolioValueAvailableForWithdrawal, investmentSummary, totalPortfolioValue, totalInvestment, totalWithdrawal, totalInterestPaidOut, totalInterestAccrued, totalInterest, err := investmentSummaryStruct.GetInvestmentSummary(auth.GetAuth(req))
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
//var dashboard investmentV1.Dashboard
dashboard.TotalInvestment = totalInvestment
dashboard.AmountRepaid = totalWithdrawal
dashboard.NetPrincipalInvestment = totalInvestment
//dashboard.Portfolio = (totalInvestment + totalInterestAccrued) - totalWithdrawal
dashboard.Portfolio = totalPortfolioValue
dashboard.PortfolioValueAvailableForWithdrawal = totalPortfolioValueAvailableForWithdrawal
var interestSummary investmentV1.InterestSummary
interestSummary.CapitalisedInterest = 0
interestSummary.InterestPaidOut = totalInterestPaidOut
interestSummary.AccruedInterest = totalInterestAccrued
interestSummary.TotalInterest = totalInterest
var estimatedReturnSummary investmentV1.EstimatedReturnSummary
estimatedReturnSummary.AbsoluteReturnRupee = 0
estimatedReturnSummary.AbsoluteReturnPercentage = 0
estimatedReturnSummary.AnnualisedReturn = 0
//var investmentSummaryItems []investmentV1.InvestmentSummary
//var investmentSummary investmentV1.InvestmentSummary
//investmentSummary.Scheme = "Flexi - 2 days - Cumulative Payout"
//investmentSummary.DateOfInvestment = "2022-09-10"
//investmentSummary.Amount = 10000
//investmentSummary.MAX_XIRR = 8
//investmentSummary.InterestRepaid = 0
//investmentSummary.PrincipalRepaid = 0
//investmentSummary.TotalRepaid = 0
//investmentSummary.PortfolioValue = 10095
//investmentSummary.EndDate = "2023-09-10"
//investmentSummaryItems = append(investmentSummaryItems, investmentSummary)
//var investmentSummary investmentSummary
/*investmentSummary.Scheme = "Flexi - 2 days - Cumulative Payout"
investmentSummary.DateOfInvestment = "2022-09-10"
investmentSummary.Amount = 10000
investmentSummary.MAX_XIRR = 8
investmentSummary.InterestRepaid = 0
investmentSummary.PrincipalRepaid = 0
investmentSummary.TotalRepaid = 0
investmentSummary.PortfolioValue = 10095
investmentSummary.EndDate = "2023-09-10"*/
//investmentSummaryItems = append(investmentSummaryItems, investmentSummary)
dashboard.InterestSummary = interestSummary
dashboard.EstimatedReturnSummary = estimatedReturnSummary
dashboard.InvestmentSummary = investmentSummary
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(dashboard)
}
}
func InvestmentV1() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var investmentStruct investmentV1.FlexiPlan
//elo.Auth.ID = auth.GetAuth(req)
err := json.Unmarshal(reqBody, &investmentStruct)
log.Print(investmentStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
validate := validator.New()
err = validate.Struct(investmentStruct)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
payout, errCheck := investmentStruct.FlexiV1()
if errCheck != nil {
log.Print(errCheck.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(payout)
}
}
func GetFrequentlyAskedQuestions() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
var questions = []map[string]string{
{"question": "What documents are required to register as an investor/lender?", "answer": "To register as an investor, you must give basic KYC information such as your Aadhar card, Pan card, and bank account details"},
{"question": "What is the average loan size of Credit Fair?", "answer": "The loan provided starts from minimum of Rs. 10,000 with maximum limit of up to Rs. 20 lakhs. It depends from segment to segment and we consider the average across all the segments, the loan size is somewhere close to Rs. 75,000"},
{"question": "What is your NPA and how much interest rate do you charge on loans?", "answer": "We have a dedicated Collections team that has helped us keep the NPA under 0.75%. The rate of interest on loans charged to borrowers ranges between 16% to 28%"},
{"question": "What are the various P2P plans and how much advisory fees can we expect?", "answer": "We have 2 types of P2P Investment plans:\ni) Flexi: This investment plan is for the customers who are looking for short term investment. There is no lock-in period in this plan. Rate of interest offered for Flexi plan is at 9% per annum.\nii)Fixed: This investment plan comes with the benefit of higher returns. The customer can choose from a lock-in period of 6, 12 and 24 months. Rate of interest offered ranges between 9.5% to 11.5% per annum based on the lock-in period selected."},
{"question": "Is my interest income through Credit Fair Capital taxable?", "answer": "All repayments you receive from borrowers on Credit Fair Capital will be without any tax deduction. Earnings will be taxable as per the income tax rules that apply to you."},
{"question": "Are there any registration charges?", "answer": "There are no registration charges to the investor. In fact, we have no additional charge whatsoever while onboarding the investor."},
{"question": "How safe is the investment?", "answer": "P2P investments have an element of risk and are directly affected by the Non-performing Asset (NPA) of the Portfolio. P2P investment with Credit Fair Capital comes with low risk and high returns due to diversification of the portfolio across hundreds of borrowers, sourcing prime borrowers, monitoring end use and in-house collections team. With the efforts of the dedicated Collections team at Credit Fair Capital, the NPA is below 0.75% as compared to industry standards at 3% to 10%."},
{"question": "In how many borrowers the investor's money is divided into?", "answer": "The number of borrowers depends on the amount invested and the minimum is 50 borrowers. The borrowers are required to have a minimum of 700 as the CIBIL score."},
{"question": "Can NRIs also invest in Credit Fair Capital?", "answer": "Yes, even NRIs can invest in Credit Fair Capital with the same documentation process. But they can participate only with their NRO accounts."},
{"question": "What are NCDs?", "answer": "Non-convertible debentures (NCDs) are fixed-income instruments, usually issued by high-rated companies in the form of a public or a private issue. They usually provide higher returns than bank fixed deposits."},
{"question": "What is P2P lending?", "answer": "P2P lending is a form of crowd-funding used to raise loans which are paid back with interest. It can be defined as the use of an online platform that matches lenders with borrowers. As per current RBI regulations, these platforms can facilitate only unsecured loans."},
{"question": "As a partner, how to register with Credit Fair Capital?", "answer": "In order to register yourself as a partner with Credit Fair Capital you can contact us at info@creditfaircapital.in"},
{"question": "As an investor, how to register with Credit Fair Capital?", "answer": "In order to register as an investor you can visit on our website https://creditfaircapital.in/ and click on Login/Register"},
{"question": "Are there any eligibility criteria for registration?", "answer": "You should be at least 18 years of age or older to be eligible to register as a partner or an investor with Credit Fair Capital."},
{"question": "Can I apply for more than one investment?", "answer": "Yes, you can invest multiple times but the limit for a P2P investor is 50 lakhs according to the existing RBI guidelines."},
{"question": "What are the benefits of having multiple investments?", "answer": "We enable better matching of your investments to your financial goals via multiple investments. \nFor example: if you need to travel in 6 months, you can invest in our 6 months product but if you need the money in 2 years, you can invest longer term."},
{"question": "How do I change or update my mobile number, email ID, bank account details associated with my account?", "answer": "There is no provision to change or update the mobile number associated with your account with Credit Fair Capital. To update your email address, bank account details, you can reach us at info@creditfaircapital.in"},
{"question": "How do I withdraw funds post maturity?", "answer": "Write to us at info@creditfaircapital.in for request of withdrawal on maturity."},
{"question": "What kind of reports are available?", "answer": "Statement of accounts, investment statements, tax reports are types of reports available for your investment."},
{"question": "Why should you consider investing at Credit Fair Capital?", "answer": "One should consider investing in Credit Fair Capital as we provide higher returns with low risk comparative to other investing firms."},
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(questions)
}
}
// Test - delete entire user
func DeleteUser() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
//reqBody, _ := ioutil.ReadAll(req.Body)
var user testUser.User
user.ID = auth.GetAuth(req)
//err := json.Unmarshal(reqBody, &user)
log.Print(user)
log.Print("DeleteUser")
user.DeleteUser()
var userRes = []map[string]string{{"Status": "OK", "message": "Deleted"}}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(userRes)
}
}
func GetWithdrawalList() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
var withdrawalList investmentV1.WithdrawalList
//accountStruct.AccountID = req.URL.Query()["account_id"][0]
withdrawalList.Auth.ID = auth.GetAuth(req)
var err error
if err != nil {
log.Error().Err(err).Msg(err.Error())
}
validate := validator.New()
err = validate.Struct(withdrawalList)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: err.Error()})
return
}
withdrawalItems, errCheck := withdrawalList.GetWithdrawalList()
if errCheck != nil {
log.Print(errCheck.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: errCheck.Error()})
return
}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(responseBodyWithdrawal{Status: "OK", Message: "Withdrawal list fetched", Data: withdrawalItems})
}
}
func GetInvestmentList() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
}
}
func PaymentConfirmation() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
var payment []investmentV1.PaymentConfirmation
err := json.Unmarshal(reqBody, &payment)
log.Print(payment)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
investmentV1.UpdatePayment(payment)
var test = map[string]string{"Status": "OK", "Message": "Payment confirmed"}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(test)
}
}
func WithdrawalConfirmation() http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
w.Header().Set("Content-Type", "application/json")
reqBody, _ := ioutil.ReadAll(req.Body)
//a := []interface{}{1, 2, 3, 4, 5}
//b := make([]int, len(a))
//amt := investmentV1.GetGainedInterestByDate("2022-10-01", b)
//log.Print(amt)
//return
var withdrawal []investmentV1.WithdrawalConfirmation
err := json.Unmarshal(reqBody, &withdrawal)
log.Print(withdrawal)
if err != nil {
log.Error().Err(err).Msg(err.Error())
server_handlers.FormatResponse(w, 400)
_ = json.NewEncoder(w).Encode(responseBody{Status: "FAIL", Message: "Unable to parse the data"})
return
}
investmentV1.UpdateWithdrawal(withdrawal)
var test = map[string]string{"Status": "OK", "Message": "Withdrawal confirmed"}
server_handlers.FormatResponse(w, 200)
_ = json.NewEncoder(w).Encode(test)
}
}
func errorValidation(err error) []ApiError {
var ve validator.ValidationErrors
if errors.As(err, &ve) {
out := make([]ApiError, len(ve))
for i, fe := range ve {
out[i] = ApiError{"FAIL", msgForTag(fe)}
}
return out
}
return nil
}
func msgForTag(fe validator.FieldError) string {
log.Print(fe.Tag())
switch fe.Tag() {
case "required":
return fe.Field() + " field is required"
case fe.Tag():
return "Invalid field " + fe.Tag()
}
return fe.Error() // default error
}
func getEncodedString(ID int64) string {
hd := hashids.NewData()
hd.Salt = os.Getenv("HASH")
hd.MinLength = 6
h, _ := hashids.NewWithData(hd)
auth_id, _ := h.EncodeInt64([]int64{ID})
return auth_id
}