添加微信支付下单
This commit is contained in:
216
trunk/center/paycenter/internal/pay.go
Normal file
216
trunk/center/paycenter/internal/pay.go
Normal file
@@ -0,0 +1,216 @@
|
||||
package internal
|
||||
|
||||
import (
|
||||
"context"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/core/option"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/services/payments/app"
|
||||
"github.com/wechatpay-apiv3/wechatpay-go/utils"
|
||||
"goutil/logUtilPlus"
|
||||
"log"
|
||||
_ "paycenter/internal/pay"
|
||||
"paycenter/internal/wxpaycofnig"
|
||||
_ "paycenter/internal/wxpaycofnig"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
var (
|
||||
mchID string = wxpaycofnig.GetWxPayConfig().MchID // 商户号
|
||||
mchCertificateSerialNumber string = wxpaycofnig.GetWxPayConfig().MchCertificateSerialNumber // 商户证书序列号
|
||||
mchAPIv3Key string = wxpaycofnig.GetWxPayConfig().MchAPIv3Key // 商户APIv3密钥
|
||||
|
||||
)
|
||||
|
||||
// Prepay 预支付
|
||||
func Prepay(outTradeNo int64, description string) (string, error) {
|
||||
|
||||
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath("/path/to/merchant/apiclient_key.pem")
|
||||
if err != nil {
|
||||
logUtilPlus.ErrorLog("load merchant private key error")
|
||||
return "", err
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
// 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力
|
||||
opts := []core.ClientOption{
|
||||
option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
|
||||
}
|
||||
client, err := core.NewClient(ctx, opts...)
|
||||
if err != nil {
|
||||
logUtilPlus.ErrorLog("new wechat pay client err:%s", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
svc := app.AppApiService{Client: client}
|
||||
resp, result, err := svc.Prepay(ctx,
|
||||
app.PrepayRequest{
|
||||
Appid: core.String("wxd678efh567hg6787"),
|
||||
Mchid: core.String("1230000109"),
|
||||
Description: core.String(description),
|
||||
OutTradeNo: core.String(strconv.FormatInt(outTradeNo, 10)),
|
||||
TimeExpire: core.Time(time.Now()),
|
||||
Attach: core.String("自定义数据说明"),
|
||||
NotifyUrl: core.String("https://www.weixin.qq.com/wxpay/pay.php"),
|
||||
GoodsTag: core.String("WXG"),
|
||||
LimitPay: []string{"LimitPay_example"},
|
||||
SupportFapiao: core.Bool(false),
|
||||
Amount: &app.Amount{
|
||||
Currency: core.String("CNY"),
|
||||
Total: core.Int64(100),
|
||||
},
|
||||
Detail: &app.Detail{
|
||||
CostPrice: core.Int64(608800),
|
||||
GoodsDetail: []app.GoodsDetail{app.GoodsDetail{
|
||||
GoodsName: core.String("iPhoneX 256G"),
|
||||
MerchantGoodsId: core.String("ABC"),
|
||||
Quantity: core.Int64(1),
|
||||
UnitPrice: core.Int64(828800),
|
||||
WechatpayGoodsId: core.String("1001"),
|
||||
}},
|
||||
InvoiceId: core.String("wx123"),
|
||||
},
|
||||
SceneInfo: &app.SceneInfo{
|
||||
DeviceId: core.String("013467007045764"),
|
||||
PayerClientIp: core.String("14.23.150.211"),
|
||||
StoreInfo: &app.StoreInfo{
|
||||
Address: core.String("广东省深圳市南山区科技中一道10000号"),
|
||||
AreaCode: core.String("440305"),
|
||||
Id: core.String("0001"),
|
||||
Name: core.String("腾讯大厦分店"),
|
||||
},
|
||||
},
|
||||
SettleInfo: &app.SettleInfo{
|
||||
ProfitSharing: core.Bool(false),
|
||||
},
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
// 处理错误
|
||||
logUtilPlus.ErrorLog("call Prepay err:%s", err.Error())
|
||||
return "", err
|
||||
}
|
||||
|
||||
if result.Response.StatusCode != 200 {
|
||||
errStr := fmt.Sprintf("status=%d resp=%s", result.Response.StatusCode, resp)
|
||||
logUtilPlus.ErrorLog(errStr)
|
||||
return "", errors.New(errStr)
|
||||
}
|
||||
|
||||
return *resp.PrepayId, nil
|
||||
}
|
||||
|
||||
// CloseOrder 关闭订单
|
||||
func CloseOrder() {
|
||||
|
||||
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath("/path/to/merchant/apiclient_key.pem")
|
||||
if err != nil {
|
||||
log.Print("加载商家私钥错误")
|
||||
}
|
||||
|
||||
ctx := context.Background()
|
||||
// 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力
|
||||
opts := []core.ClientOption{
|
||||
option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
|
||||
}
|
||||
client, err := core.NewClient(ctx, opts...)
|
||||
if err != nil {
|
||||
log.Printf("新的 WeChat Pay 客户端 Err:%s", err)
|
||||
}
|
||||
|
||||
svc := app.AppApiService{Client: client}
|
||||
result, err := svc.CloseOrder(ctx,
|
||||
app.CloseOrderRequest{
|
||||
|
||||
//商户系统内部订单号,只能是数字、大小写字母_-*且在同一个商户号下唯
|
||||
OutTradeNo: core.String("OutTradeNo_example"),
|
||||
|
||||
//直连商户的商户号,由微信支付生成并下发。
|
||||
Mchid: core.String("1230000109"),
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
// 处理错误
|
||||
log.Printf("call CloseOrder err:%s", err)
|
||||
} else {
|
||||
// 处理返回结果
|
||||
log.Printf("status=%d", result.Response.StatusCode)
|
||||
}
|
||||
}
|
||||
|
||||
// QueryOrderById 根据商户订单号查询订单
|
||||
func QueryOrderById() {
|
||||
|
||||
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath("/path/to/merchant/apiclient_key.pem")
|
||||
if err != nil {
|
||||
log.Print("load merchant private key error")
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
svc := app.AppApiService{Client: client}
|
||||
resp, result, err := svc.QueryOrderById(ctx,
|
||||
app.QueryOrderByIdRequest{
|
||||
TransactionId: core.String("TransactionId_example"),
|
||||
Mchid: core.String("Mchid_example"),
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
// 处理错误
|
||||
log.Printf("call QueryOrderById err:%s", err)
|
||||
} else {
|
||||
// 处理返回结果
|
||||
log.Printf("status=%d resp=%s", result.Response.StatusCode, resp)
|
||||
}
|
||||
}
|
||||
|
||||
// QueryOrderByOutTradeNo 根据商户订单号查询订单
|
||||
func QueryOrderByOutTradeNo() {
|
||||
// 使用 utils 提供的函数从本地文件中加载商户私钥,商户私钥会用来生成请求的签名
|
||||
mchPrivateKey, err := utils.LoadPrivateKeyWithPath("/path/to/merchant/apiclient_key.pem")
|
||||
if err != nil {
|
||||
log.Print("load merchant private key error")
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
|
||||
svc := app.AppApiService{Client: client}
|
||||
resp, result, err := svc.QueryOrderByOutTradeNo(ctx,
|
||||
app.QueryOrderByOutTradeNoRequest{
|
||||
OutTradeNo: core.String("OutTradeNo_example"),
|
||||
Mchid: core.String("Mchid_example"),
|
||||
},
|
||||
)
|
||||
|
||||
if err != nil {
|
||||
// 处理错误
|
||||
log.Printf("call QueryOrderByOutTradeNo err:%s", err)
|
||||
} else {
|
||||
// 处理返回结果
|
||||
log.Printf("status=%d resp=%s", result.Response.StatusCode, resp)
|
||||
}
|
||||
}
|
||||
96
trunk/center/paycenter/internal/pay/api.go
Normal file
96
trunk/center/paycenter/internal/pay/api.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package pay
|
||||
|
||||
import (
|
||||
"common/remark"
|
||||
"common/resultStatus"
|
||||
"common/webServer"
|
||||
"goutil/intUtil"
|
||||
"paycenter/internal"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
//注册接口
|
||||
webServer.RegisterFunction(new(PayApi))
|
||||
}
|
||||
|
||||
func init() {
|
||||
moduleName := "PayApi"
|
||||
desc := "用户接口"
|
||||
author := "tangping"
|
||||
mendor := ""
|
||||
date := "2025年1月8日15:49:03"
|
||||
remark.RegisterModuleRemark(moduleName, desc, author, mendor, date)
|
||||
}
|
||||
|
||||
// PayApi 用户接口
|
||||
type PayApi struct {
|
||||
}
|
||||
|
||||
// ---------------------------------------- 接口 --------------------------------------------------
|
||||
func init() {
|
||||
moduleName := "PayApi"
|
||||
methodName := "PlaceAnOrder"
|
||||
skipVerifyTokenPage := true
|
||||
methodDesc := "下单"
|
||||
methodAuthor := "tangping"
|
||||
methodMendor := ""
|
||||
methodDate := "2025年1月8日15:51:34"
|
||||
methodInParam := []string{"int32:充值模版id,string:玩家id,int32:区服id"}
|
||||
methodOutParam := `
|
||||
{
|
||||
"Code '类型:int'": "响应结果的状态值",
|
||||
"Message '类型:string'": "响应结果的状态值所对应的描述信息",
|
||||
"Data '类型:interface{}'": "响应结果的数据"
|
||||
{
|
||||
"OrderID '类型:int64'": "订单id",
|
||||
"prepayId '类型:int64'": "预支付会话id",
|
||||
}
|
||||
}`
|
||||
remark.RegisterMethodRemark(moduleName, methodName, methodDesc, methodAuthor, methodMendor, methodDate, methodInParam, methodOutParam, skipVerifyTokenPage)
|
||||
}
|
||||
func (a *PayApi) PlaceAnOrder(modelID int32, playerID string, serverID int64) (responseObj *webServer.ResponseObject) {
|
||||
responseObj = webServer.GetInitResponseObj()
|
||||
|
||||
//校验参数
|
||||
if modelID == 0 || playerID == "" || serverID == 0 {
|
||||
responseObj.SetResultStatus(resultStatus.APIDataError)
|
||||
return
|
||||
}
|
||||
|
||||
//获取对应充值配置
|
||||
|
||||
orderId, err := intUtil.ShuffleIntDigits(time.Now().UnixNano())
|
||||
if err != nil {
|
||||
responseObj.SetResultStatus(resultStatus.DataError)
|
||||
return
|
||||
}
|
||||
|
||||
//下微信订单
|
||||
prepayId, err := internal.Prepay(orderId, "描述!!!!!!!!!!")
|
||||
if err != nil {
|
||||
responseObj.SetResultStatus(resultStatus.APIDataError)
|
||||
return
|
||||
}
|
||||
//处理数据
|
||||
order := &Order{
|
||||
OrderID: orderId,
|
||||
PrepayId: prepayId,
|
||||
OrderMoney: 100,
|
||||
OrderStatus: 1,
|
||||
PlayerID: playerID,
|
||||
ServerID: serverID,
|
||||
UserID: playerID,
|
||||
OrderDate: time.Now(),
|
||||
}
|
||||
|
||||
//添加到数据库
|
||||
AddOrder(order)
|
||||
|
||||
resultMap := make(map[string]any)
|
||||
resultMap["orderID"] = order.OrderID
|
||||
resultMap["prepayId"] = order.PrepayId
|
||||
responseObj.SetData(resultMap)
|
||||
return
|
||||
}
|
||||
69
trunk/center/paycenter/internal/pay/logic.go
Normal file
69
trunk/center/paycenter/internal/pay/logic.go
Normal file
@@ -0,0 +1,69 @@
|
||||
package pay
|
||||
|
||||
import (
|
||||
"common/connection"
|
||||
"goutil/logUtilPlus"
|
||||
"sync"
|
||||
)
|
||||
|
||||
var (
|
||||
// 用户缓存对象
|
||||
orderMap = make(map[int64]*Order)
|
||||
rwmu sync.RWMutex
|
||||
)
|
||||
|
||||
// GetUserByID 根据用户id获取用户信息
|
||||
func GetUserByID(orderID int64) (*Order, error) {
|
||||
|
||||
//判断缓存是否存在
|
||||
var order *Order
|
||||
|
||||
func() *Order {
|
||||
rwmu.RLock()
|
||||
defer rwmu.RUnlock()
|
||||
ok := true
|
||||
if order, ok = orderMap[orderID]; ok {
|
||||
return order
|
||||
}
|
||||
return nil
|
||||
}()
|
||||
|
||||
if order != nil {
|
||||
return order, nil
|
||||
}
|
||||
|
||||
result := connection.GetPayDB().First(&order, orderID)
|
||||
if result.Error != nil {
|
||||
return nil, result.Error
|
||||
}
|
||||
|
||||
//添加缓存
|
||||
func() {
|
||||
rwmu.Lock()
|
||||
defer rwmu.Unlock()
|
||||
orderMap[order.OrderID] = order
|
||||
}()
|
||||
|
||||
return order, nil
|
||||
}
|
||||
|
||||
// AddUserCache 添加用户缓存
|
||||
func AddUserCache(order *Order) {
|
||||
rwmu.Lock()
|
||||
defer rwmu.Unlock()
|
||||
orderMap[order.OrderID] = order
|
||||
}
|
||||
|
||||
// AddOrder 添加订单
|
||||
func AddOrder(order *Order) (int64, error) {
|
||||
|
||||
//处理一些验证
|
||||
|
||||
// 写入到数据库
|
||||
result := connection.GetPayDB().Create(&order) // 通过数据的指针来创建
|
||||
if result.Error != nil {
|
||||
logUtilPlus.ErrorLog("添加支付订单失败 错误信息:", result.Error.Error())
|
||||
}
|
||||
|
||||
return order.OrderID, nil
|
||||
}
|
||||
34
trunk/center/paycenter/internal/pay/order.go
Normal file
34
trunk/center/paycenter/internal/pay/order.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package pay
|
||||
|
||||
import (
|
||||
"common/connection"
|
||||
"time"
|
||||
)
|
||||
|
||||
func init() {
|
||||
//注册数据库
|
||||
connection.RegisterDBModel(&Order{})
|
||||
}
|
||||
|
||||
type Order struct {
|
||||
//订单id
|
||||
OrderID int64 `gorm:"column:order_id;primary_key;comment:订单id" json:"order_id"`
|
||||
//订单日期
|
||||
OrderDate time.Time `gorm:"column:order_date;comment:订单日期" json:"order_date"`
|
||||
//订单号
|
||||
PrepayId string `gorm:"column:prepay_id;comment:预支付交易会话标识" json:"prepay_id"`
|
||||
//订单金额
|
||||
OrderMoney int64 `gorm:"column:order_money;comment:订单金额" json:"order_money"`
|
||||
//订单状态
|
||||
OrderStatus int32 `gorm:"column:order_status;comment:订单状态" json:"order_status"`
|
||||
//用户id
|
||||
UserID string `gorm:"column:user_id;comment:用户id" json:"user_id"`
|
||||
//区服id
|
||||
ServerID int64 `gorm:"column:server_id;comment:区服id" json:"server_id"`
|
||||
//玩家标识
|
||||
PlayerID string `gorm:"column:player_id;comment:玩家标识" json:"player_id"`
|
||||
}
|
||||
|
||||
func (order *Order) TableName() string {
|
||||
return "order"
|
||||
}
|
||||
62
trunk/center/paycenter/internal/wxpaycofnig/payconfig.go
Normal file
62
trunk/center/paycenter/internal/wxpaycofnig/payconfig.go
Normal file
@@ -0,0 +1,62 @@
|
||||
package wxpaycofnig
|
||||
|
||||
import (
|
||||
"gopkg.in/yaml.v3"
|
||||
"goutil/yamlUtil"
|
||||
"log"
|
||||
)
|
||||
|
||||
type WxPayConfig struct {
|
||||
MchID string
|
||||
MchCertificateSerialNumber string
|
||||
MchAPIv3Key string
|
||||
}
|
||||
|
||||
var (
|
||||
wxPayConfig = &WxPayConfig{}
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
||||
//加载配置
|
||||
reloadConfig()
|
||||
|
||||
//校验配置
|
||||
CheckConfig()
|
||||
}
|
||||
|
||||
// reloadConfig
|
||||
//
|
||||
// @description: reloadConfig
|
||||
//
|
||||
// parameter:
|
||||
// return:
|
||||
//
|
||||
// @error: 错误信息
|
||||
func reloadConfig() error {
|
||||
|
||||
yamlFile, err := yamlUtil.LoadFromFile("payconfig/wxpayconfig.yaml.yaml")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// 解析 YAML 文件
|
||||
err = yaml.Unmarshal(yamlFile, wxPayConfig)
|
||||
if err != nil {
|
||||
log.Fatalf("Error unmarshalling config file: %v", err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckConfig 校验配置
|
||||
func CheckConfig() error {
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetWxPayConfig 获取配置
|
||||
func GetWxPayConfig() *WxPayConfig {
|
||||
return wxPayConfig
|
||||
}
|
||||
Reference in New Issue
Block a user