|
|
package pay_service
import ( "encoding/xml" "fmt" core2 "github.com/chanxuehong/wechat/mch/core" "github.com/chanxuehong/wechat/mch/pay" "hudongzhuanjia/logger" "hudongzhuanjia/models" "hudongzhuanjia/utils" "net/http" "strconv" "time" )
const CallbackOrderUrl = "https://api.ouxuanhudong.com/PcClient/common/WeChatOauthCtl/callbackOrder"
func Order(content, ip, openid string, fee, goodType int, userId, activityId int64) (map[string]interface{}, error) { client, err := Client() if err != nil { return nil, err }
now := time.Now() timeStart := now.Format("20060101150405") timeExpire := now.Add(2 * time.Hour).Format("20060101150405") outTradeNo := utils.RandomStr(32) nonceStr := utils.RandomStr(32) resp, err := pay.UnifiedOrder2(client, &pay.UnifiedOrderRequest{ Body: content, OutTradeNo: outTradeNo, TotalFee: int64(fee), SpbillCreateIP: ip, NotifyURL: CallbackOrderUrl, TradeType: "JSAPI", DeviceInfo: "WEB", NonceStr: nonceStr, SignType: core2.SignType_MD5, TimeStart: now, OpenId: openid, }) if err != nil { return nil, err }
userOrder := new(models.UserOrder) userOrder.DeviceInfo = "WEB" userOrder.Desc = content userOrder.UserId = userId userOrder.ActivityId = activityId userOrder.FeeType = "CNY" userOrder.GoodType = goodType userOrder.OpenId = openid userOrder.OutTradeNo = outTradeNo userOrder.TimeStart = timeStart userOrder.TimeExpire = timeExpire userOrder.TotalFee = fee userOrder.TradeType = "JSAPI" userOrder.PrepayId = resp.PrepayId userOrder.Status = 0 userOrder.IsDelete = false userOrder.CreatedAt = time.Now() userOrder.UpdatedAt = time.Now() if _, err = userOrder.AddUserOrder(); err != nil { return nil, err }
timestamp := strconv.FormatInt(time.Now().Unix(), 10) //获取H5支付需要的paySign
pac := "prepay_id=" + resp.PrepayId paySign := core2.JsapiSign(client.AppId(), nonceStr, pac, core2.SignType_MD5, timestamp, ApiKey) return map[string]interface{}{ "appid": Appid, "timestamp": timestamp, "nonce_str": nonceStr, "package": pac, "sign_type": core2.SignType_MD5, "pay_sign": paySign, "out_trade_no": outTradeNo, "user_order_id": userOrder.Id, }, nil }
func UnifiedOrder(content, ip, openid string, fee int64) (map[string]interface{}, error) { client, err := Client() if err != nil { return nil, err }
now := time.Now() outTradeNo := utils.RandomStr(32) nonceStr := utils.RandomStr(32) resp, err := pay.UnifiedOrder2(client, &pay.UnifiedOrderRequest{ Body: content, OutTradeNo: outTradeNo, TotalFee: int64(fee), SpbillCreateIP: ip, NotifyURL: CallbackOrderUrl, TradeType: "JSAPI", DeviceInfo: "WEB", NonceStr: nonceStr, SignType: core2.SignType_MD5, TimeStart: now, OpenId: openid, }) if err != nil { return nil, err }
timestamp := strconv.FormatInt(time.Now().Unix(), 10) //获取H5支付需要的paySign
pac := "prepay_id=" + resp.PrepayId paySign := core2.JsapiSign(client.AppId(), nonceStr, pac, core2.SignType_MD5, timestamp, ApiKey) return map[string]interface{}{ "appid": Appid, "timestamp": timestamp, "nonce_str": nonceStr, "package": pac, "sign_type": core2.SignType_MD5, "pay_sign": paySign, "out_trade_no": outTradeNo, }, nil }
// Notify
type NotifyRequest struct { ReturnCode string `xml:"return_code,omitempty" json:"return_code,omitempty"` ReturnMsg string `xml:"return_msg,omitempty" json:"return_msg,omitempty"` ResultCode string `xml:"result_code,omitempty" json:"result_code,omitempty"` ErrCode string `xml:"err_code,omitempty" json:"err_code,omitempty"` ErrCodeDes string `xml:"err_code_des,omitempty" json:"err_code_des,omitempty"` Appid string `xml:"appid,omitempty" json:"appid,omitempty"` MchId string `xml:"mch_id,omitempty" json:"mch_id,omitempty"` DeviceInfo string `xml:"device_info,omitempty" json:"device_info,omitempty"` NonceStr string `xml:"nonce_str,omitempty" json:"nonce_str,omitempty"` Sign string `xml:"sign,omitempty" json:"sign,omitempty"` SignType string `xml:"sign_type,omitempty" json:"sign_type,omitempty"` Openid string `xml:"openid,omitempty" json:"openid,omitempty"` IsSubscribe string `xml:"is_subscribe,omitempty" json:"is_subscribe,omitempty"` TradeType string `xml:"trade_type,omitempty" json:"trade_type,omitempty"` BankType string `xml:"bank_type,omitempty" json:"bank_type,omitempty"` TotalFee int `xml:"total_fee,omitempty" json:"total_fee,omitempty"` SettlementTotalFee int `xml:"settlement_total_fee,omitempty" json:"settlement_total_fee,omitempty"` FeeType string `xml:"fee_type,omitempty" json:"fee_type,omitempty"` CashFee int `xml:"cash_fee,omitempty" json:"cash_fee,omitempty"` CashFeeType string `xml:"cash_fee_type,omitempty" json:"cash_fee_type,omitempty"` CouponFee int `xml:"coupon_fee,omitempty" json:"coupon_fee,omitempty"` CouponCount int `xml:"coupon_count,omitempty" json:"coupon_count,omitempty"` CouponType0 string `xml:"coupon_type_0,omitempty" json:"coupon_type_0,omitempty"` CouponType1 string `xml:"coupon_type_1,omitempty" json:"coupon_type_1,omitempty"` CouponId0 string `xml:"coupon_id_0,omitempty" json:"coupon_id_0,omitempty"` CouponId1 string `xml:"coupon_id_1,omitempty" json:"coupon_id_1,omitempty"` CouponFee0 int `xml:"coupon_fee_0,omitempty" json:"coupon_fee_0,omitempty"` CouponFee1 int `xml:"coupon_fee_1,omitempty" json:"coupon_fee_1,omitempty"` TransactionId string `xml:"transaction_id,omitempty" json:"transaction_id,omitempty"` OutTradeNo string `xml:"out_trade_no,omitempty" json:"out_trade_no,omitempty"` Attach string `xml:"attach,omitempty" json:"attach,omitempty"` TimeEnd string `xml:"time_end,omitempty" json:"time_end,omitempty"` }
func NotifyOrder(req *http.Request) error { res := new(NotifyRequest) if err := xml.NewDecoder(req.Body).Decode(res); err != nil { return fmt.Errorf("xml.NewDecoder.Decode:%w", err) }
if res.ReturnCode != CODE_SUCCESS { return fmt.Errorf("network error, retrun_code: %v and return_msg: %v", res.ReturnCode, res.ReturnMsg) }
if res.ResultCode != CODE_SUCCESS { return fmt.Errorf("trade error, err_code: %v and err_code_des: %v", res.ErrCode, res.ErrCodeDes) }
userOrder := new(models.UserOrder) exist, err := userOrder.GetByOutTradeNo(res.OutTradeNo) if err != nil { return err } if !exist { return fmt.Errorf("user order not exist") } userOrder.TimeEnd = res.TimeEnd userOrder.TransactionId = res.TransactionId userOrder.Status = 1 if _, err = userOrder.UpdateStatusById(userOrder.Id); err != nil { return err } // 设置一下
if userOrder.GoodType == 1 { // 霸屏
_, err = new(models.BullyScreenHistory).UpdateStatusByUserOrderId(userOrder.Id, 0) if err != nil { return err } } else if userOrder.GoodType == 2 { _, err = new(models.RewardHistory).UpdateStatusByUserOrderId(userOrder.Id, 0) if err != nil { return err } } return nil }
func Query(outTradeNo string) (*models.UserOrder, error) { client, err := Client() if err != nil { return nil, err } // 请求订单查询,成功后得到结果
res, err := pay.OrderQuery2(client, &pay.OrderQueryRequest{ OutTradeNo: outTradeNo, NonceStr: utils.RandomStr(32), SignType: core2.SignType_MD5, }) if err != nil { return nil, err }
userOrder := new(models.UserOrder) userOrder.TransactionId = res.TransactionId userOrder.TimeEnd = core2.FormatTime(res.TimeEnd) switch res.TradeState { case CODE_TRADE_CLOSED: userOrder.Status = -1 case CODE_TRADE_SUCCESS: userOrder.Status = 1 case CODE_TRADE_REVOKED: userOrder.Status = 2 case CODE_TRADE_REFUND: userOrder.Status = 3 case CODE_TRADE_PAYERROR: userOrder.Status = 4 default: userOrder.Status = 0 } if _, err = userOrder.UpdateStatusByOutTradeNo(outTradeNo, userOrder.Status); err != nil { return nil, err } return userOrder, nil }
func BatchQueryByUserId(userId int64) error { orders, err := models.GetUserOrdersByStatusAndUserId(userId, 0) if err != nil { return err }
return batchQuery(orders) }
func BatchQueryByActivityId(activityId int64) error { orders, err := models.GetUserOrdersByStatusAndActivityId(activityId, 0) if err != nil { return nil }
return batchQuery(orders) }
func batchQuery(orders []*models.UserOrder) error { for _, order := range orders { userOrder, err := Query(order.OutTradeNo) if err != nil { return err } order.Status = userOrder.Status order.TransactionId = userOrder.TransactionId order.TimeEnd = userOrder.TimeEnd if order.Status == 1 { // 付款成功
if order.GoodType == 1 { _, err = new(models.BullyScreenHistory).UpdateStatusByUserOrderId(order.Id, 0) if err != nil { return err } } else if order.GoodType == 2 { _, err = new(models.RewardHistory).UpdateStatusByUserOrderId(order.Id, 0) if err != nil { return err }
} else { logger.Sugar.Info("支付测试") } } else if order.TimeExpire <= time.Now().Format("20060101150405") { err = Close(order.OutTradeNo) if err != nil { return err }
order.Status = -1 // 关闭支付
_, err = order.UpdateStatusById(order.Id) if err != nil { return err }
} } return nil }
func Close(outTradeNo string) error { //client := wechat.NewClient(Appid, Mchid, ApiKey, true)
client, err := Client() if err != nil { return err } err = pay.CloseOrder2(client, &pay.CloseOrderRequest{ OutTradeNo: outTradeNo, NonceStr: utils.RandomStr(32), SignType: core2.SignType_MD5, }) // 请求关闭订单,成功后得到结果
if err != nil { return err } return nil }
|