微信扫码支付(4):统一下单

1.下载微信JAVA SDK

地址:https://pay.weixin.qq.com/wiki/doc/api/download/WxPayAPI_JAVA.zip

image

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=xkrWRGMW4d5Sh0Tv, code_url=weixin://wxpay/bizpayurl?pr=08rYhA9, appid=wxa45774e8ec797baa, sign=F4496EFC75F2FAE6D6C24DD50FB82F4A35F3734E7DA69AE82A0BD76636035162, trade_type=NATIVE, return_msg=OK, result_code=SUCCESS, mch_id=1532346751, return_code=SUCCESS, prepay_id=wx2323101167496591657b36d51646619704}

获得code_url的值生成二维码。

image

用微信扫码即可付款,如果是沙箱环境,生成的二维码扫码后会告知已经过期,这是正常的,改成正式环境没有这个问题。


至此微信扫码付款完结,其余接口应该可以同样打通,不再赘叙!


猜你喜欢

转载自www.cnblogs.com/huiy/p/10759688.html