银行充值简介
用户要想要投标的话,那么需要往p2p平台上进行充值
使用支付宝沙箱 调用支付宝充值接口进行测试
用户余额页面展示用户的余额 点击充值调用跳转到银行充值页面
输入密码,密码正确调转到支付宝支付平台 登录账号密码进行充值
充值成功记录到银行记录表,并且返回余额页面
支付宝
我们项目中只支持一种支付方式,支付宝,所以采用单例模式。保证只生成一个实例。
企业法人信息(营业执照,法人身份证)支付宝的流程是支付宝创建应用,获取到appid。
生成公钥私钥,私钥生成放到本地,公钥去支付宝平台换取支付宝公钥,把支付宝公钥放到本地。支付宝采用的非对称加密方式。
qps限制100,先将请求的订单号放入队列,队列具有先进先出的特性,我使用的redis list做为队列, lpush加入,写一个接口用RRange每秒获取100个请求,向支付宝发起请求,
支付成功回调失败
两种:RRange取出来放入新的队列(sortedSet)中,回调成功从新队列中删除,定时任务每隔1分钟从新队列中取出前一分钟的记录,调用支付宝的查询接口查询是否支付成功,根据支付结果更新订单状态回调接口中的处理
在回调接口中一定重新验证签名,避免回调接口被拦截,输入新订单号直接成功带来的损失。由于回调中操作了多张表操作采用事务处理。
进入到支付宝开放平台 登录获取 appid 公钥 私钥
封装
在创建好的utils文件夹里创建alipayorder.go文件,进行封装
package utilsimport ("fmt"alipay "github.com/smartwalle/alipay/v3""os"
)var (appID = "2021000120615296"privateKey = "MIIEowIBAAKCAQEAn7kWd+6GCZJ0QED03lwXYIp0dyO*****************************......"aliPublicKey = "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAnXHeUM9kx6UkSV****************....."
)var Client *alipay.Clientfunc Init() {var err errorClient, err = alipay.New(appID, privateKey, false)if err != nil {fmt.Println("初始化支付宝失败, 错误信息为", err)os.Exit(-1)}Client.LoadAliPayPublicKey(aliPublicKey)
}
flask银行存管平台
支付宝充值时调用此接口 将用户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 controllerimport ("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 stringif 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 = moneyp.ProductCode = "FAST_INSTANT_TRADE_PAY"url, err := utils.Client.TradePagePay(p)if err != nil {return ""}push_url := url.Scheme + "://" + url.Host + url.Path + "?" + url.RawQueryfmt.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)
}