1
This commit is contained in:
@@ -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
|
||||
}
|
||||
|
||||
@@ -328,7 +328,7 @@ func TestDeleteStoreSku(t *testing.T) {
|
||||
}
|
||||
|
||||
func TestDeleteSku(t *testing.T) {
|
||||
shopId := "100829"
|
||||
shopId := "804627"
|
||||
param1 := &SkuListParams{
|
||||
Page: 1,
|
||||
PageSize: 100,
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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("<table><img src=%s height=100 width=100></table>", 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("<table><img src=%s height=100 width=100></table>", v2.PicURL))
|
||||
} else {
|
||||
fmt.Println(k)
|
||||
}
|
||||
}
|
||||
time.Sleep(200 * time.Microsecond)
|
||||
}
|
||||
|
||||
}
|
||||
func TestPoiMGet(t *testing.T) {
|
||||
result, err := api.PoiMGet([]string{"17821732"})
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
282
platformapi/tonglianpayapi/tonglian_model.go
Normal file
282
platformapi/tonglianpayapi/tonglian_model.go
Normal file
@@ -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"` // 签名
|
||||
}
|
||||
194
platformapi/tonglianpayapi/tonglian_online_pay.go
Normal file
194
platformapi/tonglianpayapi/tonglian_online_pay.go
Normal file
@@ -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
|
||||
}
|
||||
101
platformapi/tonglianpayapi/tonglian_online_pay_test.go
Normal file
101
platformapi/tonglianpayapi/tonglian_online_pay_test.go
Normal file
@@ -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)
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
//}
|
||||
|
||||
149
platformapi/tonglianpayapi/yun_mis_pay.go
Normal file
149
platformapi/tonglianpayapi/yun_mis_pay.go
Normal file
@@ -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"` // 实付金额
|
||||
//}
|
||||
Reference in New Issue
Block a user