sealos 是一款云操作系统发行版,可以非常简单的管理 kubernetes 的生命周期,以及像使用 win11 一样使用云,最近写 sealos cloud 的支付模块,发现可以通过命令行做微信支付,非常有意思,现在和大家分享一下如何做到的。
输入一条命令,终端会输出二维码,直接微信扫一扫就可以付钱,这对于极客来说真是福音,对于一个藐视使用 GUI 的人来说岂不是很香?为了站在鄙视链顶端(API 鄙视 as code 鄙视 CLI 鄙视 GUI)岂能不支持这么酷的特性~
使用场景:
- 想想你充爱奇艺会员的时候咔敲个命令,扫一扫搞定,女朋友在旁边不得亚麻呆住?
- 想想现在很多屎山一样的前端页面,半天都找不到按钮在哪,一条命令充值岂不是很酸爽?
- 想想你执行一个命令突然提示欠费蹦出个二维码让你充值执行
- 想想数据库备份日志显示一个二维码,扫码继续备份
下面开始教程:
使用微信 native 支付方式
native 支付会向微信支付服务发送一条请求,微信支付会返回一个 codeurl, 直接把这个 codeurl 转化成二维码,即可用微信扫描支付。
我们自己服务端写一个获取 code-url 的接口:
ws.Route(ws.GET("/wechat/code-url").To(u.getCodeURL)
func (u Payment) getCodeURL(request *restful.Request, response *restful.Response) {
amount := request.QueryParameter("amount")
user := request.QueryParameter("user")
a, err := strconv.Atoi(amount)
codeURL, err := WechatPay(int64(a), user, "", "", os.Getenv(CallbackURL))
_, err = response.Write([]byte(codeURL))
}
这里获取谁(user)充值多少 (amout) 钱, (省去了非核心逻辑)
支付请求实现:
func WechatPay(amount int64, user, tradeNO, describe, callback string) (string, error) {
mchID := os.Getenv(MchID) // 商户号
mchCertificateSerialNumber := os.Getenv(MchCertificateSerialNumber) // 商户证书序列号
mchAPIv3Key := os.Getenv(MchAPIv3Key) // 商户APIv3密钥
mchPrivateKey, err := utils.LoadPrivateKey(os.Getenv(WechatPrivateKey))
ctx := context.Background()
opts := []core.ClientOption{
option.WithWechatPayAutoAuthCipher(mchID, mchCertificateSerialNumber, mchPrivateKey, mchAPIv3Key),
}
client, err := core.NewClient(ctx, opts...)
svc := native.NativeApiService{Client: client}
resp, _, err := svc.Prepay(ctx,
native.PrepayRequest{
Appid: core.String(os.Getenv(AppID)),
Mchid: core.String(os.Getenv(MchID)),
Description: core.String(describe),
OutTradeNo: core.String(tradeNO),
TimeExpire: core.Time(time.Now()),
Attach: core.String(user),
NotifyUrl: core.String(callback),
GoodsTag: core.String("sealos recharge"),
SupportFapiao: core.Bool(false),
Amount: &native.Amount{
Currency: core.String("CNY"),
Total: core.Int64(amount),
},
Detail: &native.Detail{
CostPrice: core.Int64(608800),
GoodsDetail: []native.GoodsDetail{
{
GoodsName: core.String("sealos cloud recharge"),
MerchantGoodsId: core.String("ABC"),
Quantity: core.Int64(1),
UnitPrice: core.Int64(828800),
WechatpayGoodsId: core.String("1001"),
}},
},
SettleInfo: &native.SettleInfo{
ProfitSharing: core.Bool(false),
},
},
)
return *resp.CodeUrl, nil
}
此接口会返回这样的一个字符串,也就是我们需要转化成二维码的:
weixin://wxpay/bizpayurl?pr=aIQrOYOzz
命令行客户端实现
以上实现了服务端代码,现在在命令行实现一下客户端代码即可,客户端无非是个 http 请求然后把返回结果用命令行二维码库转化一下即可。
RunE: func(cmd *cobra.Command, args []string) error {
fmt.Printf("Use WeChat to scan the QR code below to recharge, please make sure the username and amount are correct\n")
fmt.Printf("User: %s\n", config.User)
fmt.Printf("Amount: %d\n", config.Amount)
return api.QRTerminalPay(config.User, config.Amount*100, "")
}
实现:
func QRTerminalPay(user string, amount int64, domain string) error {
if domain == "" {
domain = "http://localhost:8071"
}
url := fmt.Sprintf("%s/payment/wechat/code-url?amount=%d&user=%s", domain, amount, user)
resp, err := http.Get(url)
defer resp.Body.Close()
b, err := io.ReadAll(resp.Body)
qrterminal.Generate(string(b), qrterminal.L, os.Stdout)
return nil
}
效果:
直接执行命令:
sealos recharge --user fanux --amount 1
终端就会输出二维码
手机微信扫一扫:
大功告成~
完整代码在 sealos 中,有需要的可以去 copy~
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。