版权声明:原创文章转载请注明出处,谢谢。 https://blog.csdn.net/hexiaohua95/article/details/85016270
小程序支付SDK,刚开始做,网上找了很多,下载了三个demo,最后发现,这玩意还是需要个干货!
讲重点:
1.下载微信官方的SDK
https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1
选择下载java版本最佳实践。
2.将以下文件拷到你的项目中
3.在同文件夹下创建此继承类
package com.***.utils.wx;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
/**
* @Description: 微信支付配置类
* @Author: hm
* @CreateDate: 2018/12/10 17:19.
* @UpdateDate: 2018/12/10 17:19.
* @Version: 1.0
*/
public class MyConfig extends WXPayConfig {
private byte[] certData;
public MyConfig() throws Exception {
// String certPath = "classpath:apiclient_cert.p12";
// File file = new File(certPath);
// InputStream certStream = new FileInputStream(file);
// this.certData = new byte[(int) file.length()];
// certStream.read(this.certData);
// certStream.close();
}
@Override
public String getAppID() {
return "你的appid";
}
@Override
public String getMchID() {
return "你的商户id";
}
@Override
public String getKey() {
return "你的商户api安全key,在商户平台api安全目录下可设置";
}
@Override
public InputStream getCertStream() {
ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
return certBis;
}
@Override
public int getHttpConnectTimeoutMs() {
return 8000;
}
@Override
public int getHttpReadTimeoutMs() {
return 10000;
}
@Override
IWXPayDomain getWXPayDomain() {
return new IWXPayDomain() {
@Override
public void report(String domain, long elapsedTimeMillis, Exception ex) {
}
@Override
public DomainInfo getDomain(WXPayConfig config) {
return new DomainInfo("api.mch.weixin.qq.com", false);
}
};
}
}
4.java后台的调用统一下单接口类
/**
* 微信统一下单接口
* @return
*/
@RequestMapping(value = "/doUnifiedOrder", method = RequestMethod.POST)
public BaseResponse<Map> doUnifiedOrder(@RequestBody BaesRequest<LicensePlate> baseRequest) {
BaseResponse<Map> response = new BaseResponse<>();
Map resultMap=new HashMap();
String openid = baseRequest.getRequestData().getOpenId();
MyConfig config = null;
WXPay wxpay =null;
try {
config = new MyConfig();
wxpay= new WXPay(config);
} catch (Exception e) {
e.printStackTrace();
}
//生成的随机字符串
String nonce_str = WXPayUtil.generateNonceStr();
//获取客户端的ip地址
//获取本机的ip地址
InetAddress addr = null;
try {
addr = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
e.printStackTrace();
}
String spbill_create_ip = addr.getHostAddress();
//支付金额,需要转成字符串类型,否则后面的签名会失败
int total_fee=1;
//商品描述
String body = "车费支付";
//商户订单号
String out_trade_no= WXPayUtil.generateNonceStr();
//统一下单接口参数
HashMap<String, String> data = new HashMap<String, String>();
data.put("appid", appid);
data.put("mch_id", mch_id);
data.put("nonce_str", nonce_str);
data.put("body", body);
data.put("out_trade_no",out_trade_no);
data.put("total_fee", String.valueOf(total_fee));
data.put("spbill_create_ip", spbill_create_ip);
data.put("notify_url", notify_url);
data.put("trade_type",TRADETYPE);
data.put("openid", openid);
try {
Map<String, String> rMap = wxpay.unifiedOrder(data);
System.out.println("统一下单接口返回: " + rMap);
String return_code = (String) rMap.get("return_code");
String result_code = (String) rMap.get("result_code");
String nonceStr = WXPayUtil.generateNonceStr();
resultMap.put("nonceStr", nonceStr);
Long timeStamp = System.currentTimeMillis() / 1000;
if ("SUCCESS".equals(return_code) && return_code.equals(result_code)) {
String prepayid = rMap.get("prepay_id");
resultMap.put("package", "prepay_id="+prepayid);
resultMap.put("signType", "MD5");
//这边要将返回的时间戳转化成字符串,不然小程序端调用wx.requestPayment方法会报签名错误
resultMap.put("timeStamp", timeStamp + "");
//再次签名,这个签名用于小程序端调用wx.requesetPayment方法
resultMap.put("appId",appid);
String sign = WXPayUtil.generateSignature(resultMap, key);
resultMap.put("paySign", sign);
System.out.println("生成的签名paySign : "+ sign);
response.setData(resultMap);
return response;
}else{
return response;
}
} catch (Exception e) {
e.printStackTrace();
return response;
}
}
5.小程序端的支付请求
payNow: function() {
var that = this;
wx.request({
url: app.data.requestUrl + 'weChatPay/doUnifiedOrder',
header: {
"Content-Type": "application/json;charset=UTF-8"
},
data: {
requestData: {
openId: app.globalData.openId
}
},
method: 'POST',
dataType: 'json',
responseType: 'text',
success: function(res) {
console.log("服务端返回订单号");
var c=res.data;
wx.requestPayment({
timeStamp: res.data.data.timeStamp,
nonceStr: res.data.data.nonceStr,
package: res.data.data.package,
signType: 'MD5',
paySign: res.data.data.paySign,
success(res) {
console.log("统一下单接口成功");
},
fail(res) {
console.log("统一下单接口失败");
}
});
},
fail: function(res) {},
complete: function(res) {},
});
}
6.超简单支付过程,只需要修改配置文件中你自己的appid等信息就可以使用了。文中没有java后台的业务逻辑,可以自己添加,这里主要实现支付功能。(为了隐私,截图中屏蔽了主体信息。)
补充:有人问BaseResponse类,只是项目中封装的一个父类,你们在自己项目可以不用管的。但还是把这两个类贴在这里吧。
BaseResponse类
public class BaseResponse<T> {
/**
* 状态码 200是成功,300是失败,301是超时
*/
private String statusCode = "200";
/**
* 错误信息, example = "error"
*/
private String message;
/**
* 返回前台的数据
*/
private T data;
public BaseResponse() {
super();
}
public BaseResponse(String statusCode, String message) {
super();
this.statusCode = statusCode;
this.message = message;
}
public BaseResponse failure() {
this.statusCode = "300";
this.message = "Response exception";
return this;
}
public BaseResponse failure(String massage) {
this.statusCode = "300";
this.message = massage;
return this;
}
public String getStatusCode() {
return statusCode;
}
public void setStatusCode(String statusCode) {
this.statusCode = statusCode;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public T getData() {
return data;
}
public void setData(T data) {
this.data = data;
}
}
BaseRequest类
public class BaesRequest<T> {
/**
* 请求对象
*/
T requestData;
public BaesRequest(){
super();
}
public T getRequestData(){
return requestData;
}
public void setRequestData(T requestData) {
this.requestData = requestData;
}
}