关于前端:SpringBootUniApp微信商家券使用

56次阅读

共计 6004 个字符,预计需要花费 16 分钟才能阅读完成。

Reference

微信官网文档

微信领取商家券 API 简介: https://pay.weixin.qq.com/wik…

后端

第三方集成服务

Github-WxJava: https://github.com/Wechat-Gro…

前端

小程序发券插件

官网小程序发券插件: https://pay.weixin.qq.com/wik…
uniapp 援用小程序发券插件的应用教训: https://ask.dcloud.net.cn/art…

后端

API: https://pay.weixin.qq.com/wik…

引入

pom.xml

<dependency>
    <groupId>com.github.binarywang</groupId>
    <artifactId>weixin-java-pay</artifactId>
    <version>4.1.0</version>
</dependency>

application.yml

留神: wx.pay.mchKey 是微信领取 apiv2 的 signkey, 加密的时候 V2 和 V3 的 key 都可能用到,详细情况看文档要求

wx:
  pay:
    appId: wxoinweoih3098340h #微信公众号或者小程序等的 appid
    mchId: 1234456789 #微信领取商户号
    certSerialNo: KOKLJB45BB45KB45OIBOB45OUBB45 #商户在微信公众平台申请服务号对应的 APPID
    apiv3Key: kljbawerkuoin324ointoin34 #微信领取商户密钥 V3 秘钥 Key
    mchKey: oeairbngonegnoINoijOIHNoino #微信领取商户密钥 V2 秘钥 Key
    certificates: https://api.mch.weixin.qq.com/v3/certificates #微信获取平台证书列表地址
    #微信对立下单的 API 地址,用于二维码领取
    payScoreNotifyUrl: https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi
    callbackUrl: https://api.sampleabc.com/api/pay/callback/    #异步接管微信领取后果告诉的回调地址
    subAppId: #服务商模式下的子商户公众账号 ID
    subMchId: #服务商模式下的子商户号
    privateKeyPath:  D:/samplePathabc/apiclient_key.pem
    privateCertPath:  D:/samplePathabc/apiclient_cert.pem
    # p12 证书的地位,能够指定绝对路径,也能够指定类门路(以 classpath: 结尾)keyPath: D:/samplePathabc/apiclient_cert.p12

相干类

以下类能够在我的项目中找到,git clone 下来后寻找即可,通过测试类能够晓得用法

接口: https://github.com/Wechat-Gro…

实现类: https://github.com/Wechat-Gro…

测试类: https://github.com/Wechat-Gro…

生成商家券

// 生成券
@PostMapping(value = "/port/to/create")
public String createCoupon(@RequestBody Map<String, String> body) throws Exception {String stockId = this.testCreateFavorStocksV3();

    return stockId;
}


// 生成商户券
public String testCreateFavorStocksV3() throws WxPayException {BusiFavorStocksCreateRequest request = new BusiFavorStocksCreateRequest();
    request.setStockName("这就是商家券 666");
    request.setBelongMerchant(wxPayService.getConfig().getMchId());
    request.setComment("这就是评论了");
    request.setGoodsName("仅供 leonard 应用");
    request.setCouponCodeMode("WECHATPAY_MODE");
    request.setOutRequestNo(wxPayService.getConfig().getMchId() + "20210204" + "1024102410");

    // 核销规定
    CouponUseRule couponUseRule = new CouponUseRule();

    // 线下核销
    couponUseRule.setUseMethod("OFF_LINE");
    // 小程序核销
    // couponUseRule.setUseMethod("MINI_PROGRAMS");
    // couponUseRule.setMiniProgramsAppid("小程序 APPID");
    //couponUseRule.setMiniProgramsPath("/pages/index/index/abc.html?sadf=xxx");

    // 券可核销工夫
    CouponAvailableTime couponAvailableTime = new CouponAvailableTime();
    couponAvailableTime.setAvailableBeginTime("2021-10-22T13:29:35+08:00");
    couponAvailableTime.setAvailableEndTime("2021-10-29T13:29:35+08:00");
    couponUseRule.setCouponAvailableTime(couponAvailableTime);

    // 固定面额满减券
    request.setStockType(StockTypeEnum.NORMAL);
    FixedNormalCoupon fixedNormalCoupon = new FixedNormalCoupon();
    fixedNormalCoupon.setDiscountAmount(31600);
    fixedNormalCoupon.setTransactionMinimum(98400);
    couponUseRule.setFixedNormalCoupon(fixedNormalCoupon);
    request.setCouponUseRule(couponUseRule);

    // 发放规定
    StockSendRule stockSendRule = new StockSendRule();
    stockSendRule.setMaxCoupons(108);
    stockSendRule.setMaxCouponsPerUser(5);
    request.setStockSendRule(stockSendRule);

    BusiFavorStocksCreateResult result = wxPayService.getMarketingBusiFavorService().createBusiFavorStocksV3(request);
    String stockId = result.getStockId();


    System.out.println("stockId: [{}]" + stockId);

    return stockId;
}

