關(guān)于微信支付和支付寶支付java實(shí)現(xiàn)

目前支付寶支付和微信支付是算是目前app的標(biāo)配了

支付寶支付在更新過后有了官方專門的sdk和demo,所以相對而言比較簡單,而微信支付稍微復(fù)雜一點(diǎn),下面的文章會附實(shí)例代碼,微信支付也是參考的github上的某位大神級人物的代碼。

首先是微信支付

先準(zhǔn)備各種數(shù)據(jù),我一般都是放到配置類中,當(dāng)然也可以放到數(shù)據(jù)庫或者配置文件中

`public final class WxpayConfig? {

?????? /**

?????? ?*商家可以考慮讀取配置文件

?????? ?*/

?????? //微信開發(fā)平臺應(yīng)用id

?????? public static final String APP_ID = "wx8888888888888888";

?????? //財(cái)付通商戶號

?????? public static final String PARTNER = "1900000109";//app請求的商戶號

?????? public static final String MCHID = "1900000109";//預(yù)支付請求的商戶號????????????????

?????? //商戶號對應(yīng)的密鑰

?????? public static final String PARTNER_KEY = "";

?????? //預(yù)支付接口

?????? public static final String PREPAY_URL =? "https://api.mch.weixin.qq.com/pay/unifiedorder";?

?????? //查詢訂單接口

?????? public static final String QUERY_ORDER_URL = "https://api.mch.weixin.qq.com/pay/orderquery";

?????? //簽名算法常量值

?????? public static final String SIGN_METHOD = "sha1";

?????? //異步通知地址

?????? public static final String NOTIFY_URL = “”;

?????? //交易類型

?????? public static final String TRADE_TYPE = "APP";

?????? //暫定包值

?????? public static final String PACKAGE = "Sign=WXPay";

?????? //返回狀態(tài)成功

?????? public static final String SUCCESS = "SUCCESS";

?????? //返回狀態(tài)失敗

?????? public static final String FAIL = "FAIL";

}`

這是關(guān)于微信支付的封裝的工具類,其中httpclient和md5加密的需要自己去封裝工具類

