Java语言开发微信小程序支付功能:
2.下载后将pom文件中需要用到的jar包导入自己的项目中,将demo全部导入到自己的工具包中,需导入的demo如下图:
3.此时缺少IWXPayDomain与WXPayConfig抽象类的具体实现,新建WXPayDomainSimpleImpl与WXPayConfigImpl来分别实现抽象类,代码如下:
WXPayDomainSimpleImpl代码:
1 packagecom.karat.cn.util;2 importorg.apache.http.conn.ConnectTimeoutException;3
4 importjava.net.UnknownHostException;5 importjava.util.HashMap;6 importjava.util.Map;7
8 /**
9 * Created by blaketang on 2017/6/16.10 */
11 public class WXPayDomainSimpleImpl implementsIWXPayDomain {12 privateWXPayDomainSimpleImpl(){}13 private static classWxpayDomainHolder{14 private static IWXPayDomain holder = newWXPayDomainSimpleImpl();15 }16 public staticIWXPayDomain instance(){17 returnWxpayDomainHolder.holder;18 }19
20 public synchronized void report(final String domain, long elapsedTimeMillis, finalException ex) {21 DomainStatics info =domainData.get(domain);22 if(info == null){23 info = newDomainStatics(domain);24 domainData.put(domain, info);25 }26
27 if(ex == null){ //success
28 if(info.succCount >= 2){ //continue succ, clear error count
29 info.connectTimeoutCount = info.dnsErrorCount = info.otherErrorCount = 0;30 }else{31 ++info.succCount;32 }33 }else if(ex instanceofConnectTimeoutException){34 info.succCount = info.dnsErrorCount = 0;35 ++info.connectTimeoutCount;36 }else if(ex instanceofUnknownHostException){37 info.succCount = 0;38 ++info.dnsErrorCount;39 }else{40 info.succCount = 0;41 ++info.otherErrorCount;42 }43 }44
45 public synchronized DomainInfo getDomain(finalWXPayConfig config) {46 DomainStatics primaryDomain =domainData.get(WXPayConstants.DOMAIN_API);47 if(primaryDomain == null ||
48 primaryDomain.isGood()) {49 return new DomainInfo(WXPayConstants.DOMAIN_API, true);50 }51
52 long now =System.currentTimeMillis();53 if(switchToAlternateDomainTime == 0){ //first switch
54 switchToAlternateDomainTime =now;55 return new DomainInfo(WXPayConstants.DOMAIN_API2, false);56 }else if(now - switchToAlternateDomainTime
59 alternateDomain.isGood() ||
60 alternateDomain.badCount()
66 switchToAlternateDomainTime = 0;67 primaryDomain.resetCount();68 DomainStatics alternateDomain =domainData.get(WXPayConstants.DOMAIN_API2);69 if(alternateDomain != null)70 alternateDomain.resetCount();71 return new DomainInfo(WXPayConstants.DOMAIN_API, true);72 }73 }74
75 static classDomainStatics {76 finalString domain;77 int succCount = 0;78 int connectTimeoutCount = 0;79 int dnsErrorCount =0;80 int otherErrorCount = 0;81
82 DomainStatics(String domain) {83 this.domain =domain;84 }85 voidresetCount(){86 succCount = connectTimeoutCount = dnsErrorCount = otherErrorCount = 0;87 }88 boolean isGood(){ return connectTimeoutCount <= 2 && dnsErrorCount <= 2; }89 intbadCount(){90 return connectTimeoutCount + dnsErrorCount * 5 + otherErrorCount / 4;91 }92 }93 private final int MIN_SWITCH_PRIMARY_MSEC = 3 * 60 * 1000; //3 minutes
94 private long switchToAlternateDomainTime = 0;95 private Map domainData = new HashMap();96 }
View Code
WXPayConfigImpl代码:
1 packagecom.karat.cn.util;2
3 importjava.io.File;4 importjava.io.FileInputStream;5 importjava.io.ByteArrayInputStream;6 importjava.io.InputStream;7
8
9 public class WXPayConfigImpl extendsWXPayConfig{10
11 /**==========================================================================**/
12 private byte[] certData;13 private staticWXPayConfigImpl INSTANCE;14
15 private WXPayConfigImpl() throwsException{16 String certPath = WXPayConfigImpl.class.getClassLoader().getResource("").getPath();17 File file = new File(certPath + "apiclient_cert.p12");18 InputStream certStream = newFileInputStream(file);19 this.certData = new byte[(int) file.length()];20 certStream.read(this.certData);21 certStream.close();22 }23
24 public static WXPayConfigImpl getInstance() throwsException{25 if (INSTANCE == null) {26 synchronized (WXPayConfigImpl.class) {27 if (INSTANCE == null) {28 INSTANCE = newWXPayConfigImpl();29 }30 }31 }32 returnINSTANCE;33 }34
35 /**==========================================================================**/
36 @Override37 publicString getAppID() {38 //TODO Auto-generated method stub
39 return "小程序AppId";40 }41
42 @Override43 publicString getMchID() {44 //TODO Auto-generated method stub
45 return "商户号";46 }47
48 @Override49 publicString getKey() {50 //TODO Auto-generated method stub
51 return "商户密钥";52 }53
54 @Override55 publicInputStream getCertStream() {56 //TODO Auto-generated method stub
57 ByteArrayInputStream certBis;58 certBis = new ByteArrayInputStream(this.certData);59 returncertBis;60 }61
62 @Override63 publicIWXPayDomain getWXPayDomain() {64 //TODO Auto-generated method stub
65 returnWXPayDomainSimpleImpl.instance();66 }67
68 }
View Code
4.向WXPayConstants.java中添加常量:
1 public static final String TRANSFERS_URL_SUFFIX = "/mmpaymkttransfers/promotion/transfers";2 public static final String SANDBOX_SENDREDPACK_URL_SUFFIX = "/sandboxnew/mmpaymkttransfers/sendredpack";3 public static final String SANDBOX_TRANSFERS_URL_SUFFIX = "/sandboxnew/mmpaymkttransfers/promotion/transfers";
5.向WXPay.java中添加如下代码:
1 /********************************************/
2 //企业付款
3 public String transfers(Map reqData) throwsException {4 return this.transfers(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());5 }6 public String transfers(Map reqData, int connectTimeoutMs, int readTimeoutMs) throwsException {7 String url;8 if (this.useSandbox) {9 url =WXPayConstants.SANDBOX_TRANSFERS_URL_SUFFIX;10 }11 else{12 url =WXPayConstants.TRANSFERS_URL_SUFFIX;13 }14 return this.requestWithCert(url, this.transfersRequestData(reqData), connectTimeoutMs, readTimeoutMs);15 }16 //企业付款
17 public Map transfersRequestData(Map reqData) throwsException {18 //商户号绑定的appid(小程序的appid)
19 reqData.put("mch_appid", config.getAppID());20 //商户号
21 reqData.put("mchid", config.getMchID());22 //随机字符串
23 reqData.put("nonce_str", WXPayUtil.generateUUID());24 reqData.put("sign", WXPayUtil.generateSignature(reqData, config.getKey(), this.signType));25 returnreqData;26 }27
28 /********************************************/
View Code
6.创建订单表以及返回给小程序端的参数vo
1 packagecom.karat.cn.wxCommon;2
3 importjava.util.Map;4
5 importorg.springframework.data.annotation.Id;6 importorg.springframework.data.mongodb.core.index.Indexed;7 importorg.springframework.data.mongodb.core.mapping.Document;8
9 /**
10 * 订单表11 *@author开发12 *13 */
14 @Document(collection = "wxWithdrawOrder")15 public classWxWithdrawOrder {16 /**
17 * id18 */
19 @Id20 privateString id;21 /**
22 * 会员id23 */
24 @Indexed25 privateString memberId;26 /**
27 * 订单号28 */
29 @Indexed(unique = true)30 privateString orderNo;31 /**
32 * 提现金额(分)33 */
34 private intmoney;35 /**
36 * 提现时间37 */
38 privateString createDate;39 /**
40 * 订单状态(0:申请失败或异常 1:已申请成功)41 */
42 privateString orderStatus;43 /**
44 * 扩展45 */
46 private Mapremark;47 /**
48 * 扩展249 */
50 privateString remark2;51
52
53 publicString getId() {54 returnid;55 }56 public voidsetId(String id) {57 this.id =id;58 }59 publicString getMemberId() {60 returnmemberId;61 }62 public voidsetMemberId(String memberId) {63 this.memberId =memberId;64 }65 publicString getOrderNo() {66 returnorderNo;67 }68 public voidsetOrderNo(String orderNo) {69 this.orderNo =orderNo;70 }71 public intgetMoney() {72 returnmoney;73 }74 public void setMoney(intmoney) {75 this.money =money;76 }77 publicString getCreateDate() {78 returncreateDate;79 }80 public voidsetCreateDate(String createDate) {81 this.createDate =createDate;82 }83 public MapgetRemark() {84 returnremark;85 }86 public void setRemark(Mapremark) {87 this.remark =remark;88 }89 publicString getRemark2() {90 returnremark2;91 }92 public voidsetRemark2(String remark2) {93 this.remark2 =remark2;94 }95 publicString getOrderStatus() {96 returnorderStatus;97 }98 public voidsetOrderStatus(String orderStatus) {99 this.orderStatus =orderStatus;100 }101 }
View Code
1 packagecom.karat.cn.vo;2 /**
3 * 调用微信支付相关信息4 *@author开发5 *6 */
7 public classVoUnifiedOrderWx {8 //时间戳
9 privateString timeStamp;10 //随机串
11 privateString nonceStr;12 //数据包
13 privateString packageValue;14 //签名
15 privateString sign;16
17 publicString getTimeStamp() {18 returntimeStamp;19 }20 public voidsetTimeStamp(String timeStamp) {21 this.timeStamp =timeStamp;22 }23 publicString getNonceStr() {24 returnnonceStr;25 }26 public voidsetNonceStr(String nonceStr) {27 this.nonceStr =nonceStr;28 }29 publicString getPackageValue() {30 returnpackageValue;31 }32 public voidsetPackageValue(String packageValue) {33 this.packageValue =packageValue;34 }35 publicString getSign() {36 returnsign;37 }38 public voidsetSign(String sign) {39 this.sign =sign;40 }41
42 }
View Code
7.创建工具类(获取系统时间)
1 packagecom.karat.cn.wxCommon;2
3 importjava.text.ParseException;4 importjava.util.Date;5
6 public classBaseToolsUtil {7 /**
8 * 获取系统时间long9 *10 *@return
11 *@throwsParseException12 */
13 public static longsystemtimeLong() {14 return newDate().getTime();15 }16 }
View Code
8.准备工作完毕,开始实现小程序支付,退款,提现功能。