一.界面展示
当用户点击'去支付'时,请求支付界面,并
展示对应订单相关数据,以及
支付方式相关操作,点击对应的支付方式,进行支付操作
该界面对应的功能:
1.进入该界面,后台逻辑判断:
是否存在该订单,如果不存在,则跳转到购物车页面;如果存在,则获取对应订单相关数据,并
渲染到页面
2.选择支付方式,根据不同支付方式进行支付操作
支付宝支付: 点击 '支付宝'支付方式,会请求后台,通过支付宝相关配置以及方法,生成一个
支付url,重定向到对应的支付url,用户扫描支付,支付完成后,跳转到服务端设置的
返回页面,然后支付宝服务器会请求配置的服务端
回调地址,进行订单校验以及对应的
订单逻辑处理
微信支付: 点击'微信支付'支付方式,也会请求后台,通过微信相关配置以及方法,生成一个支付
二维码,展示到界面,用户扫描支付完成后,微信服务器会请求配置的服务端
回调地址,进行订单校验以及对应的
订单逻辑处理(修改订单支付状态等),然后前端在这个支付页面会每个几秒(一般方法是定时
ajax轮询,或者
web_socket请求)请求一个接口,判断该订单是否支付,如果支付了,就跳转到支付成功页面
去支付页面
微信支付页面
点击'微信支付'支付方式,也会请求后台,通过微信相关配置以及方法,生成一个支付二维码,展示到界面,用户扫描支付完成后,微信服务器会请求配置的服务端回调地址,进行订单校验以及对应的订单逻辑处理(修改订单支付状态等),然后前端在这个支付页面会每个几秒(一般方法是定时ajax轮询,或者web_socket请求)请求一个接口,判断该订单是否支付,如果支付了,就跳转到支付成功页面
微信支付页面
点击 '支付宝'支付方式,会请求后台,通过支付宝相关配置以及方法,生成一个支付url,重定向到对应的支付url,用户扫描支付,支付完成后,跳转到服务端设置的返回页面,然后支付宝服务器会请求配置的服务端回调地址,进行订单校验以及对应的订单逻辑处理
二.代码展示
集成支付宝支付控制器代码
要使用
github.com/smartwalle/alipay/v3需要先引入:
直接在import中引入 github.com/smartwalle/alipay/v3,然后go mod tidy就可以了
package frontend
import (
"fmt"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/smartwalle/alipay/v3"
)
type AlipayController struct{}
//支付宝支付请求接口
func (con AlipayController) Alipay(c *gin.Context) {
//1、获取订单号 判断此订单号是否值当前用户的
//2、获取订单里面的支付信息
var privateKey = "xxx" // 必须,上一步中使用 RSA签名验签工具 生成的私钥
var client, err = alipay.New("2021xxx588", privateKey, true)
client.LoadAppPublicCertFromFile("crt/appCertPublicKey_2021xxx588.crt") // 加载应用公钥证书
client.LoadAliPayRootCertFromFile("crt/alipayRootCert.crt") // 加载支付宝根证书
client.LoadAliPayPublicCertFromFile("crt/alipayCertPublicKey_RSA2.crt") // 加载支付宝公钥证书
// 将 key 的验证调整到初始化阶段
if err != nil {
fmt.Println(err)
return
}
//支付宝PC扫描方式支付
var p = alipay.TradePagePay{}
p.NotifyURL = "http://xxx/v3/alipayNotify" // 回调地址
p.ReturnURL = "http://xxx5/v3/alipayReturn" //支付后跳转地址
p.Subject = "测试 公钥证书模式-这是一个gin订单"
template := "2006-01-02 15:04:05"
p.OutTradeNo = time.Now().Format(template)
p.TotalAmount = "0.1" //支付金额(元)
p.ProductCode = "FAST_INSTANT_TRADE_PAY" //根据支付方式调整
var url, err4 = client.TradePagePay(p)
if err4 != nil {
fmt.Println(err4)
}
//支付url
var payURL = url.String()
//重定向到支付url
c.Redirect(http.StatusFound, payURL)
}
//支付回调
func (con AlipayController) AlipayNotify(c *gin.Context) {
var privateKey = "xxx" // 必须,上一步中使用 RSA签名验签工具 生成的私钥
var client, err = alipay.New("202xxx588", privateKey, true)
client.LoadAppPublicCertFromFile("crt/appCertPublicKey_202xxx588.crt") // 加载应用公钥证书
client.LoadAliPayRootCertFromFile("crt/alipayRootCert.crt") // 加载支付宝根证书
client.LoadAliPayPublicCertFromFile("crt/alipayCertPublicKey_RSA2.crt") // 加载支付宝公钥证书
if err != nil {
fmt.Println(err)
return
}
req := c.Request
req.ParseForm()
//支付校验
ok, _ := client.VerifySign(req.Form)
fmt.Println(ok)
fmt.Println(req.Form)
//订单逻辑处理...
c.String(200, "ok")
}
//支付后跳转页面
func (con AlipayController) AlipayReturn(c *gin.Context) {
c.String(200, "支付成功")
}
集成微信支付控制器代码
查看订单支付状态方法
在controllers/frontend/BuyController.go下增加查看订单支付状态方法:前端支付页面,微信支付会每个几秒请求该接口,根据返回结果,判断是否跳转到订单支付成功页面
//查看订单支付状态
func (con BuyController) OrderPayStatus(c *gin.Context) {
id, err := models.Int(c.Query("id"))
if err != nil {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "传入参数错误",
})
return
}
//获取用户信息
user := models.User{}
models.Cookie.Get(c, "user", &user)
//获取主订单信息
order := models.Order{}
models.DB.Where("id = ?", id).Find(&order)
//判断当前数据是否合法
if user.Id != order.Uid {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "非法请求",
})
return
}
//判断是否支付
if order.PayStatus == 1 && order.OrderStatus == 1 {
c.JSON(http.StatusOK, gin.H{
"success": true,
"message": "支付成功",
})
return
} else {
c.JSON(http.StatusOK, gin.H{
"success": false,
"message": "支付成功",
})
return
}
}
路由
把微信支付,支付宝支付相关路由写入routers/frontendRouters.go中
//查看订单支付状态
defaultRouters.GET("/buy/orderPayStatus", middlewares.InitUserAuthMiddleware, frontend.BuyController{}.OrderPayStatus)
//支付宝支付
defaultRouters.GET("/alipay", middlewares.InitUserAuthMiddleware, frontend.AlipayController{}.Alipay)
//支付宝支付回调
defaultRouters.POST("/alipayNotify", frontend.AlipayController{}.AlipayNotify)
//支付宝支付完成后跳转
defaultRouters.GET("/alipayReturn", middlewares.InitUserAuthMiddleware, frontend.AlipayController{}.AlipayReturn)
//微信支付
defaultRouters.GET("/wxpay", middlewares.InitUserAuthMiddleware, frontend.WxpayController{}.Wxpay)
//微信支付回调
defaultRouters.POST("/wxpay/notify", frontend.WxpayController{}.WxpayNotify)
html
微信,支付宝支付操作处理