View Javadoc
1   package com.foxinmy.weixin4j.pay.api;
2   
3   import com.foxinmy.weixin4j.api.BaseApi;
4   import com.foxinmy.weixin4j.exception.WeixinException;
5   import com.foxinmy.weixin4j.http.weixin.WeixinRequestExecutor;
6   import com.foxinmy.weixin4j.pay.model.WeixinPayAccount;
7   import com.foxinmy.weixin4j.pay.payment.mch.MerchantResult;
8   import com.foxinmy.weixin4j.pay.sign.WeixinPaymentSignature;
9   import com.foxinmy.weixin4j.pay.type.IdQuery;
10  import com.foxinmy.weixin4j.pay.sign.WeixinSignature;
11  import com.foxinmy.weixin4j.util.RandomUtil;
12  import com.foxinmy.weixin4j.util.StringUtil;
13  import com.foxinmy.weixin4j.util.Weixin4jConfigUtil;
14  
15  import java.io.File;
16  import java.io.FileInputStream;
17  import java.io.IOException;
18  import java.io.InputStream;
19  import java.util.HashMap;
20  import java.util.Map;
21  import java.util.ResourceBundle;
22  
23  /**
24   * 商户支付
25   *
26   * @className MchApi
27   * @author jinyu(foxinmy@gmail.com)
28   * @date 2016年3月26日
29   * @since JDK 1.6
30   * @see <a href="https://pay.weixin.qq.com/wiki/doc/api/index.html">商户支付平台</a>
31   */
32  public class MchApi extends BaseApi {
33      private final static ResourceBundle WEIXIN_BUNDLE;
34  
35      private final static String PEM_CERT_PREFIX = "-----BEGIN CERTIFICATE-----";
36  
37      static {
38          WEIXIN_BUNDLE = ResourceBundle.getBundle("com/foxinmy/weixin4j/pay/weixin");
39      }
40  
41      protected final WeixinPayAccount weixinAccount;
42      protected final WeixinSignature weixinSignature;
43      private volatile WeixinRequestExecutor weixinSSLExecutor;
44  
45      public MchApi(WeixinPayAccount weixinAccount) {
46          this.weixinAccount = weixinAccount;
47          this.weixinSignature = new WeixinPaymentSignature(weixinAccount.getPaySignKey());
48      }
49  
50      @Override
51      protected ResourceBundle weixinBundle() {
52          return WEIXIN_BUNDLE;
53      }
54  
55      /**
56       * 支付接口请求基本数据
57       *
58       * @param idQuery
59       *            ID信息 可为空
60       * @return 基础map
61       */
62      protected Map<String, String> createBaseRequestMap(IdQuery idQuery) {
63          Map<String, String> map = new HashMap<String, String>();
64          map.put("appid", weixinAccount.getId());
65          map.put("mch_id", weixinAccount.getMchId());
66          map.put("nonce_str", RandomUtil.generateString(16));
67          if (StringUtil.isNotBlank(weixinAccount.getDeviceInfo())) {
68              map.put("device_info", weixinAccount.getDeviceInfo());
69          }
70          if (StringUtil.isNotBlank(weixinAccount.getSubId())) {
71              map.put("sub_appid", weixinAccount.getSubId());
72          }
73          if (StringUtil.isNotBlank(weixinAccount.getSubMchId())) {
74              map.put("sub_mch_id", weixinAccount.getSubMchId());
75          }
76          if (idQuery != null) {
77              map.put(idQuery.getType().getName(), idQuery.getId());
78          }
79          return map;
80      }
81  
82      /**
83       * 微信签名类
84       *
85       * @return
86       */
87      public WeixinSignature getWeixinSignature() {
88          return this.weixinSignature;
89      }
90  
91      /**
92       * 微信SSL
93       *
94       * @return
95       */
96      protected WeixinRequestExecutor getWeixinSSLExecutor() throws WeixinException {
97          if (weixinSSLExecutor == null) {
98              if(weixinAccount.getCertificateFile().startsWith(PEM_CERT_PREFIX)){
99                  // 证书是PEM格式,直接使用PEM内容生成请求执行类
100                 this.weixinSSLExecutor = weixinExecutor.createSSLRequestExecutor(weixinAccount.getMchId(),
101                         weixinAccount.getCertificateFile(), weixinAccount.getCertificateKey());
102             }else {
103                 // 证书是p12格式,读取证书文件并生成请求执行类
104                 try {
105                     InputStream is = null;
106                     File certificate = new File(
107                             Weixin4jConfigUtil.replaceClassPathValue(weixinAccount.getCertificateFile()));
108                     if (!certificate.exists() || !certificate.isFile()) {
109                         is = Weixin4jConfigUtil.CLASSLOADER.getResourceAsStream(certificate.getName());
110                     } else {
111                         is = new FileInputStream(certificate);
112                     }
113                     if (is == null) {
114                         throw new WeixinException("Invalid certificate file : " + certificate.toString());
115                     }
116                     this.weixinSSLExecutor = weixinExecutor.createSSLRequestExecutor(weixinAccount.getCertificateKey(), is);
117                 } catch (IOException e) {
118                     throw new WeixinException("IO Error on createSSLRequestExecutor", e);
119                 }
120             }
121         }
122         return this.weixinSSLExecutor;
123     }
124 
125     /**
126      * 设置商户信息
127      *
128      * @param merchant
129      */
130     protected <T extends MerchantResult> void declareMerchant(T merchant) {
131         merchant.setAppId(weixinAccount.getId());
132         merchant.setMchId(weixinAccount.getMchId());
133         merchant.setDeviceInfo(weixinAccount.getDeviceInfo());
134         merchant.setSubAppId(weixinAccount.getSubId());
135         merchant.setSubMchId(weixinAccount.getSubMchId());
136         merchant.setNonceStr(RandomUtil.generateString(16));
137     }
138 }