您的位置:首页 > 编程语言 > Go语言

支付宝手机网页支付之golang版

2017-12-02 17:17 441 查看
本文章主要是通过golang实现了支付宝手机网页支付的简单封装,封装的基本都是请求的必传参数,如果需要其他参数,可以自己修改BizContent结构体来满足自己的需求。

封装的文件大体分为4个文件:

config.go 用来放基本配置参数,现在只放了需要用的rsa用户私钥和阿里rsa公钥,其中用户私钥本封装文件用的pkcs8的,你也可以修改为pkcs1的

dao.go 主要是存放了BizConten结构体,里面只有必传参数,可以自行修改

sign.go 主要是生成签名字符串的,生成正确会返回一个字符串

        pay.go 主要的封装文件,实现了post请求,通过调用pay方法会返回一个编码后的body体(返回的是个网页直接输出到页面就好),还有一个err参数,正确返回nil

大致项目结构如下:

        


config.go文件 :

        

package alipay

const (
private_key = ``
alipay_public_key = ``
)


dao.go 文件 :在实际操作中,我们需要对金额做一些处理,不能直接用float,这会导致有时数据不对。在此可以使用
github.com/shopspring/decimal,或者直接金额一般到分直接用户分为单位采用整型


package alipay

type BizContent struct {
Subject     string `json:"subject"`
OutTradeNo  string `json:"out_trade_no"`
TotalAmount float32    `json:"total_amount"`
ProductCode string `json:"product_code"`
}


sign.go 文件:通过修改rsaEncrypt方法中的x509.ParsePKCS8PrivateKey(block2.Bytes),修改为x509.ParsePKCS1PrivateKey(block2.Bytes),这样就可以使用pkcs1的钥匙



package alipay
import (
"sort"
"fmt"
"encoding/base64"
"encoding/pem"
"crypto/x509"
"crypto/rsa"
"crypto/sha256"
"crypto"
"net/url"
"crypto/rand"
)

func sign(m url.Values) string {
//对url.values进行排序
sign := ""
var keys []string
for k := range m {
keys = append(keys, k)
}
sort.Strings(keys)
for i, k := range keys {
if m.Get(k) != "" {
if i==0{
sign = k+"="+m.Get(k)
}else {
sign = sign + "&"+ k+"="+m.Get(k)
}
}
}
fmt.Println(sign)
//对排序后的数据进行rsa2加密,获得sign
b,_ := rsaEncrypt([]byte(sign))
fmt.Println("加密:",b)
fmt.Println("base加密:",base64.StdEncoding.EncodeToString(b))
return base64.StdEncoding.EncodeToString(b)
}

func rsaEncrypt(origData []byte) ([]byte, error) {
key := private_key

block2, _ := pem.Decode([]byte(key))//PiravteKeyData为私钥文件的字节数组
if block2 == nil {
fmt.Println("block空")
return nil,nil
}
//priv即私钥对象,block2.Bytes是私钥的字节流
priv, err := x509.ParsePKCS8PrivateKey(block2.Bytes)
if err != nil {
fmt.Println("无法还原私钥")
return nil,nil
}
p := priv.(*rsa.PrivateKey)
h2 := sha256.New()
h2.Write(origData)
hashed := h2.Sum(nil)
signature2, err := rsa.SignPKCS1v15(rand.Reader, p,
crypto.SHA256, hashed)//签名
return signature2,err
}


pay.go 文件:

package alipay

import (
"net/url"
"time"
"net/http"
"fmt"
"io/ioutil"
"github.com/axgle/mahonia"
)

func Pay(appId string,returnUrl string,notifyUrl string,bizContent string) (s string,err error) {
var data = url.Values{}
//var clusterinfo = map[string]string{}
data.Add("app_id", appId)
data.Add("method", "alipay.trade.wap.pay")
if returnUrl != "" {
data.Add("return_url",returnUrl)
}
if notifyUrl != "" {
data.Add("notify_url", returnUrl)
}
data.Add("format", "json")
data.Add("charset", "UTF-8")
data.Add("sign_type", "RSA2")
data.Add("timestamp", time.Now().Format("2006-01-02 15:04:05"))
data.Add("version", "1.0")
data.Add("biz_content",bizContent)
data.Add("sign", sign(data))
resp, err := http.PostForm("https://openapi.alipay.com/gateway.do",data)
defer resp.Body.Close()
if err != nil {
fmt.Println(err)
return "",err
}
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
fmt.Println(err)
return "",err
}
d := mahonia.NewDecoder("utf-8")
return d.ConvertString(string(body)),err
}


调用方法,在你需要调用的方法中加入以下代码即可,例如:

func ali(c echo.Context) error {

bizContent := new(alipay.BizContent)
bizContent.Subject = "ceshi"
bizContent.OutTradeNo = "1111112312312312312"
bizContent.TotalAmount = 0.01
bizContent.ProductCode = "QUICK_WAP_WAY"
e,err := json.Marshal(bizContent)
if err != nil {
return err
}
body,err := alipay.Pay("","","",string(e))
if err != nil {
return err
}

return c.HTML(200,body)
}



                                            
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  支付宝 支付 golang