Giter Site home page Giter Site logo

smartwalle / alipay Goto Github PK

View Code? Open in Web Editor NEW
1.8K 39.0 412.0 606 KB

支付宝 AliPay SDK for Go, 集成简单,功能完善,持续更新,支持公钥证书和普通公钥进行签名和验签,支持文件上传和接口内容加密。

License: MIT License

Go 100.00%
alipay go pay golang alipaysdk

alipay's Introduction

AliPay SDK for Golang

鸣谢

jetbrains.svg

安装

启用 Go module

go get github.com/smartwalle/alipay/v3
import github.com/smartwalle/alipay/v3

未启用 Go module

go get github.com/smartwalle/alipay
import github.com/smartwalle/alipay

帮助

在集成的过程中有遇到问题,欢迎加 QQ 群 203357977 讨论。

其它支付

苹果支付 https://github.com/smartwalle/apple

PayPal https://github.com/smartwalle/paypal

银联支付 https://github.com/smartwalle/unionpay

关于各分支(版本)

  • v1 - 最老的版本,实现了完整的支付功能,目前已停止更新维护;
  • v2 - 在 v1 的基础上进行了一些优化和规范调整,目前已停止更新维护;
  • v3 - 支持公钥证书普通公钥进行签名验证,详情可以参考 https://docs.open.alipay.com/291/105974/https://docs.open.alipay.com/291/105971/,为目前主要维护分支;
  • master - 和主要维护分支同步;

推荐使用 v3 版本

v3 版本如何初始化

下面用到的 privateKey 需要特别注意一下,如果是通过“支付宝开发平台开发助手”创建的CSR文件,在 CSR 文件所在的目录下会生成相应的私钥文件,我们需要使用该私钥进行签名。

var client, err = alipay.New(appID, privateKey, isProduction)

关于应用私钥 (privateKey)

应用私钥是我们通过工具生成的私钥,调用支付宝接口的时候,我们需要使用该私钥对参数进行签名。

关于 alipay.New() 函数中的最后一个参数 isProduction

支付宝提供了用于开发时测试的 sandbox 环境,对接的时候需要注意相关的 app id 和密钥是 sandbox 环境还是 production 环境的。如果是 sandbox 环境,本参数应该传 false,否则为 true。

公钥证书模式

如果采用公钥证书方式进行验证签名,需要调用以下几个方法加载证书信息,所有证书都是从支付宝创建的应用处下载,参考 https://docs.open.alipay.com/291/105971/https://docs.open.alipay.com/291/105972/

client.LoadAppCertPublicKeyFromFile("/路径/appCertPublicKey_2017011104995404.crt") // 加载应用公钥证书
client.LoadAliPayRootCertFromFile("/路径/alipayRootCert.crt")                // 加载支付宝根证书
client.LoadAlipayCertPublicKeyFromFile("/路径/alipayCertPublicKey_RSA2.crt") // 加载支付宝公钥证书

普通公钥模式

需要注意此处用到的公钥是支付宝公钥,不是我们用工具生成的应用公钥。

如何查看支付宝公钥?

client.LoadAliPayPublicKey("aliPublicKey")

特别注意:公钥证书普通公钥不能同时存在,只能选择其中一种。

接口内容加密

详细内容访问 https://opendocs.alipay.com/common/02mse3 进行了解。

如果需要开启该功能,只需调用一下 SetEncryptKey() 方法。

client.SetEncryptKey("key")

如果不需要开启该功能,则不用调用该方法。

签名验证

内部已实现对支付宝返回的数据进行签名验证,详细信息请参考自行实现验签

需要自行对签名验证的场景有 同步回调(return_url)异步通知(notify_url) 的 HTTP 处理函数。

同步回调(return_url)

发起支付(网页支付)的时候,如果有提供 ReturnURL 参数,那么支付成功之后,支付宝会将浏览器重定向到该 URL,并附带上相关的参数。

var p = alipay.TradeWapPay{}
p.ReturnURL = "http://xxx/return"

对支付宝提供的参数进行签名验证:

