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

4 years ago
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")
}
4 years ago
// H5Callback 代码与callback 和 paySuccess同, 如果以后在H5支付中有不同的逻辑或者回调在这里修改
4 years ago
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")
4 years ago
}