1.下载微信JAVA SDK
地址:https://pay.weixin.qq.com/wiki/doc/api/download/WxPayAPI_JAVA.zip
2.配置文件及代码
#####################支付宝-开始##################### #应用ID com.test.zconfig[APP_ID]=****** #支付宝网关,含dev是测试网关,正式地址:https://openapi.alipay.com/gateway.do com.test.zconfig[OPEN_API_DOMAIN]=https://openapi.alipaydev.com/gateway.do #商户私钥 com.test.zconfig[PRIVATE_KEY]=****** #支付宝公钥 com.test.zconfig[ALIPAY_PUBLIC_KEY]=****** #订单过期时间,m=分钟 com.test.zconfig[timeout_express]=5m ##########驾驶模拟考试############## #ID前缀 com.test.zjsmnks[prefix]=zfb- #标题 com.test.zjsmnks[subject]=支付宝支付测试 #用户付款后,支付宝回调通知URL com.test.zjsmnks[notify_url]=http://localhost:8080/api/zfb/order/notice/ #####################支付宝-结束##################### #####################微信-开始##################### #应用ID com.test.wconfig[APP_ID]=****** #商户ID com.test.wconfig[MCH_ID]=****** #证书路径 com.test.wconfig[CERT_PATH]=/pay/wx/apiclient_cert.p12 #API密钥 com.test.wconfig[API_KEY]=****** #订单过期时间,m=分钟 com.test.wconfig[timeout_express]=5m ##########驾驶模拟考试############## #ID前缀 com.test.wjsmnks[prefix]=wx- #标题 com.test.wjsmnks[subject]=微信支付测试 #用户付款后,微信回调通知URL com.test.wjsmnks[notify_url]=http://localhost:8080/api/wx/order/notice/ #####################微信-结束#####################
其中apiclient_cert.p12就是在第2步证书生成时产生的。
#API密钥 填写沙箱验签密钥(第3步),正式环境时一定要改成真实的API密钥(第2步)。
3.配置文件代码 PropertiesPay
import java.util.LinkedHashMap; import java.util.Map; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.context.annotation.PropertySource; import org.springframework.stereotype.Component; /** * * 类描述: 项目主配置文件 * */ @Component @ConfigurationProperties(prefix = "com.test") @PropertySource(value = "classpath:/config/pay.properties", encoding = "utf-8") public class PropertiesPay { // 支付宝 private LinkedHashMap<String, String> zconfig = new LinkedHashMap<>(); private LinkedHashMap<String, String> zjsmnks = new LinkedHashMap<>(); // 微信 private LinkedHashMap<String, String> wconfig = new LinkedHashMap<>(); private LinkedHashMap<String, String> wjsmnks = new LinkedHashMap<>(); public final Map<String, String> getZconfig() { return zconfig; } public final void setZconfig(Map<String, String> zconfig) { this.zconfig = (LinkedHashMap<String, String>) zconfig; } public final Map<String, String> getZjsmnks() { return zjsmnks; } public final void setZjsmnks(Map<String, String> jsmnks) { this.zjsmnks = (LinkedHashMap<String, String>) jsmnks; } public final Map<String, String> getWconfig() { return wconfig; } public final void setWconfig(Map<String, String> wconfig) { this.wconfig = (LinkedHashMap<String, String>) wconfig; } public final Map<String, String> getWjsmnks() { return wjsmnks; } public final void setWjsmnks(Map<String, String> wjsmnks) { this.wjsmnks = (LinkedHashMap<String, String>) wjsmnks; } }
4.重写WXPayConfig
package com.github.wxpay.sdk; import java.io.ByteArrayInputStream; import java.io.InputStream; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.csget.properties.PropertiesPay; import com.csget.service.impl.queue.ServiceImplQueueLog; public class MyWXConfig extends WXPayConfig { private PropertiesPay propertiesPay; private Logger log = LoggerFactory.getLogger(ServiceImplQueueLog.class); private byte[] certData; public MyWXConfig(PropertiesPay propertiesPay) throws Exception { this.propertiesPay = propertiesPay; try (InputStream certStream = MyWXConfig.class.getResourceAsStream(propertiesPay.getWconfig().get("CERT_PATH"))) { this.certData = new byte[certStream.available()]; int intRead = certStream.read(this.certData); log.debug("读取字节数:{}", intRead); } } @Override public String getAppID() { return propertiesPay.getWconfig().get("APP_ID"); } @Override public String getMchID() { return propertiesPay.getWconfig().get("MCH_ID"); } @Override public String getKey() { return propertiesPay.getWconfig().get("API_KEY"); } @Override public InputStream getCertStream() { return new ByteArrayInputStream(this.certData); } @Override public IWXPayDomain getWXPayDomain() { // 这个方法需要这样实现, 否则无法正常初始化WXPay return new IWXPayDomain() { @Override public void report(String domain, long elapsedTimeMillis, Exception ex) { // do nothing } @Override public DomainInfo getDomain(WXPayConfig config) { return new IWXPayDomain.DomainInfo(WXPayConstants.DOMAIN_API, true); } }; } }
5.测试代码
import java.util.HashMap; import java.util.Map; import org.junit.Test; import org.junit.runner.RunWith; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.boot.test.context.SpringBootTest; import org.springframework.test.context.junit4.SpringRunner; import com.csget.properties.PropertiesPay; import com.github.wxpay.sdk.MyWXConfig; import com.github.wxpay.sdk.WXPay; import com.github.wxpay.sdk.WXPayUtil; import net.common.util.tool.common.UUIDUtil; @RunWith(SpringRunner.class) @SpringBootTest public class TestWXPay { @Autowired private PropertiesPay propertiesPay; @Test public void pay() throws Exception { // 使用沙箱测试 MyWXConfig myWXConfig = new MyWXConfig(propertiesPay);
// 第3个参数决定是否使用沙箱环境,false=正式环境,如果API_KEY为沙箱密钥,返回结果也会报错。 WXPay wxpay = new WXPay(myWXConfig, false, false); Map<String, String> paramMap = new HashMap<String, String>(); paramMap.put("trade_type", "NATIVE"); // 交易类型 paramMap.put("spbill_create_ip", "127.0.0.1"); // 本机的Ip paramMap.put("product_id", "1111"); // 商户根据自己业务传递的参数 必填 paramMap.put("body", "微信支付测试"); // 描述 paramMap.put("out_trade_no", UUIDUtil.getUUID()); // 商户 后台的贸易单号 paramMap.put("total_fee", "1"); // 金额必须为整数 单位为分 paramMap.put("fee_type", "CNY"); // 金额必须为整数 单位为分 paramMap.put("notify_url", "http://127.0.0.1/wx_pay_notify"); //支付成功后,回调地址 paramMap.put("appid", myWXConfig.getAppID()); // 微信公众号开发ID paramMap.put("mch_id", myWXConfig.getMchID()); // 商户号 paramMap.put("nonce_str", WXPayUtil.generateNonceStr()); // 随机数 paramMap.put("sign", WXPayUtil.generateSignature(paramMap, myWXConfig.getKey()));// 根据微信签名规则,生成签名 try { Map<String, String> resp = wxpay.unifiedOrder(paramMap); System.out.println("返回结果:" + resp); } catch (Exception e) { e.printStackTrace(); } } }
返回结果:
{nonce_str=******, code_url=weixin://wxpay/bizpayurl?pr=08rYhA9, appid=*******, sign=******, trade_type=NATIVE, return_msg=OK, result_code=SUCCESS, mch_id=******, return_code=SUCCESS, prepay_id=******}
获得code_url的值生成二维码。
用微信扫码即可付款,如果是沙箱环境,生成的二维码扫码后会告知已经过期,这是正常的,改成正式环境没有这个问题。
至此微信扫码付款完结,其余接口应该可以同样打通,不再赘叙!