用户要想要投标的话,那么需要往p2p平台上进行充值
使用支付宝沙箱 调用支付宝充值接口进行测试
用户余额页面展示用户的余额 点击充值调用跳转到银行充值页面
输入密码,密码正确调转到支付宝支付平台 登录账号密码进行充值
充值成功记录到银行记录表,并且返回余额页面
我们项目中只支持一种支付方式,支付宝,所以采用单例模式。保证只生成一个实例。
企业法人信息(营业执照,法人身份证)支付宝的流程是支付宝创建应用,获取到appid。
生成公钥私钥,私钥生成放到本地,公钥去支付宝平台换取支付宝公钥,把支付宝公钥放到本地。支付宝采用的非对称加密方式。
qps限制100,先将请求的订单号放入队列,队列具有先进先出的特性,我使用的redis list做为队列, lpush加入,写一个接口用RRange每秒获取100个请求,向支付宝发起请求,
支付成功回调失败
两种:RRange取出来放入新的队列(sortedSet)中,回调成功从新队列中删除,定时任务每隔1分钟从新队列中取出前一分钟的记录,调用支付宝的查询接口查询是否支付成功,根据支付结果更新订单状态回调接口中的处理
在回调接口中一定重新验证签名,避免回调接口被拦截,输入新订单号直接成功带来的损失。由于回调中操作了多张表操作采用事务处理。
进入到支付宝开放平台 登录获取 appid 公钥 私钥
在创建好的utils文件夹里创建alipayorder.go文件,进行封装
package utils
import (
"fmt"
alipay "github.com/smartwalle/alipay/v3"
"os"
)
var (
appID = "2021000120615296"
privateKey = "MIIEowIBAAKCAQEAn7kWd+6GCZJ0QED03lwXYIp0dyO*****************************......"
aliPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnXHeUM9kx6UkSV****************....."
)
var Client *alipay.Client
func Init() {
var err error
Client, err = alipay.New(appID, privateKey, false)
if err != nil {
fmt.Println("初始化支付宝失败, 错误信息为", err)
os.Exit(-1)
}
Client.LoadAliPayPublicKey(aliPublicKey)
}
支付宝充值时调用此接口 将用户id和金额写进充值表中
调用
#进行取钱
@user_blue.route('/recharge')
def recharge():
req = reqparse.RequestParser()
req.add_argument("user_id")
req.add_argument("money")
arse = req.parse_args()
print(arse)
sql = f"insert into recharge(user_id, money) values ({arse['user_id']},{arse['money']})"
db.update(sql)
db.commit()
return jsonify({'code': 200})
在创建好的controller中的open_troller,go进行编写
前端页面点击充值按钮调用充值校验数据接口 接受前端传过来的用户id和密码 密码正确调用银行充值接口
银行充值接口返回flask银行存管平台 银行取钱路由
接着在调用获取支付宝地址接口 通过封装的 appid 公钥私钥 获取到支付宝充值页面
充值成功回调前端 重定向到前端网页地址 顺便调用更新用户表&充值表
package controller
import (
"encoding/base64"
"encoding/json"
"fmt"
"github.com/gin-gonic/gin"
"github.com/smartwalle/alipay/v3"
"io/ioutil"
"myproject/model"
"myproject/utils"
"net/http"
"net/url"
"strconv"
"strings"
"time"
)
func Open(openGrp *gin.RouterGroup) {
openGrp.Use().GET("/zinentiqu", zinentiqu)
openGrp.Use().GET("/wenzi", Mywenzi)
openGrp.Use().POST("/upload", upload)
openGrp.Use().POST("/open", OpenBankViews)
openGrp.Use().POST("/getpayurl", getpayurl)// 充值校验数据 调用银行进行取钱 openUser() // 获取支付宝地址 UplaodAlipay()
openGrp.Use().GET("/huidiaoaly", huidiaoaly)// 回调前端 更新用户表&充值表 StatusUser()
openGrp.Use().GET("/get/open", getOpenId)// 查询开户表
openGrp.Use().GET("/get/user", getUser)// 获取用户余额
openGrp.Use().GET("/aass", aass)
}
/*
充值==》调用银行管理平台进行添加==》
alxhou4794@sandbox.com
*/
// 查询开户表
func getOpenId(c *gin.Context) {
id := c.Query("userid")
user_info := model.OpenBank{}
sql := "select * from open_banks where userid=?"
model.GetDb().Raw(sql, id).Scan(&user_info)
c.JSON(200, gin.H{"code": 200, "data": user_info})
}
// 获取用户余额
func getUser(c *gin.Context) {
id := c.Query("userid")
user_info := model.User{}
sql := "select * from users where id=?"
model.GetDb().Raw(sql, id).Scan(&user_info)
c.JSON(200, gin.H{"code": 200, "data": user_info})
}
// 调用银行充值
func openUser(user_id, money string) float64 {
var host = "http://127.0.0.1:5000/recharge"
var param = map[string]string{
"user_id": user_id,
"money": money,
}
uri, err := url.Parse(host)
if err != nil {
fmt.Println(err)
}
query := uri.Query()
for k, v := range param {
query.Set(k, v)
}
uri.RawQuery = query.Encode()
response, err := http.Get(uri.String())
if err != nil {
fmt.Println(err)
}
result, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Println(err)
}
fmt.Println(">>", string(result))
fmt.Printf("type: %T\n", result)
var v interface{}
_ = json.Unmarshal([]byte(string(result)), &v)
data := v.(map[string]interface{})
fmt.Println(data["code"])
return data["code"].(float64)
}
// 充值校验数据
func getpayurl(c *gin.Context) {
data := make(map[string]interface{})
_ = c.ShouldBind(&data)
// 判断密码是否正确
user_info := &model.OpenBank{}
sql := "select * from open_banks where userid=?"
model.GetDb().Raw(sql, data["userid"]).Scan(&user_info)
if fmt.Sprint(user_info.Password) != data["password"] {
c.JSON(200, gin.H{"code": 400, "msg": "密码错误"})
return
}
// 调用银行进行取钱
code := openUser(fmt.Sprint(data["userid"]), fmt.Sprint(data["num"]))
var url_path string
if code == 200 {
fmt.Println("000000000000000")
// 获取支付宝地址
url_path = UplaodAlipay(fmt.Sprint(data["num"]), fmt.Sprint(data["userid"]))
}
if url_path == "" {
c.JSON(200, gin.H{"code": 400, "msg": "充值失败"})
return
}
utils.GetRedis().Setex("user", 3600, data["userid"])
c.JSON(200, gin.H{"code": 200, "msg": "跳转中...", "url": url_path})
}
// 获取支付宝地址
func UplaodAlipay(money, userid string) string {
utils.Init()
orderId := time.Now().UnixNano()
var p = alipay.TradePagePay{}
p.NotifyURL = "http://localhost:8000/huidiaoaly" // 异步回调
p.ReturnURL = "http://localhost:8000/huidiaoaly" // 同步回调
p.Subject = "要充值"
p.OutTradeNo = fmt.Sprint(orderId) // 订单号
p.TotalAmount = money
p.ProductCode = "FAST_INSTANT_TRADE_PAY"
url, err := utils.Client.TradePagePay(p)
if err != nil {
return ""
}
push_url := url.Scheme + "://" + url.Host + url.Path + "?" + url.RawQuery
fmt.Println(">>>", url)
return push_url
}
/*
http://localhost:8000/news/callback?
charset = utf-8
out_trade_no = 1313423523
method = alipay.trade.page.pay.return
total_amount = 10.00
trade_no = 2022102422001493010501925475
auth_app_id = 2021000120615296
version = 1.0
app_id = 2021000120615296
sign_type = RSA2
seller_id = 2088621959391584
timestamp = 2022-10-24+16%3A31%3A59
*/
//alxhou4794@sandbox.com
// tfdfue7174@sandbox.com
// 回调前端
func huidiaoaly(c *gin.Context) {
// 回调前端
c.Redirect(http.StatusMovedPermanently, "http://localhost:8080/status/")
alipay.AckNotification(c.Writer)
order, _ := utils.Client.GetTradeNotification(c.Request)
fmt.Println("============", order.TotalAmount)
// 通知已获取信息
fmt.Println(">>>order:>>>", c.Query("userid"))
if order == nil {
fmt.Println("==验证失败==")
} else {
fmt.Println(order)
}
// TODO 更新状态
res := utils.GetRedis().Get("user")
fmt.Println("----------", res)
StatusUser(fmt.Sprint(order.TotalAmount), fmt.Sprint(res))
}
// 更新用户表&充值表
func StatusUser(money, userid string) int {
// 添加充值表
id, _ := strconv.ParseInt(userid, 10, 0)
money_float, _ := strconv.ParseFloat(money, 2000)
fmt.Println(money_float)
fmt.Printf(">>>%T\n", money_float)
db := model.GetDb()
rec_info := &model.Recharge{
Userid: int(id),
Money: int(money_float),
Status: 1,
Type: 1,
}
db.Create(rec_info)
// 更新用户表
user_info := model.User{}
sql := "select * from users where id=?"
db.Raw(sql, id).Scan(&user_info)
num := int(user_info.Tmoney) + int(money_float)
db.Exec("update users set tmoney=? where id=?", num, userid)
return 1
}
func aass(c *gin.Context) {
v := "10.01"
res, _ := strconv.ParseFloat(v, 10)
fmt.Println(res)
fmt.Printf(">>>%T\n", int(res)+1)
}