diff --git a/platformapi/dadaapi/dadaapi_test.go b/platformapi/dadaapi/dadaapi_test.go
index 3c56d70e..9ad12334 100644
--- a/platformapi/dadaapi/dadaapi_test.go
+++ b/platformapi/dadaapi/dadaapi_test.go
@@ -3,8 +3,10 @@ package dadaapi
import (
"fmt"
"git.rosy.net.cn/baseapi"
+ "git.rosy.net.cn/baseapi/utils"
"git.rosy.net.cn/jx-callback/business/model"
"go.uber.org/zap"
+ "strings"
"testing"
)
@@ -194,3 +196,58 @@ func Test222222(t *testing.T) {
// }
// }
//}
+
+func Test111(t *testing.T) {
+ SplitUniversalOrderID("313943552673")
+}
+
+func SplitUniversalOrderID(universalOrderID string) (orderID string, vendorID int) {
+ index := strings.Index(universalOrderID, "|")
+ if index != -1 {
+ orderID = universalOrderID[:index]
+ vendorID = int(utils.Str2Int64(universalOrderID[index+1:]))
+ } else {
+ if vendorID = GetPossibleVendorIDFromVendorOrderID(universalOrderID); vendorID == -1 {
+ panic(fmt.Sprintf("unkown order type, orderID:%s", universalOrderID))
+ }
+ orderID = universalOrderID
+ }
+ return orderID, vendorID
+}
+
+func GetPossibleVendorIDFromVendorOrderID(vendorOrderID string) (vendorID int) {
+ vendorID = -1
+ //if vendorOrderIDInt64 := utils.Str2Int64WithDefault(vendorOrderID, 0); vendorOrderIDInt64 > 0 {
+ orderIDLen := len(vendorOrderID)
+ // 5287873015048 13 wsc
+ // 15380342248732 14 old ebai order
+ // 800402581000221 15,16 jd order
+ // 33437032333978492 17 mtwm order
+ // 3022716176275221584 19 elm order, new ebai order
+
+ // 京东到家从2020年开始订单号的长度都会在现有基础上加一位,订单号的前两位取的是当年的最后两位数(如:2020取的20),以适应业务的发展。
+ // 改造点:
+ // 1、订单号位数变化,由原有15位数增加1位数调整为16位数,对接商家需检查是否有对订单号位数做长度校验。
+ // 2、第一位数字发生变化,由原来9开头调整为当年年份后两位数如:2020年订单开头为20;
+ if orderIDLen == len("925265130002541") || orderIDLen == len("1925265130002541") {
+ vendorID = 0
+ } else if orderIDLen == len("3022716176275221584") {
+ // vendorID = model.VendorIDELM
+ vendorID = 3 // 饿百零售开放平台订单接口中订单ID“order_id”字段长度将调整为19位,和饿了么订单ID“eleme_order_id”字段格式保持一致。
+ } else if orderIDLen == len("15380342248732") {
+ if vendorOrderID[:2] == "88" {
+ vendorID = 9
+ } else {
+ vendorID = 3
+ }
+ } else if orderIDLen == len("33437032333978492") || orderIDLen == len("116379390766579767") {
+ vendorID = 1
+ } else if orderIDLen == len("5287873015048") {
+ vendorID = 11
+ } else if orderIDLen == len("1000004390") {
+ vendorID = 9
+ } else if orderIDLen == len("18100216009800000001") || orderIDLen == len("191075245758000000039") {
+ vendorID = 5
+ }
+ return vendorID
+}
diff --git a/platformapi/ebaiapi/shop_sku_test.go b/platformapi/ebaiapi/shop_sku_test.go
index 640b51d5..ecf8e362 100644
--- a/platformapi/ebaiapi/shop_sku_test.go
+++ b/platformapi/ebaiapi/shop_sku_test.go
@@ -328,7 +328,7 @@ func TestDeleteStoreSku(t *testing.T) {
}
func TestDeleteSku(t *testing.T) {
- shopId := "100829"
+ shopId := "804627"
param1 := &SkuListParams{
Page: 1,
PageSize: 100,
diff --git a/platformapi/fnpsapi/fn_test.go b/platformapi/fnpsapi/fn_test.go
index 24576c03..75e8e8bc 100644
--- a/platformapi/fnpsapi/fn_test.go
+++ b/platformapi/fnpsapi/fn_test.go
@@ -29,8 +29,8 @@ func init() {
func TestQueryOneStore(t *testing.T) {
api = New("6705486294797503379", "c1e6c280-e618-4103-9d0a-673bc54fb22e", "51658", "")
//token, err := api.GetAccessToken()
- api.accessToken = "8cffab79-4dab-4a9a-a609-c1ff6b14109b"
- data, err := api.GetStore("20002")
+ api.accessToken = "eb855784-ca08-460b-be73-5681ceb28222"
+ data, err := api.GetStore("5000009")
fmt.Println(data)
fmt.Println(err)
}
diff --git a/platformapi/mtwmapi/mtwmapi_test.go b/platformapi/mtwmapi/mtwmapi_test.go
index 5f58ff7b..bb0b73ff 100644
--- a/platformapi/mtwmapi/mtwmapi_test.go
+++ b/platformapi/mtwmapi/mtwmapi_test.go
@@ -23,10 +23,10 @@ func init() {
//api = New("589", "a81eb3df418d83d6a1a4b7c572156d2f", "", "")
// 果园
- api = New("4123", "df2c88338b85f830cebce2a9eab56628", "", "")
+ //api = New("4123", "df2c88338b85f830cebce2a9eab56628", "", "")
//商超
- //api = New("5873", "41c479790a76f86326f89e8048964739", "", "token_hGnQOvCSkfrCOXFLHA1NMQ")
+ api = New("5873", "41c479790a76f86326f89e8048964739", "", "token_n49KrTnbe-Qatd-80sFOnQ")
//cookieStr := `
// acctId=57396785; token=0bWbK5VbK50E2BmIhIH2zHB-am_y7mB37yXHm6RLZWx4*; wmPoiId=-1;
//`
@@ -53,7 +53,7 @@ func TestGetOAuthCode(t *testing.T) {
}
func TestPreparationMealComplete(t *testing.T) {
- api.PreparationMealComplete(900658760944919842)
+ api.PreparationMealComplete(3901564910320888932)
}
func TestGetAccessToken(t *testing.T) {
diff --git a/platformapi/mtwmapi/order_test.go b/platformapi/mtwmapi/order_test.go
index a7d275a6..2bb7ae3e 100644
--- a/platformapi/mtwmapi/order_test.go
+++ b/platformapi/mtwmapi/order_test.go
@@ -31,7 +31,7 @@ func getTimeFromTimestamp(timeStamp int64) time.Time {
}
func TestOrderGetOrderDetail(t *testing.T) {
- result, err := api.OrderGetOrderDetail(2001521861299113073, false)
+ result, err := api.OrderGetOrderDetail(5401564660946475322, false)
if err != nil {
t.Fatal(err)
}
diff --git a/platformapi/mtwmapi/poi_test.go b/platformapi/mtwmapi/poi_test.go
index 73dd2c6a..3fc27d4a 100644
--- a/platformapi/mtwmapi/poi_test.go
+++ b/platformapi/mtwmapi/poi_test.go
@@ -6,6 +6,7 @@ import (
"git.rosy.net.cn/baseapi/utils"
"strings"
"testing"
+ "time"
)
const (
@@ -24,16 +25,30 @@ func TestPoiGetIDs(t *testing.T) {
}
func Test1111(t *testing.T) {
- result, err := api.PoiMGet([]string{"17821732"})
- if err != nil {
- fmt.Println(err)
+ storeIds := []int64{
+ 12524795,
}
- for _, v := range result {
- if strings.Contains(v.Name, "京西") {
- data := fmt.Sprintf("%s %s ", v.AppPoiCode, v.Name) + fmt.Sprintf("

", v.PicURL)
- fmt.Println(data)
+
+ for k, v := range storeIds {
+ result, err := api.PoiMGet([]string{utils.Int64ToStr(v)})
+ if err != nil {
+ fmt.Println(k)
+ continue
}
+ if result == nil || len(result) == 0 {
+ fmt.Println(k)
+ continue
+ }
+ for _, v2 := range result {
+ if strings.Contains(v2.Name, "京西") {
+ fmt.Println(fmt.Sprintf("
", v2.PicURL))
+ } else {
+ fmt.Println(k)
+ }
+ }
+ time.Sleep(200 * time.Microsecond)
}
+
}
func TestPoiMGet(t *testing.T) {
result, err := api.PoiMGet([]string{"17821732"})
diff --git a/platformapi/tao_vegetable/order_test.go b/platformapi/tao_vegetable/order_test.go
index 244294b8..f46ab3c6 100644
--- a/platformapi/tao_vegetable/order_test.go
+++ b/platformapi/tao_vegetable/order_test.go
@@ -22,8 +22,8 @@ func TestName(t *testing.T) {
}
func TestGetOrderDetail(t *testing.T) {
requestParam := &request591.AlibabaAelophyOrderGetRequest{OrderGetRequest: &domain591.AlibabaAelophyOrderGetOrderGetRequest{
- StoreId: utils.String2Pointer("JX667128"),
- BizOrderId: utils.Int64ToPointer(8000211756001500978),
+ StoreId: utils.String2Pointer("JX100236"),
+ BizOrderId: utils.Int64ToPointer(8000245939558000686),
}}
data, err := apiTao.QueryOrderDetail(requestParam)
@@ -74,13 +74,13 @@ func Test222(t *testing.T) {
// 接单
func TestDeliveryFinishACCEPTED(t *testing.T) {
- orderID := 8000101702997900468
- storeID := "JX102364"
+ orderID := 8000253695335600623
+ storeID := "JX666900"
param := &request591.AlibabaAelophyOrderWorkCallbackRequest{}
param.WorkCallbackRequest = &domain591.AlibabaAelophyOrderWorkCallbackWorkCallbackRequest{
- StoreId: utils.String2Pointer("JX102364"),
+ StoreId: utils.String2Pointer(storeID),
BizOrderId: utils.Int64ToPointer(int64(orderID)),
- Status: utils.String2Pointer(OrderStatusSuccess),
+ Status: utils.String2Pointer(OrderStatusPickedUp),
StatusRemark: nil,
//DelivererName: utils.String2Pointer("张廷"),
//DelivererPhone: utils.String2Pointer("SIGN"),
@@ -107,7 +107,7 @@ func TestDeliveryFinishACCEPTED(t *testing.T) {
workCallbackSubOrderInfoList = append(workCallbackSubOrderInfoList, workCallbackSubOrderInfo)
}
param.WorkCallbackRequest.WorkCallbackSubOrderInfoList = &workCallbackSubOrderInfoList
- apiTao.SetToken("50000C00432zMSClqLiSDjBr2NyiazjtFmsgTOdbBfti16a73f18k0XDfkUQywSmcjfC")
+ apiTao.SetToken("50000C00e13l3SYxqadamvelw15656b52A0xeXfaS8nyVCgitlzIq1nDwFzYdcQpIsVz")
//apiTao.SetToken("50002C01524csKWniqfypk8dbshKRTeFIOIy1a46c0cfgsvodWjsseMsXqpvWvECMj1")
err = apiTao.DeliveryFinish(param)
fmt.Println(err)
diff --git a/platformapi/tonglianpayapi/callback.go b/platformapi/tonglianpayapi/callback.go
index 7f19b46b..bd6eb2d9 100644
--- a/platformapi/tonglianpayapi/callback.go
+++ b/platformapi/tonglianpayapi/callback.go
@@ -14,7 +14,12 @@ const (
MsgTypePayZFB = "VSP511" //支付宝
MsgTypeRefundZFB = "VSP513"
- TrxStatusSuccess = "0000"
+ TrxStatusSuccess = "0000" // 交易成功
+ TrxStatusTransaction = "2000" // 支付中
+ TrxStatusTransaction2 = "2008" // 支付中
+ OnlinePayStatusSuccess = "SUCCESS"
+ OnlinePayStatusFail = "FAIL"
+ MisStatusSuccess = "Y0000" // 调用成功
)
type CallBackResult struct {
@@ -57,3 +62,50 @@ func (a *API) GetCallbackMsg(request *http.Request) (call *CallBackResult, err e
utils.Map2StructByJson(mapData, &call, false)
return call, err
}
+
+// CallBackResultOnlinePay 扫码支付回调
+type CallBackResultOnlinePay struct {
+ AppID string `json:"appID"`
+ OuttrxID string `json:"outtrxID"`
+ TrxCode string `json:"trxCode"`
+ TrxID string `json:"trxID"`
+ TrxAmt string `json:"trxAmt"`
+ TrxDate string `json:"trxDate"`
+ PayTime string `json:"payTime"`
+ ChnlTrxID string `json:"chnlTrxID"`
+ TrxStatus string `json:"trxStatus"`
+ CusID string `json:"cusID"`
+ TermNo string `json:"termNo"`
+ TermBatchid string `json:"termBatchid"`
+ TermTraceno string `json:"termTraceno"`
+ TermAuthno string `json:"termAuthno"`
+ TermRefnum string `json:"termRefnum"`
+ TrxReserved string `json:"trxReserved"`
+ SrcTrxid string `json:"srcTrxid"`
+ CusorderID string `json:"cusorderID"`
+ Acct string `json:"acct"`
+ Fee string `json:"fee"`
+ SignType string `json:"signType"`
+ Cmid string `json:"cmid"`
+ Chnlid string `json:"chnlid"`
+ Sign string `json:"sign"`
+ Initamt string `json:"initamt"`
+ Chnldata string `json:"chnldata"`
+ Accttype string `json:"accttype"`
+ Bankcode string `json:"bankcode"`
+ Logonid string `json:"logonid"`
+}
+
+func (a *API) GetCallbackOnlinePayMsg(request *http.Request) (call *CallBackResultOnlinePay, err error) {
+ data, err := ioutil.ReadAll(request.Body)
+ if err != nil {
+ return nil, err
+ }
+ values, err := utils.HTTPBody2Values(data, false)
+ if err != nil {
+ return nil, err
+ }
+ mapData := utils.URLValues2Map(values)
+ utils.Map2StructByJson(mapData, &call, false)
+ return call, err
+}
diff --git a/platformapi/tonglianpayapi/tonglian_model.go b/platformapi/tonglianpayapi/tonglian_model.go
new file mode 100644
index 00000000..879aa8ce
--- /dev/null
+++ b/platformapi/tonglianpayapi/tonglian_model.go
@@ -0,0 +1,282 @@
+package tonglianpayapi
+
+import (
+ "crypto/md5"
+ "fmt"
+ "git.rosy.net.cn/baseapi/platformapi"
+ "net/http"
+ "sort"
+ "strings"
+)
+
+const (
+ prodURL = "https://vsp.allinpay.com/apiweb"
+ prodURL2 = "https://syb.allinpay.com/apiweb"
+ sepcAction = "unitorder/pay"
+ sepcAction2 = "h5unionpay/unionorder"
+
+ sigKey = "sign"
+ PayTypeWxXcx = "W06"
+ PayTypeWxCode = "W01"
+ PayTypeZfbApp = "A03"
+ PayTypeZfbQrcode = "A01"
+ PayTypeZfbJS = "A02"
+ PayTypeH5 = "H5"
+
+ ResponseCodeSuccess = "SUCCESS"
+ ResponseCodeFail = "FAIL"
+)
+
+type API struct {
+ appID string
+ cusID string
+ appKey string
+
+ client *http.Client
+ config *platformapi.APIConfig
+}
+
+func New(appID, appKey, cusID string, config ...*platformapi.APIConfig) *API {
+ curConfig := platformapi.DefAPIConfig
+ if len(config) > 0 {
+ curConfig = *config[0]
+ }
+ return &API{
+ appID: appID,
+ appKey: appKey,
+ cusID: cusID,
+ client: &http.Client{Timeout: curConfig.ClientTimeout},
+ config: &curConfig,
+ }
+}
+
+func (a *API) signParam(params map[string]interface{}) (sig string) {
+ var valueList []string
+ for k, v := range params {
+ if k != sigKey {
+ if str := fmt.Sprint(v); str != "" {
+ valueList = append(valueList, fmt.Sprintf("%s=%s", k, str))
+ }
+ }
+ }
+ valueList = append(valueList, fmt.Sprintf("key=%s", a.appKey))
+ sort.Sort(sort.StringSlice(valueList))
+ sig = strings.Join(valueList, "&")
+ binSig := md5.Sum([]byte(sig))
+ sig = fmt.Sprintf("%X", binSig)
+ return sig
+}
+
+type CreateUnitorderOrderParam struct {
+ CusID string `json:"cusid"`
+ AppID string `json:"appid"`
+ Trxamt int `json:"trxamt"` //交易金额 单位为分
+ Reqsn string `json:"reqsn"` //商户交易单号
+ NotifyUrl string `json:"notifyUrl"` //接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
+ Acct string `json:"acct"`
+ PayType string `json:"paytype"`
+ SubAppID string `json:"subAppID"`
+}
+
+type CreateUnitOrderOrderResult struct {
+ RetCode string `json:"retCode"`
+ RetMsg string `json:"retMsg"`
+ CusID string `json:"cusID"`
+ AppID string `json:"appID"`
+ TrxID string `json:"trxID"`
+ ChnltrxID string `json:"chnltrxID"`
+ Reqsn string `json:"reqsn"`
+ RandomStr string `json:"randomStr"`
+ TrxStatus string `json:"trxStatus"`
+ FinTime string `json:"finTime"`
+ ErrMsg string `json:"errMsg"`
+ PayInfo string `json:"payInfo"`
+ Sign string `json:"sign"`
+}
+
+type PayInfo struct {
+ AppID string `json:"appID"`
+ TimeStamp string `json:"timeStamp"`
+ NonceStr string `json:"nonceStr"`
+ Package string `json:"package"`
+ SignType string `json:"signType"`
+ PaySign string `json:"paySign"`
+}
+
+type PayRefundParam struct {
+ CusID string `json:"cusid"`
+ AppID string `json:"appid"`
+ Trxamt int `json:"trxamt"` //交易金额 单位为分
+ Reqsn string `json:"reqsn"` //商户交易单号
+ OldReqsn string `json:"oldReqsn"`
+ Remark string `json:"remark"`
+ RandomStr string `json:"randomStr"`
+ Sign string `json:"sign"`
+ TrxID string `json:"trxID"`
+ OldTrxID string `json:"oldTrxID"`
+}
+
+type PayRefundResult struct {
+ RetCode string `json:"retCode"`
+ RetMsg string `json:"retMsg"`
+ CusID string `json:"cusID"`
+ AppID string `json:"appID"`
+ TrxID string `json:"trxID"`
+ Reqsn string `json:"reqsn"`
+ TrxStatus string `json:"trxStatus"`
+ FinTime string `json:"finTime"`
+ ErrMsg string `json:"errMsg"`
+ RandomStr string `json:"randomStr"`
+ Sign string `json:"sign"`
+ Fee string `json:"fee"`
+ TrxCode string `json:"trxCode"`
+}
+
+type CreateH5UnitorderOrderParam struct {
+ Trxamt int `json:"trxamt"` //交易金额 单位为分
+ Reqsn string `json:"reqsn"` //商户交易单号
+ NotifyUrl string `json:"notifyUrl"` //接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
+ Charset string `json:"charset"`
+ Returl string `json:"returl"`
+ Body string `json:"body"`
+}
+
+// OnlinePayParam 扫码枪扫码支付参数
+type OnlinePayParam struct {
+ //参数 参数名称 可空 备注
+ Orgid string `json:"orgid"` // 集团/代理商商户号 是 共享集团号/代理商参数时必填
+ Cusid string `json:"cusid"` // 商户号实际交易的商户号 否
+ Appid string `json:"appid"` // 应用ID平台分配的APPID 否
+ Version string `json:"version"` // 版本号接口版本号 可
+ Randomstr string `json:"randomstr"` // 随机字符串 否 商户自行生成的随机字符串
+ Trxamt string `json:"trxamt"` // 交易金额单位为分 否
+ Reqsn string `json:"reqsn"` // 商户交易单号 否 保证商户平台唯一
+ Body string `json:"body"` // 订单商品名称,为空则以商户名作为商品名称 是
+ Remark string `json:"remark"` // 备注 是 禁止出现+,空格,/,?,%,#,&, = 这几类特殊符号
+ Authcode string `json:"authcode"` // 支付授权码如微信, 支付宝, 银联的付款二维码 否
+ LimitPay string `json:"limit_pay"` // 支付限制 no_credit--指定不能使用信用卡支付 是 32 暂时只对微信支付和支付宝, 支付宝支付有效, 仅支持no_credit
+ GoodsTag string `json:"goods_tag"` // 订单优惠标记 订单优惠标记,用于区分订单是否可以享受优惠,字段内容在微信后台配置券时进行设置,说明详见代金券或立减优惠 是 只对微信支付有效
+ Benefitdetail string `json:"benefitdetail"` // 优惠信息Benefitdetail的json字符串, 注意是String 填写格式详见附录5.8 是
+ SubAppid string `json:"sub_appid"` // 微信子appid 微信小程序/微信公众号/APP的appid 是 只对微信支付有效
+ Chnlstoreid string `json:"chnlstoreid"` // 渠道门店编号 商户在支付渠道端的门店编号 对于支付宝支付,支付宝门店编号 对于微信支付,微信门店编号
+ Subbranch string `json:"subbranch"` // 门店号 是 4
+ Idno string `json:"idno"` // 证件号实名交易必填.填了此字段就会验证证件号和姓名 是 暂只支持支付宝
+ Extendparams string `json:"extendparams"` // 拓展参数 json字符串,注意是String一般用于渠道的活动参数填写 是 参考5.9拓展参数附录说明
+ Truename string `json:"truename"` // 付款人真实姓名实名交易必填.填了此字段就会验证证件号和姓名 是 暂只支持支付宝
+ Asinfo string `json:"asinfo"` // 分账信息 格式:cusid:type:amount cusid:type:amount… 其中 cusid:接收分账的通联商户号 type分账类型(01:按金额 02:按比率) 如果分账类型为02,则分账比率为0.5表示50%。如果分账类型为01,则分账金额以元为单位表示 是
+ Fqnum string `json:"fqnum"` // 分期
+ NotifyUrl string `json:"notify_url"` // 交易结果通知地址 接收交易结果的通知回调地址,通知url必须为直接可访问的url,不能携带参数。 https只支持默认端口 是
+ Signtype string `json:"signtype"` /// 签名方式 是
+ Unpid string `json:"unpid"` // 银联pid 仅支持代理商/服务商角色调用
+ Sign string `json:"sign"` // 签名 详见安全规范 否
+ Terminfo string `json:"terminfo"` // 终端信息终端信息的json字符串 详见附录5.10终端字段说明 否
+ Operatorid string `json:"operatorid"` // 收银员号 是
+}
+type TerminfoBase struct {
+ Termno string `json:"termno"` // 终端号 必填
+ Devicetype string `json:"devicetype"` // 设备类型 必填
+ Termsn string `json:"termsn"` // 终端序列号
+ Encryptrandnum string `json:"encryptrandnum"` // 加密随机因子
+ Secrettext string `json:"secrettext"` // 密文数据
+ Appversion string `json:"appversion"` // 终端程序版本号
+ Longitude string `json:"longitude"` // 经度 银联扫码必送
+ Latitude string `json:"latitude"` // 纬度 银联扫码必送
+ Deviceip string `json:"deviceip"` // 终端Ip 如微信支付宝交易经纬度未上送,该字段必送
+}
+
+// OnlinePayResult 扫码枪支付返回参数
+type OnlinePayResult struct {
+ Retcode string `json:"retcode"` // SUCCESS/FAIL
+ Retmsg string `json:"retmsg"` // 返回码说明
+}
+type OnlinePayRetMsg struct {
+ Cusid string `json:"cusid"` // 商户号实际交易的商户号 否
+ Appid string `json:"appid"` // 应用ID平台分配的APPID 否
+ Trxid string `json:"trxid"` // 收银宝平台的交易流水号
+ Chnltrxid string `json:"chnltrxid"` // 例如微信,支付宝平台的交易单号
+ Reqsn string `json:"reqsn"` // 商户的交易订单号
+ Trxstatus string `json:"trxstatus"` // 交易的状态,
+ Acct string `json:"acct"` // 微信支付-用户的微信openid支付宝支付-用户user_id
+ Trxcode string `json:"trxcode"` // 交易类型
+ Fintime string `json:"fintime"` // yyyyMMddHHmmss
+ Errmsg string `json:"errmsg"` // 失败的原因说明
+ Randomstr string `json:"randomstr"` // 随机生成的字符串
+ Initamt string `json:"initamt"` // 原交易金额
+ Trxamt string `json:"trxamt"` // 实际交易金额
+ Fee string `json:"fee"` // 手续费
+ Cmid string `json:"cmid"` // 渠道子商户号
+ Chnlid string `json:"chnlid"` // 渠道号
+ Chnldata string `json:"chnldata"` // 渠道信息
+ Accttype string `json:"accttype"` // 借贷标识
+ Sign string `json:"sign"` // 签名
+}
+
+// PayTransactionStatusQuery 交易状态查询
+type PayTransactionStatusQuery struct {
+ Orgid string `json:"orgid"` // 集团/代理商商户号 是 共享集团号/代理商参数时必填
+ Cusid string `json:"cusid"` // 商户号实际交易的商户号 否
+ Appid string `json:"appid"` // 应用ID平台分配的APPID 否
+ Version string `json:"version"` // 版本号接口版本号 可
+ Reqsn string `json:"reqsn"` // 商户交易单号 否 保证商户平台唯一
+ Trxid string `json:"trxid"` // 收银宝平台的交易流水号
+ Randomstr string `json:"randomstr"` // 随机字符串 否 商户自行生成的随机字符串
+ Signtype string `json:"signtype"` /// 签名方式 是
+ Sign string `json:"sign"` // 签名 详见安全规范 否
+}
+type PayTransactionStatusResult struct {
+ Cusid string `json:"cusid"` // 商户号实际交易的商户号 否
+ Appid string `json:"appid"` // 应用ID平台分配的APPID 否
+ Trxid string `json:"trxid"` // 收银宝平台的交易流水号
+ Chnltrxid string `json:"chnltrxid"` // 例如微信,支付宝平台的交易单号
+ Reqsn string `json:"reqsn"` // 商户的交易订单号
+ Trxcode string `json:"trxcode"` // 交易类型
+ Trxamt string `json:"trxamt"` // 实际交易金额
+ Trxstatus string `json:"trxstatus"` // 交易的状态,
+ Acct string `json:"acct"` // 支付平台用户标识
+ Fintime string `json:"fintime"` // yyyyMMddHHmmss
+ Randomstr string `json:"randomstr"` // 随机生成的字符串
+ Errmsg string `json:"errmsg"` // 失败的原因说明
+ Cmid string `json:"cmid"` // 渠道子商户号
+ Chnlid string `json:"chnlid"` // 渠道号
+ Initamt string `json:"initamt"` // 原交易金额
+ Fee string `json:"fee"` // 手续费
+ Chnldata string `json:"chnldata"` // 渠道信息
+ Accttype string `json:"accttype"` // 借贷标识
+ Bankcode string `json:"bankcode"` // 所属银行
+ Logonid string `json:"logonid"` // 买家账号
+ Sign string `json:"sign"` // 签名
+}
+
+// OnLineOrderRefundParam 订单退款参数
+type OnLineOrderRefundParam struct {
+ Orgid string `json:"orgid"` // 集团/代理商商户号 是 共享集团号/代理商参数时必填
+ Cusid string `json:"cusid"` // 商户号实际交易的商户号 否
+ Appid string `json:"appid"` // 应用ID平台分配的APPID 否
+ Version string `json:"version"` // 版本号接口版本号 可
+
+ Trxamt string `json:"trxamt"` // 交易金额单位为分 否
+ Reqsn string `json:"reqsn"` // 商户交易单号 否 保证商户平台唯一
+ Oldreqsn string `json:"oldreqsn"` // 原交易订单号 是
+ Oldtrxid string `json:"oldtrxid"` // 原交易流水 是
+ Remark string `json:"remark"` // 备注 是 禁止出现+,空格,/,?,%,#,&, = 这几类特殊符号
+ Benefitdetail string `json:"benefitdetail"` // 优惠信息
+ Randomstr string `json:"randomstr"` // 随机字符串 否 商户自行生成的随机字符串
+ Signtype string `json:"signtype"` /// 签名方式 是
+ Sign string `json:"sign"` // 签名 详见安全规范 否
+}
+type OnLineOrderRefundResult struct {
+ Cusid string `json:"cusid"` // 商户号实际交易的商户号 否
+ Appid string `json:"appid"` // 应用ID平台分配的APPID 否
+ Trxid string `json:"trxid"` // 收银宝平台的交易流水号
+ Reqsn string `json:"reqsn"` // 商户的交易订单号
+ Trxstatus string `json:"trxstatus"` // 交易的状态,
+ Fintime string `json:"fintime"` // yyyyMMddHHmmss
+ Errmsg string `json:"errmsg"` // 失败的原因说明
+ Fee string `json:"fee"` // 手续费
+ Trxcode string `json:"trxcode"` // 交易类型
+ Randomstr string `json:"randomstr"` // 随机生成的字符串
+ Chnltrxid string `json:"chnltrxid"` // 例如微信,支付宝平台的交易单号
+ Chnldata string `json:"chnldata"` // 渠道信息
+ Bankcode string `json:"bankcode"` // 所属银行
+ Sign string `json:"sign"` // 签名
+}
diff --git a/platformapi/tonglianpayapi/tonglian_online_pay.go b/platformapi/tonglianpayapi/tonglian_online_pay.go
new file mode 100644
index 00000000..729f0bd8
--- /dev/null
+++ b/platformapi/tonglianpayapi/tonglian_online_pay.go
@@ -0,0 +1,194 @@
+package tonglianpayapi
+
+import (
+ "crypto"
+ "crypto/rand"
+ "crypto/rsa"
+ "crypto/x509"
+ "encoding/base64"
+ "fmt"
+ "git.rosy.net.cn/baseapi/platformapi"
+ "git.rosy.net.cn/baseapi/utils"
+ "net/http"
+ "sort"
+ "strings"
+)
+
+const (
+ //RSA私钥(非JAVA适用)
+ RSAPrivateKeyNotJava = `MIIEpAIBAAKCAQEAx9qhvqwyZ5hUKoxErxjgOgpjipbmJr20tGCtd/7UXCksVE9S/JWF6+LuT9jKAQpDDU4Dniu5mpwp6vfz2S7D51bO+S2mmSyiV6//NHpWZJwP9Lsb2fbU0tJUNiXGx3P79sA7ZDi5hkho59CX+tOr/gVDKXTb4Rbyj50+N+Rxt3i/Kd4Sf8AMRodP4SxcOjS4pbmwLFcD5H35czvXSRBQkHAptJ6keiYJLmi2ylsLWnBgf0BZYp04i5EVxiUT389ji7WNOUpNedb3wjOio877VatNm4XIZx0BFZVF8ZFEzEJkVXRAxRlR71nl1uKpNPVqfPQZ8pY3RrUmCxOwnJl5vQIDAQABAoIBAB3U4jjabkmtYL7bIjN6xJmVTGd2/9K/lXYpSitzs9Iv6SiKkKoYTZ24yXbMttZx6DFXuE2HXFSaQ92JdnIwO1jQSePC7y/FDFSHdlIogrXQ38bZmR4vbHQtphlRCTtjcjRSXGso1nSXYWVc6xqrNuybb3uEMIAIU1uhjpR8Ooc2sMfmpNdqCS5SKngIsRj5FQZzBPUoBiAlKiYck/UJzUgdVyxz5hpaFqB2V6VciD3E/PSa6OtSTPVO7a1KUD1rmvADZTmAYSqYwRBqZxkb42MNDtOW8YqRFC/rTlSQOo76XvT0AGSY2ZvFC89LrIZc9hF76k8OfCi8XjrwrMKgbpcCgYEA6/WiwthWy41Ch9R9xCubkPYfulNjq9CKbYyWnmmARnnhM5iRYJidqyfw1IbSVVm9Qy3o3VBnYocOTRJUTmOmpQgWqI4t/HjCZiFZeKF30F9ytl1urCbkXYWA2lygf2ZUYiCt3/CNC0bct4nZa42sGu3TXYZKcpVqlZT6tWywu8sCgYEA2NP4Zz5zJGzskhVdsEJbL7ttv/yX7X/g6AW3IhcI108bWfoA+i6YjbDsC8aftgIHPheaW/6n+oirDwoYdgrWa2/eCIKBo5uchtDmUb8qIXog1RbryKqOevLDkGRlJ8NAOIZfGwjT3pfhbtM+wvH5PCFBywoMlxz2sWZ2x4Vzf5cCgYEAza8Jeh9rSXSRkiXAm8gHi42AisM2FwdqI6RxhxUgJE8J6BgOYc2nYxMl85yyrIPVX0Idww3bkR95b+WSZ+Kl2SX72mJV48bAbpaTj3vxHUqWjDFVz+r3Fi7R64biwStKU195McRWroXO0I7xX7fXVoIJxXTSYJ+ukUWUZaGhTZECgYEAuHv6IVYYP8jRrCWztjFvRniRk8VGOxQP9zpNrBqvMgqjufWl+TfGIuCCpi5UW1b0dJc+hcFxiQ/Zg41SbLUh5P2ki9cGmH7hOi/pl2owXZV88/FxoiXD3sZJMMTK8H8HWFC0ANuM8RqG+3WPM+0P42JkiW2+cqB5IU2OCIr6T3cCgYBSLkui8zbMJB0TfE+KGxdm3e+sX26ZE2ZqQmTfJoRcxGgkWC7oY8HdIwws1uFeO38C5SMkkT8YlJghAjIIsfIUuCWQc5tBwvcb5f78/iJRUVgHXl3dH+9HvJKh/I4NeTIX6NTlaOrkUjgnkLLWbU7+b+3SCsVnvKH7uEm5cH0Ejg==`
+ //RSA公钥
+ RSAPublicKey = `MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAx9qhvqwyZ5hUKoxErxjgOgpjipbmJr20tGCtd/7UXCksVE9S/JWF6+LuT9jKAQpDDU4Dniu5mpwp6vfz2S7D51bO+S2mmSyiV6//NHpWZJwP9Lsb2fbU0tJUNiXGx3P79sA7ZDi5hkho59CX+tOr/gVDKXTb4Rbyj50+N+Rxt3i/Kd4Sf8AMRodP4SxcOjS4pbmwLFcD5H35czvXSRBQkHAptJ6keiYJLmi2ylsLWnBgf0BZYp04i5EVxiUT389ji7WNOUpNedb3wjOio877VatNm4XIZx0BFZVF8ZFEzEJkVXRAxRlR71nl1uKpNPVqfPQZ8pY3RrUmCxOwnJl5vQIDAQAB`
+
+ //RSA私钥(JAVA适用)
+ RSAPrivateKeyJava = `MIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDH2qG+rDJnmFQqjESvGOA6CmOKluYmvbS0YK13/tRcKSxUT1L8lYXr4u5P2MoBCkMNTgOeK7manCnq9/PZLsPnVs75LaaZLKJXr/80elZknA/0uxvZ9tTS0lQ2JcbHc/v2wDtkOLmGSGjn0Jf606v+BUMpdNvhFvKPnT435HG3eL8p3hJ/wAxGh0/hLFw6NLilubAsVwPkfflzO9dJEFCQcCm0nqR6JgkuaLbKWwtacGB/QFlinTiLkRXGJRPfz2OLtY05Sk151vfCM6KjzvtVq02bhchnHQEVlUXxkUTMQmRVdEDFGVHvWeXW4qk09Wp89BnyljdGtSYLE7CcmXm9AgMBAAECggEAHdTiONpuSa1gvtsiM3rEmZVMZ3b/0r+VdilKK3Oz0i/pKIqQqhhNnbjJdsy21nHoMVe4TYdcVJpD3Yl2cjA7WNBJ48LvL8UMVId2UiiCtdDfxtmZHi9sdC2mGVEJO2NyNFJcayjWdJdhZVzrGqs27Jtve4QwgAhTW6GOlHw6hzawx+ak12oJLlIqeAixGPkVBnME9SgGICUqJhyT9QnNSB1XLHPmGloWoHZXpVyIPcT89Jro61JM9U7trUpQPWua8ANlOYBhKpjBEGpnGRvjYw0O05bxipEUL+tOVJA6jvpe9PQAZJjZm8ULz0ushlz2EXvqTw58KLxeOvCswqBulwKBgQDr9aLC2FbLjUKH1H3EK5uQ9h+6U2Or0IptjJaeaYBGeeEzmJFgmJ2rJ/DUhtJVWb1DLejdUGdihw5NElROY6alCBaoji38eMJmIVl4oXfQX3K2XW6sJuRdhYDaXKB/ZlRiIK3f8I0LRty3idlrjawa7dNdhkpylWqVlPq1bLC7ywKBgQDY0/hnPnMkbOySFV2wQlsvu22 //Jftf+DoBbciFwjXTxtZ+gD6LpiNsOwLxp+2Agc+F5pb/qf6iKsPChh2CtZrb94IgoGjm5yG0OZRvyoheiDVFuvIqo568sOQZGUnw0A4hl8bCNPel+Fu0z7C8fk8IUHLCgyXHPaxZnbHhXN/lwKBgQDNrwl6H2tJdJGSJcCbyAeLjYCKwzYXB2ojpHGHFSAkTwnoGA5hzadjEyXznLKsg9VfQh3DDduRH3lv5ZJn4qXZJfvaYlXjxsBulpOPe/EdSpaMMVXP6vcWLtHrhuLBK0pTX3kxxFauhc7QjvFft9dWggnFdNJgn66RRZRloaFNkQKBgQC4e/ohVhg/yNGsJbO2MW9GeJGTxUY7FA/3Ok2sGq8yCqO59aX5N8Yi4IKmLlRbVvR0lz6FwXGJD9mDjVJstSHk/aSL1waYfuE6L+mXajBdlXzz8XGiJcPexkkwxMrwfwdYULQA24zxGob7dY8z7Q/jYmSJbb5yoHkhTY4IivpPdwKBgFIuS6LzNswkHRN8T4obF2bd76xfbpkTZmpCZN8mhFzEaCRYLuhjwd0jDCzW4V47fwLlIySRPxiUmCECMgix8hS4JZBzm0HC9xvl/vz+IlFRWAdeXd0f70e8kqH8jg15Mhfo1OVo6uRSOCeQstZtTv5v7dIKxWe8ofu4SblwfQSO`
+ //SM2公钥
+ SM2PublicKey = `MFkwEwYHKoZIzj0CAQYIKoEcz1UBgi0DQgAE7yCR6yp3jPOgBTqWqE9D3ugudcsi4epjq3EJ6mq3Y0nrR489Pld7V5yk+QuH2SUZMFmu46/adlnN/+cd496lkg==`
+ //SM2私钥
+ SM2PrivateKey = `MIGTAgEAMBMGByqGSM49AgEGCCqBHM9VAYItBHkwdwIBAQQg1Rj + skv1B3dGwe2wGy9OF6N4vqxAGM44MR6e2kWTxhegCgYIKoEcz1UBgi2hRANCAATvIJHrKneM86AFOpaoT0Pe6C51yyLh6mOrcQnqardjSetHjz0 + V3tXnKT5C4fZJRkwWa7jr9p2Wc3/5x3j3qWS`
+ // 测试私钥
+ cusRsaPrivateTestKey = `MIICdQIBADANBgkqhkiG9w0BAQEFAASCAl8wggJbAgEAAoGBAJgHMGYsspghvP+yCbjLG43CkZuQ3YJyDcmEKxvmgblITfmiTPx2b9Y2iwDT9gnLGExTDm1BL2A8VzMobjaHfiCmTbDctu680MLmpDDkVXmJOqdlXh0tcLjhN4+iDA2KkRqiHxsDpiaKT6MMBuecXQbJtPlVc1XjVhoUlzUgPCrvAgMBAAECgYAV9saYTGbfsdLOF5kYo0dve1JxaO7dFMCcgkV+z2ujKtNmeHtU54DlhZXJiytQY5Dhc10cjb6xfFDrftuFcfKCaLiy6h5ETR8jyv5He6KH/+X6qkcGTkJBYG1XvyyFO3PxoszQAs0mrLCqq0UItlCDn0G72MR9/NuvdYabGHSzEQJBAMXB1/DUvBTHHH4LiKDiaREruBb3QtP72JQS1ATVXA2v6xJzGPMWMBGQDvRfPvuCPVmbHENX+lRxMLp39OvIn6kCQQDEzYpPcuHW/7h3TYHYc+T0O6z1VKQT2Mxv92Lj35g1XqV4Oi9xrTj2DtMeV1lMx6n/3icobkCQtuvTI+AcqfTXAkB6bCz9NwUUK8sUsJktV9xJN/JnrTxetOr3h8xfDaJGCuCQdFY+rj6lsLPBTnFUC+Vk4mQVwJIE0mmjFf22NWW5AkAmsVaRGkAmui41Xoq52MdZ8WWm8lY0BLrlBJlvveU6EPqtcZskWW9KiU2euIO5IcRdpvrB6zNMgHpLD9GfMRcPAkBUWOV/dH13v8V2Y/Fzuag/y5k3/oXi/WQnIxdYbltad2xjmofJ7DbB7MJqiZZD8jlr8PCZPwRNzc5ntDStc959`
+
+ // 回调地址
+ OnlinePayCallbackUrl = "https://callback.jxc4.com/tongLian/onLinePay"
+ // 接口地址
+ OnlinePayUrl = `https://vsp.allinpay.com/apiweb/unitorder/scanqrpay` // 扫码支付
+ OnLineTransactionQuery = `https://vsp.allinpay.com/apiweb/tranx/query` // 交易查询,查询订单的支付状态
+ OnLineRefund = `https://vsp.allinpay.com/apiweb/tranx/refund` // 同一退款接口
+)
+
+const (
+ EncryptionRsa = "RSA" // 加密方式
+)
+
+var (
+ TransactionStatus = map[string]string{
+ "0000": "交易成功",
+ "1001": "交易不存在",
+ "2008": "交易处理中,请查询交易,如果是实时交易(例如刷卡支付,交易撤销,退货),建议每隔一段时间(10秒)查询交易",
+ "2000": "交易处理中,请查询交易,如果是实时交易(例如刷卡支付,交易撤销,退货),建议每隔一段时间(10秒)查询交易",
+ "3888": "流水号重复",
+ "3099": "渠道商户错误",
+ "3014": "交易金额小于应收手续费",
+ "3031": "校验实名信息失败",
+ "3088": "交易未支付",
+ "3089": "撤销异常,如已影响资金24小时内会做差错退款处理",
+ "3050": "交易已被撤销",
+ "3999": "1",
+ "3889": "1",
+ "3045": "1",
+ }
+)
+
+// CreateOnlineBankOrder 网银创建订单(扫码枪,扫二维码支付)
+func (a *API) CreateOnlineBankOrder(param *OnlinePayParam) (statusCode, trxid, errRemake string, err error) {
+ onlineReq := utils.Struct2Map(param, "", false)
+ result, err := a.AccessAPI2(OnlinePayUrl, onlineReq)
+ if err != nil {
+ return "", "", "", err
+ }
+ // 请求接口成功后通联系统返回JSON字符串数据,把除sign之外的其他所有非空字段组成键值对,进行同样的排序和组装处理,并用通联的公钥进行验签
+ // 暂时不考虑验签
+
+ if result["retcode"].(string) != "SUCCESS" {
+ return "", "", "", fmt.Errorf(result["retmsg"].(string))
+ }
+
+ payInfo := &OnlinePayRetMsg{}
+ if err = utils.Map2StructByJson(result, payInfo, true); err != nil {
+ return "", "", "", err
+ }
+
+ return payInfo.Trxstatus, payInfo.Trxid, payInfo.Errmsg, nil
+}
+
+// QueryPayTransaction 订单交易状态查询
+func (a *API) QueryPayTransaction(param *PayTransactionStatusQuery) (statusCode, errRemake string, err error) {
+ onlineReq := utils.Struct2Map(param, "", false)
+ result, err := a.AccessAPI2(OnLineTransactionQuery, onlineReq)
+ if err != nil {
+ return "", "", err
+ }
+ if result["retcode"].(string) != "SUCCESS" {
+ return "", "", fmt.Errorf(result["retmsg"].(string))
+ }
+
+ payInfo := &PayTransactionStatusResult{}
+ if err = utils.Map2StructByJson(result, payInfo, true); err != nil {
+ return "", "", err
+ }
+
+ return payInfo.Trxstatus, payInfo.Errmsg, nil
+}
+
+// OrderRefund 退单
+func (a *API) OrderRefund(param *OnLineOrderRefundParam) (statusCode, errRemake string, err error) {
+ onlineReq := utils.Struct2Map(param, "", false)
+ result, err := a.AccessAPI2(OnLineRefund, onlineReq)
+ if err != nil {
+ return "", "", err
+ }
+ if result["retcode"].(string) != "SUCCESS" {
+ return "", "", fmt.Errorf(result["retmsg"].(string))
+ }
+
+ payInfo := &OnLineOrderRefundResult{}
+ if err = utils.Map2StructByJson(result, payInfo, true); err != nil {
+ return "", "", err
+ }
+
+ return payInfo.Trxstatus, payInfo.Errmsg, nil
+}
+
+func (a *API) AccessAPI2(action string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
+ params := make(map[string]interface{})
+ params["appid"] = a.appID
+ params["cusid"] = a.cusID
+ params["randomstr"] = utils.GetUUID()
+ params["version"] = "12"
+ params = utils.MergeMaps(params, bizParams)
+ sign, err := a.signParamRSA(params, RSAPrivateKeyNotJava)
+ if err != nil {
+ return nil, err
+ }
+ params["sign"] = sign
+
+ err = platformapi.AccessPlatformAPIWithRetry(a.client,
+ func() *http.Request {
+ request, _ := http.NewRequest(http.MethodPost, action, strings.NewReader(utils.Map2URLValues(params).Encode()))
+ request.Header.Set("charset", "UTF-8")
+ request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ return request
+ },
+ a.config,
+ func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
+ if jsonResult1 == nil {
+ return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
+ }
+ if err == nil {
+ returnCode := utils.Interface2String(jsonResult1["retcode"])
+ if returnCode != OnlinePayStatusSuccess {
+ errLevel = platformapi.ErrLevelGeneralFail
+ err = utils.NewErrorCode(utils.Interface2String(jsonResult1["retcode"])+utils.Interface2String(jsonResult1["retmsg"]), returnCode)
+ }
+ retVal = jsonResult1
+ }
+ return errLevel, err
+ })
+ return retVal, err
+}
+
+func (a *API) signParamRSA(params map[string]interface{}, RSAPrivate string) (sig string, err error) {
+ decodeString, err := base64.StdEncoding.DecodeString(RSAPrivate)
+ if err != nil {
+ return "", err
+ }
+
+ private, err := x509.ParsePKCS1PrivateKey(decodeString) //之前看java demo中使用的是pkcs8
+ if err != nil {
+ return "", err
+ }
+
+ var valueList []string
+ for k, v := range params {
+ if k != sigKey {
+ if str := fmt.Sprint(v); str != "" {
+ valueList = append(valueList, fmt.Sprintf("%s=%s", k, str))
+ }
+ }
+ }
+ sort.Sort(sort.StringSlice(valueList))
+ context := strings.Join(valueList, "&")
+ h := crypto.Hash.New(crypto.SHA1) //进行SHA1的散列
+ h.Write([]byte(context))
+ hashed := h.Sum(nil)
+
+ // 进行rsa加密签名
+ signedData, err := rsa.SignPKCS1v15(rand.Reader, private, crypto.SHA1, hashed)
+ if err != nil {
+ return "", err
+ }
+
+ signData := base64.StdEncoding.EncodeToString(signedData)
+ return signData, nil
+}
diff --git a/platformapi/tonglianpayapi/tonglian_online_pay_test.go b/platformapi/tonglianpayapi/tonglian_online_pay_test.go
new file mode 100644
index 00000000..4482d7bf
--- /dev/null
+++ b/platformapi/tonglianpayapi/tonglian_online_pay_test.go
@@ -0,0 +1,101 @@
+package tonglianpayapi
+
+import (
+ "encoding/json"
+ "fmt"
+ "git.rosy.net.cn/baseapi/utils"
+ "testing"
+)
+
+func TestSignRSA(t *testing.T) {
+ sginParma := map[string]interface{}{
+ "appid": "00000051",
+ "cusid": "990581007426001",
+ "randomstr": "82712208",
+ "signtype": "RSA",
+ "trxid": "112094120001088317",
+ "version": "11",
+ }
+ sgin, _ := api.signParamRSA(sginParma, cusRsaPrivateTestKey)
+ fmt.Println(sgin)
+ data2 := `ce6EAOj4rhoBMJM5MJCNG4qQ/CVMTWkoRuSGpSzRAnD3U3V5QyHkQUEej2eZXRaa+qSbw2/IJJSPV0sPuAia1+ccb7OnvxyZqkV9wQyimX6qAMz0K+UWFhQ5McCcQ/XsFhhezoVd5QgL7PtdvuK1AtjuzA3J9yzNmwuPssPnKnc=`
+ fmt.Println(sgin == data2)
+}
+
+func TestOnlinePayData(t *testing.T) {
+ param := &OnlinePayParam{
+ Orgid: "",
+ Cusid: "", // 不用
+ Appid: "", // 不用
+ Version: "", // 不用
+ Randomstr: "", // 不用
+ Trxamt: "1",
+ Reqsn: "202504221811",
+ Body: "测试订单",
+ Remark: "这是一个测试",
+ Authcode: "133040799834193135", // 支付授权码
+ LimitPay: "",
+ GoodsTag: "",
+ Benefitdetail: "",
+ SubAppid: "",
+ Chnlstoreid: "666667",
+ Subbranch: "",
+ Idno: "",
+ Extendparams: "",
+ Truename: "",
+ Asinfo: "",
+ Fqnum: "",
+ NotifyUrl: "https://www.callback.com/tonglian/onlinePay",
+ Signtype: "RSA",
+ Unpid: "",
+ Sign: "",
+ Terminfo: "",
+ Operatorid: "",
+ }
+ terminfo := &TerminfoBase{
+ Termno: "N502F01147",
+ Devicetype: "10",
+ Termsn: "N502F01147",
+ Encryptrandnum: "",
+ Secrettext: "",
+ Appversion: "",
+ Longitude: "+121.48352",
+ Latitude: "-03.561345",
+ Deviceip: "",
+ }
+ terminfoBByte, _ := json.Marshal(terminfo)
+ param.Terminfo = string(terminfoBByte)
+ api.CreateOnlineBankOrder(param)
+}
+
+func TestRefreshPayStatus(t *testing.T) {
+ param := &PayTransactionStatusQuery{
+ //Orgid: "",
+ //Cusid: "",
+ //Appid: "",
+ //Version: "",
+ Reqsn: "202504221811",
+ Trxid: "",
+ Randomstr: utils.GetUUID(),
+ Signtype: "RSA",
+ Sign: "",
+ }
+ api.QueryPayTransaction(param)
+}
+
+func TestOrderRefund(t *testing.T) {
+ param := &OnLineOrderRefundParam{
+ Trxamt: utils.Int2Str(1),
+ Reqsn: "202504250924",
+ Oldreqsn: "202504221811",
+ Oldtrxid: "",
+ Remark: "测试退款",
+ Benefitdetail: "",
+ Randomstr: utils.GetUUID(),
+ Signtype: EncryptionRsa,
+ Sign: "",
+ }
+
+ _, _, err := api.OrderRefund(param)
+ fmt.Println(err)
+}
diff --git a/platformapi/tonglianpayapi/tonglianpayapi.go b/platformapi/tonglianpayapi/tonglianpayapi.go
index 6d194fcc..8c62ba0e 100644
--- a/platformapi/tonglianpayapi/tonglianpayapi.go
+++ b/platformapi/tonglianpayapi/tonglianpayapi.go
@@ -1,148 +1,14 @@
package tonglianpayapi
import (
- "crypto/md5"
"fmt"
"net/http"
- "sort"
"strings"
"git.rosy.net.cn/baseapi/platformapi"
"git.rosy.net.cn/baseapi/utils"
)
-const (
- prodURL = "https://vsp.allinpay.com/apiweb"
- prodURL2 = "https://syb.allinpay.com/apiweb"
- sepcAction = "unitorder/pay"
- sepcAction2 = "h5unionpay/unionorder"
-
- sigKey = "sign"
- PayTypeWxXcx = "W06"
- PayTypeWxCode = "W01"
- PayTypeZfbApp = "A03"
- PayTypeZfbQrcode = "A01"
- PayTypeZfbJS = "A02"
- PayTypeH5 = "H5"
-
- ResponseCodeSuccess = "SUCCESS"
- ResponseCodeFail = "FAIL"
-)
-
-type API struct {
- appID string
- cusID string
- appKey string
-
- client *http.Client
- config *platformapi.APIConfig
-}
-
-type CreateUnitorderOrderParam struct {
- CusID string `json:"cusid"`
- AppID string `json:"appid"`
- Trxamt int `json:"trxamt"` //交易金额 单位为分
- Reqsn string `json:"reqsn"` //商户交易单号
- NotifyUrl string `json:"notifyUrl"` //接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
- Acct string `json:"acct"`
- PayType string `json:"paytype"`
- SubAppID string `json:"subAppID"`
-}
-
-type CreateUnitOrderOrderResult struct {
- RetCode string `json:"retCode"`
- RetMsg string `json:"retMsg"`
- CusID string `json:"cusID"`
- AppID string `json:"appID"`
- TrxID string `json:"trxID"`
- ChnltrxID string `json:"chnltrxID"`
- Reqsn string `json:"reqsn"`
- RandomStr string `json:"randomStr"`
- TrxStatus string `json:"trxStatus"`
- FinTime string `json:"finTime"`
- ErrMsg string `json:"errMsg"`
- PayInfo string `json:"payInfo"`
- Sign string `json:"sign"`
-}
-
-type PayInfo struct {
- AppID string `json:"appID"`
- TimeStamp string `json:"timeStamp"`
- NonceStr string `json:"nonceStr"`
- Package string `json:"package"`
- SignType string `json:"signType"`
- PaySign string `json:"paySign"`
-}
-
-type PayRefundParam struct {
- CusID string `json:"cusid"`
- AppID string `json:"appid"`
- Trxamt int `json:"trxamt"` //交易金额 单位为分
- Reqsn string `json:"reqsn"` //商户交易单号
- OldReqsn string `json:"oldReqsn"`
- Remark string `json:"remark"`
- RandomStr string `json:"randomStr"`
- Sign string `json:"sign"`
- TrxID string `json:"trxID"`
- OldTrxID string `json:"oldTrxID"`
-}
-
-type PayRefundResult struct {
- RetCode string `json:"retCode"`
- RetMsg string `json:"retMsg"`
- CusID string `json:"cusID"`
- AppID string `json:"appID"`
- TrxID string `json:"trxID"`
- Reqsn string `json:"reqsn"`
- TrxStatus string `json:"trxStatus"`
- FinTime string `json:"finTime"`
- ErrMsg string `json:"errMsg"`
- RandomStr string `json:"randomStr"`
- Sign string `json:"sign"`
- Fee string `json:"fee"`
- TrxCode string `json:"trxCode"`
-}
-
-type CreateH5UnitorderOrderParam struct {
- Trxamt int `json:"trxamt"` //交易金额 单位为分
- Reqsn string `json:"reqsn"` //商户交易单号
- NotifyUrl string `json:"notifyUrl"` //接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数。
- Charset string `json:"charset"`
- Returl string `json:"returl"`
- Body string `json:"body"`
-}
-
-func New(appID, appKey, cusID string, config ...*platformapi.APIConfig) *API {
- curConfig := platformapi.DefAPIConfig
- if len(config) > 0 {
- curConfig = *config[0]
- }
- return &API{
- appID: appID,
- appKey: appKey,
- cusID: cusID,
- client: &http.Client{Timeout: curConfig.ClientTimeout},
- config: &curConfig,
- }
-}
-
-func (a *API) signParam(params map[string]interface{}) (sig string) {
- var valueList []string
- for k, v := range params {
- if k != sigKey {
- if str := fmt.Sprint(v); str != "" {
- valueList = append(valueList, fmt.Sprintf("%s=%s", k, str))
- }
- }
- }
- valueList = append(valueList, fmt.Sprintf("key=%s", a.appKey))
- sort.Sort(sort.StringSlice(valueList))
- sig = strings.Join(valueList, "&")
- binSig := md5.Sum([]byte(sig))
- sig = fmt.Sprintf("%X", binSig)
- return sig
-}
-
func (a *API) AccessAPI(action string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
params := make(map[string]interface{})
params["appid"] = a.appID
diff --git a/platformapi/tonglianpayapi/tonglianpayapi_test.go b/platformapi/tonglianpayapi/tonglianpayapi_test.go
index 3bedf7b7..1ab8a5ea 100644
--- a/platformapi/tonglianpayapi/tonglianpayapi_test.go
+++ b/platformapi/tonglianpayapi/tonglianpayapi_test.go
@@ -58,3 +58,51 @@ func TestPayRefund(t *testing.T) {
OldTrxID: "122094350000087981",
})
}
+
+//
+//func TestMisPay(t *testing.T) {
+//
+// custData := &CustDataDetail{
+// BusinessId: BusinessTypeBUSIORDERTRANSQR,
+// Amount: "1",
+// OrderNo: "202504171111",
+// Memo: "",
+// QrCode: "",
+// TramsCheck: "",
+// PageAppendContent: "",
+// ValidateInfo: "",
+// BusInfo: "",
+// }
+// param := &OnMisPayReq{
+// AppId: api.appID,
+// BusinessId: BusinessTypeBUSIORDERTRANSQR,
+// CustData: "000000000002",
+// CashId: "n502f01147",
+// StoreId: "66666",
+// SignData: "",
+// AppPackageNm: "",
+// AppClassNm: "",
+// BusExtpara: "",
+// }
+// custByte, _ := json.Marshal(custData)
+// param.CustData = string(custByte)
+//
+// api.CreateMisPayOrder(param, custData)
+//}
+//
+//func TestSignMd5(t *testing.T) {
+// custData := &CustDataDetail{
+// BusinessId: "100000003",
+// Amount: "000000000002",
+// OrderNo: "123123213",
+// Memo: "",
+// QrCode: "",
+// TramsCheck: "",
+// PageAppendContent: "",
+// ValidateInfo: "",
+// BusInfo: "",
+// }
+// licence := `9a432306-b93d-4d0d-aa7d-ac2bb89dee25-20200208002855`
+// sig := api.signMisParam("100000003", licence, custData)
+// fmt.Println(sig)
+//}
diff --git a/platformapi/tonglianpayapi/yun_mis_pay.go b/platformapi/tonglianpayapi/yun_mis_pay.go
new file mode 100644
index 00000000..046de24e
--- /dev/null
+++ b/platformapi/tonglianpayapi/yun_mis_pay.go
@@ -0,0 +1,149 @@
+package tonglianpayapi
+
+//
+//import (
+// "crypto/md5"
+// "fmt"
+// "git.rosy.net.cn/baseapi/platformapi"
+// "git.rosy.net.cn/baseapi/utils"
+// "net/http"
+// "strings"
+//)
+//
+//const (
+// TongLianMisPay = "https://cloudmiscash.allinpay.com/cloudMis-transaction" // 通联mis支付(基础收款用于一般无特殊支付业务需求的标准行业,如零售、餐饮类商户及场景)
+// MisPayAction = "api/v2/process"
+//)
+//
+//const (
+// BusinessTypeBUSIORDERTRANS = "100000003" // 订单支付收款(不含查询流程)
+// BusinessTypeBUSIORDERTRANSBANK = "100100003" // 订单支付银行卡收款(不含查询)
+// BusinessTypeBUSIORDERTRANSQR = "100300003" // 订单支付扫码收款(不含查询)
+// BusinessTypeBUSIORDERSALE = "100000002" // 订单支付收款(含查询流程)
+// BusinessTypeBUSIORDERSALEBANK = "100100002" // 订单支付银行卡收款(含查询流程)
+// BusinessTypeBUSIORDERSALEQR = "100300002" // 订单支付扫码收款(含查询流程)
+//)
+//
+//func (a *API) signMisParam(businessID, licence string, custData *CustDataDetail) (sig string) {
+// var signBuffer = new(strings.Builder)
+// //signBuffer.Write([]byte(a.appID))
+// signBuffer.Write([]byte("app_id_001"))
+// signBuffer.Write([]byte(businessID))
+// signBuffer.Write([]byte(fmt.Sprintf(`{"BUSINESS_ID":"%s","AMOUNT":"%s","ORDER_NO":"%s"}`, custData.BusinessId, custData.Amount, custData.OrderNo)))
+// signBuffer.Write([]byte(licence))
+// fmt.Println(signBuffer.String())
+// binSig := md5.Sum([]byte(signBuffer.String()))
+// sig = fmt.Sprintf("%x", binSig)
+// return sig
+//}
+//
+//func (a *API) AccessMisAPI(action string, bizParams map[string]interface{}) (retVal map[string]interface{}, err error) {
+// //params := make(map[string]interface{})
+// //params["APP_ID"] = a.appID
+// ////params["randomstr"] = utils.GetUUID()
+// ////params["version"] = "12"
+// //params = utils.MergeMaps(params, bizParams)
+// //signStr := a.signParam(params)
+// //params["SIGN_DATA"] = signStr
+// fullURL := utils.GenerateGetURL(TongLianMisPay, action, nil)
+// err = platformapi.AccessPlatformAPIWithRetry(a.client,
+// func() *http.Request {
+// request, _ := http.NewRequest(http.MethodPost, fullURL, strings.NewReader(utils.Map2URLValues(bizParams).Encode()))
+// request.Header.Set("charset", "UTF-8")
+// request.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+// return request
+// },
+// a.config,
+// func(response *http.Response, bodyStr string, jsonResult1 map[string]interface{}) (errLevel string, err error) {
+// if jsonResult1 == nil {
+// return platformapi.ErrLevelRecoverableErr, fmt.Errorf("mapData is nil")
+// }
+// if err == nil {
+// returnCode := utils.Interface2String(jsonResult1["RSP_CODE"])
+// if returnCode != MisStatusSuccess {
+// errLevel = platformapi.ErrLevelGeneralFail
+// err = utils.NewErrorCode(utils.Interface2String(jsonResult1["errmsg"])+utils.Interface2String(jsonResult1["retmsg"]), returnCode)
+// }
+// retVal = jsonResult1
+// }
+// return errLevel, err
+// })
+// return retVal, err
+//}
+//
+//// CreateMisPayOrder 创建订单(扫码枪,扫二维码支付)
+//func (a *API) CreateMisPayOrder(param *OnMisPayReq, custData *CustDataDetail) (err error) {
+// param.AppId = a.appID
+// param.SignData = a.signMisParam(param.BusinessId, "", custData)
+// params := utils.Struct2MapByJson(param)
+// result, err := a.AccessMisAPI(MisPayAction, params)
+// fmt.Println(result)
+// return
+//}
+//
+//type OnMisPayReq struct {
+// AppId string `json:"APP_ID"` // 必填 应用分配ID
+// BusinessId string `json:"BUSINESS_ID"` // 必填 业务类型
+// CustData string `json:"CUST_DATA"` // 必填 具体的支付请求数据,JSON格式字符串
+// CashId string `json:"CASH_ID"` // 必填 收银机款台号
+// StoreId string `json:"STORE_ID"` // 必填 商户分店号
+// SignData string `json:"SIGN_DATA"` // 必填 计算方法参照附录1
+// AppPackageNm string `json:"APP_PACKAGE_NM"` // 非必填 指定APP包名
+// AppClassNm string `json:"APP_CLASS_NM"` // 非必填 指定类名
+// BusExtpara string `json:"BUS_EXTPARA"` // 非必填 业务扩展字段,用于特定功能,详见附录2
+//}
+//type CustDataDetail struct {
+// BusinessId string `json:"BUSINESS_ID"` // 必填 业务类型
+// Amount string `json:"AMOUNT"` // 必填 支付金额,十二位长度(单位:分,不足左补零)
+// OrderNo string `json:"ORDER_NO"` // 必填 订单编号
+// Memo string `json:"MEMO"` // 非必填 订单编号
+// QrCode string `json:"QRCODE"` // 非必填 订单编号
+// TramsCheck string `json:"TRANS_CHECK"` // 非必填 订单编号
+// PageAppendContent string `json:"PAGE_APPEND_CONTENT"` // 非必填 订单编号
+// ValidateInfo string `json:"VALIDATE_INFO"` // 非必填 订单编号
+// BusInfo string `json:"BUS_INFO"` // 非必填 订单编号
+//}
+//
+//type MisPayResp struct {
+// RspCode string `json:"RSP_CODE"` // 云MIS系统服务调用返回码, 支付返回代码请参考RSP_DATA里支付结果字段
+// RspData string `json:"RSP_DATA"` // 透传支付产品给云MIS的响应JSON字符串
+// RspDesc string `json:"RSP_DESC"` // 交易级返回描述
+// CloudMisTrxSsn string `json:"ClOUD_MIS_TRX_SSN"` // 交易成功返回,云MIS系统唯一流水号,用于查询或对账
+//}
+//
+//type MisPayRspData struct {
+// BusinessId string `json:"BUSINESS_ID"` // 必填 业务类型
+// RejCode string `json:"REJCODE"` // 交易返回码
+// RejCodeCn string `json:"REJCODE_CN"` // 交易返回码注释
+// Cups string `json:"CUPS"` // 卡组织,银行卡为空 (ALP:支付宝 WXP:微信支付)
+// MerchID string `json:"MERCH_ID"` // 商户编号
+// TerID string `json:"TER_ID"` // 终端编号
+// MerchName string `json:"MERCH_NAME"` // 商户名称
+// BatchNo string `json:"BATCH_NO"` // 批次号
+// TraceNo string `json:"TRACE_NO"` // 凭证号
+// TransTicketNo string `json:"TRANS_TICKET_NO"` // 交易单号
+// OrderNo string `json:"order_no"` // 订单编号
+// Amount string `json:"AMOUNT"` // 支付金额,十二位长度(单位:分)
+// RefNo string `json:"REF_NO"` // 系统参考号
+// CarDno string `json:"CARDNO"` // 银行卡交易时返回卡号;扫码交易返回OPENID或USERID
+// CardTypeIdenty string `json:"CARD_TYPE_IDENTY"` // 借贷记卡标识(银行卡) 0:借记 1:贷记
+// WildCardSign string `json:"WILD_CARD_SIGN"` //内外卡标识(银行卡) 0:内卡 1:外卡
+// ExpDate string `json:"EXP_DATE"` // 有效期
+// Date string `json:"DATE"` // 支付日期
+// Time string `json:"TIME"` // 支付时间
+// PrintFlag string `json:"PRINT_FLAG"` // 是否打印小票(1:打印,0:未打印)
+// CardFee string `json:"CARD_FEE"` // 手续费,十二位长度(单位:分)
+// TransCheck string `json:"TRANS_CHECK"` // 交易唯一标识
+// AuthNo string `json:"AUTH_NO"` // 授权码
+// Sign string `json:"SIGN"` // 签名
+// CardType string `json:"CARDTYPE"` // 卡类型
+// TransChannel string `json:"TRANS_CHANNEL"` // 交易渠道
+// IssNo string `json:"ISS_NO"` // 发卡行行号
+// IssName string `json:"ISS_NAME"` // 发卡行名称
+// Memo string `json:"MEMO"` // 备注信息
+// PrtCommon string `json:"PRT_COMMON"` // 打印内容公共部分(仅用于简易终端版)
+// PrtCardholder string `json:"PRT_CARDHOLDER"` // 打印内容持卡人联部分(仅用于简易终端版)
+// PrtMerchant string `json:"PRT_MERCHANT"` // 打印内容商户联部分(仅用于简易终端版)
+// DiscAmount string `json:"DISC_AMOUNT"` // 优惠金额
+// ActuallyAmount string `json:"ACTUALLY_AMOUNT"` // 实付金额
+//}