mirror of
https://github.com/yangjian102621/geekai.git
synced 2025-09-19 01:36:38 +08:00
payment for mobile page is ready
This commit is contained in:
parent
4976b967e7
commit
16ac57ced3
@ -71,6 +71,14 @@ TikaHost = "http://tika:9998"
|
||||
AccessToken = "xxl-job-api-token" # 执行器 API 通信 token
|
||||
RegistryKey = "chatgpt-plus" # 任务注册 key
|
||||
|
||||
[SmtpConfig] # 注意,阿里云服务器禁用了25号端口,请使用 465 端口,并开启 TLS 连接
|
||||
UseTls = false
|
||||
Host = "smtp.163.com"
|
||||
Port = 25
|
||||
AppName = "极客学长"
|
||||
From = "test@163.com" # 发件邮箱人地址
|
||||
Password = "" #邮箱 stmp 服务授权码
|
||||
|
||||
[AlipayConfig]
|
||||
Enabled = false # 启用支付宝支付通道
|
||||
SandBox = false # 是否启用沙盒模式
|
||||
@ -80,31 +88,12 @@ TikaHost = "http://tika:9998"
|
||||
PublicKey = "certs/alipay/appPublicCert.crt" # 应用公钥证书
|
||||
AlipayPublicKey = "certs/alipay/alipayPublicCert.crt" # 支付宝公钥证书
|
||||
RootCert = "certs/alipay/alipayRootCert.crt" # 支付宝根证书
|
||||
NotifyURL = "https://ai.r9it.com/api/payment/alipay/notify" # 支付异步回调地址
|
||||
|
||||
[HuPiPayConfig]
|
||||
Enabled = false
|
||||
Name = "wechat"
|
||||
AppId = ""
|
||||
AppSecret = ""
|
||||
ApiURL = "https://api.xunhupay.com"
|
||||
NotifyURL = "https://ai.r9it.com/api/payment/hupipay/notify"
|
||||
|
||||
[SmtpConfig] # 注意,阿里云服务器禁用了25号端口,请使用 465 端口,并开启 TLS 连接
|
||||
UseTls = false
|
||||
Host = "smtp.163.com"
|
||||
Port = 25
|
||||
AppName = "极客学长"
|
||||
From = "test@163.com" # 发件邮箱人地址
|
||||
Password = "" #邮箱 stmp 服务授权码
|
||||
|
||||
[JPayConfig] # PayJs 支付配置
|
||||
Enabled = false
|
||||
Name = "wechat" # 请不要改动
|
||||
AppId = "" # 商户 ID
|
||||
PrivateKey = "" # 秘钥
|
||||
ApiURL = "https://payjs.cn"
|
||||
NotifyURL = "https://ai.r9it.com/api/payment/payjs/notify" # 异步回调地址,域名改成你自己的
|
||||
|
||||
# 微信商户支付
|
||||
[WechatPayConfig]
|
||||
@ -114,6 +103,11 @@ TikaHost = "http://tika:9998"
|
||||
SerialNo = "" # API 证书序列号
|
||||
PrivateKey = "certs/alipay/privateKey.txt" # API 证书私钥文件路径,跟支付宝一样,把私钥文件拷贝到对应的路径,证书路径要映射到容器内
|
||||
ApiV3Key = "" # APIV3 私钥,这个是你自己在微信支付平台设置的
|
||||
NotifyURL = "https://ai.r9it.com/api/payment/wechat/notify" # 支付成功异步回调地址,域名改成自己的
|
||||
ReturnURL = "" # 支付成功同步回调地址
|
||||
|
||||
# 易支付
|
||||
[GeekPayConfig]
|
||||
Enabled = true
|
||||
AppId = "" # 商户ID
|
||||
PrivateKey = "" # 商户私钥
|
||||
ApiURL = "https://pay.geekai.cn"
|
||||
Methods = ["alipay", "wxpay", "qqpay", "jdpay", "douyin", "paypal"] # 支持的支付方式
|
||||
|
@ -58,6 +58,7 @@ type AlipayConfig struct {
|
||||
AlipayPublicKey string // 支付宝公钥文件路径
|
||||
RootCert string // Root 秘钥路径
|
||||
NotifyURL string // 异步通知地址
|
||||
ReturnURL string // 同步通知地址
|
||||
}
|
||||
|
||||
type WechatPayConfig struct {
|
||||
@ -76,6 +77,7 @@ type HuPiPayConfig struct { //虎皮椒第四方支付配置
|
||||
AppSecret string // app 密钥
|
||||
ApiURL string // 支付网关
|
||||
NotifyURL string // 异步通知地址
|
||||
ReturnURL string // 同步通知地址
|
||||
}
|
||||
|
||||
// GeekPayConfig GEEK支付配置
|
||||
@ -85,6 +87,7 @@ type GeekPayConfig struct {
|
||||
PrivateKey string // 私钥
|
||||
ApiURL string // API 网关
|
||||
NotifyURL string // 异步通知地址
|
||||
ReturnURL string // 同步通知地址
|
||||
Methods []string // 支付方式
|
||||
}
|
||||
|
||||
|
@ -73,14 +73,21 @@ func NewPaymentHandler(
|
||||
}
|
||||
|
||||
func (h *PaymentHandler) Pay(c *gin.Context) {
|
||||
payWay := c.Query("pay_way")
|
||||
payType := c.Query("pay_type")
|
||||
productId := c.Query("product_id")
|
||||
device := c.Query("device")
|
||||
userId := c.Query("user_id")
|
||||
var data struct {
|
||||
PayWay string `json:"pay_way"`
|
||||
PayType string `json:"pay_type"`
|
||||
ProductId int `json:"product_id"`
|
||||
UserId int `json:"user_id"`
|
||||
Device string `json:"device"`
|
||||
Host string `json:"host"`
|
||||
}
|
||||
if err := c.ShouldBindJSON(&data); err != nil {
|
||||
resp.ERROR(c, types.InvalidArgs)
|
||||
return
|
||||
}
|
||||
|
||||
var product model.Product
|
||||
err := h.DB.Where("id", productId).First(&product).Error
|
||||
err := h.DB.Where("id", data.ProductId).First(&product).Error
|
||||
if err != nil {
|
||||
resp.ERROR(c, "Product not found")
|
||||
return
|
||||
@ -92,36 +99,73 @@ func (h *PaymentHandler) Pay(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
var user model.User
|
||||
err = h.DB.Where("id", userId).First(&user).Error
|
||||
err = h.DB.Where("id", data.UserId).First(&user).Error
|
||||
if err != nil {
|
||||
resp.NotAuth(c)
|
||||
return
|
||||
}
|
||||
|
||||
amount, _ := decimal.NewFromFloat(product.Price).Sub(decimal.NewFromFloat(product.Discount)).Float64()
|
||||
var payURL string
|
||||
if payWay == "alipay" { // 支付宝
|
||||
returnURL := fmt.Sprintf("%s/payReturn", utils.GetBaseURL(h.App.Config.AlipayConfig.NotifyURL))
|
||||
var payURL, returnURL, notifyURL string
|
||||
switch data.PayWay {
|
||||
case "alipay":
|
||||
if h.App.Config.AlipayConfig.NotifyURL != "" { // 用于本地调试支付
|
||||
notifyURL = h.App.Config.AlipayConfig.NotifyURL
|
||||
} else {
|
||||
notifyURL = fmt.Sprintf("%s/api/payment/notify/alipay", data.Host)
|
||||
}
|
||||
if h.App.Config.AlipayConfig.ReturnURL != "" { // 用于本地调试支付
|
||||
returnURL = h.App.Config.AlipayConfig.ReturnURL
|
||||
} else {
|
||||
returnURL = fmt.Sprintf("%s/payReturn", data.Host)
|
||||
}
|
||||
money := fmt.Sprintf("%.2f", amount)
|
||||
payURL, err = h.alipayService.PayPC(payment.AlipayParams{
|
||||
OutTradeNo: orderNo,
|
||||
Subject: product.Name,
|
||||
TotalFee: money,
|
||||
ReturnURL: returnURL,
|
||||
NotifyURL: h.App.Config.AlipayConfig.NotifyURL,
|
||||
NotifyURL: notifyURL,
|
||||
})
|
||||
if err != nil {
|
||||
resp.ERROR(c, "error with generate pay url: "+err.Error())
|
||||
return
|
||||
}
|
||||
} else if payWay == "hupi" { // 虎皮椒支付
|
||||
returnURL := fmt.Sprintf("%s/payReturn", utils.GetBaseURL(h.App.Config.HuPiPayConfig.NotifyURL))
|
||||
break
|
||||
case "wechat":
|
||||
if h.App.Config.WechatPayConfig.NotifyURL != "" {
|
||||
notifyURL = h.App.Config.WechatPayConfig.NotifyURL
|
||||
} else {
|
||||
notifyURL = fmt.Sprintf("%s/api/payment/notify/wechat", data.Host)
|
||||
}
|
||||
payURL, err = h.wechatPayService.PayUrlNative(payment.WechatPayParams{
|
||||
OutTradeNo: orderNo,
|
||||
TotalFee: int(amount * 100),
|
||||
Subject: product.Name,
|
||||
NotifyURL: notifyURL,
|
||||
})
|
||||
if err != nil {
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
}
|
||||
break
|
||||
case "hupi":
|
||||
if h.App.Config.HuPiPayConfig.NotifyURL != "" {
|
||||
notifyURL = h.App.Config.HuPiPayConfig.NotifyURL
|
||||
} else {
|
||||
notifyURL = fmt.Sprintf("%s/api/payment/notify/hupi", data.Host)
|
||||
}
|
||||
if h.App.Config.HuPiPayConfig.ReturnURL != "" {
|
||||
returnURL = h.App.Config.HuPiPayConfig.ReturnURL
|
||||
} else {
|
||||
returnURL = fmt.Sprintf("%s/payReturn", data.Host)
|
||||
}
|
||||
r, err := h.huPiPayService.Pay(payment.HuPiPayParams{
|
||||
Version: "1.1",
|
||||
TradeOrderId: orderNo,
|
||||
TotalFee: fmt.Sprintf("%f", amount),
|
||||
Title: product.Name,
|
||||
NotifyURL: h.App.Config.HuPiPayConfig.NotifyURL,
|
||||
NotifyURL: notifyURL,
|
||||
ReturnURL: returnURL,
|
||||
WapName: "GeekAI助手",
|
||||
})
|
||||
@ -129,23 +173,21 @@ func (h *PaymentHandler) Pay(c *gin.Context) {
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
}
|
||||
|
||||
payURL = r.URL
|
||||
} else if payWay == "wechat" {
|
||||
payURL, err = h.wechatPayService.PayUrlNative(payment.WechatPayParams{
|
||||
OutTradeNo: orderNo,
|
||||
TotalFee: int(amount * 100),
|
||||
Subject: product.Name,
|
||||
NotifyURL: h.App.Config.WechatPayConfig.NotifyURL,
|
||||
})
|
||||
if err != nil {
|
||||
resp.ERROR(c, err.Error())
|
||||
return
|
||||
break
|
||||
case "geek":
|
||||
if h.App.Config.GeekPayConfig.NotifyURL != "" {
|
||||
notifyURL = h.App.Config.GeekPayConfig.NotifyURL
|
||||
} else {
|
||||
notifyURL = fmt.Sprintf("%s/api/payment/notify/geek", data.Host)
|
||||
}
|
||||
} else if payWay == "geek" {
|
||||
returnURL := fmt.Sprintf("%s/payReturn", utils.GetBaseURL(h.App.Config.GeekPayConfig.NotifyURL))
|
||||
if device == "wechat" {
|
||||
returnURL = fmt.Sprintf("%s/mobile/profile", utils.GetBaseURL(h.App.Config.GeekPayConfig.NotifyURL))
|
||||
if h.App.Config.GeekPayConfig.ReturnURL != "" {
|
||||
data.Host = utils.GetBaseURL(h.App.Config.GeekPayConfig.ReturnURL)
|
||||
}
|
||||
if data.Device == "wechat" { // 微信客户端打开,调回手机端用户中心页面
|
||||
returnURL = fmt.Sprintf("%s/mobile/profile", data.Host)
|
||||
} else {
|
||||
returnURL = fmt.Sprintf("%s/payReturn", data.Host)
|
||||
}
|
||||
params := payment.GeekPayParams{
|
||||
OutTradeNo: orderNo,
|
||||
@ -153,10 +195,10 @@ func (h *PaymentHandler) Pay(c *gin.Context) {
|
||||
Name: product.Name,
|
||||
Money: fmt.Sprintf("%f", amount),
|
||||
ClientIP: c.ClientIP(),
|
||||
Device: device,
|
||||
Type: payType,
|
||||
Device: data.Device,
|
||||
Type: data.PayType,
|
||||
ReturnURL: returnURL,
|
||||
NotifyURL: h.App.Config.GeekPayConfig.NotifyURL,
|
||||
NotifyURL: notifyURL,
|
||||
}
|
||||
|
||||
res, err := h.geekPayService.Pay(params)
|
||||
@ -165,6 +207,9 @@ func (h *PaymentHandler) Pay(c *gin.Context) {
|
||||
return
|
||||
}
|
||||
payURL = res.PayURL
|
||||
default:
|
||||
resp.ERROR(c, "不支持的支付渠道")
|
||||
return
|
||||
}
|
||||
|
||||
// 创建订单
|
||||
@ -183,8 +228,8 @@ func (h *PaymentHandler) Pay(c *gin.Context) {
|
||||
Subject: product.Name,
|
||||
Amount: amount,
|
||||
Status: types.OrderNotPaid,
|
||||
PayWay: payWay,
|
||||
PayType: payType,
|
||||
PayWay: data.PayWay,
|
||||
PayType: data.PayType,
|
||||
Remark: utils.JsonEncode(remark),
|
||||
}
|
||||
err = h.DB.Create(&order).Error
|
||||
|
@ -372,7 +372,7 @@ func main() {
|
||||
}),
|
||||
fx.Invoke(func(s *core.AppServer, h *handler.PaymentHandler) {
|
||||
group := s.Engine.Group("/api/payment/")
|
||||
group.GET("doPay", h.Pay)
|
||||
group.POST("doPay", h.Pay)
|
||||
group.GET("payWays", h.GetPayWays)
|
||||
group.POST("notify/alipay", h.AlipayNotify)
|
||||
group.GET("notify/geek", h.GeekPayNotify)
|
||||
|
@ -1,4 +1,4 @@
|
||||
VUE_APP_API_HOST=http://localhost:5678
|
||||
VUE_APP_API_HOST=http://www.geekai.me:6004
|
||||
VUE_APP_WS_HOST=ws://localhost:5678
|
||||
VUE_APP_USER=18888888888
|
||||
VUE_APP_PASS=12345678
|
||||
|
@ -122,7 +122,7 @@
|
||||
<script setup>
|
||||
import {onMounted, ref} from "vue"
|
||||
import {ElMessage} from "element-plus";
|
||||
import {httpGet} from "@/utils/http";
|
||||
import {httpGet, httpPost} from "@/utils/http";
|
||||
import {checkSession, getSystemInfo} from "@/store/cache";
|
||||
import UserProfile from "@/components/UserProfile.vue";
|
||||
import PasswordDialog from "@/components/PasswordDialog.vue";
|
||||
@ -200,11 +200,16 @@ const pay = (product, payWay) => {
|
||||
}
|
||||
loading.value = true
|
||||
loadingText.value = "正在生成支付订单..."
|
||||
httpGet(`${process.env.VUE_APP_API_HOST}/api/payment/doPay`, {
|
||||
let host = process.env.VUE_APP_API_HOST
|
||||
if (host === '') {
|
||||
host = `${location.protocol}://${location.host}`;
|
||||
}
|
||||
httpPost(`${process.env.VUE_APP_API_HOST}/api/payment/doPay`, {
|
||||
product_id: product.id,
|
||||
pay_way: payWay.pay_way,
|
||||
pay_type: payWay.pay_type,
|
||||
user_id: user.value.id,
|
||||
host: host,
|
||||
device: "jump"
|
||||
}).then(res => {
|
||||
showDialog.value = true
|
||||
|
@ -296,11 +296,16 @@ const pay = (product,payWay) => {
|
||||
message: '正在创建订单',
|
||||
forbidClick: true,
|
||||
});
|
||||
httpGet(`${process.env.VUE_APP_API_HOST}/api/payment/doPay`, {
|
||||
let host = process.env.VUE_APP_API_HOST
|
||||
if (host === '') {
|
||||
host = `${location.protocol}://${location.host}`;
|
||||
}
|
||||
httpPost(`${process.env.VUE_APP_API_HOST}/api/payment/doPay`, {
|
||||
product_id: product.id,
|
||||
pay_way: payWay.pay_way,
|
||||
pay_type: payWay.pay_type,
|
||||
user_id: userId.value,
|
||||
host: host,
|
||||
device: "wechat"
|
||||
}).then(res => {
|
||||
location.href = res.data
|
||||
|
Loading…
Reference in New Issue
Block a user