http.HandleFunc("/return", func (writer http.ResponseWriter, request *http.Request) {
request.ParseForm()
if err := client.VerifySign(request.Form); err != nil {
// 如果 err 不为空,则表示验签失败
fmt.Println(err)
return
}
// 业务处理
}

异步通知(notify_url)

有支付或者其它动作发生后,支付宝服务器会调用我们提供的 NotifyURL,并向其传递相关的信息。参考手机网站支付结果异步通知

var p = alipay.TradeWapPay{}
p.NotifyURL = "http://xxx/return"

解析通知并验证签名:

http.HandleFunc("/notify", func (writer http.ResponseWriter, request *http.Request) {
request.ParseForm()

// DecodeNotification 内部已调用 VerifySign 方法验证签名
var noti, err = client.DecodeNotification(request.Form)
if err != nil {
// 错误处理
fmt.Println(err)
return
}
// 业务处理
// 如果通知消息没有问题,我们需要确认收到通知消息,不然支付宝后续会继续推送相同的消息
alipay.ACKNotification(writer)
})

支持 RSA2 签名及验证

采用 RSA2 签名,不再提供 RSA 的支持。

特别注意

提供给支付宝的 NotifyURL 和 ReturnURL 最好不要附带任何参数,支付宝在生成签名信息的时候不会包含 URL 中的参数,而 VerifySign() 方法在验证签名的时候会将收到的所有参数一起验证。

如果确实需要附带参数,可以在调用 VerifySign() 方法前,将附带的参数从 request.Form 中删除。

已实现接口

中线(-)后面的名称是该接口在 Client 结构体中对应的方法名。
  • 手机网站支付接口

    alipay.trade.wap.pay - TradeWapPay()

  • 电脑网站支付

    alipay.trade.page.pay - TradePagePay()

  • 统一收单线下交易查询

    alipay.trade.query - TradeQuery()

  • 统一收单交易支付接口

    alipay.trade.pay - TradePay()

  • 统一收单交易创建接口

    alipay.trade.create - TradeCreate()

  • 统一收单线下交易预创建

    alipay.trade.precreate - TradePreCreate()

  • 统一收单交易撤销接口

    alipay.trade.cancel - TradeCancel()

  • 统一收单交易关闭接口

    alipay.trade.close - TradeClose()

  • 统一收单交易退款接口

    alipay.trade.refund - TradeRefund()

  • App 支付接口

    alipay.trade.app.pay - TradeAppPay()

  • 统一收单交易退款查询

    alipay.trade.fastpay.refund.query - TradeFastpayRefundQuery()

  • 支付宝订单信息同步接口

    alipay.trade.orderinfo.sync - TradeOrderInfoSync()

  • 单笔转账到支付宝账户接口

    alipay.fund.trans.toaccount.transfer - FundTransToAccountTransfer()

  • 查询转账订单接口

    alipay.fund.trans.order.query - FundTransOrderQuery()

  • 资金授权发码接口

    alipay.fund.auth.order.voucher.create - FundAuthOrderVoucherCreate()

  • 资金授权操作查询接口

    alipay.fund.auth.operation.detail.query - FundAuthOperationDetailQuery()

  • 资金授权撤销接口

    alipay.fund.auth.operation.cancel - FundAuthOperationCancel()

  • 资金授权解冻接口

    alipay.fund.auth.order.unfreeze - FundAuthOrderUnfreeze()

  • 资金授权冻结接口

    alipay.fund.auth.order.freeze - FundAuthOrderFreeze()

  • 线上资金授权冻结接口

    alipay.fund.auth.order.app.freeze - FundAuthOrderAppFreeze()

  • 查询对账单下载地址

    alipay.data.dataservice.bill.downloadurl.query - BillDownloadURLQuery()

  • 支付宝商家账户当前余额查询

    alipay.data.bill.balance.query - BillBalanceQuery()

  • 身份认证初始化服务

    alipay.user.certify.open.initialize - UserCertifyOpenInitialize()

  • 身份认证开始认证

    alipay.user.certify.open.certify - UserCertifyOpenCertify()

  • 身份认证记录查询

    alipay.user.certify.open.query - UserCertifyOpenQuery()

  • 用户信息授权(网站支付宝登录快速接入)

    生成授权链接 - PublicAppAuthorize()

  • 换取授权访问令牌

    alipay.system.oauth.token - SystemOauthToken()

  • 支付宝会员授权信息查询

    alipay.user.info.share - UserInfoShare()

  • App支付宝登录

    com.alipay.account.auth - AccountAuth()

  • 支付宝个人协议页面签约

    alipay.user.agreement.page.sign - AgreementPageSign()

  • 支付宝个人代扣协议查询

    alipay.user.agreement.query - AgreementQuery()

  • 支付宝个人代扣协议解约

    alipay.user.agreement.unsign - AgreementUnsign()

  • 支单笔转账接口

    alipay.fund.trans.uni.transfer - FundTransUniTransfer()

  • 转账业务单据查询接口

    alipay.fund.trans.common.query - FundTransCommonQuery()

  • 支付宝资金账户资产查询接口

    alipay.fund.account.query - FundAccountQuery()

  • 小程序获取会员手机号数据解析

    my.getPhoneNumber - DecodePhoneNumber()

集成流程

支付宝开放平台申请创建相关的应用,使用自己的支付宝账号登录即可。

沙箱环境

支付宝开放平台为每一个应用提供了沙箱环境,供开发人员开发测试使用。

沙箱环境是独立的,每一个应用都会有一个商家账号和买家账号。

沙箱环境网关地址

沙箱环境目前有两个网关地址:

大家在对接的时候一定要确认清楚是新地址还是老地址。

本 SDK 目前默认使用的是 【新地址】,如果需要使用老地址,只需要在初始化的时候通过 alipay.WithPastSandboxGateway() 指定即可。

alipay.New(appId, privateKey, isProduction, alipay.WithPastSandboxGateway())

应用信息配置

参考官网文档 进行应用的配置。

本 SDK 中的签名方法默认为 RSA2,采用支付宝提供的 RSA签名&验签工具 生成秘钥时,秘钥长度推荐 2048。所以在支付宝管理后台请注意配置 RSA2(SHA256)密钥

生成秘钥对之后,将公钥提供给支付宝(通过支付宝后台上传)对我们请求的数据进行签名验证,我们的代码中将使用私钥对请求数据签名。

请参考 如何生成 RSA 密钥

创建 Wap 支付

var privateKey = "xxx" // 必须,上一步中使用 RSA签名验签工具 生成的私钥
var client, err = alipay.New(appId, privateKey, false)
if err != nil {
fmt.Println(err)
return
}

// 加载应用公钥证书
if err = client.LoadAppCertPublicKeyFromFile("appCertPublicKey_2017011104995404.crt"); err != nil {
// 错误处理
}

// 加载支付宝根证书
if err = client.LoadAliPayRootCertFromFile("alipayRootCert.crt"); err != nil {
// 错误处理
}

// 加载支付宝公钥证书
if err = client.LoadAlipayCertPublicKeyFromFile("alipayCertPublicKey_RSA2.crt"); err != nil {
// 错误处理
}

// 加载内容密钥,可选
if err = client.SetEncryptKey("FtVd5SgrsUzYQRAPBmejHQ=="); err != nil {
// 错误处理
}

var p = alipay.TradeWapPay{}
p.NotifyURL = "http://xxx"
p.ReturnURL = "http://xxx"
p.Subject = "标题"
p.OutTradeNo = "传递一个唯一单号"
p.TotalAmount = "10.00"
p.ProductCode = "QUICK_WAP_WAY"

var url, err = client.TradeWapPay(p)
if err != nil {
fmt.Println(err)
}

// 这个 payURL 即是用于打开支付宝支付页面的 URL,可将输出的内容复制,到浏览器中访问该 URL 即可打开支付页面。
var payURL = url.String()
fmt.Println(payURL)

自定义请求

对于本库还未实现接口,可使用 alipay.Payload 结构体作为参数调用 alipay.Client 结构体的 Request() 方法。

var p = alipay.NewPayload("这里是接口名称,如:alipay.trade.query")
// 添加公共请求参数,如:app_auth_token
p.AddParam("key", "value")
// 添加请求参数(业务相关)
p.AddBizField("key", "value")

// 应用场景一:需要向支付宝服务器发起网络请求,如交易查询接口(alipay.trade.query)
var result map[string]interface{}
// result 也可以为结构体,可参照 alipay.TradeQueryRsp
var err = client.Request(p, &result)
if err != nil {
...
}

// 应用场景二:只需要生成 URL,如网页支付(alipay.trade.page.pay)
var url, err = clietn.BuildURL(p)
...

// 应用场景三:只需要对参数进行签名,如 App 支付(alipay.trade.app.pay)
var s, err = client.EncodeParam(p)
...

更多信息

文件上传

使用 自定义请求 实现 alipay.open.file.upload(支付宝文件上传接口) 功能,需要注意本接口是小程序应用的功能,需要在小程序应用中开启 搜素直达 才能正常使用。

var p = alipay.NewPayload("alipay.open.file.upload")
p.Encrypt = false // 文件上传不支持接口内容加密

// 设置参数
p.AddParam("biz_code", "content_creation")

// 添加文件
p.AddFilePath("file_content", "a.jpg", "path/a.jpg")
// 或者
p.AddFileObject("file_content", "a.jpg", io.Reader)

var result map[string]interface{}
var err = client.Request(p, &result)

链路跟踪

// HTTP客户端
httpClient := &http.Client{
    Timeout: 30 * time.Second,
    Transport: otelhttp.NewTransport(
        http.DefaultTransport,
        otelhttp.WithSpanNameFormatter(func(operation string, r *http.Request) string {
            return r.Method + " " + r.URL.Path
        }),
    ),
}

// 初始化支付宝客户端
client, err := alipay.New(appId, privateKey, false, alipay.WithHTTPClient(httpClient))
if err != nil {
    fmt.Println(err)
}

示例

网页支付

感谢你的支持

如果对你有帮助,请我喝杯咖啡吧!

支付宝 微信

License

This project is licensed under the MIT License.

alipay's People

Contributors

0x457 avatar 1dustycy avatar 42thcoder avatar aaronjheng avatar barbery avatar clearluo avatar cyjaysong avatar danielyang990 avatar davidcr7 avatar dokiwa avatar horacepeng avatar iscod avatar larryclean avatar lessmost avatar lneoe avatar madon-php avatar majian159 avatar mingzaily avatar mrsong0607 avatar panjunjie avatar smartwalle avatar wanglelecc avatar wusphinx avatar x931890193 avatar yanyixin0612 avatar yveshield avatar yzprofile avatar zwh8800 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

alipay's Issues

手机app订单签名失败

执行client.TradeAppPay(p)后,失败信息为:
asn1: structure error: tags don't match (2 vs {class:0 tag:16 length:13 isCompound:true}) {optional:false explicit:false application:false defaultValue:\u003cnil\u003e tag:\u003cnil\u003e stringType:0 timeType:0 set:false omitEmpty:false} @5

已检查私钥公钥是ok的。 查看历史issue,之前也有人遇到了这个问题,可以确定是签名的问题,那位兄弟是更换go版本后解决了, 我使用go1.10版本, 跟踪了下代码,发现返回错误的地方如下:

func SignPKCS1v15(src, key []byte, hash crypto.Hash) ([]byte, error) {
	var h = hash.New()
	h.Write(src)
	var hashed = h.Sum(nil)

	var err error
	var block *pem.Block
	block, _ = pem.Decode(key)
	if block == nil {
		return nil, errors.New("private key error")
	}

	var pri *rsa.PrivateKey
	pri, err = x509.ParsePKCS1PrivateKey(block.Bytes)
	if err != nil {
		return nil, err
	}
       ... ...

具体出错的代码是: pri, err = x509.ParsePKCS1PrivateKey(block.Bytes), 该err为asn1: structure error: tags don't match。。。

补充:已跟踪到下面的代码问题, asn1.Unmarshal 失败了:

ParsePKCS1PrivateKey(der []byte) (*rsa.PrivateKey, error) {
	var priv pkcs1PrivateKey
	rest, err := asn1.Unmarshal(der, &priv)

我的环境信息:

go env

GOARCH="amd64"
GOBIN=""
GOCACHE="/Users/shiqinfeng/Library/Caches/go-build"
GOEXE=""
GOHOSTARCH="amd64"
GOHOSTOS="darwin"
GOOS="darwin"
GOPATH="/Users/shiqinfeng/Documents/go_workspace"
GORACE=""
GOROOT="/usr/local/go"
GOTMPDIR=""
GOTOOLDIR="/usr/local/go/pkg/tool/darwin_amd64"
GCCGO="gccgo"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/1p/c_0vpz0j47sb4cvvwppl04mw0000gn/T/go-build629607236=/tmp/go-build -gno-record-gcc-switches -fno-common"

go version

go version go1.10.2 darwin/amd64

crypto/rsa: verification error

Hi,

我现在遇到一个非常奇怪的问题。
单笔转账支付在本地测试都是ok的,但是一到线上服务器,同样的代码,参数,结果就返回 “crypto/rsa: verification error”, 请问有人遇到过同样的问题吗?

本地环境

request------------->>>{ 01234 ALIPAY_LOGONID [email protected] 0.10  xxx }
response------------->>>&{{10000 Success   01234 20180423110070001502150080693587 2018-04-23 09:35:38} LEEG+P+BbCqIFt4t7s0ik/RcsdNx1NFVXg1aiNQRmnfM/15KJGKqzkga/KYJSGfzJaRtp8yY8z/mBsTBGVb53F3jPEqOITPl985U0awS3KdXs5Q1LbAetLn+5HVjpvfvb17dyLrA2IedSJ1bbh5uL7kTDCnLU1OWZeT7yeZaDO0m6zDTNus7XG+C+m6ksx0iBlyGmN1cVN/yGXndWIRWkj09SqNBjklk2JZ/RF2bSmJbT3RAG2p/pcVC9IHZVv8BQzlKSatJdGavcay4+ZSK4hgs2DTk97QQsycffHa5ktSHNuD4wZ88d2Jb15rfyAMQoFuuKaoLGglIb4mguawNyg==}

线上执行结果:
(线上虽然报这个错误,但是转账实际上已经完成)

request------------->>>{ 01234 ALIPAY_LOGONID [email protected] 0.10  xxx }
2018-04-23 10:35:46.767 ERROR:28050:payment/transfer.go:21: response------------->>><nil>
2018-04-23 10:35:46.767 ERROR:28050:payment/transfer.go:23: crypto/rsa: verification error
2018-04-23 10:35:46.767 ERROR:28050:cmsd/p.go:49: crypto/rsa: verification error

验签失败,请指点下

请教下,我在使用的时候一直验签不过,报错信息如下:
crypto/rsa: verification error

采用的是RSA2加密方式
库是采用最新版本
调用接口为:alipay.trade.precreate (统一收单线下交易预创建)

返回的验签数据如下:
{"code":"10000","msg":"Success","sub_code":"","sub_msg":"","out_trade_no":"123456789","qr_code":"https://qr.alipay.com/bax06556bw4qmhfcofn500a4"}
sign
JJLTxJM0T636iTPriJ7pUFikznjFZvQIilNUQI80AkReb3rHVxFpZzxhvG99G3Ms8pt0ePSPBAVonDYOOPUkcfGh +sCmVAAfZWY/IRlUB/F6Jw3N1NU9GxTbiGS2Q2VVpurIaRq5T8HTorbuUTHbeRM6/aut7H5QuP5o1lOhBOW0nKRVP3dhb/Xx0HP2c2E+6Edxl3TByLvVbqP3fpmxP58GBUbkHSUcEb8ShUB7M/l4pKy3u5dti4zeW3SWBqScZiH2mQbectrUY1n3uPromohiQmIfocviBGxATPj4nMzuKoDtl2Fuvp4TUctxBJNg2Z s2B64I2e93GUywMfwqEQ==

支付宝公钥:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqnjvtwG/VsfPReiaOhHt
Hbfu93W2RrSAJ61Hgod4M2iT78mD9tS/Wn7n7CxOR6I95pI8OAih8wCbNpx7bvFj
q/KvjNeXCIqXwqUA6BtaT/ECDZLijtV9Xvtr8TMVm+FXr59HQw8urdFpC+lUx/ZW
bgWtyIFIhvxdUNjmuXHV34FzN5A94N2fk75E9UOH8XF3Q2jWmUF5tM/cznBzQ/B9
SP0+0AjnzKQgeF65lF7pi8CcBVlU3IOuJNAZHRAZBDVZxOEOoXKfCGiFN6njlzcC
gbjpuyMF4WnK9ihCMcr3Lntjg6TWtVtXQbh6RWu9b5Jz+zjYUKlafAYAvU5JE6Wi
FwIDAQAB
-----END PUBLIC KEY-----

alipay.trade.app.pay 接口RSA2 方式,sign 生成 是空字符串

此接口RSA2 方式,sign 生成 是空字符串,返回参数如下:

app_id=2015082000223895&biz_content={"body":"iPhone7 ","subject":"iPhone7 ","out_trade_no":"20170531220","timeout_express":"90m","total_amount":"1.00","seller_id":"1011007","product_code":"QUICK_MSECURITY_PAY"}&charset=utf-8&format=JSON&method=alipay.trade.app.pay&notify_url=https://domain.com/trade_notify&sign=&sign_type=RSA2&timestamp=2017-05-31 02:24:23&version=1.0

License

这个代码开源采用的什么协议?

golang rsa2解析 error

本 SDK 中的签名方法默认为 RSA2,采用支付宝提供的 RSA签名&验签工具 生成秘钥时,秘钥的格式必须为 PKCS1,秘钥长度推荐 2048。所以在支付宝管理后台请注意配置 RSA2(SHA256)密钥。

这里用支付宝的 pkcs1 2048 生成的应用私钥,使用 x509.ParsePKCS1PrivateKey 解析错误。

 asn1: structure error: tags don't match (16 vs {class:0 tag:13 length:45 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue:<nil> tag:<nil> stringType:0 timeType:0 set:false omitEmpty:false} pkcs1PrivateKey @2

请问官方文档上直接输出Response到HTML跟这个项目的区别是?

我看了下,这个项目使用的是按参数组合URL,
官方现在文档上是从服务端获取表单内容然后直接输出到商户页面里面,
这两者实现的区别是什么?
这项目的实现方式是否为支付宝接口1.0?
如果是按1.0的老版本接口实现的话,那么这个项目的兼容性是否在将来会有问题?

TradeAppPay报错

asn1: structure error: tags don't match (2 vs {class:0 tag:16 length:13 isCompound:true}) {optional:false explicit:false application:false defaultValue: tag: stringType:0 timeType:0 set:false omitEmpty:false} @5

能否接受极简式的封装

看了一些实现,有些地方还比较细,但代码封装过于冗余。能否接受极简式的封装。还有一个问题代码中太多var 式的写法与 不要使用this 这个关键字,如能接受极简封装我可以pr
我发几个重点修改点设计

type AliSign interface {
	Get_Signtype() string
	Sign(keys []string, param url.Values) (string, error)
	CanVerify() bool
	VerifyResponseData(data []byte, sign string) error
}

type RSA_sign struct {
	sig       *SignPKCS
	sign_type string
	hash      crypto.Hash
}

type SignPKCS struct {
	pri *rsa.PrivateKey
	pub *rsa.PublicKey
}
....
var (
	RSA  = &RSA_sign{sign_type: K_SIGN_TYPE_RSA, hash: crypto.SHA1}
	RSA2 = &RSA_sign{sign_type: K_SIGN_TYPE_RSA2, hash: crypto.SHA256}
)

授权转支付接口,缺少auth_no参数

文档中的

model.setAuthNo("2018041210002001660228733635"); // 填写预授权冻结交易号

AliPayTradePay这个struct中没有这个字段,刚开始误以为是AuthCode,后来把AuthCode的tag改为auth_no,接口才成功返回

AliPay.publicKey 在New的时候被赋值了但是未被使用

你好,首先感谢开发出这个SDK,很好用。

我在使用时发现,调用 alipay.New 时会传入 publicKey,但是 publicKey 变量仅仅做了赋值操作,在后续的代码中并没有被使用到,而是使用了 AliPay.AliPayPublicKey 字段作为验签的公钥。感觉这样使用起来并不是很直观,请问这么设计是有意为之还是bug呢?

谢谢

无法使,结果如下,求解。

1、TradeWapPay 返回一个url有何用?原支付宝SDK是返回一个body,再把body response回到浏览器内执行。
2、为何现行网站上ProductCode 是 QUICK_WAP_WAY 而不是当前这个SDK内的值?
3、调完后,返回的内容是

“原来浏览器版本低是硬伤!
建议使用UC、Chrome、IE10等高版本浏览器”

不解

"golang.org/x/crypto/pbkdf2"找不到此包

$ go get -u github.com/smartwalle/alipay
package golang.org/x/crypto/pbkdf2: unrecognized import path "golang.org/x/crypto/pbkdf2" (https fetch: Get https://golang.org/x/crypto/pbkdf2?go-get=1: dial tcp 216.239.37.1:443: connectex: A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond.)

一点建议

建议新开一个develop分支来开发功能

授权转支付接口未支持

授权转支付alipay.trade.pay,现在这个接口只返回order_str,咨询过蚂蚁技术了,需要调alipay.trade.pay发起请求

undefined: AliPayTradePagePay

go test trade.go

command-line-arguments

./trade.go:10: undefined: AliPay
./trade.go:10: undefined: AliPayTradePagePay
./trade.go:33: undefined: AliPay
./trade.go:33: undefined: AliPayTradeQueryResponse
./trade.go:33: undefined: AliPayTradeQuery
./trade.go:39: undefined: AliPay
./trade.go:39: undefined: AliPayTradeCloseResponse
./trade.go:39: undefined: AliPayTradeClose
./trade.go:45: undefined: AliPay
./trade.go:45: undefined: AliPayTradeRefundResponse
./trade.go:45: too many errors

获取网页URL不带参数

在配置应用时是:接口内容加密方式: AES密钥,你们有这个吗?用test的密钥生成的支付URL是带参的,可是我自己的密钥生成的没有带参,导致无法使用,怎么解决呢?

private key error

很荣幸能使用这个库,目前在开发中遇到一个。我在沙箱环境的配置如下:
这个是阿里云公钥:
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAscUcOO9OZUjknBCPE7X0VRs7957WWj0Gc
Zv2/guwyM1iB9mCopGMkUhBJTcXDbXB90gxWVr88grIu1tVSmWBLaB8RreFhyCcrFn49tKxjTB5awm1xp
bDG2OJqWBpmRYVR7BVP9N5KfVBjvswN/2uXmBkkzvv1fykBlfu2QhOT8HLBhLe4nCQTGZiUzi4/5SUG
R5UKZlWmYhGiNOGfMykyt8uX+m3P1DMIkkS5Jx8EKBnAap5/XP+2LeF2GmiZuhSZFgD/2NQZtmBIgOk
IzcmpQ8NgUMfSSytnS3TfK/xCjoATmwq2E7qA03Q8wE7Fi3+6kHevTqK30F/iv1/pdm+yQIDAQAB
-----END PUBLIC KEY-----

我的私钥:
MIIEowIBAAKCAQEAslgBTclEFZl7oLmILdpJhNAC1YKko13glLP1vVp84UpnB+q1d2pMHMiU4wqXFlU+rqrheYQh13MGmslxza5GrAvP7KOpRD8AiVj93777/rh14c7/cel+ByXkK2xMxcQaYi4bR9eLE6ac0KeOJnPuhQQjeRcdNsQUfwoBvc1+hJzUcP6WeikYUN/OBxnBTgPOiPCWx/kVJ1ZjqiXD3N2d2KALjtYVQQ7chObgsUdCNCh241Omdg1SDbJwcRjjRJSLoFqi3zh49Ms+xnCHPIReYdfUL9MqLEDMCWd3B7TrwJ/qE0cz4lyiQ1/JgQg2cKk2t/3B3HEcLSdoREJIpnWZ9wIDAQABAoIBAHasrSFv3oho+6U2EHJCoU1phZlCOAAlxf3tyoZYImVgNzNDccGm0EMPDlQOhf9sdiuQtj1AOay+dBSoG7x8TbbKnW+gcFBjhB3hQ/6RfepAIOFD9yN79ksXYb+rb2LiXZQbjje+LGPFKPCHrsXTu1J0MI6xXNVGoUTwCbydc6UWAXCkKAY7Bb4TxSKSCTeVmbHHqyw30f32GJOZTfKY1rB5rrgfP8S6UV6lpKLK+JoAyL9BzPmub0zPIEGDiJYiWsk4pJF5bGRldR+mfm9pXAYmSvJ0pYHezfT9Zrm0XaWJQZIDty06aszTEj2fbFHPdLvIIcvcPZNztjuYo3OHlUECgYEA6zdUSde7JVls9gyvlWvb26KNxWEOqzab0aAp/GlG2TuoaLOiE3yXGJNTwK5WWpjnnnMXy3hNGWnHowX9U3ZqmIMZRGX/yTe/BAeWSMlrr/+QFnRmWYZMy3YvzZYsPL1bNgBNTpPr4dM9Kelcpp5l74ORDpMfSPvhbuIKNJiUhzECgYEAwho0CLzB0qaGU145lz134cM3JlU6kIJJPKoWodLzqZc5XSGKTLfttYtSRm9yx+bOekGoBMRF8F7kidw3Vsi19ek2oLZal/cU4o6B95i/yTayqqBFlyoB821PtTxy9LdceKX7c0EeEFAGo8SaTcAvEdZX7xqasHpTkkiGoJwPuacCgYEAu9rbmYIPODwcdsIY9ThIRjikC3CBm6IofhnxjmKyL8qirMRSfEe0EO+RI0DZPNADpBt9dIZm5RYDWCLveFoJtjZ11pez2ouIJfq9PvKG6/AqrpRWLcfBy3lfokz+laARmaZSF6Cx8hCYN8HlujilZs3n6wD7KnnoSHuE9Q6rCPECgYB2AcBI35lnHF7mKI8S6AgOdcT9xStJ2Cv2eeIwmDQTkyEJAe83HUuj6AQpVnCOIEDAC1K/MyTiMo73Ua9DT9twmkzgAH2rjkhgRQu3IGLZTivpmG82rA9rk7W2Ff490YyivSbWt2wztrOStWCqjIERcyMa9y28xWIxuW5ADyFwWQKBgFpabJllRYx3M1j6x7Su8hvckACemC/MvtD6Hgnyo65RWB9pyRjn344ScYWIlfPu/UBlx6AFbT6WIwRIvTPeea1HnnNgxoQ9H188bb31A/uQWw08fiq8BQUZxTNWgmBco5VL3wNZLOHK02kbLeLSp6BIKVNi1OkvPQ2wYBb9Q/g6

应用公钥:
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAslgBTclEFZl7oLmILdpJhNAC1YKko13glLP1vVp84UpnB+q1d2pMHMiU4wqXFlU+rqrheYQh13MGmslxza5GrAvP7KOpRD8AiVj93777/rh14c7/cel+ByXkK2xMxcQaYi4bR9eLE6ac0KeOJnPuhQQjeRcdNsQUfwoBvc1+hJzUcP6WeikYUN/OBxnBTgPOiPCWx/kVJ1ZjqiXD3N2d2KALjtYVQQ7chObgsUdCNCh241Omdg1SDbJwcRjjRJSLoFqi3zh49Ms+xnCHPIReYdfUL9MqLEDMCWd3B7TrwJ/qE0cz4lyiQ1/JgQg2cKk2t/3B3HEcLSdoREJIpnWZ9wIDAQAB

image

image

开发中一直返回:
private key error
请问是我的配置文件哪里不对吗?谢谢!

签名时报错

执行x509.ParsePKCS1PrivateKey(block.Bytes)时报错
asn1: structure error: tags don't match (2 vs {class:0 tag:16 length:13 isCompound:true}) {optional:false explicit:false application:false private:false defaultValue: tag: stringType:0 timeType:0 set:false omitEmpty:false}

公钥和私钥如何处理?

比如用支付的生成工具生成了公钥 aaa 私钥 bbb
变成这样如字符串就行了吗?
-----BEGIN PUBLIC KEY-----
aaa
-----END PUBLIC KEY-----

私钥也是这样吗?

x509: trailing data after ASN.1 of public-key

go version

GOOS:  darwin macOS High Sierra 10.13.6 (17G7024)
GOVersion: go version go1.12 darwin/amd64

test code as following:

// Author: Turing Zhu
// Date: 2019-06-17 13:43
// File : main.go

package main

import (
	"crypto"
	"encoding/base64"
	"fmt"
	"github.com/smartwalle/alipay/encoding"
)

func main() {
	s := "app_id=2016093000630659&auth_app_id=2016093000630659&buyer_id=2088102178211755&buyer_logon_id=lpp***@sandbox.com&buyer_pay_amount=398.00&charset=utf-8&fund_bill_list=[{\"amount\":\"398.00\",\"fundChannel\":\"ALIPAYACCOUNT\"}]&gmt_create=2019-06-17 19:03:08&gmt_payment=2019-06-17 19:03:08&invoice_amount=398.00&notify_id=2019061700222190309011751000293349&notify_time=2019-06-17 19:03:09&notify_type=trade_status_sync&out_trade_no=Rent20190617190239201906171902396218&point_amount=0.00&receipt_amount=398.00&[email protected]&seller_id=2088102177935681&subject=充值&total_amount=398.00&trade_no=2019061722001411751000039062&trade_status=TRADE_SUCCESS&version=1.0"
	data := []byte(s)
	sign := "QaaRXf6owI8G7haQrJI2E6oR+R8SOMb9VxS27LFdpy04/lZA3YSvobGluQPGF/p3uIGXrW/iRPZYR+FXVSUFNUhddG1VDemUgmZvfpxEQ1zjzYyQOOpXXZC7Di8riUEu+7dtYk2RgbGywNopVnceo5gPRRHtudfc+jI9B/jxH6iWenqE2eXWCbfNR53qGxgfkXYc+SkpnICReoSHZ86v+WqBAU2jXucdgBJmcopzlHQ5Vj63MFXPCIVJECp4s5ay2F2Bg/GWfoMEJMrcxU/PZAEKt/PsAd31v+ImxXpoNIC7m2MtdcLjhMQgcVvqNKMafVWopsXyK91ffSSIso7BPw=="
	signType := "RSA"
	publicKey := "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAtVFboC7U6EH8Jp+Nk8O7ZUQa9D7gdKDCkX0y/kYu9UBwdD1OMF9E8AD//U9mQmYunrPjys1gX40sqa5nyqp/PcPVxFRYT4sRTDGY328vPqO0t1hKeGzSxDRbzhsxaltLcK55kFIAs7PrFwCIxnLkzg6wpMrobgMFSw4MsrCFvNTF9chOAcR6eeZlWCtxBJBU7WrRoJByRlo8vVcRCGpGqDh7ulb8OKq4fZ8eSAXqnnxuZcWChI40VuEsswvmaPpTi0CpLdpmW72n6EBuYryztifKgNIWJCLBtnJdekLlOThpi7GPAOr8EjZG6v6Thz7jpwk32QHLTRuqeYZ++Pny3wIDAQABMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwiNFPnamdp5PBgC02xDgk/ZwGPTbaqXQNSaQbrsi9uK/g5XVHlTbFV3uN+5OA1Ib7iK5uIC5cbIUjLqFXmTcDdRavaovmhwEL8QSOEQJXwWtNte/I1dFCdwxqJhiBiHqn55JldwAExq/4H5ecbHRXZIcPyxG/e0zp085uIleFv3F6RR6ZLyqEsHTcvU3YsTbnUF/cxLxAP1FO35lJmYaLRZg48NhMUab/VMVOzyROFDFdWlnrrinIxHKfiJ3xNkeeLjcyDDz8UYw9FZaxXrdum0ZwmClPzKuvfvFJ36ymxCQE78CPp+xP5Ieyn1iwMrvxgOXCL7w0/vtzvFfo03w2QIDAQAB"
	ok, err := verifyData(data, signType, sign, []byte(encoding.FormatPublicKey(publicKey)))
	fmt.Printf("ok=%v, err=%s\n", ok, err)
}


func verifyData(data []byte, signType, sign string, key []byte) (ok bool, err error) {
	signBytes, err := base64.StdEncoding.DecodeString(sign)
	if err != nil {
		return false, err
	}


	err = encoding.VerifyPKCS1v15(data, signBytes, key, crypto.SHA256)
	if err != nil {
		return false, err
	}
	return true, nil
}

output

ok=false, err=x509: trailing data after ASN.1 of public-key

报错,你的签名方法是不是不兼容了?

秘钥和公钥都是正确的,报下面错误

asn1: structure error: tags don't match (2 vs {class:0 tag:16 length:13 isCompound:true}) {optional:false explicit:false application:false defaultValue: tag: stringType:0 timeType:0 set:false omitEmpty:false} @5

TradePagePay返回url不能访问

rand.String() undefined

麻烦修改一下ali_sms.go里用到的这个方法,好像你引用的goroom的rand.String变成了rand.GetRand().String(),

生成的url不带任何参数

`package tools

import (
"baby/controllers"
"github.com/smartwalle/alipay"
"github.com/astaxie/beego"
)

var (
appID = ""
partnerID = "
**" //老版接口用

//RSA2签名 标准密钥格式除了首行和尾行外,每行64个字符
//这个是支付宝公钥

aliPublicKey = []byte(`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA+sfnysdoyMKAL/YUjWNa
   ....................
5Sw0RRDqARDnxBxijdhDn/iBLboSkS3veNMLmm0gGa8dSubkdnvW4gEOLG/LM8Zy
BQIDAQAB
-----END PUBLIC KEY-----`)

//
publicKey = []byte(`-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAuyQ76zze1Abvvz7EL/pe
   ..................
SLKjRxEvNxqA5XQDpqO3JQKzzihaKd5CnD81e5erkMVAG51bNCeScw3jb3SJigU0
sQIDAQAB
-----END PUBLIC KEY-----`)

//RSA2签名 标准密钥格式除了首行和尾行外,每行64个字符
//这个是自己的私钥
privateKey = []byte(`-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEAuyQ76zze1Abvvz7EL/peT3mMe8QlQO3ViqaMhpRVWO2vseI0
w3dP3F1Koqq9sdQas5kViontQ3FJeTqpcD5PtA/A6zVb+LYEj8/dzV09T+944ebt
    *************
EYr3L550lFWavk6KWh8f+BV+jq+aCh7jwPRspHuugTngjfTpAgYR
-----END RSA PRIVATE KEY-----
`)

)

type AlipayController struct {
controllers.BaseController
}

var client = alipay.New(appID, partnerID, publicKey, privateKey, false)

func init() {
client.AliPayPublicKey = aliPublicKey
}

// @router /api/alipay/test
func (this *AlipayController) TestAlipayOrder() {
var p = alipay.AliPayTradePagePay{}
p.NotifyURL = "http://www.baituolebaby.com/alipay"
p.ReturnURL = "http://www.baituolebaby.com/alipayCallback"
p.Subject = "修正了中文的 Bug"
p.OutTradeNo = "trade_no_20170623011"
p.TotalAmount = "10.00"
p.ProductCode = "FAST_INSTANT_TRADE_PAY"
var url, e = client.TradePagePay(p)
beego.Error(url.String())
this.ReturnSuccess("e", e)
}
`

我得到的url永远都只是https://openapi.alipaydev.com/gateway.do 而且无论我的私钥,公钥怎么乱填,
那个 代表错误的e永远都是nil

public key error

在收到回调通知验签的过程中,VerifyPKCS1v15报”public key error“。我的ALIPAY_PUBLIC = 支付宝沙盒配置那里的“查看支付宝公钥”,是否还需要对这个公钥进行转换么?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.