个人小程序如何申请微信支付功能? 给大家看看效果
![]()
一、准备材料
① 个体户营业执照
可以去当地 工商局免费办理(一般提供一个地址,三份身份证复印件) 可以去淘宝代理,收费(60-200元)
②新的QQ邮箱
目前一个手机号码可以注册5个,民生手机号码不能注册QQ
③服务器,域名
材料准备号。 现在开始认证小程序
二、认证小程序
①自我认证(300元)
②三方认证(淘宝19.9元)
需要材料是 需要提供认证小程序: 法人姓名 二、法人微信号 3.法人手机号 4.营业执照全称 5.统一信用代码号
三、支付商户号申请
申请支付需提供信息: 1.营业执照照片 2.法人身份证正反面 3、门头照片 店里每张照片 (如果已经有小程序不需要提供) 4.公司需要提供公共账户(个人需要以法人名义提供银行卡的区域是哪个) 5.手机号,邮箱
到目前为止,所有的准备工作都很好,你可以写代码
四、写代码
分析思路
1、 JSAPI下单(生成预付款id)
请求参数 官方文档:https://pay.weixin.qq.com/wiki/doc/apiv3/apis/chapter3_1_1.shtml
{
"mchid": "1900006XXX", //后台获取 "out_trade_no": "1217752501201407033233368318", ///自行生成 "appid": "wxdace645e0bc2cXXX", //后台获取 "description": "Image形象店-深圳腾大-QQ公仔", ///自行填写 "notify_url": "https://weixin.qq.com/", ///自行填写(一般自己的域名) "amount": {
"total": 1, ///自行填写 "currency": "CNY" //固定填写 }, "payer": {
"openid": "o4GgauInH_RCEdvrrNGrntXDuXXX" //用户的openid } }
返回:
{
"prepay_id": "wx26112221580621e9b071c00d9e093b0000" }
2、返回 wx.requestPayment 需要参数
官方文档:https://developers.weixin.qq.com/miniprogram/dev/api/payment/wx.requestPayment.html
wx.requestPayment({
timeStamp: '', nonceStr: '', package: '', signType: 'MD5',
paySign: '',
success (res) {
},
fail (res) {
}
})
3、引入的依赖
<dependency>
<groupId>com.github.wechatpay-apiv3</groupId>
<artifactId>wechatpay-apache-httpclient</artifactId>
<version>0.3.0</version>
</dependency>
4、Service 代码
/** * 微信支付 * @param code 解析code出openid * @param des 商品描述 * @param total 金额 * @param appId 小程序appid * @param secret 小程序秘钥 * @return 结果 * @throws Exception 抛出异常 */ public ResultInfo pay(String code, String des, double total,String appId,String secret ) throws Exception { //1、参数准备 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ObjectMapper objectMapper = new ObjectMapper(); //解析openId String openId = weChatService.analysisOpenId(code, appId,secret); ObjectNode rootNode = objectMapper.createObjectNode(); rootNode.put("mchid", WxConfig.mchId) //商户号 .put("appid", appId) //小程序appid .put("description", des) //商品描述 .put("notify_url", WxConfig.notify_url) //通知地址 .put("out_trade_no", System.currentTimeMillis() + "");//订单号 rootNode.putObject("amount") .put("total", (long) (total * 100));//金额:单位是分 乘100换成元 rootNode.putObject("payer") .put("openid", openId);//客户openid objectMapper.writeValue(bos, rootNode); //2、解析证书 PrivateKey merchantPrivateKey = PemUtil.loadPrivateKey(WxConfig.privateKey); //使用定时更新的签名验证器,不需要传入证书 ScheduledUpdateCertificatesVerifier verifier = new ScheduledUpdateCertificatesVerifier( new WechatPay2Credentials(WxConfig.mchId, new PrivateKeySigner(WxConfig.mchSerialNumber, merchantPrivateKey)), WxConfig.apiV3Key.getBytes(StandardCharsets.UTF_8)); //通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新 WechatPayHttpClientBuilder builder = WechatPayHttpClientBuilder.create() .withMerchant(WxConfig.mchId, WxConfig.mchSerialNumber, merchantPrivateKey) .withValidator(new WechatPay2Validator(verifier)); // 通过WechatPayHttpClientBuilder构造的HttpClient,会自动的处理签名和验签,并进行证书自动更新 HttpClient httpClient = builder.build(); HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi"); httpPost.addHeader("Accept", "application/json"); httpPost.addHeader("Content-type", "application/json; charset=utf-8"); httpPost.setEntity(new StringEntity(bos.toString("UTF-8"), "UTF-8")); //开始请求 HttpResponse response = httpClient.execute(httpPost); //得到结果 String bodyAsString = EntityUtils.toString(response.getEntity()); //处理结果 JSONObject jsonObject = JSONObject.parseObject(bodyAsString); //出现错误,抛出 if (jsonObject.containsKey("code")) { ThrowException.illegal(true, jsonObject.getString("message")); } //3、加密
标签 String prepay_id = jsonObject.getString("prepay_id");//预支付id String timeStamp = String.valueOf(System.currentTimeMillis());//时间戳 String nonceStr = createRandomStringByLength(32);//32位随机数 //字符串连接 StringBuffer stringBuffer = new StringBuffer(); stringBuffer.append(appId + "\n");//appid stringBuffer.append(timeStamp + "\n");//时间戳 stringBuffer.append(nonceStr + "\n");//随机数 stringBuffer.append("prepay_id=" + prepay_id + "\n");//预支付id Signature signature = Signature.getInstance("SHA256withRSA"); signature.initSign(merchantPrivateKey); signature.update(stringBuffer.toString().getBytes("UTF-8")); byte[] signBytes = signature.sign(); String paySign = Base64.encodeBytes(signBytes);//加密 //返回结果 JSONObject params = new JSONObject(); params.put("appId", appId); params.put("timeStamp", timeStamp); params.put("nonceStr", nonceStr); params.put("prepay_id", prepay_id); params.put("signType", "RSA"); params.put("paySign", paySign); ResultInfo resultInfo = new ResultInfo(); resultInfo.setResult(params); return resultInfo; } //生产随机数 private String createRandomStringByLength(int length) { Random random = new Random(); StringBuffer sb = new StringBuffer(); for (int i = 0; i < length; i++) { int number = random.nextInt(WxConfig.base.length()); sb.append(WxConfig.base.charAt(number)); } return sb.toString(); }
// code解析出openId
public String analysisOpenId(String code,String appid,String secret){
String url = "https://api.weixin.qq.com/sns/jscode2session" + //固定
"?appid=" + appid + //小程序id
"&secret=" + secret + //小程序密码
"&js_code=" + code +
"&grant_type=authorization_code"; //固定
RestTemplate restTemplate = new RestTemplate();
String str = restTemplate.getForObject(url, String.class);
WeChatCode weChatCode=JSON.parseObject(str, WeChatCode.class);
if (weChatCode==null){
ThrowException.illegal(true,"code获取openId失败");
return null;
}else{
return weChatCode.getOpenid();
}
}
5、小程序 封装的支付
const pay = function (des, total) {
return new Promise((resolve, reject) => {
wx.showLoading({
title: '加载中...',
})
wx.login({
success(res) {
wx.request({
url: 'https://xxxx.com:8080/KYB/WeChat/getPrePayId',
data: {
code: res.code,
des: des,
total: total,
},
header: {
"content-type": "application/x-www-form-urlencoded"
},
method: 'GET',
success: res => {
if (res.data.code == 200) {
wx.hideLoading();
const params = res.data.result;
wx.requestPayment({
timeStamp: params.timeStamp + '',
nonceStr: params.nonceStr,
package: 'prepay_id=' + params.prepay_id,
signType: params.signType,
paySign: params.paySign,
success(res) {
resolve("success")
},
fail(res) {
reject("fail")
}
})
} else {
wx.showModal({
title: res.data.msg,
showCancel: false
})
reject("返回失败");
}
}
})
}
})
})
}
module.exports = pay;