• 微信小程序支付(基于Java实现微信JSAPI支付):SDK与DEMO下载整理


    Java语言开发微信小程序支付功能:

    1.通过https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=11_1路径到官方下载Java的支付SDK。

    2.下载后将pom文件中需要用到的jar包导入自己的项目中,将demo全部导入到自己的工具包中,需导入的demo如下图:

    3.此时缺少IWXPayDomain与WXPayConfig抽象类的具体实现,新建WXPayDomainSimpleImpl与WXPayConfigImpl来分别实现抽象类,代码如下:

    WXPayDomainSimpleImpl代码:

     1 package com.karat.cn.util;
     2 import org.apache.http.conn.ConnectTimeoutException;
     3 
     4 import java.net.UnknownHostException;
     5 import java.util.HashMap;
     6 import java.util.Map;
     7 
     8 /**
     9  * Created by blaketang on 2017/6/16.
    10  */
    11 public class WXPayDomainSimpleImpl implements IWXPayDomain {
    12     private WXPayDomainSimpleImpl(){}
    13     private static class WxpayDomainHolder{
    14         private static IWXPayDomain holder = new WXPayDomainSimpleImpl();
    15     }
    16     public static IWXPayDomain instance(){
    17         return WxpayDomainHolder.holder;
    18     }
    19 
    20     public synchronized void report(final String domain, long elapsedTimeMillis, final Exception ex) {
    21         DomainStatics info = domainData.get(domain);
    22         if(info == null){
    23             info = new DomainStatics(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 instanceof ConnectTimeoutException){
    34             info.succCount = info.dnsErrorCount = 0;
    35             ++info.connectTimeoutCount;
    36         }else if(ex instanceof UnknownHostException){
    37             info.succCount = 0;
    38             ++info.dnsErrorCount;
    39         }else{
    40             info.succCount = 0;
    41             ++info.otherErrorCount;
    42         }
    43     }
    44 
    45     public synchronized DomainInfo getDomain(final WXPayConfig 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 < MIN_SWITCH_PRIMARY_MSEC){
    57             DomainStatics alternateDomain = domainData.get(WXPayConstants.DOMAIN_API2);
    58             if(alternateDomain == null ||
    59                 alternateDomain.isGood() ||
    60                 alternateDomain.badCount() < primaryDomain.badCount()){
    61                 return new DomainInfo(WXPayConstants.DOMAIN_API2, false);
    62             }else{
    63                 return new DomainInfo(WXPayConstants.DOMAIN_API, true);
    64             }
    65         }else{  //force switch back
    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 class DomainStatics {
    76         final String 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         void resetCount(){
    86             succCount = connectTimeoutCount = dnsErrorCount = otherErrorCount = 0;
    87         }
    88         boolean isGood(){ return connectTimeoutCount <= 2 && dnsErrorCount <= 2; }
    89         int badCount(){
    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<String, DomainStatics> domainData = new HashMap<String, DomainStatics>();
    96 }
    View Code

    WXPayConfigImpl代码:

     1 package com.karat.cn.util;
     2 
     3 import java.io.File;
     4 import java.io.FileInputStream;
     5 import java.io.ByteArrayInputStream;
     6 import java.io.InputStream;
     7 
     8 
     9 public class WXPayConfigImpl extends WXPayConfig{
    10 
    11     /**==========================================================================**/
    12     private byte[] certData;
    13     private static WXPayConfigImpl INSTANCE;
    14 
    15     private WXPayConfigImpl() throws Exception{
    16         String certPath = WXPayConfigImpl.class.getClassLoader().getResource("").getPath();
    17         File file = new File(certPath + "apiclient_cert.p12");
    18         InputStream certStream = new FileInputStream(file);
    19         this.certData = new byte[(int) file.length()];
    20         certStream.read(this.certData);
    21         certStream.close();
    22     }
    23 
    24     public static WXPayConfigImpl getInstance() throws Exception{
    25         if (INSTANCE == null) {
    26             synchronized (WXPayConfigImpl.class) {
    27                 if (INSTANCE == null) {
    28                     INSTANCE = new WXPayConfigImpl();
    29                 }
    30             }
    31         }
    32         return INSTANCE;
    33     }
    34     
    35     /**==========================================================================**/
    36     @Override
    37     public String getAppID() {
    38         // TODO Auto-generated method stub
    39         return "小程序AppId";
    40     }
    41 
    42     @Override
    43     public String getMchID() {
    44         // TODO Auto-generated method stub
    45         return "商户号";
    46     }
    47 
    48     @Override
    49     public String getKey() {
    50         // TODO Auto-generated method stub
    51         return "商户密钥";
    52     }
    53 
    54     @Override
    55     public InputStream getCertStream() {
    56         // TODO Auto-generated method stub
    57         ByteArrayInputStream certBis;
    58         certBis = new ByteArrayInputStream(this.certData);
    59         return certBis;
    60     }
    61 
    62     @Override
    63     public IWXPayDomain getWXPayDomain() {
    64         // TODO Auto-generated method stub
    65         return WXPayDomainSimpleImpl.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<String, String> reqData) throws Exception {
     4         return this.transfers(reqData, config.getHttpConnectTimeoutMs(), this.config.getHttpReadTimeoutMs());
     5     }
     6     public String transfers(Map<String, String> reqData,  int connectTimeoutMs, int readTimeoutMs) throws Exception {
     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<String, String> transfersRequestData(Map<String, String> reqData) throws Exception {
    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         return reqData;
    26     }
    27     
    28     /********************************************/
    View Code

    6.创建订单表以及返回给小程序端的参数vo

      1 package com.karat.cn.wxCommon;
      2 
      3 import java.util.Map;
      4 
      5 import org.springframework.data.annotation.Id;
      6 import org.springframework.data.mongodb.core.index.Indexed;
      7 import org.springframework.data.mongodb.core.mapping.Document;
      8 
      9 /**
     10  * 订单表
     11  * @author 开发
     12  *
     13  */
     14 @Document(collection = "wxWithdrawOrder")
     15 public class WxWithdrawOrder {
     16     /**
     17      * id
     18      */
     19     @Id
     20     private String id;
     21     /**
     22      * 会员id
     23      */
     24     @Indexed
     25     private String memberId;
     26     /**
     27      * 订单号
     28      */
     29     @Indexed(unique = true)
     30     private String orderNo;
     31     /**
     32      * 提现金额(分)
     33      */
     34     private int money;
     35     /**
     36      * 提现时间
     37      */
     38     private String createDate;
     39     /**
     40      * 订单状态(0:申请失败或异常 1:已申请成功)
     41      */
     42     private String orderStatus;
     43     /**
     44      * 扩展
     45      */
     46     private Map<String, String> remark;
     47     /**
     48      * 扩展2
     49      */
     50     private String remark2;
     51     
     52     
     53     public String getId() {
     54         return id;
     55     }
     56     public void setId(String id) {
     57         this.id = id;
     58     }
     59     public String getMemberId() {
     60         return memberId;
     61     }
     62     public void setMemberId(String memberId) {
     63         this.memberId = memberId;
     64     }
     65     public String getOrderNo() {
     66         return orderNo;
     67     }
     68     public void setOrderNo(String orderNo) {
     69         this.orderNo = orderNo;
     70     }
     71     public int getMoney() {
     72         return money;
     73     }
     74     public void setMoney(int money) {
     75         this.money = money;
     76     }
     77     public String getCreateDate() {
     78         return createDate;
     79     }
     80     public void setCreateDate(String createDate) {
     81         this.createDate = createDate;
     82     }
     83     public Map<String, String> getRemark() {
     84         return remark;
     85     }
     86     public void setRemark(Map<String, String> remark) {
     87         this.remark = remark;
     88     }
     89     public String getRemark2() {
     90         return remark2;
     91     }
     92     public void setRemark2(String remark2) {
     93         this.remark2 = remark2;
     94     }
     95     public String getOrderStatus() {
     96         return orderStatus;
     97     }
     98     public void setOrderStatus(String orderStatus) {
     99         this.orderStatus = orderStatus;
    100     }
    101 }
    View Code
     1 package com.karat.cn.vo;
     2 /**
     3  *  调用微信支付相关信息
     4  * @author 开发
     5  *
     6  */
     7 public class VoUnifiedOrderWx {
     8     // 时间戳
     9     private String timeStamp;
    10     // 随机串
    11     private String nonceStr;
    12     // 数据包
    13     private String packageValue;
    14     // 签名
    15     private String sign;
    16     
    17     public String getTimeStamp() {
    18         return timeStamp;
    19     }
    20     public void setTimeStamp(String timeStamp) {
    21         this.timeStamp = timeStamp;
    22     }
    23     public String getNonceStr() {
    24         return nonceStr;
    25     }
    26     public void setNonceStr(String nonceStr) {
    27         this.nonceStr = nonceStr;
    28     }
    29     public String getPackageValue() {
    30         return packageValue;
    31     }
    32     public void setPackageValue(String packageValue) {
    33         this.packageValue = packageValue;
    34     }
    35     public String getSign() {
    36         return sign;
    37     }
    38     public void setSign(String sign) {
    39         this.sign = sign;
    40     }
    41     
    42 }
    View Code

    7.创建工具类(获取系统时间)

     1 package com.karat.cn.wxCommon;
     2 
     3 import java.text.ParseException;
     4 import java.util.Date;
     5 
     6 public class BaseToolsUtil {
     7     /**
     8      * 获取系统时间long
     9      * 
    10      * @return
    11      * @throws ParseException
    12      */
    13     public static long systemtimeLong() {
    14         return new Date().getTime();
    15     }
    16 }
    View Code

    8.准备工作完毕,开始实现小程序支付,退款,提现功能。

  • 相关阅读:
    黄金作为货币的本质
    万有引力和做功。
    Arp攻击实战
    Android SDK下载项的说明
    宇宙、事象
    事件视界
    微积分
    金融的三大基础货币,股票,期货。
    pos机的热敏纸尺寸
    去除text历史记录
  • 原文地址:https://www.cnblogs.com/LJing21/p/10376418.html
Copyright © 2020-2023  润新知