`public class? WxpayUtil {

?????? /**

?????? ?*隨機(jī)串

?????? ?* @return

?????? ?*/

?????? public static String getNonceStr() {

????????????? Random random = new Random();

????????????? return? MD5Util.getMD5String(String.valueOf(random.nextInt(10000)));

?????? }

?????? /**

?????? ?*時(shí)間戳

?????? ?* @return

?????? ?*/

?????? public static String getTimeStamp() {

????????????? return? String.valueOf(System.currentTimeMillis() / 1000);

?????? }

?????? /**

?????? ?*解析xml,返回第一級元素鍵值對。如果第一級元素有子節(jié)點(diǎn),則此節(jié)點(diǎn)的值是子節(jié)點(diǎn)的xml數(shù)據(jù)。

?????? ?* @param strxml

?????? ?* @return

?????? ?* @throws JDOMException

?????? ?* @throws IOException

?????? ?*/

?????? @SuppressWarnings("unchecked")

?????? public static Map? parseToMap(String strXml) throws JDOMException, IOException {

????????????? strXml =? strXml.replaceFirst("encoding=\".*\"",? "encoding=\"UTF-8\"");

????????????? if(null == strXml ||? "".equals(strXml)) {

???????????????????? return null;

????????????? }

????????????? Map m = new? HashMap<>();


????????????? InputStream in = new? ByteArrayInputStream(strXml.getBytes("UTF-8"));

????????????? SAXBuilder builder = new? SAXBuilder();

????????????? Document doc =? builder.build(in);

????????????? Element root =? doc.getRootElement();

????????????? List list =? root.getChildren();

????????????? Iterator it =? list.iterator();

????????????? while(it.hasNext()) {

???????????????????? Element e = it.next();

???????????????????? String k = e.getName();

???????????????????? String v = "";

???????????????????? List? children = e.getChildren();

???????????????????? if(children.isEmpty()) {

??????????????????????????? v =? e.getTextNormalize();

???????????????????? } else {

??????????????????????????? v =? getChildrenText(children);

???????????????????? }

???????????????????? m.put(k, v);

????????????? }

????????????? //關(guān)閉流

????????????? in.close();

????????????? return m;

?????? }


?????? /**

?????? ?*獲取子結(jié)點(diǎn)的xml

?????? ?* @param children

?????? ?* @return String

?????? ?*/

?????? @SuppressWarnings("unchecked")

?????? private static String? getChildrenText(List children) {

????????????? StringBuffer sb = new? StringBuffer();

????????????? if(!children.isEmpty()) {

???????????????????? Iterator? it = children.iterator();

???????????????????? while(it.hasNext()) {

??????????????????????????? Element e =? it.next();

??????????????????????????? String name =? e.getName();

??????????????????????????? String value =? e.getTextNormalize();

??????????????????????????? List? list = e.getChildren();

??????????????????????????? sb.append("<"? + name + ">");

??????????????????????????? if(!list.isEmpty())? {

?????????????????????????????????? sb.append(getChildrenText(list));

??????????????????????????? }

??????????????????????????? sb.append(value);

??????????????????????????? sb.append("");

???????????????????? }

????????????? }

????????????? return sb.toString();

?????? }

?????? /**

?????? ?*只支持String,并且value非空

?????? ?* @param map

?????? ?* @return

?????? ?*/

?????? public static String? parseToXml(Map map){

????????????? StringBuffer sb = new? StringBuffer("");

????????????? for(Map.Entry entry : map.entrySet()){

???????????????????? sb.append("<"+entry.getKey()+">");

???????????????????? sb.append("");

???????????????????? sb.append("");

????????????? }

????????????? sb.append("");

????????????? return sb.toString();

?????? }


?????? /**

???? * POST提交XML對象

???? * @param document

???? */?


??? public static String postXmlClient(String? url,String xmlParams) throws Exception {?


//??? ???? return? HttpUtils.postXmlEntity(url, xmlParams).getContent();

???? return? HttpClient.postRequest(url, xmlParams);

??? }?

}


這是關(guān)于微信支付一些參數(shù)處理的方法

public class? WxpayHelper {

?????? ?/**

???? *除去數(shù)組中的空值和簽名參數(shù)

???? * @param sArray簽名參數(shù)組

???? * @return去掉空值與簽名參數(shù)后的新簽名參數(shù)組

???? */

??? public static Map? paraFilter(Map sArray) {

??????? Map result =? new HashMap();

??????? if (sArray == null || sArray.size()? <= 0) {

??????????? return result;

??????? }

??????? for (String key : sArray.keySet()) {

??????????? String value = sArray.get(key);

??????????? if (value == null ||? value.equals("") || key.equalsIgnoreCase("sign") ||? key.equalsIgnoreCase("key")) {

??????????????? continue;

??????????? }

??????????? result.put(key, value);

??????? }

??????? return result;

??? }


??? /**

???? *把數(shù)組所有元素,并按照“參數(shù)=參數(shù)值”的模式用“&”字符拼接成字符串

???? * @param params需要參與字符拼接的參數(shù)組

???? * @param sorts?? 是否需要排序 true 或者false

???? * @return拼接后字符串

???? */

??? public static String? createLinkString(Map params) {

??????? List keys = new? ArrayList(params.keySet());

??????? Collections.sort(keys);

??????? String prestr = "";

??????? for (int i = 0; i < keys.size();? i++) {

??????????? String key = keys.get(i);

??????????? String value = params.get(key);

??????????? if (i == keys.size() - 1) {//拼接時(shí),不包括最后一個(gè)&字符

??????????????? prestr = prestr + key +? "=" + value;

??????????? } else {

??????????????? prestr = prestr + key +? "=" + value + "&";

??????????? }

??????? }

??????? return prestr;

??? }


??? /**

???? *驗(yàn)簽響應(yīng)簽名

???? * @param paras

???? * @return

???? */

??? public static boolean? verify(Map paras){

???? String? sign = paras.get("sign");

???? if(StringUtils.isBlank(sign))? return false;

???? return? sign.equals(WxpayBuilder.buildRequestMysign(paraFilter(paras)));

??? }


??? /**

???? *響應(yīng)成功

???? * @param loggerAgent -日志代理

???? * @return String

???? */

??? /*public static String yes(ILoggerAgent? loggerAgent){

???? Map? return_wx = new HashMap<>();

???? return_wx.put("return_code",? WxpayConfig.SUCCESS);

???? loggerAgent.payParamsLogger(null? , "WX-NOTIFY", false, return_wx);

???? return? WxpayUtil.parseToXml(return_wx);

??? }*/

?? }


public class? WxpayBuilder {

?????? ?/**

???? *生成簽名結(jié)果

???? * @param sPara要簽名的數(shù)組

???? * @return簽名結(jié)果字符串

???? */

?????? public static String? buildRequestMysign(Map sPara) {

???? String? prestr =? WxpayHelper.createLinkString(sPara)+"&key="+WxpayConfig.PARTNER_KEY;

???? LogFactory.getInstance().getLogger().debug("微信支付簽名的字符串:"+prestr);

??????? return? MD5Util.getMD5String(prestr).toUpperCase();

??? }


??? public static Map? buildRequestPara(Map sParaTemp) {

??????? //除去數(shù)組中的空值和簽名參數(shù)

??????? Map sPara =? WxpayHelper.paraFilter(sParaTemp);

??????? //生成簽名結(jié)果

??????? String mysign =? buildRequestMysign(sPara);


? LogFactory.getInstance().getLogger().debug("微信支付簽名數(shù)據(jù):"+mysign);

??????? //簽名結(jié)果與簽名方式加入請求提交參數(shù)組中

??????? sPara.put("sign", mysign);

?????? ?return sPara;

??? }

}`

