123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255 |
- 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
- }
|