Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
S
system_pay
Project
Project
Details
Activity
Releases
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
王沛
system_pay
Commits
47990473
Commit
47990473
authored
Jun 26, 2023
by
wangp
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
拉卡拉统一支付微信回调
parent
fbce7a23
Changes
6
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
512 additions
and
7 deletions
+512
-7
notice.go
controller/api/v1/pay/notice.go
+38
-0
response.go
controller/base/response.go
+12
-0
notice.go
models/notice.go
+26
-0
business.go
repository/pay/business.go
+93
-0
notice.go
repository/pay/notice.go
+149
-0
pay.go
repository/pay/pay.go
+194
-7
No files found.
controller/api/v1/pay/notice.go
0 → 100755
View file @
47990473
package
pay
import
(
"github.com/gin-gonic/gin"
"system_pay/controller/base"
"system_pay/models"
"system_pay/repository/pay"
)
// 卡拉卡统一支付回调
type
NoticeController
struct
{
}
// WxNotice 拉卡拉统一支付微信回调
// @Summary 拉卡拉统一支付微信回调
// @Description 拉卡拉统一支付微信回调
// @Tags 拉卡拉统一支付回调
// @Accept application/json
// @Produce application/json
// @Param language header string ture "语言类型 zh-CN简体中文 en-US英文 ja 日文 默认中文"
// @Success 200
// @router /api/v1/pay/wx_notice [post]
func
(
l
*
PayController
)
WxNotice
(
c
*
gin
.
Context
)
{
ph
:=
new
(
models
.
WxNoticeInput
)
err
:=
c
.
ShouldBind
(
ph
)
if
err
!=
nil
{
response
:=
new
(
base
.
ResponseDataWxNotice
)
response
.
Code
=
"FAIL"
response
.
Message
=
"执行失败"
base
.
ResponseWxNotice
(
c
,
response
)
return
}
// 绑定
response
,
err
:=
pay
.
WxNotice
(
ph
)
base
.
ResponseWxNotice
(
c
,
response
)
}
controller/base/response.go
View file @
47990473
...
...
@@ -72,4 +72,16 @@ func ResponseErrorMsg(c *gin.Context, msg string) {
Message
:
msg
,
Data
:
nil
,
})
}
// ResponseDataWxNotice 微信回调后 处理完逻辑返回给微信的信息
type
ResponseDataWxNotice
struct
{
Code
string
`json:"code"`
//SUCCESS/FAIL
Message
string
`json:"message"`
//执行成功/错误原因
}
func
ResponseWxNotice
(
c
*
gin
.
Context
,
data
*
ResponseDataWxNotice
)
{
c
.
JSON
(
http
.
StatusOK
,
&
ResponseDataWxNotice
{
Code
:
data
.
Code
,
Message
:
data
.
Message
,
})
}
\ No newline at end of file
models/notice.go
0 → 100755
View file @
47990473
package
models
// WxNoticeInput 微信回调输入参数
type
WxNoticeInput
struct
{
ChannelId
uint8
`json:"channel_id" description:"平台类型 1: saas 2: shop 3: shop mobile 4: 收银台"`
MerchantNo
string
`json:"merchant_no" description:"平台信息"`
OrderCreateTime
string
`json:"order_create_time" description:"商品描述"`
OrderEfficientTime
string
`json:"order_efficient_time" description:"商品详情"`
OrderInfo
string
`json:"order_info" description:"附加信息"`
OrderStatus
float64
`json:"order_status" description:"商品金额,个位为分"`
OutOrderNo
string
`json:"out_order_no" description:"客户端回调的url"`
PayOrderNo
int
`json:"pay_order_no" description:"1: 微信,2: 支付宝, 3: 拉卡拉 4: 收钱吧"`
TermNo
uint8
`json:"term_no" description:"1: 微信 Native 2:微信小程序 3:微信内支付 4:h5 跳微信 5:支付宝(web)-扫码或登录支付宝账户 6:alipay(mobile) 7:alipay(app) 9: B2C 10:bk支付宝web 11:bk 支付宝手机"`
TotalAmount
string
`json:"total_amount" description:"此参数 支付类型是 JS API 的时候 必传"`
TransMerchantNo
string
`json:"trans_merchant_no" description:"WAP网站URL地址, 支付方式为微信MWEB时 必传"`
TransTermNo
string
`json:"trans_term_no" description:"WAP网站名称, 支付方式为微信MWEB时 必传"`
}
// CallbackResponse is 回调给业务方的信息
type
CallbackResponse
struct
{
OutTradeNo
string
`json:"out_trade_no"`
// 订单号
ReturnMsg
string
`json:"return_msg"`
// 是否成功
AttachInfo
string
`json:"attach_info"`
// 附加信息
TransactionID
string
`json:"transaction_id"`
// 微信支付订单号
TradeNo
string
`json:"trade_no"`
// 支付宝交易流水号
}
repository/pay/business.go
0 → 100644
View file @
47990473
package
pay
import
(
"encoding/json"
"io/ioutil"
"net/http"
"strings"
"time"
"github.com/astaxie/beego"
)
var
(
callBackNumMap
=
map
[
int
]
int64
{
1
:
1
,
2
:
2
,
3
:
4
,
4
:
8
,
5
:
16
,
6
:
32
,
7
:
64
,
8
:
128
,
9
:
256
,
10
:
512
,
11
:
1024
,
12
:
2048
,
}
)
func
callBackBusinessService
(
outTradeNo
,
url
string
,
data
interface
{})
{
body
,
_
:=
json
.
Marshal
(
data
)
// callBackResponseData is 业务方回调过来的数据
type
callBackResponseData
struct
{
Code
int
Message
string
Data
interface
{}
}
number
:=
1
for
{
client
:=
&
http
.
Client
{}
req
,
err
:=
http
.
NewRequest
(
http
.
MethodPost
,
url
,
strings
.
NewReader
(
string
(
body
)))
req
.
Header
.
Set
(
"Content-Type"
,
"application/json"
)
resp
,
err
:=
client
.
Do
(
req
)
if
err
!=
nil
{
beego
.
Error
(
"网络请求错误"
)
second
:=
callBackNumMap
[
number
]
timeSleep
:=
float64
(
time
.
Second
)
*
float64
(
second
)
number
++
beego
.
Info
(
"当前等待: "
,
number
,
"订单号: "
,
outTradeNo
)
time
.
Sleep
(
time
.
Duration
(
int64
(
timeSleep
)))
continue
}
bodyResp
,
err
:=
ioutil
.
ReadAll
(
resp
.
Body
)
beego
.
Info
(
"bodyResp: "
,
string
(
bodyResp
))
if
err
!=
nil
{
beego
.
Error
(
"从 业务方 response sbody中取数据失败"
)
second
:=
callBackNumMap
[
number
]
timeSleep
:=
float64
(
time
.
Second
)
*
float64
(
second
)
number
++
beego
.
Info
(
"当前等待: "
,
number
,
"订单号: "
,
outTradeNo
)
time
.
Sleep
(
time
.
Duration
(
int64
(
timeSleep
)))
continue
}
resp
.
Body
.
Close
()
// 解析业务方数据
businessResp
:=
new
(
callBackResponseData
)
if
err
:=
json
.
Unmarshal
(
bodyResp
,
businessResp
);
err
!=
nil
{
beego
.
Error
(
"解析业务方返回的数据失败"
,
string
(
bodyResp
))
return
}
if
businessResp
.
Code
==
0
||
businessResp
.
Message
==
"SUCCESS"
{
beego
.
Info
(
"回调业务方成功: "
,
"订单号: "
,
outTradeNo
,
"回调了%v次"
,
number
)
return
}
if
number
>=
12
{
beego
.
Info
(
"当前等待: "
,
number
,
"订单号: "
,
outTradeNo
,
"结束回调"
)
return
}
second
:=
callBackNumMap
[
number
]
timeSleep
:=
float64
(
time
.
Second
)
*
float64
(
second
)
beego
.
Info
(
"当前等待: "
,
number
,
"订单号: "
,
outTradeNo
)
number
++
time
.
Sleep
(
time
.
Duration
(
int64
(
timeSleep
)))
}
}
repository/pay/notice.go
0 → 100755
View file @
47990473
package
pay
import
(
"encoding/json"
"fmt"
"strconv"
"system_pay/controller/base"
"system_pay/models"
"system_pay/mysql"
)
// 拉卡拉微信支付回调 - AliPayNotice
func
WxNotice
(
input
*
models
.
WxNoticeInput
)
(
*
base
.
ResponseDataWxNotice
,
error
)
{
fmt
.
Println
(
"接口输入参数"
)
fmt
.
Println
(
input
)
response
:=
new
(
base
.
ResponseDataWxNotice
)
db
,
err
:=
mysql
.
NewShopConn
()
if
err
!=
nil
{
response
.
Code
=
"FAIL"
response
.
Message
=
"参数格式校验错误"
return
response
,
err
}
fmt
.
Println
(
"111"
)
//1.订单合法check
var
billID
int64
var
attach
,
url
string
err
=
db
.
QueryRow
(
"select ifnull(id, 0), attach, notify_pay_url from pay_bill where payment_order_code = ?"
,
input
.
OutOrderNo
)
.
Scan
(
&
billID
,
&
attach
,
&
url
)
if
err
!=
nil
||
billID
==
0
||
billID
==
2
{
response
.
Code
=
"FAIL"
response
.
Message
=
"db operation fail"
return
response
,
err
}
fmt
.
Println
(
"222"
)
//2.存入 notice_request_body
err
=
InsertPayBillDetailNoticeRequestBody
(
billID
,
input
)
if
err
!=
nil
{
//beego.Error("微信回调, 根据订单id 插入回调Request参数 失败: ", err)
response
.
Code
=
"FAIL"
response
.
Message
=
"db operation fail"
InsertPayBillDetailNoticeResponseBody
(
billID
,
response
)
return
response
,
err
}
fmt
.
Println
(
"333"
)
//3.存入 notice_response_body
//err = InsertPayBillDetailNoticeResponseBody(billID, response)
//if err != nil {
// beego.Error("微信回调, 根据订单id 插入回调Response参数 失败: ", err)
// response.ReturnCode = "FAIL"
// response.ReturnMsg = "db operation fail"
// return err
//}
//beego.Info("回调成功 订单成功")
//type CallbackResponse struct {
// OutTradeNo string `json:"out_trade_no"` // 订单号
// ReturnMsg string `json:"return_msg"` // 是否成功
// AttachInfo string `json:"attach_info"` // 附加信息
// TransactionID string `json:"transaction_id"` // 微信支付订单号
// TradeNo string `json:"trade_no"` // 支付宝交易流水号
//}
if
url
!=
""
{
//4.回调业务方「回调函数」
callbackResponse
:=
new
(
models
.
CallbackResponse
)
callbackResponse
.
ReturnMsg
=
"SUCCESS"
//callbackResponse.OutTradeNo = input.OutTradeNo
//callbackResponse.TransactionID = input.TransactionId
callbackResponse
.
OutTradeNo
=
strconv
.
Itoa
(
input
.
PayOrderNo
)
//交易凭据单号 todo
callbackResponse
.
TransactionID
=
strconv
.
Itoa
(
input
.
PayOrderNo
)
//交易凭据单号 todo
attachMap
:=
make
(
map
[
string
]
interface
{},
0
)
_
=
json
.
Unmarshal
([]
byte
(
attach
),
&
attachMap
)
if
attachMap
[
"store_sn"
]
.
(
string
)
==
""
{
callbackResponse
.
AttachInfo
=
attachMap
[
"old_attach"
]
.
(
string
)
}
else
{
callbackResponse
.
AttachInfo
=
attach
//商户订单号(谛宝多多)
}
go
callBackBusinessService
(
input
.
OutOrderNo
,
url
,
callbackResponse
)
fmt
.
Println
(
"444"
)
}
response
.
Code
=
"SUCCESS"
response
.
Message
=
"执行成功"
InsertPayBillDetailNoticeResponseBody
(
billID
,
response
)
return
response
,
nil
}
// InsertPayBillDetailNoticeRequestBody is 插入支付订单详情表中的 下单参数字段 notice_request_body
func
InsertPayBillDetailNoticeRequestBody
(
billID
int64
,
noticeRequestBody
interface
{})
error
{
db
,
err
:=
mysql
.
NewShopConn
()
if
err
!=
nil
{
return
err
}
body
,
err
:=
json
.
Marshal
(
noticeRequestBody
)
if
err
!=
nil
{
return
err
}
insertPayBillDetailSQL
:=
`update pay_bill_detail set notice_request_body = ? where pay_bill_id = ?`
result
,
err
:=
db
.
Exec
(
insertPayBillDetailSQL
,
string
(
body
),
billID
)
if
err
!=
nil
{
return
err
}
_
,
err
=
result
.
RowsAffected
()
if
err
!=
nil
{
return
err
}
return
nil
}
// InsertPayBillDetailNoticeResponseBody is 插入支付订单详情表中的 下单参数字段 notice_response_body
func
InsertPayBillDetailNoticeResponseBody
(
billID
int64
,
noticeResponseBody
interface
{})
error
{
db
,
err
:=
mysql
.
NewShopConn
()
if
err
!=
nil
{
return
err
}
body
,
err
:=
json
.
Marshal
(
noticeResponseBody
)
if
err
!=
nil
{
return
err
}
insertPayBillDetailSQL
:=
`update pay_bill_detail set notice_response_body = ? where pay_bill_id = ?`
result
,
err
:=
db
.
Exec
(
insertPayBillDetailSQL
,
string
(
body
),
billID
)
if
err
!=
nil
{
return
err
}
_
,
err
=
result
.
RowsAffected
()
if
err
!=
nil
{
return
err
}
return
nil
}
repository/pay/pay.go
View file @
47990473
...
...
@@ -11,10 +11,12 @@ import (
"encoding/pem"
"errors"
"fmt"
"github.com/astaxie/beego"
"github.com/astaxie/beego/httplib"
rand2
"math/rand"
"strings"
"system_pay/models"
"system_pay/mysql"
"time"
)
...
...
@@ -31,11 +33,11 @@ func UnifiedOrder(input *models.PlaceAnOrderParamInput) (interface{}, error) {
//}
//rtn := make(map[string]string)
fmt
.
Println
(
"接口输入参数"
)
fmt
.
Println
(
"
拉卡拉支付
接口输入参数"
)
fmt
.
Println
(
input
)
data
:=
make
(
map
[
string
]
interface
{})
data
[
"req_time"
]
=
"202
20714160009
"
data
[
"req_time"
]
=
"202
30626100000
"
data
[
"version"
]
=
"3.0"
data
[
"out_org_code"
]
=
"OP00000003"
...
...
@@ -57,22 +59,29 @@ func UnifiedOrder(input *models.PlaceAnOrderParamInput) (interface{}, error) {
// "extend_info": "自动化测试",
// "callback_url": ""
input
.
NoticeURL
=
"https://test.pet-dbc.cn/uni/api/repayment/PayCallBack"
//input.NoticeURL = "https://test.pet-dbc.cn/uni/api/repayment/PayCallBack"
//input.NoticeURL = "https://test.pet-dbc.cn/mobile/notifywx.php"
input
.
ReturnURL
=
"https://test.pet-dbc.cn"
// 构造回调url
input
.
NoticeURL
=
GetNoticeURL
(
input
.
SourceCode
)
// 传递给支付渠道的
//p.ServeNoticeUrl = noticeURLx
data2
:=
make
(
map
[
string
]
interface
{})
//data2["out_trade_no"] = "FD660E1FAA3A4470933CDEDAE1EC1DUU"
data2
[
"out_trade_no"
]
=
RandomString
(
32
)
data2
[
"merchant_no"
]
=
"822290070111135"
//data2["merchant_no"] = "822290070111135"
data2
[
"merchant_no"
]
=
"8222900701107M5"
data2
[
"term_no"
]
=
"29034705"
//data2["merchant_no"] = "8222900581201QB"
//data2["term_no"] = "D0027598"
data2
[
"auth_code"
]
=
"135178236713755038"
data2
[
"total_amount"
]
=
"1
23
"
data2
[
"total_amount"
]
=
"1"
//data2["out_order_no"] = "08F4542EEC6A4497BC419161747A92UU"
data2
[
"out_order_no"
]
=
RandomString
(
32
)
data2
[
"order_efficient_time"
]
=
"202306
20130000
"
//订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天
data2
[
"order_efficient_time"
]
=
"202306
30235959
"
//订单有效期 格式yyyyMMddHHmmss,最大支持下单时间+2天
data2
[
"notify_url"
]
=
input
.
NoticeURL
//订单支付成功后商户接收订单通知的地址 http://xxx.xxx.com
data2
[
"callback_url"
]
=
input
.
ReturnURL
//客户端下单完成支付后返回的商户网页跳转地址
...
...
@@ -502,4 +511,182 @@ func RandomString(n int) string {
result
[
i
]
=
letters
[
rand2
.
Intn
(
len
(
letters
))]
}
return
string
(
result
)
}
\ No newline at end of file
}
// GetNoticeURL is 获取回调地址
func
GetNoticeURL
(
sourceCode
uint8
)
string
{
domainName
:=
beego
.
AppConfig
.
String
(
"DomainName"
)
// <= 5 是微信
if
sourceCode
<
5
{
return
domainName
+
"/v1/pay/wx_notice"
}
// > 5 是支付宝
return
domainName
+
"/v1/pay/alipay_notice"
//
//if isServe == 0 {
// // payType 1: 原生 2: paymax
// if payType == 1 {
//
// // <= 5 是微信 > 5 是支付宝
// if sourceCode < 5 {
// return domainName + "/v1/notice/wx"
// }
//
// return domainName + "/v1/notice/ali"
// }
//
// return domainName + "/v1/notice/paymax"
//}
//
//// <= 5 是微信 > 5 是支付宝
//if sourceCode < 5 {
// return domainName + "/v1/notice/serve_wx"
//}
//
//return domainName + "/v1/notice/serve_ali"
}
// BillPayStateSuccess is 微信回调后 把订单状态 置为结算成功
func
BillPayStateSuccess
(
billID
int64
)
error
{
db
,
err
:=
mysql
.
NewShopConn
()
if
err
!=
nil
{
return
err
}
insertPayBillDetailSQL
:=
`update pay_bill set result_code = 1 where id = ?`
result
,
err
:=
db
.
Exec
(
insertPayBillDetailSQL
,
billID
)
if
err
!=
nil
{
return
err
}
_
,
err
=
result
.
RowsAffected
()
if
err
!=
nil
{
return
err
}
return
nil
}
// BillPayStateFail is 微信回调后 把订单状态 置为结算失败
func
BillPayStateFail
(
billID
int64
)
error
{
db
,
err
:=
mysql
.
NewShopConn
()
if
err
!=
nil
{
return
err
}
insertPayBillDetailSQL
:=
`update pay_bill set result_code = 2 where id = ?`
result
,
err
:=
db
.
Exec
(
insertPayBillDetailSQL
,
billID
)
if
err
!=
nil
{
return
err
}
_
,
err
=
result
.
RowsAffected
()
if
err
!=
nil
{
return
err
}
return
nil
}
//InsertPayBill is 插入 支付订单表中
func
InsertPayBill
(
p
*
models
.
PlaceAnOrderParamInput
,
orderID
string
)
(
int64
,
error
)
{
db
,
err
:=
mysql
.
NewShopConn
()
if
err
!=
nil
{
return
0
,
err
}
var
billID
int64
insertSQL
:=
`insert pay_bill set platform_type = ?, platform_info = ?,
source_code = ?, payment_order_code = ?, paymoney = ?*1000, commodity_describe = ?,
commodity_detail = ?, attach = ?, notify_pay_url = ?, pay_type = ?, is_serve = ?`
result
,
err
:=
db
.
Exec
(
insertSQL
,
p
.
PlatformType
,
p
.
PlatformInfo
,
p
.
SourceCode
,
orderID
,
p
.
GoodsPrice
,
p
.
GoodsDes
,
p
.
GoodsDetail
,
p
.
AttachInfo
,
p
.
NoticeURL
,
p
.
PayType
,
p
.
IsServe
)
if
err
!=
nil
{
return
billID
,
err
}
billID
,
err
=
result
.
LastInsertId
()
if
err
!=
nil
{
return
billID
,
err
}
return
billID
,
nil
}
// InsertPayBillDetailRequestBody is 插入支付订单详情表中的 下单参数字段 request_body
func
InsertPayBillDetailRequestBody
(
billID
int64
,
requestBody
interface
{})
error
{
db
,
err
:=
mysql
.
NewShopConn
()
if
err
!=
nil
{
return
err
}
body
,
err
:=
json
.
Marshal
(
requestBody
)
if
err
!=
nil
{
return
err
}
insertPayBillDetailSQL
:=
`insert pay_bill_detail set pay_bill_id = ?, request_body = ?`
result
,
err
:=
db
.
Exec
(
insertPayBillDetailSQL
,
billID
,
string
(
body
))
if
err
!=
nil
{
return
err
}
_
,
err
=
result
.
LastInsertId
()
if
err
!=
nil
{
return
err
}
return
nil
}
// InsertPayBillDetailResponseBody is 插入支付订单详情表中的 下单参数字段 response_body
func
InsertPayBillDetailResponseBody
(
billID
int64
,
responseBody
interface
{})
error
{
db
,
err
:=
mysql
.
NewShopConn
()
if
err
!=
nil
{
return
err
}
body
,
err
:=
json
.
Marshal
(
responseBody
)
if
err
!=
nil
{
return
err
}
insertPayBillDetailSQL
:=
`update pay_bill_detail set response_body = ? where pay_bill_id = ?`
result
,
err
:=
db
.
Exec
(
insertPayBillDetailSQL
,
string
(
body
),
billID
)
if
err
!=
nil
{
return
err
}
_
,
err
=
result
.
RowsAffected
()
if
err
!=
nil
{
return
err
}
return
nil
}
func
InsertPayBillDetailResponseBodyString
(
billID
int64
,
responseBody
string
)
error
{
db
,
err
:=
mysql
.
NewShopConn
()
if
err
!=
nil
{
return
err
}
insertPayBillDetailSQL
:=
`update pay_bill_detail set response_body = ? where pay_bill_id = ?`
result
,
err
:=
db
.
Exec
(
insertPayBillDetailSQL
,
responseBody
,
billID
)
if
err
!=
nil
{
return
err
}
_
,
err
=
result
.
RowsAffected
()
if
err
!=
nil
{
return
err
}
return
nil
}
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment