Go语言之对接支付宝当面付程序示例
本帖最后由 PAOLO 于 2023-4-14 14:05 编辑package main
import (
"fmt"
"net/http"
"net/url"
"strconv"
"time"
)
func main() {
// 支付宝应用ID
appId := ""
// 商户私钥
privateKey := ""
// 支付宝公钥
publicKey := ""
// 支付金额,单位为元
amount := 0.01
// 订单号
orderId := "1234567890"
// 商品简称
subject := "测试商品"
// 构造请求参数
values := url.Values{}
values.Set("app_id", appId)
values.Set("method", "alipay.trade.precreate")
values.Set("format", "JSON")
values.Set("charset", "utf-8")
values.Set("sign_type", "RSA2")
values.Set("timestamp", time.Now().Format("2006-01-02 15:04:05"))
values.Set("version", "1.0")
bizContent := fmt.Sprintf(`{"out_trade_no":"%s","total_amount":"%.2f","subject":"%s"}`, orderId, amount, subject)
values.Set("biz_content", bizContent)
// 计算签名
sign := calculateSign(values, privateKey)
// 添加签名
values.Set("sign", sign)
// 发送请求
resp, err := http.PostForm("https://openapi.alipay.com/gateway.do", values)
if err != nil {
fmt.Println("Error:", err)
return
}
// 解析响应
qrCodeUrl, err := parseResponse(resp, publicKey)
if err != nil {
fmt.Println("Error:", err)
return
}
// 打印二维码 URL
fmt.Println(qrCodeUrl)
}
// 计算签名
func calculateSign(values url.Values, privateKey string) string {
signStr := getSignString(values)
sign, err := signWithRSA2(signStr, privateKey)
if err != nil {
fmt.Println("Error:", err)
return ""
}
return sign
}
// 解析响应
func parseResponse(resp *http.Response, publicKey string) (string, error) {
var respMap mapinterface{}
err := parseJsonResp(resp, &respMap)
if err != nil {
return "", err
}
if respMap["alipay_trade_precreate_response"] == nil {
return "", fmt.Errorf("Invalid response: %v", respMap)
}
if respMap["alipay_trade_precreate_response"].(mapinterface{})["code"].(string) != "10000" {
return "", fmt.Errorf("%s: %s", respMap["alipay_trade_precreate_response"].(mapinterface{})["sub_msg"].(string),
respMap["alipay_trade_precreate_response"].(mapinterface{})["msg"].(string))
}
qrCodeUrl := respMap["alipay_trade_precreate_response"].(mapinterface{})["qr_code"].(string)
isSuccess, err := verifyRespSign(respMap["alipay_trade_precreate_response"].(mapinterface{}), publicKey)
if !isSuccess {
return "", err
}
return qrCodeUrl, nil
}
// 构造待签名字符串
func getSignString(values url.Values) string {
keys := make([]string, 0, len(values))
for k := range values {
if k == "sign" || k == "sign_type" {
continue
}
keys = append(keys, k)
}
sortedKeys := sortKeys(keys)
var signStr string
for i, k := range sortedKeys {
if i == 0 {
signStr = k + "=" + values.Get(k)
} else {
signStr += "&" + k + "=" + values.Get(k)
}
}
return signStr
}
// 对参数进行字典序排序
func sortKeys(keys []string) []string {
sorted := make([]string, len(keys))
copy(sorted, keys)
for i := 0; i < len(sorted)-1; i++ {
for j := i + 1; j > 0; j-- {
if sorted > sorted {
sorted, sorted = sorted, sorted
} else {
break
}
}
}
return sorted
}
// 使用RSA2算法签名
func signWithRSA2(signStr string, privateKey string) (string, error) {
signer, err := NewSigner(privateKey)
if err != nil {
return "", err
}
return signer.Sign(signStr)
}
// 验证响应签名
func verifyRespSign(respMap mapinterface{}, publicKey string) (bool, error) {
sign := respMap["sign"].(string)
signType := respMap["sign_type"].(string)
delete(respMap, "sign")
delete(respMap, "sign_type")
signStr := getSignStringFromMap(respMap)
verifier := NewVerifier(publicKey, signType)
return verifier.Verify(signStr, sign)
}
// 获取待签名字符串
func getSignStringFromMap(m mapinterface{}) string {
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
sortedKeys := sortKeys(keys)
signStr := ""
for i, k := range sortedKeys {
if i == 0 {
signStr = k + "=" + fmt.Sprintf("%v", m)
} else {
signStr += "&" + k + "=" + fmt.Sprintf("%v", m)
}
}
return signStr
}
此程序使用阿里云网关方式访问支付宝 API,生成当面付二维码。在代码中,需要提供以下几个变量的值:
[*]appId:应用ID,即支付宝开放平台用户中心的应用ID。
[*]privateKey:商户的私钥,用于生成签名。
[*]publicKey:支付宝的公钥,用于验证支付宝 API 返回的签名。
[*]amount:支付金额,单位为元。
[*]orderId:商户系统中的订单号。
[*]subject:商品简称。
程序首先将请求参数构造为 url.Values 对象,然后计算签名并添加到参数中。随后发送POST请求到支付宝API,获取响应并解析其中的二维码URL。最后,将二维码URL打印到控制台上,以便进行扫码支付。
注意:在运行程序前,请根据自己的应用和配置信息更新代码中的变量值。 非常感谢,谢谢楼主{:1_893:} 这是查询支付宝的收款信息再打算播报吗?
0.6用不起{:1_907:} rxxcy 发表于 2023-4-14 20:53
0.6用不起
可以申请减免的,好多渠道可以比银行收单低 1107934496 发表于 2023-4-18 08:56
可以申请减免的,好多渠道可以比银行收单低
请问怎么减免呢? gtsing 发表于 2023-11-14 22:11
请问怎么减免呢?
现在问我有些晚了,已经离职了。
支付宝内对商家有很多优惠,比如线下商家签约当面付后,让bd给提资料可以降到1.5
页:
[1]