package services import ( "context" "encoding/json" "errors" "fmt" "github.com/wechatpay-apiv3/wechatpay-go/core" "github.com/wechatpay-apiv3/wechatpay-go/services/payments/jsapi" payUtils "github.com/wechatpay-apiv3/wechatpay-go/utils" "hongze/hongze_mfyx/models" "hongze/hongze_mfyx/models/order" "hongze/hongze_mfyx/utils" "time" ) //const ( // MchPKFileName = "./utils/cert/apiclient_key.pem" // Mchid = "1624495680" // MchCertificateSerialNumber = "5ED2719CFAE5205763034AD80BF4B8A33533C418" // MchAPIv3Key = "W1tbnzQrzQ7yRRNuQCIHjis8dgdasKVX" //) // //// 微信商户建立连接 //func getWechatClient() (context.Context, *core.Client, error) { // // 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名 // mchPrivateKey, err := payUtils.LoadPrivateKeyWithPath(MchPKFileName) // if err != nil { // log.Print("load merchant private key error") // return nil, nil, err // } // ctx := context.Background() // // 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力 // opts := []core.ClientOption{ // option.WithWechatPayAutoAuthCipher(Mchid, MchCertificateSerialNumber, mchPrivateKey, MchAPIv3Key), // } // client, err := core.NewClient(ctx, opts...) // if err != nil { // log.Printf("new wechat pay client err:%s", err) // return nil, nil, err // } // return ctx, client, nil //} // 生成预支付交易单 func ExampleJsapiApiServicePrepay(orderDetail *order.CygxOrder, unionId string) (JsapiApiResp order.PrepayWithRequestPaymentResponse, err error) { //var err error defer func() { if err != nil { fmt.Println(err) go utils.SendAlarmMsg(fmt.Sprint("生成预支付交易单失败 ExampleJsapiApiServicePrepay, err:", err.Error(), "unionId:", unionId), 2) } }() userRecord, e := models.GetUserRecordByUnionId(unionId, 10) if e != nil && e.Error() != utils.ErrNoRow() { err = errors.New("GetUserRecordByUnionId, Err: " + e.Error()) return } ctx := context.Background() svc := jsapi.JsapiApiService{Client: utils.WechatCertClient} // 得到prepay_id,以及调起支付所需的参数和签名 resp, _, err := svc.PrepayWithRequestPayment(ctx, jsapi.PrepayRequest{ Appid: core.String(utils.WxAppId), Mchid: core.String(utils.Mchid), Description: core.String(orderDetail.SourceTitle), OutTradeNo: core.String(orderDetail.OutTradeNo), Attach: core.String(""), NotifyUrl: core.String(utils.WxPayJsapiNotifyUrl), TimeExpire: core.Time(time.Now().Add(10 * time.Minute)), Amount: &jsapi.Amount{ Total: core.Int64(int64(orderDetail.OrderMoney * 100)), // 分 }, Payer: &jsapi.Payer{ Openid: core.String(userRecord.OpenId), }, }, ) if err != nil { //log.Printf("PrepayWithRequestPayment err:%s", err) return } JsapiApiResp.PrepayId = *resp.PrepayId JsapiApiResp.Appid = *resp.Appid JsapiApiResp.TimeStamp = *resp.TimeStamp JsapiApiResp.NonceStr = *resp.NonceStr JsapiApiResp.Package = *resp.Package JsapiApiResp.SignType = *resp.SignType JsapiApiResp.PaySign = *resp.PaySign return } type WechatPayCallback struct { MchID string `json:"mchid"` AppID string `json:"appid"` OutTradeNo string `json:"out_trade_no"` TransactionID string `json:"transaction_id"` TradeType string `json:"trade_type"` TradeState string `json:"trade_state"` TradeStateDesc string `json:"trade_state_desc"` BankType string `json:"bank_type"` Attach string `json:"attach"` SuccessTime time.Time `json:"success_time"` Payer struct { OpenID string `json:"openid"` } `json:"payer"` Amount struct { Total int `json:"total"` PayerTotal int `json:"payer_total"` Currency string `json:"currency"` PayerCurrency string `json:"payer_currency"` } `json:"amount"` } // 微信支付回调内容解密 func WxDecodeNotify(body []byte) (wechatPayCallback *WechatPayCallback) { var err error defer func() { if err != nil { fmt.Println(err) go utils.SendAlarmMsg(fmt.Sprint("微信支付回调内容解密失败 WxDecodeNotify, err:", err.Error()), 2) } }() var prepaymap map[string]interface{} _ = json.Unmarshal(body, &prepaymap) var prepaymap2 = prepaymap["resource"].(map[string]interface{}) nonce := prepaymap2["nonce"].(string) associatedData := prepaymap2["associated_data"].(string) ciphertext := prepaymap2["ciphertext"].(string) tx, e := payUtils.DecryptAES256GCM(utils.MchAPIv3Key, associatedData, nonce, ciphertext) if e != nil { err = errors.New("DecryptAES256GCM, Err: " + e.Error()) return } var datamap *WechatPayCallback _ = json.Unmarshal([]byte(tx), &datamap) wechatPayCallback = datamap return } // Transaction type Transaction struct { Amount TransactionAmount `json:"amount,omitempty"` Appid string `json:"appid,omitempty"` Attach string `json:"attach,omitempty"` BankType string `json:"bank_type,omitempty"` Mchid string `json:"mchid,omitempty"` OutTradeNo string `json:"out_trade_no,omitempty"` Payer TransactionPayer `json:"payer,omitempty"` PromotionDetail []PromotionDetail `json:"promotion_detail,omitempty"` SuccessTime time.Time `json:"success_time,omitempty"` TradeState string `json:"trade_state,omitempty"` TradeStateDesc string `json:"trade_state_desc,omitempty"` TradeType string `json:"trade_type,omitempty"` TransactionId string `json:"transaction_id,omitempty"` } // TransactionAmount type TransactionAmount struct { Currency string `json:"currency,omitempty"` PayerCurrency string `json:"payer_currency,omitempty"` PayerTotal int64 `json:"payer_total,omitempty"` Total int64 `json:"total,omitempty"` } // PromotionDetail type PromotionDetail struct { // 券ID CouponId *string `json:"coupon_id,omitempty"` // 优惠名称 Name *string `json:"name,omitempty"` // GLOBAL:全场代金券;SINGLE:单品优惠 Scope *string `json:"scope,omitempty"` // CASH:充值;NOCASH:预充值。 Type *string `json:"type,omitempty"` // 优惠券面额 Amount *int64 `json:"amount,omitempty"` // 活动ID,批次ID StockId *string `json:"stock_id,omitempty"` // 单位为分 WechatpayContribute *int64 `json:"wechatpay_contribute,omitempty"` // 单位为分 MerchantContribute *int64 `json:"merchant_contribute,omitempty"` // 单位为分 OtherContribute *int64 `json:"other_contribute,omitempty"` // CNY:人民币,境内商户号仅支持人民币。 Currency *string `json:"currency,omitempty"` GoodsDetail []PromotionGoodsDetail `json:"goods_detail,omitempty"` } // PromotionGoodsDetail type PromotionGoodsDetail struct { // 商品编码 GoodsId *string `json:"goods_id"` // 商品数量 Quantity *int64 `json:"quantity"` // 商品价格 UnitPrice *int64 `json:"unit_price"` // 商品优惠金额 DiscountAmount *int64 `json:"discount_amount"` // 商品备注 GoodsRemark *string `json:"goods_remark,omitempty"` } // TransactionPayer type TransactionPayer struct { Openid string `json:"openid,omitempty"` } // 根据订单号查询订单状态 func GetQueryOrderByOutTradeNo(outTradeNo string) (tradeState string, statusCode int, itemResp *Transaction) { var err error defer func() { if err != nil { fmt.Println("err", err) go utils.SendAlarmMsg(fmt.Sprint("根据订单号查询订单状态 失败 GetQueryOrderByOutTradeNo, err:", err.Error(), "outTradeNo", outTradeNo), 2) } }() ctx := context.Background() svc := jsapi.JsapiApiService{Client: utils.WechatCertClient} resp, result, err := svc.QueryOrderByOutTradeNo(ctx, jsapi.QueryOrderByOutTradeNoRequest{ OutTradeNo: core.String(outTradeNo), Mchid: core.String(utils.Mchid), }, ) statusCode = result.Response.StatusCode //订单状态码不存在直接返回 if statusCode == 404 { err = nil return } tradeState = *resp.TradeState data, err := json.Marshal(resp) if err != nil { return } jsonstr := string(data) //item := new(Transaction) if err = json.Unmarshal([]byte(jsonstr), &itemResp); err != nil { return } //utils.FileLog.Info(jsonstr) ////itemResp = item //fmt.Println(itemResp) //fmt.Println(tradeState) //fmt.Println(itemResp.TransactionId) return }