使用例程

其中業(yè)務(wù)接口信息,參考https://pay.weixin.qq.com/wiki/doc/api/app/app.php?chapter=9_7&index=3


? `? ? ?/**

?????? ?*微信訂單邏輯

?????? ?*

?????? ?* @throws Exception

?????? ?*/

?????? public?

? Map wxPayLogic() throws Exception {

????????????? //微信業(yè)務(wù)代碼

????????????? Map xmlData? = new HashMap();

????????????? xmlData.put("appid",? WxpayConfig.APP_ID);

????????????? xmlData.put("mch_id",? WxpayConfig.MCHID);

????????????? xmlData.put("nonce_str",? WxpayUtil.getNonceStr());

????????????? xmlData.put("out_trade_no",);

????????????? xmlData.put("total_fee",);

????????????? xmlData.put("spbill_create_ip",“”);

????????????? //從數(shù)據(jù)字典里面去主機(jī)地址

????????????? DataDictionary dataDictionary =? dataDictionaryService.getDicByKey("PAY_CALLBACK");

????????????? xmlData.put("notify_url",? dataDictionary.getValue() + WxpayConfig.NOTIFY_URL);

????????????? xmlData.put("trade_type",? WxpayConfig.TRADE_TYPE);

????????????? xmlData.put("body",? "");

????????????? //少寫簽名

????????????? Map result? = WxpayBuilder.buildRequestPara(xmlData);

????????????? // Map? result = WxpayHelper.paraFilter(xmlData);

????????????? String xmlParams =? WxpayUtil.parseToXml(result);

????????????? LogFactory.getInstance().getLogger().debug("微信支付請求報(bào)文:" + xmlParams);

????????????? String xmlResult =? WxpayUtil.postXmlClient(WxpayConfig.PREPAY_URL, xmlParams);

????????????? Map map =? WxpayUtil.parseToMap(xmlResult);

????????????? LogFactory.getInstance().getLogger().debug("微信支付返回報(bào)文:" + JsonHelper.toJson(map));

????????????? //返回時(shí)SUCCESS

????????????? if? (WxpayConfig.SUCCESS.equals(map.get("return_code"))) {

???????????????????? //驗(yàn)證返回是否成功

???????????????????? if? (WxpayConfig.SUCCESS.equals(map.get("result_code"))) {

??????????????????????????? //除去簽名和空值

??????????????????????????? Map paraFilter = WxpayHelper.paraFilter(map);

??????????????????????????? //獲得簽名

??????????????????????????? String mysign =? WxpayBuilder.buildRequestMysign(paraFilter);

??????????????????????????? //驗(yàn)證簽名

??????????????????????????? if? (mysign.equals(map.get("sign"))) {

?????????????????????????????????? String? prepay_id = map.get("prepay_id");

?????????????????????????????????? //驗(yàn)證簽名成功

??????????????????? //進(jìn)行操作

??????????????????????????? } else {

?????????????????????????????????? //簽名驗(yàn)證失敗

?????????????????????????????????? LogFactory.getInstance().getLogger().debug("微信支付驗(yàn)證簽名失敗");

??????????????????????????? }

???????????????????? } else {

??????????????????????????? // result_code返回失敗

??????????????????????????? String err_code =? map.get("err_code");

??????????????????????????? String? err_code_des = map.get("err_code_des");

??????????????????????????? chargeRecord.setCauses(err_code+err_code_des);

??????????????????????????? LogFactory.getInstance().getLogger().debug("微信支付結(jié)果失敗:失敗碼為"+err_code+",失敗原因是"+err_code_des);

??????????????????????????? chargeRecord.setState(2);

???????????????????? }

????????????? } else {

???????????????????? // return_code返回失敗

???????????????????? String return_msg =? map.get("return_msg");

???????????????????? LogFactory.getInstance().getLogger().debug("微信支付返回失?。悍祷叵椋? + return_msg);

???????????????????? return null;

????????????? }

????????????? //微信支付

????????????? Map? mapBack = new HashMap<>();

????????????? mapBack.put("appid",? WxpayConfig.APP_ID);

????????????? mapBack.put("partnerid",? WxpayConfig.PARTNER);

????????????? mapBack.put("prepayid",? chargeRecord.getOpenId());

????????????? mapBack.put("package",? WxpayConfig.PACKAGE);

????????????? mapBack.put("noncestr",? WxpayUtil.getNonceStr());

????????????? mapBack.put("timestamp",? WxpayUtil.getTimeStamp());

????????????? return? WxpayBuilder.buildRequestPara(mapBack);

?????? }`

