700字范文,内容丰富有趣,生活中的好帮手!
700字范文 > 微信支付-小程序支付全流程

微信支付-小程序支付全流程

时间:2019-06-23 09:14:29

相关推荐

微信支付-小程序支付全流程

点击蓝色字关注我们!

一个努力中的公众号

长的好看的人都关注了

本文给大家讲解微信小程序支付全流程,以及相关功能源代码,项目不开放,带来不便尽请谅解。小程序支付主要包含如下几步骤,1.预下单-调用微信统一下单接口进行预下单。2.小程序拿到支付参数唤醒支付。3.支付成功后发起退款申请

本文使用okHttpUtil进行接口交互使用goole的gson与阿里的fastJson进行解析JsonObect,

使用封装的http工具类进行携带证书进行接口交互

使用封装的工具类实现map转xml等。相关工具类代码过多,所以在本文最后有下载方式

下面是正文:

微信支付文档:https://pay./wiki/doc/api/wxa/wxa_api.php?chapter=9_1

一.获取微信用户的openId:

用户登录小程序通过授权得到微信code,然后将微信code、秘钥、密文传递后端,后端进行解密后得到微信openId(前端也可以进行解密,但建议放后端)

下面是获取openId的代码(java)

//微信接口url

https://api./sns/jscode2session

