369 lines
11 KiB
Go
369 lines
11 KiB
Go
package bundle
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"fonchain-fiee/api/bundle"
|
||
"fonchain-fiee/api/order"
|
||
"fonchain-fiee/api/payment"
|
||
"fonchain-fiee/pkg/config"
|
||
"fonchain-fiee/pkg/model/login"
|
||
"fonchain-fiee/pkg/service"
|
||
"fonchain-fiee/pkg/service/bundle/common"
|
||
bundleModel "fonchain-fiee/pkg/service/bundle/model"
|
||
"io"
|
||
"math"
|
||
"net/http"
|
||
"strconv"
|
||
|
||
"github.com/gin-gonic/gin"
|
||
"github.com/gin-gonic/gin/binding"
|
||
)
|
||
|
||
func CreateStripeCheckoutSession(c *gin.Context) {
|
||
var req order.CreateStripeCheckoutSessionRequest
|
||
|
||
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
|
||
// 获取 用户信息
|
||
userInfo := login.GetUserInfoFromC(c)
|
||
|
||
// 检查 订单信息
|
||
detail, detailErr := service.BundleProvider.OrderRecordsDetail(context.Background(), &bundle.OrderRecordsDetailRequest{
|
||
OrderNo: req.OutTradeNo,
|
||
})
|
||
|
||
if detailErr != nil {
|
||
service.Error(c, detailErr)
|
||
return
|
||
}
|
||
|
||
fmt.Println("detail.OrderRecord.CustomerID :", detail.OrderRecord.CustomerID)
|
||
|
||
// 判断 是否是 本人操作
|
||
if strconv.FormatUint(userInfo.ID, 10) != detail.OrderRecord.CustomerID {
|
||
service.Error(c, errors.New(common.NotMatchOrderInfo))
|
||
return
|
||
}
|
||
|
||
fmt.Println("detail.OrderRecord.TotalAmount :", detail.OrderRecord.TotalAmount)
|
||
fmt.Println("req.ProductAllPrice :", req.ProductAllPrice)
|
||
fmt.Println("detail.OrderRecord.TotalAmount*100 :", detail.OrderRecord.TotalAmount*100)
|
||
|
||
//金额校验
|
||
orderAmountInCents := int64(math.Round(float64(detail.OrderRecord.TotalAmount * 100)))
|
||
reqAmountInCents := int64(math.Round(float64(req.ProductAllPrice)))
|
||
if orderAmountInCents != reqAmountInCents {
|
||
fmt.Println("111111111111111111111111111111111111")
|
||
service.Error(c, errors.New(common.InvalidOrderAmount))
|
||
return
|
||
}
|
||
|
||
fmt.Println("detail.OrderRecord.Status :", detail.OrderRecord.Status)
|
||
fmt.Println("detail.OrderRecord.CheckoutSessionId :", detail.OrderRecord.CheckoutSessionId)
|
||
fmt.Println("detail.OrderRecord.PayTime :", detail.OrderRecord.PayTime)
|
||
|
||
// 如果 当前订单 是 已签未支付 且 存在 checkoutSessionId 需要 查询 支付结果
|
||
if detail.OrderRecord.Status == bundleModel.OrderSigned && detail.OrderRecord.CheckoutSessionId != "" && detail.OrderRecord.PayTime == "" {
|
||
// 查询支付结果
|
||
stripeInfosRes, stripeInfosErr := service.OrderProvider.QueryStripeInfoByCheckSessionIds(context.Background(), &order.QueryStripeInfoRequest{
|
||
CheckoutSessionIds: []string{detail.OrderRecord.CheckoutSessionId},
|
||
})
|
||
|
||
if stripeInfosErr != nil {
|
||
service.Error(c, errors.New(common.ErrorQueryStripeInfo))
|
||
return
|
||
}
|
||
|
||
if stripeInfosRes != nil && len(stripeInfosRes.StripeInfos) > 0 {
|
||
for _, stripeInfo := range stripeInfosRes.StripeInfos {
|
||
if stripeInfo.OutTradeNo == detail.OrderRecord.OrderNo && stripeInfo.PaymentIntentStatus == "paid" {
|
||
_, updateOrderRecordErr := service.BundleProvider.UpdateOrderRecord(context.Background(), &bundle.OrderRecord{
|
||
Uuid: detail.OrderRecord.Uuid,
|
||
Status: bundleModel.OrderPaid,
|
||
PayTime: common.GetBeijingTime(),
|
||
})
|
||
fmt.Println("detail.OrderRecord.Uuid :", detail.OrderRecord.Uuid)
|
||
if updateOrderRecordErr != nil {
|
||
service.Error(c, detailErr)
|
||
return
|
||
}
|
||
service.Success(c, &service.Response{
|
||
Msg: common.HadPay,
|
||
Code: 0,
|
||
})
|
||
return
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
//调用微服务获取支付地址
|
||
result, err := service.OrderProvider.CreateStripeCheckoutSession(context.Background(), &req)
|
||
if err != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
|
||
fmt.Println("result.CheckoutSessionId :", result.CheckoutSessionId)
|
||
fmt.Println("result.CheckoutSessionUrl :", result.CheckoutSessionUrl)
|
||
|
||
//更新订单状态
|
||
_, updateOrderRecordErr := service.BundleProvider.UpdateOrderRecord(context.Background(), &bundle.OrderRecord{
|
||
Uuid: detail.OrderRecord.Uuid,
|
||
CheckoutSessionId: result.CheckoutSessionId,
|
||
CheckoutSessionUrl: result.CheckoutSessionUrl,
|
||
})
|
||
|
||
if updateOrderRecordErr != nil {
|
||
service.Error(c, updateOrderRecordErr)
|
||
return
|
||
}
|
||
|
||
service.Success(c, result)
|
||
|
||
}
|
||
|
||
func CreateAntomPay(c *gin.Context) {
|
||
var req order.CreateStripeCheckoutSessionRequest
|
||
|
||
if err := c.ShouldBindBodyWith(&req, binding.JSON); err != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
|
||
// 获取 用户信息
|
||
userInfo := login.GetUserInfoFromC(c)
|
||
|
||
// 检查 订单信息
|
||
detail, detailErr := service.BundleProvider.OrderRecordsDetail(context.Background(), &bundle.OrderRecordsDetailRequest{
|
||
OrderNo: req.OutTradeNo,
|
||
})
|
||
|
||
if detailErr != nil {
|
||
service.Error(c, detailErr)
|
||
return
|
||
}
|
||
|
||
fmt.Println("detail.OrderRecord.CustomerID :", detail.OrderRecord.CustomerID)
|
||
|
||
// 判断 是否是 本人操作
|
||
if strconv.FormatUint(userInfo.ID, 10) != detail.OrderRecord.CustomerID {
|
||
service.Error(c, errors.New(common.NotMatchOrderInfo))
|
||
return
|
||
}
|
||
|
||
fmt.Println("detail.OrderRecord.TotalAmount :", detail.OrderRecord.TotalAmount)
|
||
fmt.Println("req.ProductAllPrice :", req.ProductAllPrice)
|
||
fmt.Println("detail.OrderRecord.TotalAmount*100 :", detail.OrderRecord.TotalAmount*100)
|
||
|
||
//金额校验
|
||
orderAmountInCents := int64(math.Round(float64(detail.OrderRecord.TotalAmount * 100)))
|
||
reqAmountInCents := int64(math.Round(float64(req.ProductAllPrice)))
|
||
if orderAmountInCents != reqAmountInCents {
|
||
fmt.Println("111111111111111111111111111111111111")
|
||
service.Error(c, errors.New(common.InvalidOrderAmount))
|
||
return
|
||
}
|
||
|
||
fmt.Println("detail.OrderRecord.Status :", detail.OrderRecord.Status)
|
||
fmt.Println("detail.OrderRecord.CheckoutSessionId :", detail.OrderRecord.CheckoutSessionId)
|
||
fmt.Println("detail.OrderRecord.PayTime :", detail.OrderRecord.PayTime)
|
||
|
||
// 如果 当前订单 是 已签未支付 且 存在 checkoutSessionId 需要 查询 支付结果
|
||
if detail.OrderRecord.Status == bundleModel.OrderSigned && detail.OrderRecord.CheckoutSessionId != "" && detail.OrderRecord.PayTime == "" {
|
||
// 查询支付结果
|
||
stripeInfosRes, stripeInfosErr := service.PaymentProvider.QueryAntomPayByCheckoutSessionId(context.Background(), &payment.AntomPayQueryRequest{
|
||
CheckoutSessionIds: []string{detail.OrderRecord.CheckoutSessionId},
|
||
})
|
||
|
||
if stripeInfosErr != nil {
|
||
service.Error(c, errors.New(common.ErrorQueryStripeInfo))
|
||
return
|
||
}
|
||
|
||
if stripeInfosRes != nil && len(stripeInfosRes.Infos) > 0 {
|
||
for _, info := range stripeInfosRes.Infos {
|
||
if info.OutTradeNo == detail.OrderRecord.OrderNo && info.Status == "paid" {
|
||
_, updateOrderRecordErr := service.BundleProvider.UpdateOrderRecord(context.Background(), &bundle.OrderRecord{
|
||
Uuid: detail.OrderRecord.Uuid,
|
||
Status: bundleModel.OrderPaid,
|
||
PayTime: common.GetBeijingTime(),
|
||
})
|
||
fmt.Println("detail.OrderRecord.Uuid :", detail.OrderRecord.Uuid)
|
||
if updateOrderRecordErr != nil {
|
||
service.Error(c, detailErr)
|
||
return
|
||
}
|
||
service.Success(c, &service.Response{
|
||
Msg: common.HadPay,
|
||
Code: 0,
|
||
})
|
||
return
|
||
}
|
||
}
|
||
}
|
||
}
|
||
|
||
var antomReq payment.CreatePayRequest
|
||
antomReq.Payee = "Antom"
|
||
antomReq.Platform = "antom"
|
||
antomReq.ChannelType = "antom"
|
||
antomReq.ProductDescription = req.ProductDescription
|
||
antomReq.BusinessType = "useless"
|
||
antomReq.Domain = "fiee"
|
||
antomReq.Amount = req.ProductAllPrice
|
||
antomReq.Currency = req.ProductPriceCurrency
|
||
antomReq.OutTradeNo = req.OutTradeNo
|
||
antomReq.ReturnUrl = req.SuccessUrl
|
||
|
||
//调用微服务获取支付地址
|
||
result, err := service.PaymentProvider.CreatePay(context.Background(), &antomReq)
|
||
if err != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
|
||
fmt.Println("result.CheckoutSessionId :", result.CheckoutSessionId)
|
||
fmt.Println("result.Url :", result.Url)
|
||
|
||
//更新订单状态
|
||
_, updateOrderRecordErr := service.BundleProvider.UpdateOrderRecord(context.Background(), &bundle.OrderRecord{
|
||
Uuid: detail.OrderRecord.Uuid,
|
||
CheckoutSessionId: result.CheckoutSessionId,
|
||
CheckoutSessionUrl: result.Url,
|
||
})
|
||
fmt.Println("=====================================")
|
||
resp := &order.CreateStripeCheckoutSessionResponse{}
|
||
resp.CheckoutSessionUrl = result.Url
|
||
resp.CheckoutSessionId = result.CheckoutSessionId
|
||
fmt.Println("resp:", resp)
|
||
|
||
if updateOrderRecordErr != nil {
|
||
fmt.Println("有更新报错:", updateOrderRecordErr)
|
||
service.Error(c, updateOrderRecordErr)
|
||
return
|
||
}
|
||
|
||
service.Success(c, resp)
|
||
|
||
}
|
||
|
||
func StripeCheckoutSessionWebhook(c *gin.Context) {
|
||
var req order.GetCheckoutWebhookRequest
|
||
c.Request.Body = http.MaxBytesReader(c.Writer, c.Request.Body, int64(65536))
|
||
payloadBytes, err := io.ReadAll(c.Request.Body)
|
||
if err != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
req.Payload = string(payloadBytes)
|
||
req.Signature = c.GetHeader("Stripe-Signature")
|
||
req.WebhookKey = config.Webhookkey
|
||
fmt.Printf("webhookKey:%s\n", req.WebhookKey)
|
||
resp, err := service.OrderProvider.CommonCheckoutWebhook(c, &req)
|
||
if err != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
fmt.Println("resp.PaymentIntentStatus:", resp.PaymentIntentStatus)
|
||
if resp.PaymentIntentStatus == "paid" {
|
||
//支付成功
|
||
_, updateStatusErr := service.BundleProvider.UpdateOrderRecordByOrderNo(context.Background(), &bundle.OrderRecord{
|
||
OrderNo: resp.OutTradeNo,
|
||
PayTime: common.GetBeijingTime(),
|
||
Status: bundleModel.OrderPaid,
|
||
})
|
||
if updateStatusErr != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
|
||
}
|
||
service.Success(c)
|
||
}
|
||
|
||
func AntomWebhook(c *gin.Context) {
|
||
|
||
var err error
|
||
data, err := io.ReadAll(c.Request.Body)
|
||
if err != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
|
||
// 将数据转换为字符串形式并记录日志(如果数据过大则不记录)
|
||
dataStr := string(data)
|
||
fmt.Println("================ Antom回调参数:", dataStr)
|
||
|
||
// 将读取到的数据解析为 map[string]interface{}
|
||
var reqMap map[string]interface{}
|
||
if err := json.Unmarshal(data, &reqMap); err != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
|
||
// 提取需要的字段
|
||
notifyType, _ := reqMap["notifyType"].(string)
|
||
resultMap, resultExists := reqMap["result"].(map[string]interface{})
|
||
if !resultExists {
|
||
service.Error(c, errors.New("result 字段不存在或类型错误"))
|
||
return
|
||
}
|
||
|
||
requestId, _ := reqMap["paymentRequestId"].(string)
|
||
paymentId, _ := reqMap["paymentId"].(string)
|
||
paymentTime, _ := reqMap["paymentTime"].(string)
|
||
|
||
// 提取 result 字段中的子字段
|
||
resultStatus, _ := resultMap["resultStatus"].(string)
|
||
resultMessage, _ := resultMap["resultMessage"].(string)
|
||
|
||
// 打印提取的字段(可以根据需要处理)
|
||
fmt.Println("通知类型:", notifyType)
|
||
fmt.Println("订单号:", requestId)
|
||
fmt.Println("支付ID:", paymentId)
|
||
fmt.Println("支付时间:", paymentTime)
|
||
fmt.Println("支付结果状态:", resultStatus)
|
||
fmt.Println("支付结果消息:", resultMessage)
|
||
/*
|
||
* S: 当 notifyType 为PAYMENT_RESULT时,表示支付成功;当 notifyType 为PAYMENT_PENDING时,表示支付处理中。
|
||
* F: 表示支付失败。
|
||
* */
|
||
params := &payment.AntomNotifyPayRequest{
|
||
NotifyType: notifyType,
|
||
RequestId: requestId,
|
||
PaymentId: paymentId,
|
||
PaymentTime: paymentTime,
|
||
ResultStatus: resultStatus,
|
||
ResultMessage: resultMessage,
|
||
ChannelCode: "Antom", // fiee对应payment的渠道码
|
||
}
|
||
|
||
resp, err := service.PaymentProvider.AntomWebhook(c, params)
|
||
if err != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
fmt.Println("resp.Status:", resp.Status)
|
||
if resp.Status == "paid" {
|
||
//支付成功
|
||
_, updateStatusErr := service.BundleProvider.UpdateOrderRecordByOrderNo(context.Background(), &bundle.OrderRecord{
|
||
OrderNo: resp.OutTradeNo,
|
||
PayTime: common.GetBeijingTime(),
|
||
Status: bundleModel.OrderPaid,
|
||
})
|
||
if updateStatusErr != nil {
|
||
service.Error(c, err)
|
||
return
|
||
}
|
||
|
||
}
|
||
service.Success(c)
|
||
}
|