支付異步回傳

接收到異步通知之后,才算是付款成功

`@Controller

@RequestMapping(value? = "/api")

public class? WxPayCallbackController extends BaseController {


?????? @Autowired

?????? OrderLogic orderLogic;

?????? @Autowired

?????? RedisFactory redisFactory;

?????? @Autowired

?????? ApplicationContext applicationContext;


?????? @RequestMapping(value =? "/wxPayCallback", method = RequestMethod.POST)

?????? @ResponseBody

?????? public String? wxPayCallback(@RequestBody String body) {

????????????? MDC.put("seqID",? SeqIdGenerator.generate());//日志序列

????????????? LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的異步支付結(jié)果通知信息data=" + body);

????????????? Map? resultMap = new HashMap<>();

????????????? if? (StringUtils.isNotBlank(body)) {

???????????????????? try {

??????????????????????????? Map map = WxpayUtil.parseToMap(body);

??????????????????????????? //返回代碼

??????????????????????????? if? (WxpayConfig.SUCCESS.equals(map.get("return_code"))) {

?????????????????????????????????? //驗(yàn)證簽名

?????????????????????????????????? if? (WxpayHelper.verify(map)) {

????????????????????????????????????????? //驗(yàn)證業(yè)務(wù)結(jié)果是否成功

????????????????????????????????????????? String? outTradeNo = map.get("out_trade_no");

????????????????????????????????????????? if? (WxpayConfig.SUCCESS.equals(map.get("result_code"))) {

???????????????????????????????????????????????? //設(shè)置支付類型,1為支付寶,2為微信

???????????????????????????????????????????????? map.put("payType","2");

?????????????????????????? //通過所有驗(yàn)證,啟動事件,通過spring的監(jiān)聽器進(jìn)行監(jiān)聽,并執(zhí)行付款成功后的業(yè)務(wù)

???????????????????????????????????????????????? applicationContext.publishEvent(new? OrderFinishEvent(map));

????????????????????????????????????????? }? else {

???????????????????????????????????????????????? //業(yè)務(wù)結(jié)果失敗

???????????????????????????????????????????????? LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的異步支付業(yè)務(wù)結(jié)果失敗");

???????????????????????????????????????????????? orderLogic.updateState(outTradeNo,2);

???????????????????????????????????????????????? resultMap.put("return_code",? WxpayConfig.SUCCESS);

????????????????????????????????????????? }

?????????????????????????????????? } else {

????????????????????????????????????????? //簽名失敗

????????????????????????????????????????? LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的異步支付簽名失敗");

????????????????????????????????????????? resultMap.put("return_code",? WxpayConfig.FAIL);

????????????????????????????????????????? resultMap.put("return_msg",? "簽名失敗");

?????????????????????????????????? }

??????????????????????????? } else {

?????????????????????????????????? //返回結(jié)果失敗

?????????????????????????????????? LogFactory.getInstance().getPayCallbackLogger().info("接收到微信的異步支付返回結(jié)果失敗");

?????????????????????????????????? resultMap.put("return_code",? WxpayConfig.FAIL);

?????????????????????????????????? resultMap.put("return_msg",? "參數(shù)格式校驗(yàn)錯(cuò)誤");

??????????????????????????? }

???????????????????? } catch (Exception e) {

??????????????????????????? e.printStackTrace();

???????????????????? }

????????????? } else {

???????????????????? //返回結(jié)果為空

???????????????????? LogFactory.getInstance().getPayCallbackLogger().info("參數(shù)格式校驗(yàn)錯(cuò)誤");

???????????????????? resultMap.put("return_code",? WxpayConfig.FAIL);

???????????????????? resultMap.put("return_msg",? "參數(shù)格式校驗(yàn)錯(cuò)誤");

????????????? }

????????????? return? WxpayUtil.parseToXml(resultMap);

?????? }


}`

