java微信支付後臺服務方法

java微信支付後臺服務方法

前言

記錄一下支付功能的一些方法, 僅供學習參考,不涉及商業內容,一些基本環境先說一下,後面就不再說了
jdk1.8 springBoot2.0 maven

微信支付對接流程

使用微信沙箱做演示
首先要登錄微信開放平臺-資源中心-開放平臺改爲選擇微信支付-app支付(我這裏演示使用)-API列表-統一下單

  1. 引入支付寶第三方jar包
<dependency>
	<groupId>org.apache.httpcomponents</groupId>
	<artifactId>httpclient</artifactId>
</dependency>

<dependency>
	<groupId>com.google.zxing</groupId>
	<artifactId>core</artifactId>
	<version>3.3.0</version>
</dependency>
  1. 編寫一個配置微信參數的類(我這裏直接下載使用的微信demo代碼, 有很多引用類方法我就不展示了)
import org.springframework.util.ResourceUtils;

import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;

public class WXConfig extends WXPayConfig {
    private static byte[] certData;

    // 應用ID
    public static final String APP_ID = "";
    // mchId
    public static final String MCH_ID = "";
    // 商戶密鑰
    public static final String KEY = "";
    // 證書
    public static final String APP_CERT_PATH = "/static/CRT/apiclient_cert.p12";

    private volatile static WXConfig wxConfig = null;

    public static WXConfig getInstance() throws Exception {
        if (wxConfig == null) {
            synchronized (WXConfig.class) {
                if (wxConfig == null) {
                    File file = new File(ResourceUtils.getURL("classpath:").getPath());
                    InputStream certStream = new FileInputStream(file);
                    certData = new byte[(int) file.length()];
                    certStream.read(certData);
                    certStream.close();
                    return new WXConfig();
                }
            }
        }
        return wxConfig;
    }

    private WXConfig() {
    }

    public String getAppID() {
        return APP_ID;
    }

    public String getMchID() {
        return MCH_ID;
    }

    public String getKey() {
        return KEY;
    }

    public InputStream getCertStream() {
        ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);
        return certBis;
    }

    public int getHttpConnectTimeoutMs() {
        return 8000;
    }

    public int getHttpReadTimeoutMs() {
        return 10000;
    }

    @Override
    IWXPayDomain getWXPayDomain() {
        return new IWXPayDomainImpl();
    }
}
  1. 阿里支付的方法
/**
 * 微信支付接口
 *
 * @param outTradeNo  訂單號
 * @param notifyUrl   回調地址
 * @param totalAmount 金額
 * @param passbackParams 附加字段
 */
public static Map<String, String> wxpay(HttpServletRequest request, String outTradeNo, String totalAmount, String notifyUrl, String passbackParams) throws Exception {
    WXConfig config = WXConfig.getInstance();
    // 正式環境
    WXPay wxpay = new WXPay(config);
    // 測試環境
    // WXPay wxpay = new WXPay(config, notifyUrl, false, true);
    Map<String, String> data = new HashMap<>();
    data.put("body", "充值");
    data.put("attach", passbackParams);
    data.put("out_trade_no", outTradeNo);
    data.put("device_info", "");
    data.put("fee_type", "CNY");
    data.put("total_fee", totalAmount);
    data.put("spbill_create_ip", getRemoteHost(request));
    data.put("notify_url", notifyUrl);
    data.put("trade_type", "APP");  // 此處指定爲APP支付
    return wxpay.unifiedOrder(data);
}
  1. 支付完成之後,會被微信調用回調的方法,注意這個方法必須是外網能夠訪問的, 可以在阿里雲linux服務器上面,運行一個後端服務, 接受回調的方法
/**
 * 獲取微信相關參數
 */
private Map<String, String> wxResponseMap(HttpServletRequest request) throws Exception {
    // 獲取返回數據
    StringBuilder xmlStr = new StringBuilder();
    try (BufferedReader br = request.getReader()) {
        String line;
        while ((line = br.readLine()) != null)
            xmlStr.append(line);
    } catch (IOException e) {
        e.printStackTrace();
        throw e;
    }
    return WXPayUtil.xmlToMap(xmlStr.toString());
}

@PostMapping(value = "/recharge")
@ApiOperation(value = "微信回調-充值")
public String callback() throws Exception {
    Map<String, String> map = wxResponseMap();
    return PayUtils.notifyUrl(() -> {
        //...業務邏輯
        return null;
    }, map);
}

/**
 * @param supplier  業務邏輯
 * @param data      參數
 */
public static String notifyUrl(Supplier<Void> supplier, Map<String, String> data) throws Exception {
    WXConfig config = WXConfig.getInstance();
    WXPay wxpay = new WXPay(config);
//        WXPay wxpay = new WXPay(config, false, true);
    Map<String, String> result = Maps.newHashMap();

    log.debug("____________________微信返回參數start_______________________");
    log.debug(JSON.toJSONString(data));
    log.debug("out_trade_no: " + data.get("out_trade_no"));
    log.debug("return_code: " + data.get("return_code"));
    log.debug("result_code: " + data.get("result_code"));
    log.debug("____________________微信返回參數end_______________________");

    // 簽名驗證
    if (wxpay.isPayResultNotifySignatureValid(data)) {
        if ("SUCCESS".equals(data.get("return_code")) && "SUCCESS".equals(data.get("result_code"))) {
            // 業務代碼
            supplier.get();
            result.put("return_code", "SUCCESS");
            result.put("return_msg", "校驗成功");
            log.debug("異步回調業務處理完畢.");
        } else {
            result.put("return_code", "FAIL");
            result.put("return_msg", "狀態碼爲FAIL");
            log.error("驗籤通過,但是狀態碼  return_code: " + data.get("return_code") + " result_code: " + data.get("result_code"));
        }
    } else {
        result.put("return_code", "FAIL");
        result.put("return_msg", "簽名失敗");
        log.error("簽名失敗");
    }
    return WXPayUtil.mapToXml(result);
}
  1. 回調方法執行完成之後,再次查詢微信訂單是否生成方法
/**
 * 支付寶支付訂單的查詢
 */
public static Boolean existsOrder(String outTradeNo) throws Exception {
    WXConfig config = WXConfig.getInstance();
    WXPay wxpay = new WXPay(config);
//        WXPay wxpay = new WXPay(config, false, true);

    Map<String, String> data = new HashMap<>();
    data.put("out_trade_no", outTradeNo);
    Map<String, String> resp = wxpay.orderQuery(data);

    if (!"SUCCESS".equals(resp.get("return_code")))
            throw new RuntimeException(resp.get("return_msg"));
    if (!"SUCCESS".equals(resp.get("result_code"))) {
        throw new RuntimeException(resp.get("return_msg"));
    }
    return true;
}
  1. 這樣微信支付流程就完成了
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章