Golang 2022沙箱实现支付宝支付
Gopay
微信、支付宝、PayPal、Apple 的Go版本SDK。【极简、易用的聚合支付SDK】
github:https://github.com/go-pay/gopay
go get -u github.com/go-pay/gopay
支付宝
密钥和授权回调地址
获取密钥
得到以下:
- 应用公钥证书 appCertPublicKey.crt
- 应用私钥(非 Java 语言)
- 支付宝公钥证书 alipayCertPublicKey_RSA2.crt
- 支付宝公钥证书 alipayRootCert.crt
将证书中的内容复制到文件中或着已证书文件的形式加载
package cert
var (
Appid = "2021000116674577"
// 应用私钥
AppPrivateKey = "MIIEpAIBAAKCAQEAoX6ZLfwZz3NDkwjaVhai18yVxQaUgA47aZuOe2AtG2hfeQ1LJ9GN7aTPAGdnuXMaRj9RRKllRw+vJq2FmAKo........"
// 支付宝公钥证书
AlipayPublicContentRSA2 = []byte(`MIIDszCCApu...................
`)
// 支付宝根证书
AlipayRootContent = []byte(`.....................................................
-----END CERTIFICATE-----`)
// 应用公钥证书
AppPublicContent = []byte(`-----BEGIN CERTIFICATE-----.................................`)
)
以文件的方式加载
package cert
import (
"io/ioutil"
"os"
)
var (
Appid string
// 应用私钥
AppPrivateKey string
// 支付宝公钥证书
AlipayPublicContentRSA2 []byte
// 支付宝根证书
AlipayRootContent []byte
// 应用公钥证书
AppPublicContent []byte
)
func Init() {
RSA2, _ := os.Open("alipayCertPublicKey_RSA2.crt")
rootKey, _ := os.Open("alipayRootCert.crt")
appPublicKey, _ := os.Open("appCertPublicKey.crt")
AlipayPublicContentRSA2, _ = ioutil.ReadAll(RSA2)
AlipayRootContent, _ = ioutil.ReadAll(rootKey)
AppPublicContent, _ = ioutil.ReadAll(appPublicKey)
AppPrivateKey = "MIIEpAIBAAKCAQEAoX6Z==................."
Appid = "2021000116674577"
}
回调地址
注意这里一定要是公网地址!
如果你是本地开发可以使用外网穿透实现 https://i.cpolar.com/m/4M81
电脑网站支付
https://github.com/go-pay/gopay/blob/main/doc/alipay.md
https://opendocs.alipay.com/apis/api_1/alipay.trade.page.pay?scene=22
package pay
import (
"context"
"fmt"
"github.com/go-pay/gopay"
"github.com/go-pay/gopay/alipay"
"github.com/go-pay/gopay/pkg/xlog"
"micro-shop-api/order-web/config/cert"
)
var (
TradeStatusWaitBuyerPay string = "WAIT_BUYER_PAY" // 交易创建等待买家支付
TradeStatusClose = "TRADE_CLOSED" // 交易关闭
TradeStatusSuccess = "TRADE_SUCCESS" // 支付成功
TradeStatusFinished = "TRADE_FINISHED" // 交易完结(不可退款)
)
// Notify 支付宝异步通知
// 使用的 gin框架
func Notify(ctx *gin.Context) {
// 解析异步请求的参数
notifyReq, err := alipay.ParseNotifyToBodyMap(ctx.Request)
if err != nil {
zap.S().Errorf("解析参数错误:%s", err.Error())
response.Fail(ctx, status2.InvalidParameter)
return
}
// 验证消息是否是支付宝发送的 保证安全性
// 支付宝步通知验签(公钥证书模式)
ok, err := alipay.VerifySignWithCert(global.Config.Alipay.AlipayPublicContentRSA2, notifyReq)
if !ok || err != nil {
zap.S().Errorf("支付宝异步通知验签失败:%s", err.Error())
response.Fail(ctx, status2.InnerError)
return
}
// 以下是业务逻辑
// 更新订单状态
orderSn := notifyReq["out_trade_no"].(string)
orderStatus := notifyReq["trade_status"].(string)
_, err = global.OrderSrvClient.UpdateOrderStatus(context.Background(), &proto.OrderStatus{OrderSn: orderSn, Status: orderStatus})
if err != nil {
zap.S().Errorf("支付成功但更新状态失败,支付状态:%s, 订单号:%s, err:%s", orderStatus, orderSn, err.Error())
response.Fail(ctx, status2.InnerError)
return
}
// ====异步通知,返回支付宝平台的信息====
// 文档:https://opendocs.alipay.com/open/203/105286
// 程序执行完后必须打印输出“success”(不包含引号)。如果商户反馈给支付宝的字符不是success这7个字符,支付宝服务器会不断重发通知,直到超过24小时22分钟。一般情况下,25小时以内完成8次通知(通知的间隔频率一般是:4m,10m,10m,1h,2h,6h,15h)
// 也就是最大努力通知
ctx.String(http.StatusOK, "success")
}
func Alipay() {
// 初始化支付宝客户端
// appId:应用ID
// privateKey:应用私钥,支持PKCS1和PKCS8
// isProd:是否是正式环境
client, err := alipay.NewClient(cert.Appid, cert.AppPrivateKey, false)
if err != nil {
xlog.Error(err)
return
}
// 打开Debug开关,输出日志,默认关闭
client.DebugSwitch = gopay.DebugOn
// 设置支付宝请求 公共参数
// 注意:具体设置哪些参数,根据不同的方法而不同,此处列举出所有设置参数
client.SetLocation(alipay.LocationShanghai). // 设置时区,不设置或出错均为默认服务器时间
SetCharset(alipay.UTF8). // 设置字符编码,不设置默认 utf-8
SetSignType(alipay.RSA2). // 设置签名类型,不设置默认 RSA2
SetReturnUrl("https://lzscxb.js.cool"). // 设置返回URL,付款结束后跳转的url
SetNotifyUrl("http://3n3swpx.nat.ipyingshe.com/v1/pay/alipay/notify") // 设置异步通知URL
// 自动同步验签(只支持证书模式)
// 传入 alipayCertPublicKey_RSA2.crt 内容
client.AutoVerifySign(cert.AlipayPublicContentRSA2)
// 公钥证书模式,需要传入证书,以下两种方式二选一
// 证书路径
//err := client.SetCertSnByPath("appCertPublicKey.crt", "alipayRootCert.crt", "alipayCertPublicKey_RSA2.crt")
// 证书内容
err = client.SetCertSnByContent(cert.AppPublicContent, cert.AlipayRootContent, cert.AlipayPublicContentRSA2)
if err != nil {
panic(err)
}
// 初始化 BodyMap
bm := make(gopay.BodyMap)
bm.Set("subject", "订单支付"). // 标题
Set("out_trade_no", "lzscxb_order_id:6666666"). // 订单号,支付成功后会返回
Set("total_amount", "0.01"). // 订单金额
Set("timeout_express", "2m"). // 支付超时时间
Set("product_code", "FAST_INSTANT_TRADE_PAY") // 必填 具体参考文档
aliRsp, err := client.TradePagePay(context.Background(), bm)
if err != nil {
xlog.Error("err:", err)
return
}
fmt.Println(aliRsp)
}
如果出现以下情况,请尝试清空浏览器缓存或更换浏览器访问