付款成功統(tǒng)一處理事件監(jiān)聽

`@Component

public class OrderFinishLister {




? @EventListener


? public void onApplicationEvent(OrderFinishEvent event){//這里不能拋出異常,外層無法處理,會造成中斷


? try {

??????????? Map params =? (HashMap) event.getSource();

??????????? String payType =? params.get("payType");

??????????? String outTradeNo =? params.get("out_trade_no");

??????????? String trade_no = null;

??????????? String buyerLogonId = null;

??????????? String buyerId = null;

??????????? String transactionId = null;

??????????? UserOrder order = null;



? if("1".equals(payType)){

??????????????? //支付寶

???????????????? trade_no =? params.get("trade_no");

???????????????? buyerLogonId =? params.get("buyer_logon_id");

???????????????? buyerId =? params.get("buyer_id");

?????????????? ??//執(zhí)行付款成功后的業(yè)務(wù)邏輯


? LogFactory.getInstance().getLogger().debug("支付寶獲取支付更新狀態(tài):" + outTradeNo);

??????????? }else? if("2".equals(payType)){

??????????????? //微信

???????????????? transactionId =? params.get("transaction_id");

??????????????? //執(zhí)行微信付款成功后的業(yè)務(wù)邏輯


? LogFactory.getInstance().getLogger().debug("微信獲取支付更新狀態(tài):" + outTradeNo);

??????????? }


? }catch (Exception e){

??????????? e.printStackTrace();


? }


? }

}`

這就是單獨(dú)的微信支付業(yè)務(wù)流程

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,506評論 19 139
  • 該文僅對于中間這種支付方式有參考價(jià)值喲 一、開發(fā)背景 在微信公眾號中,需要進(jìn)行微信支付且為微信公眾號網(wǎng)頁支付。 二...
    英文名叫夏天閱讀 2,003評論 0 7
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語法,類相關(guān)的語法,內(nèi)部類的語法,繼承相關(guān)的語法,異常的語法,線程的語...
    子非魚_t_閱讀 34,623評論 18 399
  • 文/添一抹嵐 昨晚小妹的朋友圈里,貼出一張照片。不是她鐘愛的自拍照,也不是春之藍(lán)天白云,無限風(fēng)光,她發(fā)的竟是老屋照...
    添一抹嵐閱讀 1,170評論 60 35
  • 以后等你工作了,會比現(xiàn)在更忙,比現(xiàn)在認(rèn)識更多的人,處理更多的關(guān)系,參加更多更多的應(yīng)酬,考慮更多的事情,就更加沒有時(shí)...
    小草載著陽光閱讀 166評論 0 0

友情鏈接更多精彩內(nèi)容