查问商家券详情

// 获取券详情
@PostMapping(value = "/port/to/get")
public AjaxResult getCouponDetails(@RequestBody Map<String, String> body) throws Exception {String stockId = body.get("stockId");

    BusiFavorStocksGetResult result = this.testGetBusiFavorStocksV3(stockId);

    return AjaxResult.success(result);
}

//  获取商家券详细信息
public BusiFavorStocksGetResult testGetBusiFavorStocksV3(String stockId) throws WxPayException {BusiFavorStocksGetResult result = wxPayService.getMarketingBusiFavorService().getBusiFavorStocksV3(stockId);
    System.out.println(result);

    return result;
}

生成小程序版本 发商户券 申请所需参数

@Resource
private WxPayService wxPayService;

// 生成小程序版本 发商户券 申请所需参数
@GetMapping(value = "/get/coupon/params/{stockId}")
public Map<String, String> generateCouponParams(@PathVariable("stockId") String stockId) throws Exception {Coupon coupon = couponMapper.selectCouponByStockId(stockId);

    BusiFavorCouponsUrlRequest request = new BusiFavorCouponsUrlRequest();
    request.setOutRequestNo(coupon.getOutRequestNo);
    request.setSendCouponMerchant(this.wxPayService.getConfig().getMchKey());
    request.setStockId(stockId);
    // 签名
    String sign = this.buildBusiFavorCouponinfoMiniapp(request);

    Map<String, String> result = new HashMap<>();
    result.put("stock_id", stockId);
    result.put("out_request_no", request.getOutRequestNo());
    result.put("sign", request.getSign());
    result.put("send_coupon_merchant", request.getSendCouponMerchant());

    return result;
}

// 签名
public String buildBusiFavorCouponinfoMiniapp(BusiFavorCouponsUrlRequest request) throws WxPayException {// 官网签名拼接要求 ( 留神 out_request_no0 和 stock_id0 字段最初有 0,即便是 1 张券)
    // out_request_no0=abc123&send_coupon_merchant=10016226&stock_id0=1234567&key=xxxxx

    Map<String, String> signMap = new HashMap<>(8);
    signMap.put("out_request_no0", request.getOutRequestNo());
    signMap.put("send_coupon_merchant", request.getSendCouponMerchant());
    signMap.put("stock_id0", request.getStockId());

    String sign = SignUtils.createSign(signMap, WxPayConstants.SignType.HMAC_SHA256, this.wxPayService.getConfig().getMchKey(), null);

    return sign;
}

前端

引入

step 1:

在 manifest.json 中点击源码视图, 在 mp-weixin 里增加:

"plugins": {  
    "sendCoupon": {  
        "version": "latest",  
        "provider": "wxf3f436ba9bd4be7b"  
    }  
}

step2:

在 pages.json 的 globalStyle 里增加

"usingComponents": {"send-coupon": "plugin://sendCoupon/send-coupon"}

step3:

在须要调用插件的页面中调用, 依照微信的对接文档对接即可. 惟一须要留神的是,发券的事件 bindcustomevent 改为 @customevent

<template>  
    <send-coupon  
        @customevent="couponCallback"  
        :send_coupon_params="send_coupon_params"  
        :sign="sign"  
        :send_coupon_merchant="send_coupon_merchant">  
        <view> 支付 </view>  
    </send-coupon>  
</template>

<script>
    export default {data() {
            return {
                send_coupon_params: [{
                    stock_id: "",
                    out_request_no: "",
                }],
                sign: '',
                send_coupon_merchant: ''
            }
        },
        methods: {async init() {const res = this.$http.get('/get/coupon/params/' + stockId);
                this.send_coupon_params = [{
                    stock_id: res.data.stock_id,
                    out_request_no: res.data.out_request_no
                }];
                this.sign = res.data.sign;
                this.send_coupon_merchant = res.data.send_coupon_merchant;
            }
            couponCallback(e) {
                // 外部有 coupon_code 等信息
                console.log(e);
            },
            onLoad() {this.init();
            }
        }
    }
</script>

END

正文完
 0