C:\Users\Administrator\Documents\支付宝开放平台开发助手\RSA密钥
注意这里的授权回调,我们在内网测试的时候,这里需要使用到内网穿透技术,否则是无法接收到回调的
package main
import (
"fmt"
"github.com/smartwalle/alipay/v3"
)
func main() {
appID := "开放平台的appID"
privateKey := "应用私钥"
aliPublicKey := "支付宝公钥"
var client, err = alipay.New(appID, privateKey, false)
if err != nil {
panic(err)
}
err = client.LoadAliPayPublicKey(aliPublicKey)
if err != nil {
panic(err)
}
var p = alipay.TradePagePay{} // page支付方式使用
p.NotifyURL = "http://xxx" // 支付结果回调的url,注意内网穿透问题
p.ReturnURL = "http://127.0.0.1:8089" // 支付成功后倒计时结束跳转的页面
p.Subject = "标题"
p.OutTradeNo = "sn12389342479" //传递一个唯一单号
p.TotalAmount = "10.00"
p.ProductCode = "FAST_INSTANT_TRADE_PAY" // page支付必须使用这个配置
url, err := client.TradePagePay(p)
if err != nil {
panic(err)
}
fmt.Println(url.String())
}
{
"host": "192.168.124.9",
"name": "order_web",
"port": 8083,
"tags": ["mxshop","imooc","bobby","order","web"],
"goods_srv": {
"name": "goods_srv"
},
"order_srv": {
"name": "order_srv"
},
"inventory_srv": {
"name": "inventory_srv"
},
"jwt": {
"key": "VYLDYq3&hGWjWqF$K1ih"
},
"consul": {
"host": "192.168.124.51",
"port": 8500
},
"alipay":{
"app_id":"",
"private_key":"",
"ali_public_key":"",
"notify_url":"",
"return_url":""
}
}
package config
type SrvConfig struct {
Name string `mapstructure:"name" json:"name"`
}
type JWTConfig struct {
SigningKey string `mapstructure:"key" json:"key"`
}
type ConsulConfig struct {
Host string `mapstructure:"host" json:"host"`
Port int `mapstructure:"port" json:"port"`
}
type AlipayConfig struct {
AppID string `mapstructure:"app_id" json:"app_id"`
PrivateKey string `mapstructure:"private_key" json:"private_key"`
AliPublicKey string `mapstructure:"ali_public_key" json:"ali_public_key"`
NotifyURL string `mapstructure:"notify_url" json:"notify_url"`
ReturnURL string `mapstructure:"return_url" json:"return_url"`
}
type ServerConfig struct {
Name string `mapstructure:"name" json:"name"`
Host string `mapstructure:"host" json:"host"`
Tags []string `mapstructure:"tags" json:"tags"`
Port int `mapstructure:"port" json:"port"`
GoodsSrvInfo SrvConfig `mapstructure:"goods_srv" json:"goods_srv"`
OrderSrvInfo SrvConfig `mapstructure:"order_srv" json:"order_srv"`
InventorySrvInfo SrvConfig `mapstructure:"inventory_srv" json:"inventory_srv"`
JWTInfo JWTConfig `mapstructure:"jwt" json:"jwt"`
ConsulInfo ConsulConfig `mapstructure:"consul" json:"consul"`
AliPayInfo AlipayConfig `mapstructure:"alipay" json:"alipay"`
}
type NacosConfig struct {
Host string `mapstructure:"host"`
Port uint64 `mapstructure:"port"`
Namespace string `mapstructure:"namespace"`
User string `mapstructure:"user"`
Password string `mapstructure:"password"`
DataId string `mapstructure:"dataid"`
Group string `mapstructure:"group"`
}
func New(ctx *gin.Context) {
orderForm := forms.CreateOrderForm{}
if err := ctx.ShouldBindJSON(&orderForm); err != nil {
api.HandleValidatorError(ctx, err)
}
userId, _ := ctx.Get("userId")
rsp, err := global.OrderSrvClient.CreateOrder(context.Background(), &proto.OrderRequest{
UserId: int32(userId.(uint)),
Name: orderForm.Name,
Mobile: orderForm.Mobile,
Address: orderForm.Address,
Post: orderForm.Post,
})
if err != nil {
zap.S().Errorw("新建订单失败")
api.HandleGrpcErrorToHttp(err, ctx)
return
}
// 这里跳过了支付宝的支付的url生成和跳转,这个为了测试使用
if global.ServerConfig.AliPayInfo.AppID == "2021000121645456" {
ctx.JSON(http.StatusOK, gin.H{
"id": rsp.Id,
})
}
//生成支付宝的支付url
client, err := alipay.New(global.ServerConfig.AliPayInfo.AppID, global.ServerConfig.AliPayInfo.PrivateKey, false)
if err != nil {
zap.S().Errorw("实例化支付宝失败")
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
})
return
}
err = client.LoadAliPayPublicKey(global.ServerConfig.AliPayInfo.AliPublicKey)
if err != nil {
zap.S().Errorw("加载支付宝的公钥失败")
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
})
return
}
var p = alipay.TradePagePay{}
p.NotifyURL = global.ServerConfig.AliPayInfo.NotifyURL
p.ReturnURL = global.ServerConfig.AliPayInfo.ReturnURL
p.Subject = "订单-" + rsp.OrderSn
p.OutTradeNo = rsp.OrderSn
p.TotalAmount = strconv.FormatFloat(float64(rsp.Total), 'f', 2, 64)
p.ProductCode = "FAST_INSTANT_TRADE_PAY"
url, err := client.TradePagePay(p)
if err != nil {
zap.S().Errorw("生成支付url失败")
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
})
return
}
ctx.JSON(http.StatusOK, gin.H{
"id": rsp.Id,
"alipay_url": url.String(),
})
}
package router
import (
"github.com/gin-gonic/gin"
"web_api/order_web/api/order"
"web_api/order_web/api/pay"
"web_api/order_web/middlewares"
)
func InitOrderRouter(Router *gin.RouterGroup) {
OrderRouter := Router.Group("orders").Use(middlewares.SetUserId())
{
OrderRouter.GET("", order.List) // 订单列表
//BannerRouter.GET("", middlewares.JWTAuth(), middlewares.IsAdminAuth(), order.List) // 订单列表
OrderRouter.POST("", order.New) // 新建订单
OrderRouter.GET("/:id/", order.Detail) // 订单详情
}
PayRouter := Router.Group("pay")
{
PayRouter.POST("alipay/notify", pay.Notify)
}
}
package pay
import (
"context"
"github.com/gin-gonic/gin"
"github.com/smartwalle/alipay/v3"
"go.uber.org/zap"
"net/http"
"web_api/order_web/proto"
"web_api/order_web/global"
)
func Notify(ctx *gin.Context) {
//支付宝回调通知
client, err := alipay.New(global.ServerConfig.AliPayInfo.AppID, global.ServerConfig.AliPayInfo.PrivateKey, false)
if err != nil {
zap.S().Errorw("实例化支付宝失败")
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
})
return
}
err = client.LoadAliPayPublicKey(global.ServerConfig.AliPayInfo.AliPublicKey)
if err != nil {
zap.S().Errorw("加载支付宝的公钥失败")
ctx.JSON(http.StatusInternalServerError, gin.H{
"msg": err.Error(),
})
return
}
notify, err := client.GetTradeNotification(ctx.Request) //这个会自动验证签名是否正确
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{})
return
}
_, err = global.OrderSrvClient.UpdateOrderStatus(context.Background(), &proto.OrderStatus{
OrderSn: notify.OutTradeNo, // 商户订单号,这个是我们自己生成的订单号
Status: string(notify.TradeStatus),
})
if err != nil {
ctx.JSON(http.StatusInternalServerError, gin.H{})
return
}
ctx.String(http.StatusOK, "success")
}