有没有见过在 terminal 里用微信支付? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
lameleg
V2EX    开源软件

有没有见过在 terminal 里用微信支付?

  •  1
     
  •   lameleg 2022-08-18 11:24:53 +08:00 2555 次点击
    这是一个创建于 1151 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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~

    7 条回复    2022-08-19 19:46:10 +08:00
    singerll
        1
    singerll  
       2022-08-18 11:28:36 +08:00 via Android   1
    那么问题来了,这个码是不是还要用 gui 去扫。。。
    lameleg
        2
    lameleg  
    OP
       2022-08-18 11:35:38 +08:00
    @singerll 这锅只能甩给微信团队了 哈哈。 要是加密货币就完全脱离 GUI 了
    snoopyhai
        3
    snoopyhai  
       2022-08-18 14:56:19 +08:00
    二维码为什么是图片. 不应该是用字符矩阵一个么
    lameleg
        4
    lameleg  
    OP
       2022-08-18 17:30:53 +08:00
    @snoopyhai 这可不是图片,字符拼起来的
    lameleg
        5
    lameleg  
    OP
       2022-08-18 19:17:39 +08:00   1
    @snoopyhai ASCII 'half blocks'
    fxzx
        6
    fxzx  
       2022-08-19 18:14:24 +08:00 via Android
    HICA 就是这样收款的
    my3157
        7
    my3157  
       2022-08-19 19:46:10 +08:00 via Android
    首先得有个女朋友
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     2591 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 43ms UTC 05:17 PVG 13:17 LAX 22:17 JFK 01:17
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86