
1package main
2
3import (
4 "bytes"
5 "demo/wxpay_utility"
6 "encoding/json"
7 "fmt"
8 "net/http"
9 "net/url"
10 "time"
11)
12
13func main() {
14
15 config, err := wxpay_utility.CreateMchConfig(
16 "19xxxxxxxx",
17 "1DDE55AD98Exxxxxxxxxx",
18 "/path/to/apiclient_key.pem",
19 "PUB_KEY_ID_xxxxxxxxxxxxx",
20 "/path/to/wxp_pub.pem",
21 )
22 if err != nil {
23 fmt.Println(err)
24 return
25 }
26
27 request := &CreateBusiFavorStockRequest{
28 StockName: wxpay_utility.String("8月1日活动券"),
29 BelongMerchant: wxpay_utility.String("10000098"),
30 Comment: wxpay_utility.String("活动使用"),
31 GoodsName: wxpay_utility.String("填写商家券可适用的商品或服务"),
32 StockType: BUSIFAVORSTOCKTYPE_NORMAL.Ptr(),
33 CouponUseRule: &CouponUseRule{
34 CouponAvailableTime: &FavorAvailableTime{
35 AvailableBeginTime: wxpay_utility.Time(time.Now()),
36 AvailableEndTime: wxpay_utility.Time(time.Now()),
37 AvailableDayAfterReceive: wxpay_utility.Int64(3),
38 AvailableWeek: &AvailableWeek{
39 WeekDay: []int64{int64(1)},
40 AvailableDayTime: []AvailableCurrentDayTime{AvailableCurrentDayTime{
41 BeginTime: wxpay_utility.Int64(3600),
42 EndTime: wxpay_utility.Int64(86399),
43 }},
44 },
45 IrregularyAvaliableTime: []IrregularAvailableTime{IrregularAvailableTime{
46 BeginTime: wxpay_utility.Time(time.Now()),
47 EndTime: wxpay_utility.Time(time.Now()),
48 }},
49 WaitDaysAfterReceive: wxpay_utility.Int64(7),
50 },
51 FixedNormalCoupon: &FixedValueStockMsg{
52 DiscountAmount: wxpay_utility.Int64(5),
53 TransactionMinimum: wxpay_utility.Int64(100),
54 },
55 DiscountCoupon: &DiscountMsg{
56 DiscountPercent: wxpay_utility.Int64(88),
57 TransactionMinimum: wxpay_utility.Int64(100),
58 },
59 ExchangeCoupon: &ExchangeMsg{
60 ExchangePrice: wxpay_utility.Int64(100),
61 TransactionMinimum: wxpay_utility.Int64(100),
62 },
63 UseMethod: COUPONUSEMETHOD_OFF_LINE.Ptr(),
64 MiniProgramsAppid: wxpay_utility.String("wx23232232323"),
65 MiniProgramsPath: wxpay_utility.String("/path/index/index"),
66 },
67 StockSendRule: &StockSendRule{
68 MaxAmount: wxpay_utility.Int64(100000),
69 MaxCoupons: wxpay_utility.Int64(100),
70 MaxCouponsPerUser: wxpay_utility.Int64(5),
71 MaxAmountByDay: wxpay_utility.Int64(1000),
72 MaxCouponsByDay: wxpay_utility.Int64(100),
73 NaturalPersonLimit: wxpay_utility.Bool(false),
74 PreventApiAbuse: wxpay_utility.Bool(false),
75 Transferable: wxpay_utility.Bool(false),
76 Shareable: wxpay_utility.Bool(false),
77 },
78 OutRequestNo: wxpay_utility.String("100002322019090134234sfdf"),
79 CustomEntrance: &CustomEntrance{
80 MiniProgramsInfo: &MiniAppInfo{
81 MiniProgramsAppid: wxpay_utility.String("wx234545656765876"),
82 MiniProgramsPath: wxpay_utility.String("/path/index/index"),
83 EntranceWords: wxpay_utility.String("欢迎选购"),
84 GuidingWords: wxpay_utility.String("获取更多优惠"),
85 },
86 Appid: wxpay_utility.String("wx324345hgfhfghfg"),
87 HallId: wxpay_utility.String("233455656"),
88 StoreId: wxpay_utility.String("233554655"),
89 CodeDisplayMode: CODEDISPLAYMODE_NOT_SHOW.Ptr(),
90 },
91 DisplayPatternInfo: &DisplayPatternInfo{
92 Description: wxpay_utility.String("xxx门店可用"),
93 MerchantLogoUrl: wxpay_utility.String("https://xxx"),
94 MerchantName: wxpay_utility.String("微信支付"),
95 BackgroundColor: wxpay_utility.String("xxxxx"),
96 CouponImageUrl: wxpay_utility.String("图片cdn地址"),
97 FinderInfo: &FinderInfo{
98 FinderId: wxpay_utility.String("sph6Rngt2T4RlUf"),
99 FinderVideoId: wxpay_utility.String("export/UzFfAgtgekIEAQAAAAAAb4MgnPInmAAAAAstQy6ubaLX4KHWvLEZgBPEwIEgVnk9HIP-zNPgMJofG6tpdGPJNg_ojtEjoT94"),
100 FinderVideoCoverImageUrl: wxpay_utility.String("https://wxpaylogo.qpic.cn/xxx"),
101 },
102 },
103 CouponCodeMode: COUPONCODEMODE_WECHATPAY_MODE.Ptr(),
104 NotifyConfig: &NotifyConfig{
105 NotifyAppid: wxpay_utility.String("wx23232232323"),
106 },
107 Subsidy: wxpay_utility.Bool(false),
108 }
109
110 response, err := CreateBusifavorStock(config, request)
111 if err != nil {
112 fmt.Printf("请求失败: %+v\n", err)
113
114 return
115 }
116
117
118 fmt.Printf("请求成功: %+v\n", response)
119}
120
121func CreateBusifavorStock(config *wxpay_utility.MchConfig, request *CreateBusiFavorStockRequest) (response *CreateBusiFavorStockResponse, err error) {
122 const (
123 host = "https://api.mch.weixin.qq.com"
124 method = "POST"
125 path = "/v3/marketing/busifavor/stocks"
126 )
127
128 reqUrl, err := url.Parse(fmt.Sprintf("%s%s", host, path))
129 if err != nil {
130 return nil, err
131 }
132 reqBody, err := json.Marshal(request)
133 if err != nil {
134 return nil, err
135 }
136 httpRequest, err := http.NewRequest(method, reqUrl.String(), bytes.NewReader(reqBody))
137 if err != nil {
138 return nil, err
139 }
140 httpRequest.Header.Set("Accept", "application/json")
141 httpRequest.Header.Set("Wechatpay-Serial", config.WechatPayPublicKeyId())
142 httpRequest.Header.Set("Content-Type", "application/json")
143 authorization, err := wxpay_utility.BuildAuthorization(config.MchId(), config.CertificateSerialNo(), config.PrivateKey(), method, reqUrl.RequestURI(), reqBody)
144 if err != nil {
145 return nil, err
146 }
147 httpRequest.Header.Set("Authorization", authorization)
148
149 client := &http.Client{}
150 httpResponse, err := client.Do(httpRequest)
151 if err != nil {
152 return nil, err
153 }
154 respBody, err := wxpay_utility.ExtractResponseBody(httpResponse)
155 if err != nil {
156 return nil, err
157 }
158 if httpResponse.StatusCode >= 200 && httpResponse.StatusCode < 300 {
159
160 err = wxpay_utility.ValidateResponse(
161 config.WechatPayPublicKeyId(),
162 config.WechatPayPublicKey(),
163 &httpResponse.Header,
164 respBody,
165 )
166 if err != nil {
167 return nil, err
168 }
169 response := &CreateBusiFavorStockResponse{}
170 if err := json.Unmarshal(respBody, response); err != nil {
171 return nil, err
172 }
173
174 return response, nil
175 } else {
176 return nil, wxpay_utility.NewApiException(
177 httpResponse.StatusCode,
178 httpResponse.Header,
179 respBody,
180 )
181 }
182}
183
184type CreateBusiFavorStockRequest struct {
185 StockName *string `json:"stock_name,omitempty"`
186 BelongMerchant *string `json:"belong_merchant,omitempty"`
187 Comment *string `json:"comment,omitempty"`
188 GoodsName *string `json:"goods_name,omitempty"`
189 StockType *BusiFavorStockType `json:"stock_type,omitempty"`
190 CouponUseRule *CouponUseRule `json:"coupon_use_rule,omitempty"`
191 StockSendRule *StockSendRule `json:"stock_send_rule,omitempty"`
192 OutRequestNo *string `json:"out_request_no,omitempty"`
193 CustomEntrance *CustomEntrance `json:"custom_entrance,omitempty"`
194 DisplayPatternInfo *DisplayPatternInfo `json:"display_pattern_info,omitempty"`
195 CouponCodeMode *CouponCodeMode `json:"coupon_code_mode,omitempty"`
196 NotifyConfig *NotifyConfig `json:"notify_config,omitempty"`
197 Subsidy *bool `json:"subsidy,omitempty"`
198}
199
200type CreateBusiFavorStockResponse struct {
201 StockId *string `json:"stock_id,omitempty"`
202 CreateTime *string `json:"create_time,omitempty"`
203}
204
205type BusiFavorStockType string
206
207func (e BusiFavorStockType) Ptr() *BusiFavorStockType {
208 return &e
209}
210
211const (
212 BUSIFAVORSTOCKTYPE_NORMAL BusiFavorStockType = "NORMAL"
213 BUSIFAVORSTOCKTYPE_DISCOUNT BusiFavorStockType = "DISCOUNT"
214 BUSIFAVORSTOCKTYPE_EXCHANGE BusiFavorStockType = "EXCHANGE"
215)
216
217type CouponUseRule struct {
218 CouponAvailableTime *FavorAvailableTime `json:"coupon_available_time,omitempty"`
219 FixedNormalCoupon *FixedValueStockMsg `json:"fixed_normal_coupon,omitempty"`
220 DiscountCoupon *DiscountMsg `json:"discount_coupon,omitempty"`
221 ExchangeCoupon *ExchangeMsg `json:"exchange_coupon,omitempty"`
222 UseMethod *CouponUseMethod `json:"use_method,omitempty"`
223 MiniProgramsAppid *string `json:"mini_programs_appid,omitempty"`
224 MiniProgramsPath *string `json:"mini_programs_path,omitempty"`
225}
226
227type StockSendRule struct {
228 MaxAmount *int64 `json:"max_amount,omitempty"`
229 MaxCoupons *int64 `json:"max_coupons,omitempty"`
230 MaxCouponsPerUser *int64 `json:"max_coupons_per_user,omitempty"`
231 MaxAmountByDay *int64 `json:"max_amount_by_day,omitempty"`
232 MaxCouponsByDay *int64 `json:"max_coupons_by_day,omitempty"`
233 NaturalPersonLimit *bool `json:"natural_person_limit,omitempty"`
234 PreventApiAbuse *bool `json:"prevent_api_abuse,omitempty"`
235 Transferable *bool `json:"transferable,omitempty"`
236 Shareable *bool `json:"shareable,omitempty"`
237}
238
239type CustomEntrance struct {
240 MiniProgramsInfo *MiniAppInfo `json:"mini_programs_info,omitempty"`
241 Appid *string `json:"appid,omitempty"`
242 HallId *string `json:"hall_id,omitempty"`
243 StoreId *string `json:"store_id,omitempty"`
244 CodeDisplayMode *CodeDisplayMode `json:"code_display_mode,omitempty"`
245}
246
247type DisplayPatternInfo struct {
248 Description *string `json:"description,omitempty"`
249 MerchantLogoUrl *string `json:"merchant_logo_url,omitempty"`
250 MerchantName *string `json:"merchant_name,omitempty"`
251 BackgroundColor *string `json:"background_color,omitempty"`
252 CouponImageUrl *string `json:"coupon_image_url,omitempty"`
253 FinderInfo *FinderInfo `json:"finder_info,omitempty"`
254}
255
256type CouponCodeMode string
257
258func (e CouponCodeMode) Ptr() *CouponCodeMode {
259 return &e
260}
261
262const (
263 COUPONCODEMODE_WECHATPAY_MODE CouponCodeMode = "WECHATPAY_MODE"
264 COUPONCODEMODE_MERCHANT_API CouponCodeMode = "MERCHANT_API"
265 COUPONCODEMODE_MERCHANT_UPLOAD CouponCodeMode = "MERCHANT_UPLOAD"
266)
267
268type NotifyConfig struct {
269 NotifyAppid *string `json:"notify_appid,omitempty"`
270}
271
272type FavorAvailableTime struct {
273 AvailableBeginTime *time.Time `json:"available_begin_time,omitempty"`
274 AvailableEndTime *time.Time `json:"available_end_time,omitempty"`
275 AvailableDayAfterReceive *int64 `json:"available_day_after_receive,omitempty"`
276 AvailableWeek *AvailableWeek `json:"available_week,omitempty"`
277 IrregularyAvaliableTime []IrregularAvailableTime `json:"irregulary_avaliable_time,omitempty"`
278 WaitDaysAfterReceive *int64 `json:"wait_days_after_receive,omitempty"`
279}
280
281type FixedValueStockMsg struct {
282 DiscountAmount *int64 `json:"discount_amount,omitempty"`
283 TransactionMinimum *int64 `json:"transaction_minimum,omitempty"`
284}
285
286type DiscountMsg struct {
287 DiscountPercent *int64 `json:"discount_percent,omitempty"`
288 TransactionMinimum *int64 `json:"transaction_minimum,omitempty"`
289}
290
291type ExchangeMsg struct {
292 ExchangePrice *int64 `json:"exchange_price,omitempty"`
293 TransactionMinimum *int64 `json:"transaction_minimum,omitempty"`
294}
295
296type CouponUseMethod string
297
298func (e CouponUseMethod) Ptr() *CouponUseMethod {
299 return &e
300}
301
302const (
303 COUPONUSEMETHOD_OFF_LINE CouponUseMethod = "OFF_LINE"
304 COUPONUSEMETHOD_MINI_PROGRAMS CouponUseMethod = "MINI_PROGRAMS"
305 COUPONUSEMETHOD_SELF_CONSUME CouponUseMethod = "SELF_CONSUME"
306 COUPONUSEMETHOD_PAYMENT_CODE CouponUseMethod = "PAYMENT_CODE"
307)
308
309type MiniAppInfo struct {
310 MiniProgramsAppid *string `json:"mini_programs_appid,omitempty"`
311 MiniProgramsPath *string `json:"mini_programs_path,omitempty"`
312 EntranceWords *string `json:"entrance_words,omitempty"`
313 GuidingWords *string `json:"guiding_words,omitempty"`
314}
315
316type CodeDisplayMode string
317
318func (e CodeDisplayMode) Ptr() *CodeDisplayMode {
319 return &e
320}
321
322const (
323 CODEDISPLAYMODE_NOT_SHOW CodeDisplayMode = "NOT_SHOW"
324 CODEDISPLAYMODE_BARCODE CodeDisplayMode = "BARCODE"
325 CODEDISPLAYMODE_QRCODE CodeDisplayMode = "QRCODE"
326)
327
328type FinderInfo struct {
329 FinderId *string `json:"finder_id,omitempty"`
330 FinderVideoId *string `json:"finder_video_id,omitempty"`
331 FinderVideoCoverImageUrl *string `json:"finder_video_cover_image_url,omitempty"`
332}
333
334type AvailableWeek struct {
335 WeekDay []int64 `json:"week_day,omitempty"`
336 AvailableDayTime []AvailableCurrentDayTime `json:"available_day_time,omitempty"`
337}
338
339type IrregularAvailableTime struct {
340 BeginTime *time.Time `json:"begin_time,omitempty"`
341 EndTime *time.Time `json:"end_time,omitempty"`
342}
343
344type AvailableCurrentDayTime struct {
345 BeginTime *int64 `json:"begin_time,omitempty"`
346 EndTime *int64 `json:"end_time,omitempty"`
347}
348