You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

243 lines
7.8 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package alipay
import (
"errors"
"log"
"recook/internal/api/mobile/pay/public"
"recook/internal/dbc"
"recook/internal/model/order"
"recook/internal/service/comFunc"
"github.com/astaxie/beego"
"github.com/gin-gonic/gin"
"github.com/golangkit/formatime"
"recook/internal/back"
"strconv"
"strings"
"time"
)
type PayCallbackNotification struct {
AuthAppId string `form:"auth_app_id" json:"auth_app_id"` // App Id
NotifyTime string `form:"notify_time" json:"notify_time"` // 通知时间
NotifyType string `form:"notify_type" json:"notify_type"` // 通知类型
NotifyId string `form:"notify_id" json:"notify_id"` // 通知校验ID
AppId string `form:"app_id" json:"app_id"` // 开发者的app_id
Charset string `form:"charset" json:"charset"` // 编码格式
Version string `form:"version" json:"version"` // 接口版本
SignType string `form:"sign_type" json:"sign_type"` // 签名类型
Sign string `form:"sign" json:"sign"` // 签名
TradeNo string `form:"trade_no" json:"trade_no"` // 支付宝交易号
OutTradeNo string `form:"out_trade_no" json:"out_trade_no"` // 商户订单号
OutBizNo string `form:"out_biz_no" json:"out_biz_no"` // 商户业务号
BuyerId string `form:"buyer_id" json:"buyer_id"` // 买家支付宝用户号
BuyerLogonId string `form:"buyer_logon_id" json:"buyer_logon_id"` // 买家支付宝账号
SellerId string `form:"seller_id" json:"seller_id"` // 卖家支付宝用户号
SellerEmail string `form:"seller_email" json:"seller_email"` // 卖家支付宝账号
TradeStatus string `form:"trade_status" json:"trade_status" binding:"required"` // 交易状态 TRADE_CLOSED 未付款交易超时关闭,或支付完成后全额退款 TRADE_SUCCESS 交易支付成功 TRADE_FINISHED 交易结束,不可退款
// TradeStatus string `form:"trade_status" json:"trade_status"` // 交易状态 TRADE_CLOSED 未付款交易超时关闭,或支付完成后全额退款 TRADE_SUCCESS 交易支付成功 TRADE_FINISHED 交易结束,不可退款
TotalAmount string `form:"total_amount" json:"total_amount"` // 订单金额
ReceiptAmount string `form:"receipt_amount" json:"receipt_amount"` // 实收金额
InvoiceAmount string `form:"invoice_amount" json:"invoice_amount"` // 开票金额
BuyerPayAmount string `form:"buyer_pay_amount" json:"buyer_pay_amount"` // 付款金额
PointAmount string `form:"point_amount" json:"point_amount"` // 集分宝金额
RefundFee string `form:"refund_fee" json:"refund_fee"` // 总退款金额
Subject string `form:"subject" json:"subject"` // 总退款金额
Body string `form:"body" json:"body"` // 商品描述
GmtCreate string `form:"gmt_create" json:"gmt_create"` // 交易创建时间
GmtPayment string `form:"gmt_payment" json:"gmt_payment"` // 交易付款时间
GmtRefund string `form:"gmt_refund" json:"gmt_refund"` // 交易退款时间
GmtClose string `form:"gmt_close" json:"gmt_close"` // 交易结束时间
FundBillList string `form:"fund_bill_list" json:"fund_bill_list"` // 支付金额信息
PassbackParams string `form:"passback_params" json:"passback_params"` // 回传参数
}
func (r *PayCallbackNotification) IsOK() bool {
return r.TradeStatus == "TRADE_SUCCESS"
}
func (r *PayCallbackNotification) IsClosed() bool {
return r.TradeStatus == "TRADE_CLOSED"
}
func (r *PayCallbackNotification) IsPayNotify() bool {
return len(r.OutBizNo) == 0
}
func PayCallback(c *gin.Context) {
var result PayCallbackNotification
err := c.Bind(&result)
if err != nil {
log.Println(err)
c.String(200, "error")
return
}
//新增结束
if result.IsPayNotify() {
paySuccess(c, result)
} else {
// refundSuccess(c, result)
}
}
func paySuccessMore(orderID int, result PayCallbackNotification) error {
var od []order.Information
if err := dbc.DB.Find(&od, "virtual_id = ?", orderID).Error; err != nil {
jsonStr, _ := json.Marshal(&result)
log.Println(jsonStr)
log.Println(err.Error())
return err
}
ignore := false
for _, v := range od {
if v.Status == 1 {
ignore = true
}
}
if ignore {
return nil
}
tx := dbc.DB.Begin()
{
for _, v := range od {
completeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", result.GmtPayment, time.Local)
if err := public.PaySuccessCallback(tx, v, formatime.NewSecondFrom(completeTime)); err != nil {
tx.Rollback()
return errors.New(err.Error())
}
}
}
tx.Commit()
return nil
}
func paySuccess(c *gin.Context, result PayCallbackNotification) {
rightPart := strings.Split(result.OutTradeNo, "M2")[1]
orderId, err := strconv.Atoi(rightPart)
if err != nil || result.IsOK() == false {
c.String(400, "error")
return
}
if !public.JudgeString(rightPart) {
if err = paySuccessMore(orderId, result); err != nil {
c.String(400, "error")
return
}
c.Set("status", "SyncOrder")
c.Set("id", orderId)
c.String(200, "success")
return
}
var orderInfo order.Information
err = dbc.DB.First(&orderInfo, "id = ?", orderId).Error
{
if err != nil {
jsonStr, _ := json.Marshal(&result)
log.Println(jsonStr)
c.String(400, "error")
return
}
if orderInfo.Status == 1 {
// 重复的通知 不用处理
c.String(200, "success")
return
}
}
tx := dbc.DB.Begin()
{
completeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", result.GmtPayment, time.Local)
if err = public.PaySuccessCallback(tx, orderInfo, formatime.NewSecondFrom(completeTime)); err != nil {
tx.Rollback()
back.Err(c, err.Error())
return
}
}
tx.Commit()
c.Set("status", "SyncOrder")
c.Set("id", orderInfo.ID)
c.String(200, "success")
}
// H5Callback 代码与callback 和 paySuccess同, 如果以后在H5支付中有不同的逻辑或者回调在这里修改
func H5Callback(c *gin.Context) {
// beego.Info(123)
// body, _ := ioutil.ReadAll(c.Request.Body)
// comFunc.PrintErr(string(body))
beego.Info(c.ContentType())
// beego.Info(string(body))
var result PayCallbackNotification
err := c.Bind(&result)
bs, _ := json.Marshal(result)
beego.Info(string(bs))
if err != nil {
comFunc.PrintErr(err)
c.String(200, "error")
return
}
if result.IsPayNotify() {
h5PaySuccess(c, result)
} else {
// refundSuccess(c, result)
}
}
func h5PaySuccess(c *gin.Context, result PayCallbackNotification) {
rightPart := strings.Split(result.OutTradeNo, "M2")[1]
orderId, err := strconv.Atoi(rightPart)
if err != nil || result.IsOK() == false {
c.String(400, "error")
return
}
if !public.JudgeString(rightPart) {
if err := paySuccessMore(orderId, result); err != nil {
c.String(400, "error")
return
}
c.Set("status", "SyncOrder")
c.Set("id", orderId)
c.String(200, "success")
return
}
var orderInfo order.Information
err = dbc.DB.First(&orderInfo, "id = ?", orderId).Error
{
if err != nil {
jsonStr, _ := json.Marshal(&result)
log.Println(jsonStr)
c.String(400, "error")
return
}
if orderInfo.Status == 1 {
// 重复的通知 不用处理
c.String(200, "success")
return
}
}
tx := dbc.DB.Begin()
{
completeTime, _ := time.ParseInLocation("2006-01-02 15:04:05", result.GmtPayment, time.Local)
if err = public.PaySuccessCallback(tx, orderInfo, formatime.NewSecondFrom(completeTime)); err != nil {
tx.Rollback()
back.Err(c, err.Error())
return
}
}
tx.Commit()
c.Set("status", "SyncOrder")
c.Set("id", orderInfo.ID)
c.String(200, "success")
}