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

本文章主要是通过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)
}







 

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值