mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-18 01:06:39 +08:00
geek payment notify api is ready
This commit is contained in:
parent
2beffd3dd3
commit
f887a39912
@ -57,7 +57,8 @@ type AlipayConfig struct {
|
|||||||
PublicKey string // 用户公钥文件路径
|
PublicKey string // 用户公钥文件路径
|
||||||
AlipayPublicKey string // 支付宝公钥文件路径
|
AlipayPublicKey string // 支付宝公钥文件路径
|
||||||
RootCert string // Root 秘钥路径
|
RootCert string // Root 秘钥路径
|
||||||
NotifyHost string // 通知回调地址
|
NotifyURL string // 异步通知地址
|
||||||
|
ReturnURL string // 同步回调地址
|
||||||
}
|
}
|
||||||
|
|
||||||
type WechatPayConfig struct {
|
type WechatPayConfig struct {
|
||||||
@ -67,7 +68,8 @@ type WechatPayConfig struct {
|
|||||||
SerialNo string // 商户证书的证书序列号
|
SerialNo string // 商户证书的证书序列号
|
||||||
PrivateKey string // 用户私钥文件路径
|
PrivateKey string // 用户私钥文件路径
|
||||||
ApiV3Key string // API V3 秘钥
|
ApiV3Key string // API V3 秘钥
|
||||||
NotifyHost string // 通知回调地址
|
NotifyURL string // 异步通知地址
|
||||||
|
ReturnURL string // 同步回调地址
|
||||||
}
|
}
|
||||||
|
|
||||||
type HuPiPayConfig struct { //虎皮椒第四方支付配置
|
type HuPiPayConfig struct { //虎皮椒第四方支付配置
|
||||||
@ -76,7 +78,8 @@ type HuPiPayConfig struct { //虎皮椒第四方支付配置
|
|||||||
AppId string // App ID
|
AppId string // App ID
|
||||||
AppSecret string // app 密钥
|
AppSecret string // app 密钥
|
||||||
ApiURL string // 支付网关
|
ApiURL string // 支付网关
|
||||||
NotifyHost string // 通知回调地址
|
NotifyURL string // 异步通知地址
|
||||||
|
ReturnURL string // 同步回调地址
|
||||||
}
|
}
|
||||||
|
|
||||||
// GeekPayConfig GEEK支付配置
|
// GeekPayConfig GEEK支付配置
|
||||||
@ -85,7 +88,8 @@ type GeekPayConfig struct {
|
|||||||
AppId string // 商户 ID
|
AppId string // 商户 ID
|
||||||
PrivateKey string // 私钥
|
PrivateKey string // 私钥
|
||||||
ApiURL string // API 网关
|
ApiURL string // API 网关
|
||||||
NotifyHost string // 通知回调地址
|
NotifyURL string // 异步通知地址
|
||||||
|
ReturnURL string // 同步回调地址
|
||||||
}
|
}
|
||||||
|
|
||||||
type XXLConfig struct { // XXL 任务调度配置
|
type XXLConfig struct { // XXL 任务调度配置
|
||||||
|
@ -39,6 +39,7 @@ type PaymentHandler struct {
|
|||||||
geekPayService *payment.GeekPayService
|
geekPayService *payment.GeekPayService
|
||||||
wechatPayService *payment.WechatPayService
|
wechatPayService *payment.WechatPayService
|
||||||
snowflake *service.Snowflake
|
snowflake *service.Snowflake
|
||||||
|
userService *service.UserService
|
||||||
fs embed.FS
|
fs embed.FS
|
||||||
lock sync.Mutex
|
lock sync.Mutex
|
||||||
signKey string // 用来签名的随机秘钥
|
signKey string // 用来签名的随机秘钥
|
||||||
@ -51,6 +52,7 @@ func NewPaymentHandler(
|
|||||||
geekPayService *payment.GeekPayService,
|
geekPayService *payment.GeekPayService,
|
||||||
wechatPayService *payment.WechatPayService,
|
wechatPayService *payment.WechatPayService,
|
||||||
db *gorm.DB,
|
db *gorm.DB,
|
||||||
|
userService *service.UserService,
|
||||||
snowflake *service.Snowflake,
|
snowflake *service.Snowflake,
|
||||||
fs embed.FS) *PaymentHandler {
|
fs embed.FS) *PaymentHandler {
|
||||||
return &PaymentHandler{
|
return &PaymentHandler{
|
||||||
@ -59,6 +61,7 @@ func NewPaymentHandler(
|
|||||||
geekPayService: geekPayService,
|
geekPayService: geekPayService,
|
||||||
wechatPayService: wechatPayService,
|
wechatPayService: wechatPayService,
|
||||||
snowflake: snowflake,
|
snowflake: snowflake,
|
||||||
|
userService: userService,
|
||||||
fs: fs,
|
fs: fs,
|
||||||
lock: sync.Mutex{},
|
lock: sync.Mutex{},
|
||||||
BaseHandler: BaseHandler{
|
BaseHandler: BaseHandler{
|
||||||
@ -72,12 +75,12 @@ func NewPaymentHandler(
|
|||||||
func (h *PaymentHandler) Pay(c *gin.Context) {
|
func (h *PaymentHandler) Pay(c *gin.Context) {
|
||||||
payWay := c.Query("pay_way")
|
payWay := c.Query("pay_way")
|
||||||
payType := c.Query("pay_type")
|
payType := c.Query("pay_type")
|
||||||
productId := c.Query("pid")
|
productId := c.Query("product_id")
|
||||||
device := c.Query("device")
|
device := c.Query("device")
|
||||||
userId := c.Query("user_id")
|
userId := c.Query("user_id")
|
||||||
|
|
||||||
var product model.Product
|
var product model.Product
|
||||||
err := h.DB.First(&product, productId).Error
|
err := h.DB.Debug().Where("id", productId).First(&product).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
resp.ERROR(c, "Product not found")
|
resp.ERROR(c, "Product not found")
|
||||||
return
|
return
|
||||||
@ -126,23 +129,20 @@ func (h *PaymentHandler) Pay(c *gin.Context) {
|
|||||||
var payURL string
|
var payURL string
|
||||||
if payWay == "alipay" { // 支付宝
|
if payWay == "alipay" { // 支付宝
|
||||||
money := fmt.Sprintf("%.2f", order.Amount)
|
money := fmt.Sprintf("%.2f", order.Amount)
|
||||||
notifyURL := fmt.Sprintf("%s/api/payment/notify/alipay", h.App.Config.AlipayConfig.NotifyHost)
|
|
||||||
returnURL := fmt.Sprintf("%s/member", h.App.Config.AlipayConfig.NotifyHost)
|
|
||||||
if device == "mobile" {
|
if device == "mobile" {
|
||||||
payURL, err = h.alipayService.PayMobile(payment.AlipayParams{
|
payURL, err = h.alipayService.PayMobile(payment.AlipayParams{
|
||||||
OutTradeNo: orderNo,
|
OutTradeNo: orderNo,
|
||||||
Subject: product.Name,
|
Subject: product.Name,
|
||||||
TotalFee: money,
|
TotalFee: money,
|
||||||
ReturnURL: returnURL,
|
NotifyURL: h.App.Config.AlipayConfig.NotifyURL,
|
||||||
NotifyURL: notifyURL,
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
payURL, err = h.alipayService.PayPC(payment.AlipayParams{
|
payURL, err = h.alipayService.PayPC(payment.AlipayParams{
|
||||||
OutTradeNo: orderNo,
|
OutTradeNo: orderNo,
|
||||||
Subject: product.Name,
|
Subject: product.Name,
|
||||||
TotalFee: money,
|
TotalFee: money,
|
||||||
ReturnURL: returnURL,
|
ReturnURL: h.App.Config.AlipayConfig.ReturnURL,
|
||||||
NotifyURL: notifyURL,
|
NotifyURL: h.App.Config.AlipayConfig.NotifyURL,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -155,7 +155,8 @@ func (h *PaymentHandler) Pay(c *gin.Context) {
|
|||||||
TradeOrderId: orderNo,
|
TradeOrderId: orderNo,
|
||||||
TotalFee: fmt.Sprintf("%f", order.Amount),
|
TotalFee: fmt.Sprintf("%f", order.Amount),
|
||||||
Title: order.Subject,
|
Title: order.Subject,
|
||||||
NotifyURL: fmt.Sprintf("%s/api/payment/notify/hupi", h.App.Config.HuPiPayConfig.NotifyHost),
|
NotifyURL: h.App.Config.HuPiPayConfig.NotifyURL,
|
||||||
|
ReturnURL: h.App.Config.HuPiPayConfig.ReturnURL,
|
||||||
WapName: "GeekAI助手",
|
WapName: "GeekAI助手",
|
||||||
}
|
}
|
||||||
r, err := h.huPiPayService.Pay(params)
|
r, err := h.huPiPayService.Pay(params)
|
||||||
@ -175,8 +176,6 @@ func (h *PaymentHandler) Pay(c *gin.Context) {
|
|||||||
|
|
||||||
c.Redirect(302, uri)
|
c.Redirect(302, uri)
|
||||||
} else if order.PayWay == "geek" {
|
} else if order.PayWay == "geek" {
|
||||||
notifyURL := fmt.Sprintf("%s/api/payment/notify/geek", h.App.Config.GeekPayConfig.NotifyHost)
|
|
||||||
returnURL := fmt.Sprintf("%s/member", h.App.Config.GeekPayConfig.NotifyHost)
|
|
||||||
params := payment.GeekPayParams{
|
params := payment.GeekPayParams{
|
||||||
OutTradeNo: orderNo,
|
OutTradeNo: orderNo,
|
||||||
Method: "web",
|
Method: "web",
|
||||||
@ -185,8 +184,8 @@ func (h *PaymentHandler) Pay(c *gin.Context) {
|
|||||||
ClientIP: c.ClientIP(),
|
ClientIP: c.ClientIP(),
|
||||||
Device: device,
|
Device: device,
|
||||||
Type: payType,
|
Type: payType,
|
||||||
ReturnURL: returnURL,
|
ReturnURL: h.App.Config.GeekPayConfig.ReturnURL,
|
||||||
NotifyURL: notifyURL,
|
NotifyURL: h.App.Config.GeekPayConfig.NotifyURL,
|
||||||
}
|
}
|
||||||
|
|
||||||
res, err := h.geekPayService.Pay(params)
|
res, err := h.geekPayService.Pay(params)
|
||||||
@ -218,45 +217,26 @@ func (h *PaymentHandler) notify(orderNo string, tradeNo string) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
var user model.User
|
var user model.User
|
||||||
res = h.DB.First(&user, order.UserId)
|
err := h.DB.First(&user, order.UserId).Error
|
||||||
if res.Error != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("error with fetch user info: %v", res.Error)
|
return fmt.Errorf("error with fetch user info: %v", res.Error)
|
||||||
logger.Error(err)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var remark types.OrderRemark
|
var remark types.OrderRemark
|
||||||
err := utils.JsonDecode(order.Remark, &remark)
|
err = utils.JsonDecode(order.Remark, &remark)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("error with decode order remark: %v", err)
|
err := fmt.Errorf("error with decode order remark: %v", err)
|
||||||
logger.Error(err)
|
logger.Error(err)
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
var opt string
|
// 增加用户算力
|
||||||
var power int
|
err = h.userService.IncreasePower(int(order.UserId), remark.Power, model.PowerLog{
|
||||||
if remark.Days > 0 { // VIP 充值
|
Type: types.PowerRecharge,
|
||||||
if user.ExpiredTime >= time.Now().Unix() {
|
Model: order.PayWay,
|
||||||
user.ExpiredTime = time.Unix(user.ExpiredTime, 0).AddDate(0, 0, remark.Days).Unix()
|
Remark: fmt.Sprintf("充值算力,金额:%f,订单号:%s", order.Amount, order.OrderNo),
|
||||||
opt = "VIP充值,VIP 没到期,只延期不增加算力"
|
})
|
||||||
} else {
|
if err != nil {
|
||||||
user.ExpiredTime = time.Now().AddDate(0, 0, remark.Days).Unix()
|
|
||||||
user.Power += h.App.SysConfig.VipMonthPower
|
|
||||||
power = h.App.SysConfig.VipMonthPower
|
|
||||||
opt = "VIP充值"
|
|
||||||
}
|
|
||||||
user.Vip = true
|
|
||||||
} else { // 充值点卡,直接增加次数即可
|
|
||||||
user.Power += remark.Power
|
|
||||||
opt = "点卡充值"
|
|
||||||
power = remark.Power
|
|
||||||
}
|
|
||||||
|
|
||||||
// 更新用户信息
|
|
||||||
res = h.DB.Updates(&user)
|
|
||||||
if res.Error != nil {
|
|
||||||
err := fmt.Errorf("error with update user info: %v", res.Error)
|
|
||||||
logger.Error(err)
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -264,29 +244,16 @@ func (h *PaymentHandler) notify(orderNo string, tradeNo string) error {
|
|||||||
order.PayTime = time.Now().Unix()
|
order.PayTime = time.Now().Unix()
|
||||||
order.Status = types.OrderPaidSuccess
|
order.Status = types.OrderPaidSuccess
|
||||||
order.TradeNo = tradeNo
|
order.TradeNo = tradeNo
|
||||||
res = h.DB.Updates(&order)
|
err = h.DB.Updates(&order).Error
|
||||||
if res.Error != nil {
|
if err != nil {
|
||||||
err := fmt.Errorf("error with update order info: %v", res.Error)
|
return fmt.Errorf("error with update order info: %v", err)
|
||||||
logger.Error(err)
|
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 更新产品销量
|
// 更新产品销量
|
||||||
h.DB.Model(&model.Product{}).Where("id = ?", order.ProductId).UpdateColumn("sales", gorm.Expr("sales + ?", 1))
|
err = h.DB.Model(&model.Product{}).Where("id = ?", order.ProductId).
|
||||||
|
UpdateColumn("sales", gorm.Expr("sales + ?", 1)).Error
|
||||||
// 记录算力充值日志
|
if err != nil {
|
||||||
if power > 0 {
|
return fmt.Errorf("error with update product sales: %v", err)
|
||||||
h.DB.Create(&model.PowerLog{
|
|
||||||
UserId: user.Id,
|
|
||||||
Username: user.Username,
|
|
||||||
Type: types.PowerRecharge,
|
|
||||||
Amount: power,
|
|
||||||
Balance: user.Power,
|
|
||||||
Mark: types.PowerAdd,
|
|
||||||
Model: order.PayWay,
|
|
||||||
Remark: fmt.Sprintf("%s,金额:%f,订单号:%s", opt, order.Amount, order.OrderNo),
|
|
||||||
CreatedAt: time.Now(),
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -139,9 +139,15 @@ const routes = [
|
|||||||
{
|
{
|
||||||
path: '/admin/login',
|
path: '/admin/login',
|
||||||
name: 'admin-login',
|
name: 'admin-login',
|
||||||
meta: {title: 'Geek-AI 控制台登录'},
|
meta: {title: '控制台登录'},
|
||||||
component: () => import('@/views/admin/Login.vue'),
|
component: () => import('@/views/admin/Login.vue'),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
path: '/payReturn',
|
||||||
|
name: 'pay-return',
|
||||||
|
meta: {title: '支付回调'},
|
||||||
|
component: () => import('@/views/PayReturn.vue'),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
name: 'admin',
|
name: 'admin',
|
||||||
path: '/admin',
|
path: '/admin',
|
||||||
|
@ -106,6 +106,12 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<el-dialog v-model="showDialog" :show-close=false hide-footer width="auto">
|
||||||
|
<div style="padding-bottom: 10px">
|
||||||
|
<el-button type="success" @click="payCallback(true)">支付成功</el-button>
|
||||||
|
<el-button type="danger" @click="payCallback(false)">支付失败</el-button>
|
||||||
|
</div>
|
||||||
|
</el-dialog>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -143,6 +149,7 @@ const payWays = ref([])
|
|||||||
const vipInfoText = ref("")
|
const vipInfoText = ref("")
|
||||||
const store = useSharedStore()
|
const store = useSharedStore()
|
||||||
const profileKey = ref(0)
|
const profileKey = ref(0)
|
||||||
|
const showDialog = ref(false)
|
||||||
|
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
@ -195,6 +202,7 @@ const pay = (product, payWay) => {
|
|||||||
}).then(res => {
|
}).then(res => {
|
||||||
window.open(res.data, '_blank');
|
window.open(res.data, '_blank');
|
||||||
loading.value = false
|
loading.value = false
|
||||||
|
showDialog.value = true
|
||||||
}).catch(e => {
|
}).catch(e => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
ElMessage.error("生成支付订单失败:" + e.message)
|
ElMessage.error("生成支付订单失败:" + e.message)
|
||||||
@ -210,6 +218,13 @@ const redeemCallback = (success) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const payCallback = (success) => {
|
||||||
|
showDialog.value = false
|
||||||
|
if (success) {
|
||||||
|
profileKey.value += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="stylus">
|
<style lang="stylus">
|
||||||
|
13
web/src/views/PayReturn.vue
Normal file
13
web/src/views/PayReturn.vue
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
支付回调
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import {useRouter} from "vue-router";
|
||||||
|
|
||||||
|
const router = useRouter()
|
||||||
|
console.log(router.currentRoute.value.query)
|
||||||
|
window.close()
|
||||||
|
</script>
|
Loading…
Reference in New Issue
Block a user