50

支付二维码融合 Go实现

 5 years ago
source link: https://studygolang.com/articles/17803?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

个人店铺线下支付二维码,一般会放2个(1个微信收款码,一个支付宝收款码)

网上也提供很多多个二维码融合的技术,这里仅提供思路,以及GoLang实现的样例代码。

具体效果可看:

  1. 个人电铺注册 http://pay.xiaoa7.top:8090/register 需要提交个人的微信、支付宝收款码

  2. 个人融合二维码 http://pay.xiaoa7.top:8090/qr/ 注册时你填写商铺代码,可以将生成的二维码,打印在任何地方。

目前只支持微信,支付宝;后续可扩展支持其他。

融合二维码支付流程:

1.商户在支付宝、微信中生成个人收款码,存储到手机。

2.浏览器访问(微信里直接扫码打开这个地址也可以) http://pay.xiaoa7.top:8090/register ,提交收款码图片

3.服务端Go 调用zbar 识别图片中二维码内容。微信是wxfp开头,支付宝是 https://xxx 的,实际就是收款二维码的内容。服务端数据库记录商户ID,微信收款码wxfp,支付宝收款码 https://xx

4.为商户生成一个内容为url的二维码,格式如下: http://pay.xiaoa7.top:8090/pay/ 商户id。这个二维码商户可以下载,打印。

5.消费者用手机(支付宝、微信)扫码时,实际上会访问 http://pay.xiaoa7.top:8090/pay/ 商户id,这个Action

6.依据useragent识别来源:微信、支付宝、qq、京东等支付

7.支付宝之类的,可以直接http 301跳转,就可以到给商户个人付款界面。微信需要服务端以商户收款码内容(wxfpXXX)生成二维码图片,(这个过程可以在注册时直接生成,以备后续使用,不用每次都生成,而且可以美化,加上商户信息,提示消费者长按付款),生成支付二维码图片,消费者长按图片,选择识别图片二维码,实现支付到商户个人账户。

在这一步,跳转前可以做一些记录,如记录商户交易请求,每日商户交易次数等等。

GoLang代码

var (

ali_user_agent, _ = regexp.Compile("(?i:Alipay)")

wx_user_agent, _  = regexp.Compile("(?i:MicroMessenger)")

)

//识别二维码内容

func DecodeQR(src multipart.File) (string, error) {

defer src.Close()

img, _, _ := image.Decode(src)

ret, err := deqr.GetDataFromImage(img)

if err != nil {

return "", err

}

return strings.Join(ret, ","), nil

}

//注册

func registerAct(w http.ResponseWriter, r *http.Request) {

mid := r.FormValue("mid")

var wxpay, alipay string

fi, _, _ := r.FormFile("wxpay")

wxpay, err := DecodeQR(fi)

if err != nil {

fmt.Println(err.Error())

return

}

fi, _, _ = r.FormFile("alipay")

alipay, err = DecodeQR(fi)

if err != nil {

fmt.Println(err.Error())

return

}

//生二维码

person_qr, _ := qrcode.Encode(fmt.Sprintf(*payurltpl, mid), qrcode.Medium, 256)

wxpay_qr, _ := qrcode.Encode(wxpay, qrcode.High, 256)

bs, _ := json.Marshal(merchant{

WxPayUrl:  wxpay,

AliPayUrl: alipay,

PayQR:    person_qr,

WxPayQR:  wxpay_qr,

})

db.Save("merchant", mid, bs)

http.Redirect(w, r, "/qr/"+mid, 301)

}



//支付码

func pay(w http.ResponseWriter, r *http.Request) {

if len(r.RequestURI) < 5 {

return

}

mid := r.RequestURI[5:]

bs, err := db.Get("merchant", mid)

m := new(merchant)

if err != nil {

return

}

json.Unmarshal(bs, m)

if ali_user_agent.MatchString(r.UserAgent()) {

http.Redirect(w, r, m.AliPayUrl, 301)

} else if wx_user_agent.MatchString(r.UserAgent()) {

//生成图片输出,二维码图,有待美化

w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate")

w.Header().Set("Pragma", "no-cache")

w.Header().Set("Expires", "0")

w.Header().Set("Content-Type", "image/png")

w.Write(m.WxPayQR)

} else {

fmt.Fprintln(w, "请使用微信、支付宝扫描")

}

}

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK