Sfoglia il codice sorgente

add Reverse: for v1.0.0

tags/v1.0.0
Hjj 2 anni fa
parent
commit
12db19b864
14 ha cambiato i file con 469 aggiunte e 55 eliminazioni
  1. +50
    -0
      db/db_sys_cfg.go
  2. +7
    -0
      db/model/sys_cfg.go
  3. +7
    -0
      go.mod
  4. +256
    -0
      lib/local_alipay/api.go
  5. +17
    -0
      md/alipay.go
  6. +19
    -0
      md/app_redis_key.go
  7. +9
    -0
      md/platform.go
  8. +0
    -1
      pay/init.go
  9. +0
    -22
      pay/pay.go
  10. +43
    -0
      pay/pay_by_own.go
  11. +45
    -0
      pay/pay_config.go
  12. +16
    -4
      pay/pay_test.go
  13. +0
    -10
      stringutil/reverse.go
  14. +0
    -18
      stringutil/reverse_test.go

+ 50
- 0
db/db_sys_cfg.go Vedi File

@@ -0,0 +1,50 @@
package db

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/db/model"
"code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/md"
cache "code.fnuoos.com/go_rely_warehouse/zyos_go_tools.git/utils/cache"
"fmt"
"xorm.io/xorm"
)

// 获取一条记录
func SysCfgGetOne(Db *xorm.Engine, key string) (*model.SysCfg, error) {
var cfgList model.SysCfg
if has, err := Db.Where("`key`=?", key).Get(&cfgList); err != nil || has == false {
return nil, err
}
return &cfgList, nil
}

//单条记录获取DB
func SysCfgGetWithDb(eg *xorm.Engine, masterId string, HKey string) string {
cacheKey := fmt.Sprintf(md.AppCfgCacheKey, masterId, HKey[0:1])
get, err := cache.HGetString(cacheKey, HKey)
if err != nil || get == "" {
cfg, err := SysCfgGetOne(eg, HKey)
if err != nil || cfg == nil {
return ""
}

// key是否存在
cacheKeyExist := false
if cache.Exists(cacheKey) {
cacheKeyExist = true
}

// 设置缓存
_, err = cache.HSet(cacheKey, HKey, cfg.Val)
if err != nil {
return ""
}
if !cacheKeyExist { // 如果是首次设置 设置过期时间
_, err := cache.Expire(cacheKey, md.CfgCacheTime)
if err != nil {
return ""
}
}
return cfg.Val
}
return get
}

+ 7
- 0
db/model/sys_cfg.go Vedi File

@@ -0,0 +1,7 @@
package model

type SysCfg struct {
Key string `json:"key" xorm:"not null pk comment('键') VARCHAR(127)"`
Val string `json:"val" xorm:"comment('值') TEXT"`
Memo string `json:"memo" xorm:"not null default '' comment('备注') VARCHAR(255)"`
}

+ 7
- 0
go.mod Vedi File

@@ -3,7 +3,14 @@ module code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git
go 1.16

require (
code.fnuoos.com/go_rely_warehouse/zyos_go_tools.git v1.0.3 // indirect
github.com/go-pay/gopay v1.5.78
github.com/go-redis/redis v6.15.9+incompatible
github.com/go-sql-driver/mysql v1.6.0
github.com/gomodule/redigo/redis v0.0.1
github.com/iGoogle-ink/gopay v1.5.36
go.uber.org/zap v1.13.0
gopkg.in/natefinch/lumberjack.v2 v2.0.0
xorm.io/builder v0.3.10 // indirect
xorm.io/xorm v1.3.0
)

+ 256
- 0
lib/local_alipay/api.go Vedi File

@@ -0,0 +1,256 @@
package local_alipay

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/md"
"code.fnuoos.com/go_rely_warehouse/zyos_go_tools.git/utils/logx"
"fmt"
"github.com/iGoogle-ink/gopay"
"github.com/iGoogle-ink/gopay/alipay"
)

// TradeAppPay is 支付宝APP支付
// 抖音头条小程序使用APP调起
func TradeAppPay(appID, priKey, subject, orderID, amount, notiURL, RSA, PKCS string, paySet *md.PayData) (string, error) {
//初始化支付宝客户端
// appID 是在支付宝申请的APPID
// priKey 是支付宝私钥
// subject 是支付订单的主题
// orderID 是智莺这边生成的订单id
// amount 是付费金额
// notiURL 通知地址url
// passback_params 回调通知参数

client := alipay.NewClient(appID, priKey, true)
client.DebugSwitch = gopay.DebugOn
//判断密钥的类型
rsa_type := alipay.RSA2
pkcs_type := alipay.PKCS1
if RSA == "1" {
rsa_type = alipay.RSA
}
if PKCS == "1" {
pkcs_type = alipay.PKCS8
}
if paySet.PayAliUseType == "1" {
rsa_type = alipay.RSA2
pkcs_type = alipay.PKCS8
}
//配置公共参数
client.SetCharset("utf-8").
SetSignType(rsa_type).
SetPrivateKeyType(pkcs_type)
if notiURL != "" {
client.SetNotifyUrl(notiURL)
}
//新支付宝支付
if paySet.PayAliUseType == "1" {
appCertSN, err := alipay.GetCertSN(paySet.WxAppletFilepathUrl + "/" + paySet.PayAppCertSn)
fmt.Println("-应用-")
fmt.Println(appCertSN)
if err != nil {
fmt.Println(err)
return "", err
}
if appCertSN == "" {
fmt.Println(err)
return "", err
}
client.SetAppCertSN(appCertSN)
//aliPayRootCertSN, err := local_alipay.GetCertSN(cfg.WxappletFilepath.URL + "/" + paySet.PayAlipayRootCertSn)
aliPayRootCertSN := "687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6"
client.SetAliPayRootCertSN(aliPayRootCertSN)
aliPayPublicCertSN, err := alipay.GetCertSN(paySet.WxAppletFilepathUrl + "/" + paySet.PayAlipayrsaPublicKey)
fmt.Println("-公钥-")
fmt.Println(aliPayPublicCertSN)

if err != nil {
fmt.Println(err)
return "", err
}
if aliPayPublicCertSN == "" {
fmt.Println(err)
return "", err
}
client.SetAliPayPublicCertSN(aliPayPublicCertSN)
}
fmt.Println(client)
//请求参数
body := make(gopay.BodyMap)
body.Set("subject", subject)
body.Set("body", subject)
body.Set("out_trade_no", orderID)
body.Set("total_amount", amount)
body.Set("timeout_express", "30m")

// body.Set("passback_params", orderID)
//手机APP支付参数请求
payParam, err := client.TradeAppPay(body)
if err != nil {
return "", logx.Warn(err)
}
return payParam, nil
}

// TradeAppPay is 支付宝H5支付
func TradeWapPay(appID, priKey, subject, orderID, amount, notiURL, RSA, PKCS, page_url string, paySet *md.PayData) (string, error) {
//aliPayPublicKey := "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1wn1sU/8Q0rYLlZ6sq3enrPZw2ptp6FecHR2bBFLjJ+sKzepROd0bKddgj+Mr1ffr3Ej78mLdWV8IzLfpXUi945DkrQcOUWLY0MHhYVG2jSs/qzFfpzmtut2Cl2TozYpE84zom9ei06u2AXLMBkU6VpznZl+R4qIgnUfByt3Ix5b3h4Cl6gzXMAB1hJrrrCkq+WvWb3Fy0vmk/DUbJEz8i8mQPff2gsHBE1nMPvHVAMw1GMk9ImB4PxucVek4ZbUzVqxZXphaAgUXFK2FSFU+Q+q1SPvHbUsjtIyL+cLA6H/6ybFF9Ffp27Y14AHPw29+243/SpMisbGcj2KD+evBwIDAQAB"
privateKey := priKey
//判断密钥的类型
rsa_type := alipay.RSA2
pkcs_type := alipay.PKCS1
if RSA == "1" {
rsa_type = alipay.RSA
}
if PKCS == "1" {
pkcs_type = alipay.PKCS8
}
if paySet.PayAliUseType == "1" {
rsa_type = alipay.RSA2
pkcs_type = alipay.PKCS8
}
//初始化支付宝客户端
// appId:应用ID
// privateKey:应用秘钥
// isProd:是否是正式环境
client := alipay.NewClient(appID, privateKey, true)
//配置公共参数
client.SetCharset("utf-8").
SetSignType(rsa_type).
SetPrivateKeyType(pkcs_type).
SetReturnUrl(page_url).
SetNotifyUrl(notiURL)
//新支付宝支付
if paySet.PayAliUseType == "1" {
appCertSN, err := alipay.GetCertSN(paySet.WxAppletFilepathUrl + "/" + paySet.PayAppCertSn)
if err != nil {
fmt.Println(err)
return "", err
}
if appCertSN == "" {
fmt.Println(err)
return "", err
}
client.SetAppCertSN(appCertSN)
//aliPayRootCertSN, err := local_alipay.GetCertSN(paySet.WxAppletFilepathUrl + "/" + paySet.PayAlipayRootCertSn)
//if err != nil {
// fmt.Println(err)
// return "", err
//}
//if aliPayRootCertSN == "" {
// fmt.Println(err)
// return "", err
//}
aliPayRootCertSN := "687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6"
client.SetAliPayRootCertSN(aliPayRootCertSN)
aliPayPublicCertSN, err := alipay.GetCertSN(paySet.WxAppletFilepathUrl + "/" + paySet.PayAlipayrsaPublicKey)
if err != nil {
fmt.Println(err)
return "", err
}
if aliPayPublicCertSN == "" {
fmt.Println(err)
return "", err
}
client.SetAliPayPublicCertSN(aliPayPublicCertSN)
}
//请求参数
body := make(gopay.BodyMap)
body.Set("subject", subject)
body.Set("out_trade_no", orderID)
// quit_url is 用户付款中途退出返回商户网站的地址
body.Set("quit_url", notiURL)
body.Set("total_amount", amount)
// product_code is 销售产品码,商家和支付宝签约的产品码
body.Set("product_code", "QUICK_WAP_WAY")
//手机网站支付请求
payUrl, err := client.TradeWapPay(body)
if err != nil {
return "", logx.Warn(err)

}
return payUrl, nil
}

// TradeAppPay is 支付宝小程序本身支付
func TradeCreate(appID, priKey, subject, orderID, amount, notiURL, RSA, PKCS string, paySet *md.PayData) (*alipay.TradeCreateResponse, error) {
//aliPayPublicKey := "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA1wn1sU/8Q0rYLlZ6sq3enrPZw2ptp6FecHR2bBFLjJ+sKzepROd0bKddgj+Mr1ffr3Ej78mLdWV8IzLfpXUi945DkrQcOUWLY0MHhYVG2jSs/qzFfpzmtut2Cl2TozYpE84zom9ei06u2AXLMBkU6VpznZl+R4qIgnUfByt3Ix5b3h4Cl6gzXMAB1hJrrrCkq+WvWb3Fy0vmk/DUbJEz8i8mQPff2gsHBE1nMPvHVAMw1GMk9ImB4PxucVek4ZbUzVqxZXphaAgUXFK2FSFU+Q+q1SPvHbUsjtIyL+cLA6H/6ybFF9Ffp27Y14AHPw29+243/SpMisbGcj2KD+evBwIDAQAB"
privateKey := priKey
rsa_type := alipay.RSA2
pkcs_type := alipay.PKCS1
if RSA == "1" {
rsa_type = alipay.RSA
}
if PKCS == "1" {
pkcs_type = alipay.PKCS8
}
if paySet.PayAliUseType == "1" {
rsa_type = alipay.RSA2
pkcs_type = alipay.PKCS8
}
//初始化支付宝客户端
// appId:应用ID
// privateKey:应用私钥,支持PKCS1和PKCS8
// isProd:是否是正式环境
client := alipay.NewClient(appID, privateKey, true)
//配置公共参数
client.SetCharset("utf-8").
SetSignType(rsa_type).
SetPrivateKeyType(pkcs_type).
SetNotifyUrl(notiURL)
if paySet.PayAliUseType == "1" {
appCertSN, err := alipay.GetCertSN(paySet.WxAppletFilepathUrl + "/" + paySet.PayAppCertSn)
if err != nil {
fmt.Println(err)
return nil, err
}
if appCertSN == "" {
fmt.Println(err)
return nil, err
}
client.SetAppCertSN(appCertSN)
//aliPayRootCertSN, err := local_alipay.GetCertSN(paySet.WxAppletFilepathUrl + "/" + paySet.PayAlipayRootCertSn)
//if err != nil {
// fmt.Println(err)
// return nil, err
//}
//if aliPayRootCertSN == "" {
// fmt.Println(err)
// return nil, err
//}
aliPayRootCertSN := "687b59193f3f462dd5336e5abf83c5d8_02941eef3187dddf3d3b83462e1dfcf6"
client.SetAliPayRootCertSN(aliPayRootCertSN)
aliPayPublicCertSN, err := alipay.GetCertSN(paySet.WxAppletFilepathUrl + "/" + paySet.PayAlipayrsaPublicKey)
if err != nil {
fmt.Println(err)
return nil, err
}
if aliPayPublicCertSN == "" {
fmt.Println(err)
return nil, err
}
client.SetAliPayPublicCertSN(aliPayPublicCertSN)
}
//请求参数
body := make(gopay.BodyMap)
body.Set("subject", subject)
// 支付宝小程序支付时 buyer_id 为必传参数,需要提前获取,获取方法如下两种
// 1、local_alipay.SystemOauthToken() 返回取值:rsp.SystemOauthTokenResponse.UserId
// 2、client.SystemOauthToken() 返回取值:aliRsp.SystemOauthTokenResponse.UserId
buyer_id, err := client.SystemOauthToken(body)
if err != nil {
return nil, logx.Warn(err)
}
body.Set("buyer_id", buyer_id)
body.Set("out_trade_no", orderID)
body.Set("total_amount", amount)
//创建订单
aliRsp, err := client.TradeCreate(body)

if err != nil {
return nil, logx.Warn(err)
}
logx.Warn("aliRsp:", *aliRsp)
logx.Warn("aliRsp.TradeNo:", aliRsp.Response.TradeNo)
return aliRsp, nil

}

+ 17
- 0
md/alipay.go Vedi File

@@ -0,0 +1,17 @@
package md

type AliPayPayParams struct {
Subject string `json:"subject" binding:"required"`
Amount string `json:"amount" binding:"required"`
OrderType string `json:"order_type" binding:"required"`
OrdId string `json:"ord_id"`
}

type PayData struct {
PayAppCertSn string `json:"pay_app_cert_sn"`
PayAlipayRootCertSn string `json:"pay_alipay_root_cert_sn"`
PayAlipayrsaPublicKey string `json:"pay_alipayrsa_public_key"`
PayAliUseType string `json:"pay_ali_use_type"`
PriKey string `json:"pay_ali_new_private_key"`
WxAppletFilepathUrl string `json:"wx_applet_filepath_url"`
}

+ 19
- 0
md/app_redis_key.go Vedi File

@@ -0,0 +1,19 @@
package md

// 缓存key统一管理, %s格式化为masterId
const (
AppCfgCacheKey = "%s:cfg_cache:%s" // 占位符: masterId, key的第一个字母
VirtualCoinCfgCacheKey = "%s:virtual_coin_cfg"
PlanRewardCfgCacheKey = "%s:plan_reward_cfg"
UnionSetCacheCfg = "%s:union_set_cfg:%s" // 联盟设置缓存key

UserFinValidUpdateLock = "%s:user_fin_valid_update_lock:%s" // 用户余额更新锁(能拿到锁才能更新余额)

WithdrawApplyQueueListKey = "withdraw_apply_queue" // 提现队列

TplBottomNavRedisKey = "%s:tpl_nav_bottom_key:%s" // master_id platform

SysModByIdRedisKey = "%s:sys_mod_tpl_by_id:%s"

CfgCacheTime = 86400
)

+ 9
- 0
md/platform.go Vedi File

@@ -0,0 +1,9 @@
package md

const (
/*********** DEVICE ***********/
PLATFORM_ALIPAY_APPLET = "alipay_applet"
PLATFORM_WAP = "wap" //h5
PLATFORM_ANDROID = "android"
PLATFORM_IOS = "ios"
)

+ 0
- 1
pay/init.go Vedi File

@@ -26,7 +26,6 @@ func Init(host, name, user, psw string) error {
cfg.MaxLifetime = 30
cfg.MaxOpenConns = 100
cfg.MaxIdleConns = 100
cfg.Path = "tmp/%s.log"
if err := db.InitDB(&cfg); err != nil {
return err
}


+ 0
- 22
pay/pay.go Vedi File

@@ -1,22 +0,0 @@
package pay

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/db"
"code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/db/model"
"errors"
)

func JudgePayChannel(mid, paySceneIdentifier string) (model.PayChannelMaster, error) {
var payChannelMaster = model.PayChannelMaster{}
res, err := db.Db.Where("app_id = ?", mid).And("identifier = ?", paySceneIdentifier).Get(&payChannelMaster)
if err != nil {
return payChannelMaster, err
}
if !res {
return payChannelMaster, errors.New("查询数据失败")
}
if payChannelMaster.ChannelId == 0 {
return payChannelMaster, errors.New("请联系服务商绑定支付渠道")
}
return payChannelMaster, nil
}

+ 43
- 0
pay/pay_by_own.go Vedi File

@@ -0,0 +1,43 @@
package pay

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/lib/local_alipay"
"code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/md"
"code.fnuoos.com/go_rely_warehouse/zyos_go_tools.git/e"
"code.fnuoos.com/go_rely_warehouse/zyos_go_tools.git/utils"
"fmt"
)

//自有支付 支付宝
func Alipay(args map[string]string) (string, error) {
var paySet = &md.PayData{
PayAppCertSn: args["pay_app_cert_sn"],
PayAlipayRootCertSn: args["pay_alipay_root_cert_sn"],
PayAlipayrsaPublicKey: args["pay_alipayrsa_public_key"],
PayAliUseType: args["pay_ali_use_type"],
WxAppletFilepathUrl: args["wx_applet_filepath_url"],
}
if args["private_key"] == "" || args["app_id"] == "" {
return "", e.NewErr(400, "请在后台正确配置支付宝")
}
var param interface{}
var err error
switch args["platform"] {
case md.PLATFORM_ALIPAY_APPLET:
param, err = local_alipay.TradeCreate(args["app_id"], args["private_key"], args["subject"], args["ord_id"], args["amount"], args["notify_url"], args["rsa"], args["pkcs"], paySet)
case md.PLATFORM_WAP:
param, err = local_alipay.TradeWapPay(args["app_id"], args["private_key"], args["subject"], args["ord_id"], args["amount"], args["notify_url"], args["rsa"], args["pkcs"], args["page_url"], paySet)
case md.PLATFORM_ANDROID, md.PLATFORM_IOS:
param, err = local_alipay.TradeAppPay(args["app_id"], args["private_key"], args["subject"], args["ord_id"], args["amount"], args["notify_url"], args["rsa"], args["pkcs"], paySet)
default:
return "", e.NewErr(400, "支付平台不存在")
}
if err != nil {
fmt.Println("支付宝错误日志")
fmt.Println(param)
fmt.Println(err)
return "", e.NewErr(400, "支付宝订单创建失败")
}
return utils.AnyToString(param), nil

}

+ 45
- 0
pay/pay_config.go Vedi File

@@ -0,0 +1,45 @@
package pay

import (
"code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/db"
"code.fnuoos.com/go_rely_warehouse/zyos_go_pay.git/db/model"
"code.fnuoos.com/go_rely_warehouse/zyos_go_tools.git/e"
"code.fnuoos.com/go_rely_warehouse/zyos_go_tools.git/utils/cache"
"xorm.io/xorm"
)

//支付渠道获取
func JudgePayChannel(mid, paySceneIdentifier string) (model.PayChannelMaster, error) {
var payChannelMaster = model.PayChannelMaster{}
res, err := db.Db.Where("app_id = ?", mid).And("identifier = ?", paySceneIdentifier).Get(&payChannelMaster)
if err != nil {
return payChannelMaster, err
}
if !res {
return payChannelMaster, e.NewErr(400, "查询数据失败")
}
if payChannelMaster.ChannelId == 0 {
return payChannelMaster, e.NewErr(400, "请联系服务商绑定支付渠道")
}
return payChannelMaster, nil
}

//客户端支付宝配置
func OwnCustomAlipayConfig(eg *xorm.Engine, args map[string]string) map[string]string {
cache.NewRedis(args["redis_addr"])
var paySet = map[string]string{
"pay_app_cert_sn": db.SysCfgGetWithDb(eg, args["master_id"], "pay_app_cert_sn"),
"pay_alipay_root_cert_sn": db.SysCfgGetWithDb(eg, args["master_id"], "pay_alipay_root_cert_sn"),
"pay_alipayrsa_public_key": db.SysCfgGetWithDb(eg, args["master_id"], "pay_alipayrsa_public_key"),
"pay_ali_use_type": db.SysCfgGetWithDb(eg, args["master_id"], "pay_ali_use_type"),
"private_key": db.SysCfgGetWithDb(eg, args["master_id"], "pay_ali_private_key"),
"app_id": db.SysCfgGetWithDb(eg, args["master_id"], "pay_ali_app_id"),
"rsa": db.SysCfgGetWithDb(eg, args["master_id"], "pay_ali_key_len_type"),
"pkcs": db.SysCfgGetWithDb(eg, args["master_id"], "pay_ali_key_format_type"),
}
if paySet["pay_ali_use_type"] == "1" {
paySet["private_key"] = db.SysCfgGetWithDb(eg, args["master_id"], "pay_ali_new_private_key")
paySet["app_id"] = db.SysCfgGetWithDb(eg, args["master_id"], "pay_ali_new_app_id")
}
return paySet
}

+ 16
- 4
pay/pay_test.go Vedi File

@@ -5,10 +5,6 @@ import (
)

func TestPay(t *testing.T) {
err := Init("119.23.182.117:3306", "zyos_website", "root", "Fnuo123com@")
if err != nil {
t.Errorf("Reverse == %s", err)
}
channel, err := JudgePayChannel("35618318", "mall")
if err != nil {
t.Errorf("Reverse == %s", err)
@@ -16,3 +12,19 @@ func TestPay(t *testing.T) {

t.Log(channel.Identifier)
}
func TestPayConfig(t *testing.T) {
//args := map[string]string{
// "app_id": "",
// "private_key": "",
// "subject": "哈哈哈",
// "ord_id": "1",
// "amount": "1",
// "notify_url": "",
// "rsa": "0",
// "pkcs": "0",
// "pay_ali_use_type": "0",
// "wx_applet_filepath_url": "",
// "platform": "ios",
//}
//Alipay(args)
}

+ 0
- 10
stringutil/reverse.go Vedi File

@@ -1,10 +0,0 @@
package stringutil

// Reverse returns its argument string reversed rune-wise left to right.
func Reverse(s string) string {
r := []rune(s)
for i, j := 0, len(r)-1; i < len(r)/2; i, j = i+1, j-1 {
r[i], r[j] = r[j], r[i]
}
return string(r)
}

+ 0
- 18
stringutil/reverse_test.go Vedi File

@@ -1,18 +0,0 @@
package stringutil

import "testing"

func TestReverse(t *testing.T) {
for _, c := range []struct {
in, want string
}{
{"Hello, world", "dlrow ,olleH"},
{"Hello, 世界", "界世 ,olleH"},
{"", ""},
} {
got := Reverse(c.in)
if got != c.want {
t.Errorf("Reverse(%q) == %q, want %q", c.in, got, c.want)
}
}
}

Caricamento…
Annulla
Salva