package main
import (
"context"
"errors"
"fmt"
"github.com/go-pay/gopay"
"github.com/go-pay/gopay/alipay"
"github.com/go-pay/gopay/pkg/xlog"
"github.com/kataras/iris/v12"
"net/url"
)
//应用私钥
var privateKey = ``
func main() {
// 1初始化支付宝客户端
client, err := alipay.NewClient("appid", privateKey, 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://127.0.0.1:80/return"). //跳转页面
SetNotifyUrl("https://本地地址80端口映射的域名/notify") // 异步通知URL 可被外网访问 post请求//.SetAppAuthToken() // 设置第三方应用授权
// 自动同步验签(只支持证书模式)
// 传入 alipayCertPublicKey_RSA2.crt 内容
// client.AutoVerifySign([]byte(`-----BEGIN CERTIFICATE-----
//-----END CERTIFICATE-----
//`))
// 公钥证书模式,需要传入证书,证书路径
err = client.SetCertSnByPath("appCertPublicKey.crt", "alipayRootCert.crt", "alipayCertPublicKey_RSA2.crt")
if err != nil {
xlog.Error(err)
return
}
// 2web服务器
app := iris.New()
app.Get("/pay", func(ctx iris.Context) { //支付
Pay(context.Background(), client)
})
app.Get("/return", func(ctx iris.Context) { //返回页
ReturnUrl(ctx)
})
app.Post("/notify", func(ctx iris.Context) { //通知页
err = NotifyUrl(ctx)
if err != nil {
fmt.Println("通知页", err)
}
})
err = app.Run(iris.Addr(":80"))
if err != nil {
fmt.Println(err)
return
}
}
// Pay 手机网站支付
func Pay(ctx context.Context, client *alipay.Client) {
//请求参数
bm := make(gopay.BodyMap)
bm.Set("subject", "手机网站支付")
bm.Set("out_trade_no", "LP20220628") //一个订单号只能支付一次
bm.Set("total_amount", "0.01") //1分钱
fmt.Println("body:", bm)
//发送请求
payUrl, err := client.TradeWapPay(ctx, bm) //内部已经处理了签名
if err != nil {
xlog.Error(err)
return
}
//支付界面链接,直接粘贴到手机浏览器里即可支付
fmt.Println(payUrl)
}
// ReturnUrl 返回页 同步get,可在本机上测试
func ReturnUrl(ctx iris.Context) {
ctx.WriteString("ReturnUrl success")
}
// NotifyUrl 通知页 异步post,必须外网可访问,必须返回success否则会一直通知
func NotifyUrl(ctx iris.Context) error {
body, err := ctx.GetBody()
if err != nil {
fmt.Errorf("%v", err)
return err
}
fmt.Println("body", string(body))
values, err := url.ParseQuery(string(body))
if err != nil {
fmt.Errorf("%v", err)
return err
}
datas, err := alipay.ParseNotifyByURLValues(values) //证书异步验签
if err != nil {
fmt.Errorf("%v", err)
return err
}
//验签
ok, err := alipay.VerifySignWithCert("alipayCertPublicKey_RSA2.crt", datas)
if ok == false || err != nil {
fmt.Errorf("%v", err)
return errors.New("校验失败")
}
fmt.Println(datas)
tradeStatus := datas.Get("trade_status")
fmt.Printf(tradeStatus)
//todo 处理业务逻辑
//交易状态
if tradeStatus == "TRADE_SUCCESS" {
fmt.Println("交易成功")
} else {
fmt.Errorf("交易异常")
}
//返回success
ctx.WriteString("success")
return nil
}