forked from shenghui0779/sdk-go
-
Notifications
You must be signed in to change notification settings - Fork 0
/
pappay.go
389 lines (347 loc) · 14.2 KB
/
pappay.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
package mch
import (
"strconv"
"github.com/accaolei/gochat/wx"
)
// Contract 微信纯签约协议
type Contract struct {
// 必填字段
PlanID string // 协议模板id,设置路径见开发步骤
ContractCode string // 商户侧的签约协议号,由商户生成
RequestSerial int64 // 商户请求签约时的序列号,要求唯一性,纯数字, 范围不能超过Int64的范围
ContractDisplayAccount string // 签约用户的名称,用于页面展示,参数值不支持UTF8非3字节编码的字符,如表情符号,故请勿使用微信昵称
SpbillCreateIP string // 用户客户端的真实IP地址,H5签约必填
Timestamp int64 // 系统当前时间戳,10位
NotifyURL string // 用于接收签约成功消息的回调通知地址,对notify_url参数值需进行encode处理,注意是对参数值进行encode
// 选填字段
ReturnAPP bool // APP签约选填,签约后是否返回app,注:签约参数appid必须为发起签约的app所有,且在微信开放平台注册过
ReturnWeb bool // 公众号签约选填,签约后是否返回签约页面的referrer url, 不填或获取不到referrer则不返回; 跳转referrer url时会自动带上参数from_wxpay=1
OuterID int64 // 小程序签约选填,用户在商户侧的标识
ReturnAPPID string // H5签约选填,商户具有指定返回app的权限时,签约成功将返回appid指定的app应用,如不填且签约发起时的浏览器UA可被微信识别,则跳转到浏览器,否则留在微信
}
// ContractOrder 支付并签约
type ContractOrder struct {
// 必填参数
OutTradeNO string // 商户系统内部的订单号,32个字符内、可包含字母,其他说明见商户订单号
TotalFee int // 订单总金额,单位为分,详见支付金额
SpbillCreateIP string // APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
TradeType string // 取值如下:JSAPI,NATIVE,APP,MWEB,详细说明见参数规定
Body string // 商品或支付单简要描述
PlanID string // 协议模板id,设置路径见开发步骤
ContractCode string // 商户侧的签约协议号,由商户生成
RequestSerial int64 // 商户请求签约时的序列号,要求唯一性,纯数字, 范围不能超过Int64的范围
ContractDisplayAccount string // 签约用户的名称,用于页面展示,参数值不支持UTF8非3字节编码的字符,如表情符号,故请勿使用微信昵称
PaymentNotifyURL string // 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数
ContractNotifyURL string // 签约信息回调通知的url
// 选填参数
DeviceInfo string // 终端设备号(门店号或收银设备ID),注意:PC网页或公众号内支付请传"WEB"
Detail string // 商品名称明细列表
Attach string // 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
FeeType string // 符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
TimeStart string // 订单生成时间,格式为yyyyMMddHHmmss,如:2009年12月25日9点10分10秒 表示为:20091225091010
TimeExpire string // 订单失效时间,格式为yyyyMMddHHmmss,如:2009年12月27日9点10分10秒 表示为:20091227091010
GoodsTag string // 商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
ProductID string // trade_type=NATIVE,此参数必传。此id为二维码中包含的商品ID,商户自行定义
LimitPay string // no_credit--指定不能使用信用卡支付
OpenID string // trade_type=JSAPI,此参数必传,用户在商户appid下的唯一标识
}
// PappayData 扣款数据
type PappayData struct {
// 必填参数
OutTradeNO string // 商户系统内部的订单号,32个字符内、可包含字母,其他说明见商户订单号
TotalFee int // 订单总金额,单位为分,详见支付金额
SpbillCreateIP string // APP和网页支付提交用户端ip,Native支付填调用微信支付API的机器IP
ContractID string // 签约成功后,微信返回的委托代扣协议id
Body string // 商品或支付单简要描述
NotifyURL string // 接收微信支付异步通知回调地址,通知url必须为直接可访问的url,不能携带参数
// 选填参数
Detail string // 商品名称明细列表
Attach string // 附加数据,在查询API和支付通知中原样返回,该字段主要用于商户携带订单的自定义数据
FeeType string // 符合ISO 4217标准的三位字母代码,默认人民币:CNY,其他值列表详见货币类型
GoodsTag string // 商品标记,代金券或立减优惠功能的参数,说明详见代金券或立减优惠
Receipt bool // 是否在支付成功消息和支付详情页中出现开票入口,注:需要在微信支付商户平台或微信公众平台开通电子发票功能
}
// APPEntrust APP纯签约
func APPEntrust(c *Contract) wx.Action {
return wx.NewAPI(PappayAPPEntrustURL,
wx.WithMethod(wx.MethodPost),
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
body := wx.WXML{
"appid": appid,
"mch_id": mchid,
"plan_id": c.PlanID,
"contract_code": c.ContractCode,
"request_serial": strconv.FormatInt(c.RequestSerial, 10),
"contract_display_account": c.ContractDisplayAccount,
"version": "1.0",
"timestamp": strconv.FormatInt(c.Timestamp, 10),
"notify_url": c.NotifyURL,
"sign_type": SignMD5,
}
if c.ReturnAPP {
body["return_app"] = "Y"
}
return body, nil
}),
)
}
// OAEntrust 公众号纯签约
func OAEntrust(c *Contract) wx.Action {
return wx.NewAPI(ContractOAEntrust,
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
body := wx.WXML{
"appid": appid,
"mch_id": mchid,
"plan_id": c.PlanID,
"contract_code": c.ContractCode,
"request_serial": strconv.FormatInt(c.RequestSerial, 10),
"contract_display_account": c.ContractDisplayAccount,
"version": "1.0",
"timestamp": strconv.FormatInt(c.Timestamp, 10),
"notify_url": c.NotifyURL,
"sign_type": SignMD5,
}
if c.ReturnWeb {
body["return_web"] = "1"
}
return body, nil
}),
)
}
// MPEntrust 小程序纯签约,返回小程序所需的 extraData 数据
func MPEntrust(c *Contract) wx.Action {
return wx.NewAPI(ContractMPEntrust,
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
extraData := wx.WXML{
"appid": appid,
"mch_id": mchid,
"plan_id": c.PlanID,
"contract_code": c.ContractCode,
"request_serial": strconv.FormatInt(c.RequestSerial, 10),
"contract_display_account": c.ContractDisplayAccount,
"timestamp": strconv.FormatInt(c.Timestamp, 10),
"notify_url": c.NotifyURL,
"sign_type": SignMD5,
}
if c.OuterID != 0 {
extraData["outerid"] = strconv.FormatInt(c.OuterID, 10)
}
return extraData, nil
}),
)
}
// H5Entrust H5纯签约
func H5Entrust(c *Contract) wx.Action {
return wx.NewAPI(ContractH5Entrust,
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
body := wx.WXML{
"appid": appid,
"mch_id": mchid,
"plan_id": c.PlanID,
"contract_code": c.ContractCode,
"request_serial": strconv.FormatInt(c.RequestSerial, 10),
"contract_display_account": c.ContractDisplayAccount,
"version": "1.0",
"timestamp": strconv.FormatInt(c.Timestamp, 10),
"clientip": c.SpbillCreateIP,
"notify_url": c.NotifyURL,
"sign_type": SignHMacSHA256,
}
if c.ReturnAPPID != "" {
body["return_appid"] = c.ReturnAPPID
}
return body, nil
}),
)
}
// EntrustByOrder 支付中签约
func EntrustByOrder(order *ContractOrder) wx.Action {
return wx.NewAPI(PappayContractOrderURL,
wx.WithMethod(wx.MethodPost),
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
body := wx.WXML{
"appid": appid,
"mch_id": mchid,
"contract_appid": appid,
"contract_mchid": mchid,
"nonce_str": nonce,
"fee_type": "CNY",
"trade_type": order.TradeType,
"body": order.Body,
"out_trade_no": order.OutTradeNO,
"total_fee": strconv.Itoa(order.TotalFee),
"spbill_create_ip": order.SpbillCreateIP,
"plan_id": order.PlanID,
"contract_code": order.ContractCode,
"request_serial": strconv.FormatInt(order.RequestSerial, 10),
"contract_display_account": order.ContractDisplayAccount,
"notify_url": order.PaymentNotifyURL,
"contract_notify_url": order.ContractNotifyURL,
"sign_type": SignMD5,
}
if order.DeviceInfo != "" {
body["device_info"] = order.DeviceInfo
}
if order.Detail != "" {
body["detail"] = order.Detail
}
if order.Attach != "" {
body["attach"] = order.Attach
}
if order.FeeType != "" {
body["fee_type"] = order.FeeType
}
if order.TimeStart != "" {
body["time_start"] = order.TimeStart
}
if order.TimeExpire != "" {
body["time_expire"] = order.TimeExpire
}
if order.GoodsTag != "" {
body["goods_tag"] = order.GoodsTag
}
if order.ProductID != "" {
body["product_id"] = order.ProductID
}
if order.LimitPay != "" {
body["limit_pay"] = order.LimitPay
}
if order.OpenID != "" {
body["openid"] = order.OpenID
}
return body, nil
}),
)
}
// QueryContractByID 根据微信返回的委托代扣协议id查询签约关系
func QueryContractByID(contractID string) wx.Action {
return wx.NewAPI(PappayContractQueryURL,
wx.WithMethod(wx.MethodPost),
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
return wx.WXML{
"appid": appid,
"mch_id": mchid,
"contract_id": contractID,
"version": "1.0",
"sign_type": SignMD5,
}, nil
}),
)
}
// QueryContractByCode 根据签约协议号查询签约关系,需要商户平台配置的代扣模版id
func QueryContractByCode(planID, contractCode string) wx.Action {
return wx.NewAPI(PappayContractQueryURL,
wx.WithMethod(wx.MethodPost),
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
return wx.WXML{
"appid": appid,
"mch_id": mchid,
"plan_id": planID,
"contract_code": contractCode,
"version": "1.0",
"sign_type": SignMD5,
}, nil
}),
)
}
// PappayApply 申请扣款
func PappayApply(data *PappayData) wx.Action {
return wx.NewAPI(PappayApplyURL,
wx.WithMethod(wx.MethodPost),
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
body := wx.WXML{
"appid": appid,
"mch_id": mchid,
"nonce_str": nonce,
"fee_type": "CNY",
"trade_type": TradePAP,
"notify_url": data.NotifyURL,
"body": data.Body,
"out_trade_no": data.OutTradeNO,
"total_fee": strconv.Itoa(data.TotalFee),
"contract_id": data.ContractID,
"spbill_create_ip": data.SpbillCreateIP,
"sign_type": SignMD5,
}
if data.Detail != "" {
body["detail"] = data.Detail
}
if data.Attach != "" {
body["attach"] = data.Attach
}
if data.FeeType != "" {
body["fee_type"] = data.FeeType
}
if data.GoodsTag != "" {
body["goods_tag"] = data.GoodsTag
}
if data.Receipt {
body["receipt"] = "Y"
}
return body, nil
}),
)
}
// DeleteContractByID 根据微信返回的委托代扣协议id解约
func DeleteContractByID(contractID, remark string) wx.Action {
return wx.NewAPI(PappayContractDeleteURL,
wx.WithMethod(wx.MethodPost),
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
return wx.WXML{
"appid": appid,
"mch_id": mchid,
"contract_id": contractID,
"version": "1.0",
"contract_termination_remark": remark,
"sign_type": SignMD5,
}, nil
}),
)
}
// DeleteContractByCode 根据签约协议号解约,需要商户平台配置的代扣模版id
func DeleteContractByCode(planID, contractCode, remark string) wx.Action {
return wx.NewAPI(PappayContractDeleteURL,
wx.WithMethod(wx.MethodPost),
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
return wx.WXML{
"appid": appid,
"mch_id": mchid,
"plan_id": planID,
"contract_code": contractCode,
"version": "1.0",
"contract_termination_remark": remark,
"sign_type": SignMD5,
}, nil
}),
)
}
// QueryPappayByTransactionID 根据微信订单号查询扣款信息
func QueryPappayByTransactionID(transactionID string) wx.Action {
return wx.NewAPI(PappayOrderQueryURL,
wx.WithMethod(wx.MethodPost),
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
return wx.WXML{
"appid": appid,
"mch_id": mchid,
"transaction_id": transactionID,
"nonce_str": nonce,
"sign_type": SignMD5,
}, nil
}),
)
}
// QueryPappayByOutTradeNO 根据商户订单号查询扣款信息
func QueryPappayByOutTradeNO(outTradeNO string) wx.Action {
return wx.NewAPI(PappayOrderQueryURL,
wx.WithMethod(wx.MethodPost),
wx.WithWXML(func(appid, mchid, nonce string) (wx.WXML, error) {
return wx.WXML{
"appid": appid,
"mch_id": mchid,
"out_trade_no": outTradeNO,
"nonce_str": nonce,
"sign_type": SignMD5,
}, nil
}),
)
}