java集成微信支付
生活随笔
收集整理的這篇文章主要介紹了
java集成微信支付
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
廢話不多說,直接上代碼
首先附上一位大佬的連接:https://blog.csdn.net/m_sicily/article/details/82493171pom
<dependency><groupId>com.github.wxpay</groupId><artifactId>wxpay-sdk</artifactId><version>0.0.3</version> </dependency> <dependency><groupId>org.dom4j</groupId><artifactId>dom4j</artifactId><version>2.1.3</version> </dependency>WxMD5Util:標簽加密工具類
import com.github.wxpay.sdk.WXPayConstants; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.Arrays; import java.util.Map; import java.util.Set; public class WxMD5Util {public String getSign(Map<String, String> data) throws Exception {MyWXPayConfig config = new MyWXPayConfig();Set<String> keySet = data.keySet();String[] keyArray = keySet.toArray(new String[keySet.size()]);Arrays.sort(keyArray);StringBuilder sb = new StringBuilder();for (String k : keyArray) {if (k.equals(WXPayConstants.FIELD_SIGN)) {continue;}if (data.get(k).trim().length() > 0) // 參數值為空,則不參與簽名sb.append(k).append("=").append(data.get(k).trim()).append("&");}sb.append("key=").append(config.getKey());MessageDigest md = null;try {md = MessageDigest.getInstance("MD5");} catch (NoSuchAlgorithmException e) {e.printStackTrace();}byte[] array = new byte[0];try {array = md.digest(sb.toString().getBytes("UTF-8"));} catch (UnsupportedEncodingException e) {e.printStackTrace();}StringBuilder sb2 = new StringBuilder();for (byte item : array) {sb2.append(Integer.toHexString((item & 0xFF) | 0x100).substring(1, 3));}return sb2.toString().toUpperCase();} }MyWXPayConfig:微信支付配置項
import com.github.wxpay.sdk.WXPayConfig;import java.io.ByteArrayInputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream;public class MyWXPayConfig implements WXPayConfig {private byte[] certData;public static final String APP_ID = "應用id";public static final String KEY = "秘鑰";public static final String MCH_ID = "商戶id";@Overridepublic String getAppID() {return APP_ID;}@Overridepublic String getMchID() {return MCH_ID;}@Overridepublic String getKey() {return KEY;}@Overridepublic InputStream getCertStream() {ByteArrayInputStream certBis = new ByteArrayInputStream(this.certData);return certBis;}@Overridepublic int getHttpConnectTimeoutMs() {return 8000;}@Overridepublic int getHttpReadTimeoutMs() {return 10000;} }WXService:接口
import java.util.Map;public interface WXService {/*** 獲取預付訂單等參數*/Map<String, String> unifiedOrder(String attach, String total_fee) throws Exception;/*** 支付異步結果通知*/String payBack(String notifyData); }WXServiceImpl:實現類
import com.alibaba.fastjson.JSONObject; import com.github.wxpay.sdk.WXPay; import com.github.wxpay.sdk.WXPayConfig; import com.github.wxpay.sdk.WXPayConstants; import com.github.wxpay.sdk.WXPayUtil; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service;import java.math.BigDecimal; import java.util.HashMap; import java.util.Map; import java.util.SortedMap; import java.util.TreeMap;@Slf4j @Service public class WXServiceImpl implements WXService {public static final String SPBILL_CREATE_IP = "127.0.0.1";public static final String NOTIFY_URL = "回調接口的地址";public static final String TRADE_TYPE_APP = "APP";@Autowiredprivate RedisService redisService;@Autowiredprivate UserInfoController userInfoController;@Overridepublic Map<String, String> unifiedOrder(String attach, String money) throws Exception {BigDecimal totalPrice = new BigDecimal(money);String totalFee = totalPrice.multiply(new BigDecimal(100)).toBigInteger().toString();WxMD5Util md5Util = new WxMD5Util();Map<String, String> returnMap = new HashMap<>();MyWXPayConfig config = new MyWXPayConfig();WXPay wxpay = new WXPay(config);Map<String, String> data = new HashMap<>();//生成商戶訂單號,不可重復,UUID就行Long aLong = SnowFlakeGenerator.generateId();data.put("appid", config.getAppID());data.put("mch_id", config.getMchID());String body = "訂單支付";data.put("body", body);String sign1 = md5Util.getSign(data);System.out.println(sign1);data.put("sign", sign1);data.put("nonce_str", WXPayUtil.generateNonceStr());data.put("out_trade_no", aLong.toString());data.put("total_fee", totalFee);//自己的服務器IP地址data.put("spbill_create_ip", SPBILL_CREATE_IP);//異步通知地址(請注意必須是外網)data.put("notify_url", NOTIFY_URL);// 將用戶id存入redis中,out_trade_no:userId,(根據各自業務需求)// Long userId = JSONObject.parseObject(attach).getLong("userId");// redisService.set(aLong.toString(), userId, 60*10);//交易類型data.put("trade_type", TRADE_TYPE_APP);//附加數據,在查詢API和支付通知中原樣返回,該字段主要用于商戶攜帶訂單的自定義數據data.put("attach", attach);try {//使用官方API請求預付訂單Map<String, String> response = wxpay.unifiedOrder(data);System.out.println("response:" + response);//獲取返回碼String returnCode = response.get("return_code");//若返回碼為SUCCESS,則會返回一個result_code,再對該result_code進行判斷if (returnCode.equals("SUCCESS")) {//主要返回以下5個參數String resultCode = response.get("result_code");returnMap.put("appid", response.get("appid"));returnMap.put("mch_id", response.get("mch_id"));returnMap.put("nonce_str", response.get("nonce_str"));returnMap.put("sign", response.get("sign"));returnMap.put("total_fee", money);//resultCode 為SUCCESS,才會返回prepay_id和trade_typeif ("SUCCESS".equals(resultCode)) {//獲取預支付交易回話標志returnMap.put("trade_type", response.get("trade_type"));returnMap.put("prepay_id", response.get("prepay_id"));return returnMap;} else {//此時返回沒有預付訂單的數據return returnMap;}} else {return returnMap;}} catch (Exception e) {System.out.println(e);//系統等其他錯誤的時候}return returnMap;}@Overridepublic String payBack(String notifyData) {MyWXPayConfig config = null;try {config = new MyWXPayConfig();} catch (Exception e) {e.printStackTrace();}WXPay wxpay = new WXPay(config);String xmlBack = "";Map<String, String> notifyMap = null;try {notifyMap = WXPayUtil.xmlToMap(notifyData); // 調用官方SDK轉換成map類型數據if (wxpay.isPayResultNotifySignatureValid(notifyMap)) {//驗證簽名是否有效,有效則進一步處理String return_code = notifyMap.get("return_code");//狀態String out_trade_no = notifyMap.get("out_trade_no");//商戶訂單號String total_fee = notifyMap.get("total_fee");//支付金額if (return_code.equals("SUCCESS")) {if (out_trade_no != null) {log.info("支付成功");log.info("微信手機支付金額:{}", total_fee);log.info("微信手機支付回調成功訂單號:{}", out_trade_no);// 注意特殊情況:訂單已經退款,但收到了支付結果成功的通知,不應把商戶的訂單狀態從退款改成支付成功// 注意特殊情況:微信服務端同樣的通知可能會多次發送給商戶系統,所以數據持久化之前需要檢查是否已經處理過了,處理了直接返回成功標志//業務數據持久化//TODO 入賬邏輯//TODO 入賬邏輯//TODO 入賬邏輯xmlBack = "<xml>" + "<return_code><![CDATA[SUCCESS]]></return_code>" + "<return_msg><![CDATA[OK]]></return_msg>" + "</xml> ";} else {log.info("微信手機支付回調失敗訂單號:{}", out_trade_no);xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[報文為空]]></return_msg>" + "</xml> ";}}return xmlBack;} else {// 簽名錯誤,如果數據里沒有sign字段,也認為是簽名錯誤//失敗的數據要不要存儲?log.error("手機支付回調通知簽名錯誤");xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[報文為空]]></return_msg>" + "</xml> ";return xmlBack;}} catch (Exception e) {log.error("手機支付回調通知失敗", e);xmlBack = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[報文為空]]></return_msg>" + "</xml> ";}return xmlBack;}WXPayController:控制層
import com.alibaba.fastjson.JSONObject; import io.swagger.annotations.Api; import io.swagger.annotations.ApiOperation; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Isolation; import org.springframework.transaction.annotation.Propagation; import org.springframework.transaction.annotation.Transactional; import org.springframework.web.bind.annotation.*;import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.BufferedReader; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.math.BigDecimal; import java.util.HashMap; import java.util.Map;@RestController @RequestMapping("/wxPay") @Api(value = "WeiXinPayController", tags = "微信下單支付") public class WXPayController {@Autowiredprivate WXService wxService;/*** 統一下單*/@AccessAuth@PostMapping("/unifiedOrder")@ApiOperation(value = "微信下單")public CommonResult unifiedOrder(@RequestBody JSONObject param) throws Exception{// 獲取下單金額BigDecimal moneyDecimal = param.getBigDecimal("money");if (moneyDecimal == null) {return CommonResult.failed("填寫正確的下單金額");}String attach = "你需要傳遞的參數";//請求預支付訂單Map<String, String> result = wxService.unifiedOrder(attach, moneyDecimal.toString());WxMD5Util md5Util = new WxMD5Util();//返回APP端的數據Map<String, String> map = new HashMap<>();map.put("appid", result.get("appid"));map.put("partnerid", result.get("mch_id"));map.put("prepayid", result.get("prepay_id"));map.put("package","Sign=WXPay");map.put("noncestr", result.get("nonce_str"));map.put("timestamp", String.valueOf(System.currentTimeMillis()/1000));map.put("sign", md5Util.getSign(map));map.put("extdata", attach);return CommonResult.success(map);}/*** 支付異步結果通知,我們在請求預支付訂單時傳入的地址*/@RequestMapping(value = "/wxPayNotify", method = {RequestMethod.GET, RequestMethod.POST})@ApiOperation(value = "微信支付回調接口")@Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.REPEATABLE_READ, rollbackFor = Exception.class)public String wxPayNotify(HttpServletRequest request, HttpServletResponse response) {String resXml;try {InputStream inputStream = request.getInputStream();//將InputStream轉換成xmlStringBufferedReader reader = new BufferedReader(new InputStreamReader(inputStream));StringBuilder sb = new StringBuilder();String line;try {while ((line = reader.readLine()) != null) {sb.append(line + "\n");}} catch (IOException e) {System.out.println(e.getMessage());} finally {try {inputStream.close();} catch (IOException e) {e.printStackTrace();}}resXml = sb.toString();String result = wxService.payBack(resXml);return result;} catch (Exception e) {System.out.println("微信手機支付失敗:" + e.getMessage());String result = "<xml>" + "<return_code><![CDATA[FAIL]]></return_code>" + "<return_msg><![CDATA[報文為空]]></return_msg>" + "</xml> ";return result;}} } public class CommonResult<T> {private long code;private String message;private T data;protected CommonResult() {}protected CommonResult(long code, String message, T data) {this.code = code;this.message = message;this.data = data;}/*** 成功返回結果** @param data 獲取的數據*/public static <T> CommonResult<T> success(T data) {return new CommonResult<T>(ResultCode.SUCCESS.getCode(), ResultCode.SUCCESS.getMessage(), data);}/*** 成功返回結果** @param data 獲取的數據* @param message 提示信息*/public static <T> CommonResult<T> success(T data, String message) {return new CommonResult<T>(ResultCode.SUCCESS.getCode(), message, data);}/*** 失敗返回結果* @param message 提示信息*/public static <T> CommonResult<T> failed(String message) {return new CommonResult<T>(ResultCode.FAILED.getCode(), message, null);}/*** 成功返回結果** @param data 獲取的數據* @param message 提示信息*/public static <T> CommonResult<T> failed(T data, String message) {return new CommonResult<T>(ResultCode.FAILED.getCode(), message, data);}/*** 失敗返回結果*/public static <T> CommonResult<T> failed() {return failed(ResultCode.FAILED);}public long getCode() {return code;}public void setCode(long code) {this.code = code;}public String getMessage() {return message;}public void setMessage(String message) {this.message = message;}public T getData() {return data;}public void setData(T data) {this.data = data;} } public enum ResultCode implements IErrorCode {SUCCESS(200, "操作成功"),FAILED(999999, "操作失敗");private long code;private String message;private ResultCode(long code, String message) {this.code = code;this.message = message;}public long getCode() {return code;}public String getMessage() {return message;} } ~有寫錯的或者有更優雅的寫法記得@ 我~總結
以上是生活随笔為你收集整理的java集成微信支付的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 如何在FreePBX ISO 中文版本安
- 下一篇: 想知道未来孩子长相?Python人脸融合