treasurer/handlers/payment.go

197 lines
5.7 KiB
Go
Raw Normal View History

2023-05-16 16:21:56 +00:00
package handlers
import (
"errors"
"fmt"
"net/http"
"strconv"
"bitbucket.org/skeris/treasurer/dal"
"bitbucket.org/skeris/treasurer/payway"
"github.com/gorilla/mux"
tb "gopkg.in/tucnak/telebot.v2"
)
type RequestCreatePayment struct {
RequesterID string `json:"requester_id" validate:"required"`
Amount float64 `json:"amount" validate:">0"`
PaymentType string `json:"payment_type" validate:"required"` // Тип пополнения dal.PayWayPayment.ApiId
Currency string `json:"currency"`
PayWayID string `json:"payway_id" validate:"required"` // Присылать именно ID, а не shortName! id: fk1, sn: fk
Email string `json:"email"`
Phone string `json:"phone"`
OnAccept Action `json:"on_accept"`
OnDecline Action `json:"on_decline"`
OnTimeout Action `json:"on_timeout"`
}
type Action struct {
ActionType string `json:"action_type" validate:"required,format=^(mail|vk|tg|sms|request)$"`
Target string `json:"target" validate:"required"`
Data string `json:"data" validate:"required"`
}
func CreatePaymentHandler(h *Handler, pwc *payway.PayWay, crush *tb.Bot) {
var request RequestCreatePayment
err := h.handlePostRequest(&request)
if err != nil {
fmt.Println("handlePostRequest", err)
return
}
fmt.Println("Skeris1")
record := &dal.Payment{
RequesterID: request.RequesterID,
UserIP: h.r.RemoteAddr,
Email: request.Email,
Phone: request.Phone,
Status: "open",
Amount: request.Amount,
PaymentType: request.PaymentType,
Currency: request.Currency,
PayWayID: request.PayWayID,
IsRefill: true,
OnAccept: dal.Action{ActionType: request.OnAccept.ActionType, Data: request.OnAccept.Data},
OnDecline: dal.Action{ActionType: request.OnDecline.ActionType, Data: request.OnDecline.Data},
OnTimeout: dal.Action{ActionType: request.OnTimeout.ActionType, Data: request.OnTimeout.Data},
}
fmt.Println("Skeris2")
id, err := h.mongo.InsertPayment(h.r.Context(), record)
fmt.Println("Skeris3")
if err != nil {
fmt.Println("InsertPayment", err)
h.reportError(http.StatusInternalServerError, "failed", err)
return
}
fmt.Println("Skeris4")
pw := pwc.GetPayWayById(request.PayWayID)
fmt.Println("Skeris5")
if pw == nil {
errs := "got bad pay_way: " + request.PayWayID
h.reportError(http.StatusBadRequest, errs, errors.New(errs))
return
}
if request.Email == "" {
request.Email = "solovyevdanil@yandex.ru"
}
if request.Phone == "" {
request.Phone = "+79885895677"
}
if request.PaymentType == "2" {
request.PaymentType = "Qiwi"
}
fmt.Println("Skeris6")
url, err := pw.CreatePaymentUrl(
fmt.Sprintf("%.2f", request.Amount),
id,
request.PaymentType, // Использовать значение -1 для тестов
request.Currency,
"ru",
request.Email,
request.Phone,
request.RequesterID,
h.r.RemoteAddr,
)
fmt.Println("Skeris7")
if err != nil {
fmt.Println("CreatePaymentUrl", err)
if _, err := crush.Send(tb.ChatID(-1001572699960),
fmt.Sprintf("Платёжка %s не справилась создать ссылку и вот почему: %s", request.PayWayID, err.Error())); err != nil {
fmt.Println("CAN NOT NOTIFY", err)
}
h.reportError(http.StatusInternalServerError, "failed", err)
return
}
fmt.Println("Skeris8")
h.sendResponse(Response{
Success: true,
Message: map[string]string{"id": id, "url": url},
})
}
func PaymentListenerHandler(h *Handler, pwc *payway.PayWay) {
payWay := mux.Vars(h.r)["payWay"]
var err error
switch payWay {
case "fk":
var request payway.ReqPaymentListenerFk
err = h.handleGetRequest(&request)
if err != nil {
h.reportError(http.StatusInternalServerError, "failed", err)
return
}
err = pwc.Cache[payWay].PaymentListener(h.r.Context(), h.r.RemoteAddr, &request, h.mongo)
if err != nil {
h.reportError(http.StatusInternalServerError, "failed", err)
return
}
// уведомляем фрикассу о получении данных
// @TODO: не уверен что надо слать в конце, а не в начале... Может случиться так что фрикасса начнет бесконечно
// долбить сервис даже если имеется ошибка в данных.
_, err = fmt.Fprint(h.w, "YES")
if err != nil {
h.reportError(http.StatusInternalServerError, "failed", err)
return
}
case "bt":
var request payway.ReqPaymentListenerBt
if err := h.r.ParseForm(); err != nil {
return
}
request.Sign = h.r.Form.Get("sign")
request.OrderId = h.r.Form.Get("orderId")
request.UserComment = h.r.Form.Get("user_comment")
amt, err := strconv.ParseFloat(h.r.Form.Get("amount"), 64)
request.Amount = amt
err = pwc.Cache[payWay].PaymentListener(h.r.Context(), h.r.RemoteAddr, &request, h.mongo)
if err != nil {
h.reportError(http.StatusInternalServerError, "failed", err)
return
}
//// уведомляем фрикассу о получении данных
//// @TODO: не уверен что надо слать в конце, а не в начале... Может случиться так что фрикасса начнет бесконечно
//// долбить сервис даже если имеется ошибка в данных.
_, err = fmt.Fprint(h.w, "OK")
//if err != nil {
// h.reportError(http.StatusInternalServerError, "failed", err)
// return
//}
}
}
type GetPayWaysResp struct {
Name string `json:"name"`
ID string `json:"ID"`
}
func GetPayWays(h *Handler, pwc *payway.PayWay) {
paymentList, err := pwc.GetPaymentList()
if err != nil {
h.reportError(http.StatusInternalServerError, fmt.Sprint(err), err)
return
}
h.sendResponse(Response{
Success: true,
Message: paymentList,
})
}