记录一下调用微信支付的 Go SDK 流程。
# 安装
go get -u github.com/wechatpay-apiv3/wechatpay-go |
# 初始化
根据文档示例,各个模块还是比较清晰。JSAPI 支付,APP 支付和扫码支付的调用都类似,需要初始化 core.Client
对象,再以此 client 初始化各个类型的支付服务。
import ( | |
"context" | |
"os" | |
"github.com/wechatpay-apiv3/wechatpay-go/core" | |
"github.com/wechatpay-apiv3/wechatpay-go/utils" | |
"github.com/wechatpay-apiv3/wechatpay-go/core/option" | |
) | |
func InitClient() { | |
// SDK 提供的加载证书功能,使用证书路径加载 | |
mchPrivateKey, err := utils.LoadPrivateKeyWithPath("path/of/cert") | |
if err != nil { | |
return nil, err | |
} | |
ctx := context.Background() | |
// 使用商户私钥等初始化 client,并使它具有自动定时获取微信支付平台证书的能力 | |
opts := []core.ClientOption{ | |
// 商户号, 商户证书序列号, 商户证书, 商户 APIv3 密钥 | |
option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key), | |
} | |
client, err := core.NewClient(ctx, opts...) | |
... | |
} |
# 初始化不同服务
使用得到的 client 初始化不同的支付服务
// JSAPI 支付 | |
jas := &jsapi.JsapiApiService{Client: client} | |
// 扫码支付 | |
nas := &native.NativeApiService{Client: client} | |
// App 支付 | |
aps := &app.AppApiService{Client: client} | |
// 退款 | |
rfs := &refunddomestic.RefundsApiService{Client: client} |
# 支付
支付的步骤也类似,先使用上述的服务对象,调用 Prepay
方法进行预下单
- 扫码支付预下单返回一个二维码链接,用户扫该二维码支付
- JSAPI 预下单将返回 prepay_id 以及其他 js 接口需要的参数供前端使用
- APP 预下单只返回 prepay_id ,需要手动进行签名生成,用以 APP 内唤起微信来支付
APP 参数签名参照文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_2_4.shtml
noneStr, err := utils.GenerateNonce() | |
if err != nil { | |
return err | |
} | |
timestamp := strconv.FormatInt(time.Now().Unix(), 10) | |
sb := strings.Builder{} | |
sb.WriteString(appID) | |
sb.WriteString("\n") | |
sb.WriteString(timestamp) | |
sb.WriteString("\n") | |
sb.WriteString(noneStr) | |
sb.WriteString("\n") | |
sb.WriteString(prepayId) | |
sb.WriteString("\n") | |
//client 对象提供了签名的方法 | |
signStr, err := client.Sign(context.Background(), sb.String()) | |
if err != nil { | |
return nil, err | |
} | |
// 最后得到需要的 时间戳,随机字符串,以及签名 | |
fmt.Println(timestamp, noneStr, signStr) |
接受回调通知:回调通知的验签与解密