/*** 解析小程序登录数据获取参数* @param code ---微信code* @param encryptedData --- 加密参数* @param iv --- 秘钥* @return*/public Result<?> getAuthByApplet(String code, String encryptedData,String iv) {Map<String, Object> resultMap = new HashMap<>();try {log.debug("=========小程序获取unionId=============: "+ code);//封装参数Map<String, String> params = new HashMap<String, String>();//获取小程序的openIdparams.put("appid", appletId);//微信秘钥params.put("secret", appletSecret);params.put("js_code", code);params.put("grant_type", "authorization_code");//调用接口进行读取参数JsonObject retJson = OkHttpUtils.doGetRetJson(appletOpenIdUrl, params);log.debug(retJson.toString());//如果获取到了openIdif(retJson.get("openid") != null) {//获取会话密钥(session_key)String session_key = retJson.get("session_key").getAsString();resultMap.put("session_key", session_key);resultMap.put("openId", retJson.get("openid").getAsString());}else{throw new Exception("code已失效,请重新获取");}return Result.ok(resultMap);} catch (Exception e) {log.error(e.getMessage(), e);throw new RuntimeException();}}

得到openId后要进行业务保存,因为小程序很多接口都依赖openId,而且同一小程序下,每个微信号的openId是一样的。

二:统一下单与小程序支付

通过业务系统的封装参数,得到支付的商品信息,价格,业务订单后,封装参数,进行加密得到sign签名,然后调用统一下单接口进行下单,成功后返回小程序支付参数。

(需要注意的是微信预下单请求参数要求是xml格式,全String类型)

//微信预下单接口url

https://api.mch./pay/unifiedorder

/**

* 微信支付-统一下单

* @param body --- 商品描述

* @param outTradeNo --- 业务系统订单号

* @param totalFee --- 支付金额

* @param spBillCreateIP ---支付人所在

* @param openId --- 支付人的微信openId

* @return

*/

@Override

public Map<String, String> toPay(String body, String outTradeNo, String totalFee, String spBillCreateIP, String openId) {

try{

Map<String, String> map = new HashMap<>(); //封装支付必须参数

SortedMap<Object,Object> params = new TreeMap<Object,Object>();

//支付类型 String tradeType = "JSAPI";

//支付后回调地址

String notifyUrl = "";

String nonceStr = RandomUtil.randomString(16);

//小程序id

params.put("appid", appletId);

//商户平台id

params.put("mch_id", mchId);

//随机字符串

params.put("nonce_str", nonceStr);

//商品描述

params.put("body", body);

//商品订单号

params.put("out_trade_no", outTradeNo);

//价格的单位为分

params.put("total_fee", totalFee);

//支付ip

params.put("spbill_create_ip", spBillCreateIP);

//异步回调api

params.put("notify_url", notifyUrl);

//JSAPI、h5调用

params.put("trade_type", tradeType);

//支付用户openid

params.put("openid", openId);

String sign = WxPaySignatureUtils.createSign(params, key);

params.put("sign", sign);

String requestXML = WxPaySignatureUtils.getRequestXml(params);

log.info("发送给微信的报文:" + requestXML);

log.info("加密后的的签名字符串:" + sign);

//调用微信接口

String result = OkHttpUtils.postXml(unifiedorder, requestXML);

log.info("-------------------请求返回结果------------------");

log.info(result);

map = WXPayUtil.xmlToMap(result);

//如果返回有数据

if(map != null){

//并且返回有sign

if(map.get("sign") != null){

return map;

}

}

return map;

}catch (Exception e) {

log.error(e.getMessage(), e);

throw new RuntimeException();

}

}

接口请求成功后,微信返回也是xml格式的报文,需要将xml转为map或其他,本文使用map接收参数,预下单后,微信会返回预付订单标识,标识用于进支付

//预付订单标识String prepayId = resultMap.get("prepay_id");

然后封装小程序支付所需参数

//签名类型,默认为MD5String signType = "MD5";SortedMap<Object,Object> params = new TreeMap<Object,Object>();params.put("appId", appletId);params.put("timeStamp", timestamp + "");params.put("timeStamp", timestamp + "");params.put("nonceStr", nonceStr);params.put("package", "prepay_id=" + prepayId);params.put("signType", signType);//生成签名String sign = WxPaySignatureUtils.createSign(params, key);params.put("paySign", sign);

将支付参数返回给小程序,小程序通过组件requestPayment唤醒支付

小程序支付代码如下:

wx.requestPayment({

timeStamp:param.result.timeStamp,

nonceStr:param.result.nonceStr,

package:param.result.package,

signType:param.result.signType,

paySign:param.result.paySign,

success:function(res){

console.log(res);

wx.showToast({

title:'支付成功',

icon:'success',

duration:2000

});

},

fail:function(res){

wx.showModal({

title:'支付失败',

content:'<text>',

showCancel:false

})

}

})

三: 退款

小程序支付成功后,可以通过支付订单号进行退款操作,需要注意的是,退款需要http携带商户证书进行支付,这里图图已经封装好工具类只需要修改下证书的url就可以愉快使用了

//微信退款使用的url

https://api.mch./secapi/pay/refund

/*** 微信支付-退款* @param transaction_id ---微信支付订单* @param out_refund_no --- 系统退款单号* @param total_fee --- 订单总金额* @param refund_fee --- 退款金额* @return*/@Overridepublic Map<String, String> refundToPay(String transaction_id, String out_refund_no, String out_trade_no, int total_fee, int refund_fee) {//定义返回参数Map<String, String> map = new HashMap<>();try{SortedMap<Object,Object> params = new TreeMap<Object,Object>();String notifyUrl = "";String nonceStr = RandomUtil.randomString(16);//小程序idparams.put("appid", appletId);//商户平台idparams.put("mch_id", mchId);//随机字符串params.put("nonce_str", nonceStr);//系统订单号params.put("out_trade_no", out_trade_no);//微信订单号params.put("transaction_id", transaction_id);//系统退款单号params.put("out_refund_no", out_refund_no);//订单金额params.put("total_fee", total_fee);//退款金额params.put("refund_fee", refund_fee);//签名String sign = WxPaySignatureUtils.createSign(params, key);params.put("sign", sign);//封装请求报文String requestXML = WxPaySignatureUtils.getRequestXml(params);log.info("发送给微信的报文:" + requestXML);log.info("加密后的的签名字符串:" + sign);//调用微信接口String result = WXPayUtil.doRefundRequest(mchId, refund, requestXML, certificateUrl);log.info("-------------------请求返回结果------------------");log.info(result);if(StrUtil.isNotEmpty(result)){map = WXPayUtil.xmlToMap(result);//如果返回有数据if(map != null){//并且返回有signif(map.get("sign") != null){return map;}}}else{log.info("-------------------请求返回空结果------------------");}return map;}catch (Exception e) {log.error(e.getMessage(), e);throw new RuntimeException();}}

本文中所使用到的工具类,图图已经帮大家打包好了,一份在百度网盘,为防止百度网盘失效,在图图的QQ群中也有一份。

百度网盘下载链接

链接:/s/1YbMrvO3qK1rdmyYyET2xzw

提取码:ljv6

本文先总结到此,后面继续更新技术一些文章。大家一起加油鸭!

如果对您有帮助 请点个关注,万分感谢

(QQ招聘群 710566091

微信招聘群 请加图图微信)

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。