|
|
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")
|
|
|
}
|