Loading

Golang 2022沙箱实现支付宝支付

Gopay

微信、支付宝、PayPal、Apple 的Go版本SDK。【极简、易用的聚合支付SDK】
github:https://github.com/go-pay/gopay

go get -u github.com/go-pay/gopay

支付宝

https://open.alipay.com/platform/appDaily.htm

密钥和授权回调地址

获取密钥

image-20220307195026431

得到以下:

  1. 应用公钥证书 appCertPublicKey.crt
  2. 应用私钥(非 Java 语言)
  3. 支付宝公钥证书 alipayCertPublicKey_RSA2.crt
  4. 支付宝公钥证书 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"
}

image-20220307160646231

回调地址
注意这里一定要是公网地址!
如果你是本地开发可以使用外网穿透实现 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)
}

如果出现以下情况,请尝试清空浏览器缓存或更换浏览器访问

image-20220307194725391

posted @ 2022-06-07 13:30  白日醒梦  阅读(1027)  评论(0编辑  收藏  举报