p2p银行充值功能模块 支付宝调用

银行充值简介

用户要想要投标的话,那么需要往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)
}

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 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)
}

请添加图片描述

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值