java實(shí)現(xiàn)微信支付功能
微信支付的具體實(shí)現(xiàn)方法,供大家參考,具體內(nèi)容如下
工具類(用于在微信支付服務(wù)后臺(tái)生成預(yù)支付交易單)
package com.fengdi.lianmeng.zhifu.weixin;
import com.fengdi.lianmeng.util.MD5;
import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.Map;
/**
*
* 類說(shuō)明:除被掃支付場(chǎng)景以外,店鋪系統(tǒng)先調(diào)用該接口在微信支付服務(wù)后臺(tái)生成預(yù)支付交易單,
* 返回正確的預(yù)支付交易回話標(biāo)識(shí)后再按掃碼、JSAPI、APP等不同場(chǎng)景生成交易串調(diào)起支付。
* @author 聶楓
* 2016年1月8日上午11:33:21
*/
public class UnifiedorderReq{
/**
* 公眾賬號(hào)ID
*/
private String appid;
/**
* 店鋪號(hào)
*/
private String mch_id;
/**
* 設(shè)備號(hào)
*/
private String device_info;
/**
* 隨機(jī)字符串
*/
private String nonce_str;
/**
* 簽名
*/
private String sign;
/**
* 商品描述
*/
private String body;
/**
* 商品詳情
*/
private String detail;
/**
* 附加數(shù)據(jù)
*/
private String attach;
/**
* 店鋪訂單號(hào)
*/
private String out_trade_no;
/**
* 貨幣類型
*/
private String fee_type;
/**
* 總金額
*/
private Integer total_fee;
/**
* 終端IP
*/
private String spbill_create_ip;
/**
* 交易起始時(shí)間
*/
private String time_start;
/**
* 交易結(jié)束時(shí)間
*/
private String time_expire;
/**
* 商品標(biāo)記
*/
private String goods_tag;
/**
* 通知地址
*/
private String notify_url;
/**
* 交易類型
*/
private String trade_type;
/**
* 商品ID
*/
private String product_id;
/**
* 指定支付方式
*/
private String limit_pay;
/**
* 用戶標(biāo)識(shí)
*/
private String openid;
public String getAppid() {
return appid;
}
public void setAppid(String appid) {
this.appid = appid;
}
public String getMch_id() {
return mch_id;
}
public void setMch_id(String mch_id) {
this.mch_id = mch_id;
}
public String getDevice_info() {
return device_info;
}
public void setDevice_info(String device_info) {
this.device_info = device_info;
}
public String getNonce_str() {
return nonce_str;
}
public void setNonce_str(String nonce_str) {
this.nonce_str = nonce_str;
}
public String getSign() {
return sign;
}
public void setSign(String sign) {
this.sign = sign;
}
public String getBody() {
return body;
}
public void setBody(String body) {
this.body = body.length()>40?body.substring(0, 40):body;
}
public String getDetail() {
return detail;
}
public void setDetail(String detail) {
this.detail = detail;
}
public String getAttach() {
return attach;
}
public void setAttach(String attach) {
this.attach = attach;
}
public String getOut_trade_no() {
return out_trade_no;
}
public void setOut_trade_no(String out_trade_no) {
this.out_trade_no = out_trade_no;
}
public String getFee_type() {
return fee_type;
}
public void setFee_type(String fee_type) {
this.fee_type = fee_type;
}
public Integer getTotal_fee() {
return total_fee;
}
public void setTotal_fee(Integer total_fee) {
this.total_fee = total_fee;
}
public String getSpbill_create_ip() {
return spbill_create_ip;
}
public void setSpbill_create_ip(String spbill_create_ip) {
this.spbill_create_ip = spbill_create_ip;
}
public String getTime_start() {
return time_start;
}
public void setTime_start(String time_start) {
this.time_start = time_start;
}
public String getTime_expire() {
return time_expire;
}
public void setTime_expire(String time_expire) {
this.time_expire = time_expire;
}
public String getGoods_tag() {
return goods_tag;
}
public void setGoods_tag(String goods_tag) {
this.goods_tag = goods_tag;
}
public String getNotify_url() {
return notify_url;
}
public void setNotify_url(String notify_url) {
this.notify_url = notify_url;
}
public String getTrade_type() {
return trade_type;
}
public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}
public String getProduct_id() {
return product_id;
}
public void setProduct_id(String product_id) {
this.product_id = product_id;
}
public String getLimit_pay() {
return limit_pay;
}
public void setLimit_pay(String limit_pay) {
this.limit_pay = limit_pay;
}
public String getOpenid() {
return openid;
}
public void setOpenid(String openid) {
this.openid = openid;
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
builder.append("UnifiedorderReq [appid=");
builder.append(appid);
builder.append(", mch_id=");
builder.append(mch_id);
builder.append(", device_info=");
builder.append(device_info);
builder.append(", nonce_str=");
builder.append(nonce_str);
builder.append(", sign=");
builder.append(sign);
builder.append(", body=");
builder.append(body);
builder.append(", detail=");
builder.append(detail);
builder.append(", attach=");
builder.append(attach);
builder.append(", out_trade_no=");
builder.append(out_trade_no);
builder.append(", fee_type=");
builder.append(fee_type);
builder.append(", total_fee=");
builder.append(total_fee);
builder.append(", spbill_create_ip=");
builder.append(spbill_create_ip);
builder.append(", time_start=");
builder.append(time_start);
builder.append(", time_expire=");
builder.append(time_expire);
builder.append(", goods_tag=");
builder.append(goods_tag);
builder.append(", notify_url=");
builder.append(notify_url);
builder.append(", trade_type=");
builder.append(trade_type);
builder.append(", product_id=");
builder.append(product_id);
builder.append(", limit_pay=");
builder.append(limit_pay);
builder.append(", openid=");
builder.append(openid);
builder.append("]");
return builder.toString();
}
public String toSignString(){
Class<?> clz = this.getClass();
Field[] fields = clz.getDeclaredFields();
StringBuilder builder = new StringBuilder();
for (Field field : fields) {
builder.append(field.getName());
}
return builder.toString();
}
public String signString(){
StringBuilder builder = new StringBuilder();
builder.append("appid="+appid);
if(attach!=null){
builder.append("&attach="+attach);
}
builder.append("&body="+body);
builder.append("&mch_id="+mch_id);
builder.append("&nonce_str="+nonce_str);
builder.append("¬ify_url="+notify_url);
if(!trade_type.equals("APP")) {
builder.append("&openid="+openid);
}
builder.append("&out_trade_no="+out_trade_no);
builder.append("&spbill_create_ip="+spbill_create_ip);
builder.append("&total_fee="+total_fee);
builder.append("&trade_type="+trade_type);
builder.append("&key="+FgWxConfig.mobilekey);
return builder.toString();
}
public String wapSignString(){
StringBuilder builder = new StringBuilder();
builder.append("appid="+appid);
if(attach!=null){
builder.append("&attach="+attach);
}
builder.append("&body="+body);
builder.append("&mch_id="+mch_id);
builder.append("&nonce_str="+nonce_str);
builder.append("¬ify_url="+notify_url);
if(!trade_type.equals("APP")) {
builder.append("&openid="+openid);
}
builder.append("&out_trade_no="+out_trade_no);
builder.append("&spbill_create_ip="+spbill_create_ip);
builder.append("&total_fee="+total_fee);
builder.append("&trade_type="+trade_type);
builder.append("&key="+FgWxConfig.key);
return builder.toString();
}
public String toXml(){
return "<xml>" +
"<appid>"+appid+"</appid>"+
(attach != null? "<attach>"+attach+"</attach>" : "")+
"<body>"+body+"</body>"+
"<mch_id>"+mch_id+"</mch_id>"+
"<nonce_str>"+nonce_str+"</nonce_str>"+
"<notify_url>"+notify_url+"</notify_url>"+
(trade_type.equals("APP") == true?"":"<openid>"+openid+"</openid>")+
"<out_trade_no>"+out_trade_no+"</out_trade_no>"+
"<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
"<total_fee>"+total_fee+"</total_fee>"+
"<trade_type>"+trade_type+"</trade_type>"+
"<sign>"+MD5.encryptByMD5(signString()).toUpperCase()+"</sign>"+
"</xml>";
}
public String toWapXml(){
return "<xml>" +
"<appid>"+appid+"</appid>"+
(attach != null? "<attach>"+attach+"</attach>" : "")+
"<body>"+body+"</body>"+
"<mch_id>"+mch_id+"</mch_id>"+
"<nonce_str>"+nonce_str+"</nonce_str>"+
"<notify_url>"+notify_url+"</notify_url>"+
(trade_type.equals("APP") == true?"":"<openid>"+openid+"</openid>")+
"<out_trade_no>"+out_trade_no+"</out_trade_no>"+
"<spbill_create_ip>"+spbill_create_ip+"</spbill_create_ip>"+
"<total_fee>"+total_fee+"</total_fee>"+
"<trade_type>"+trade_type+"</trade_type>"+
"<sign>"+MD5.encryptByMD5(wapSignString()).toUpperCase()+"</sign>"+
"</xml>";
}
/*支付查詢簽名字符串*/
public String signQueryString(String transaction_id){
StringBuilder builder = new StringBuilder();
builder.append("appid="+appid);
builder.append("&body="+body);
builder.append("&mch_id="+mch_id);
builder.append("&nonce_str="+nonce_str);
builder.append("&transaction_id="+transaction_id);
builder.append("&key="+FgWxConfig.mobilekey);
return builder.toString();
}
/*支付查詢*/
public String toQueryXml(String transaction_id){
StringBuilder sBuilder=new StringBuilder();
sBuilder.append("<xml>");
sBuilder.append("<appid>"+appid+"</appid>");
sBuilder.append("<body>"+body+"</body>");
sBuilder.append("<mch_id>"+mch_id+"</mch_id>");
sBuilder.append("<nonce_str>"+nonce_str+"</nonce_str>");
sBuilder.append("<transaction_id>"+transaction_id+"</transaction_id>");
sBuilder.append("<sign>"+MD5.encryptByMD5(signQueryString(transaction_id)).toUpperCase()+"</sign>");
sBuilder.append("</xml>");
return sBuilder.toString();
}
public Map<String,Object> toMap(){
Map<String, Object> params = new HashMap<String, Object>();
params.put("appid", appid);
if(attach!=null){
params.put("attach", attach);
}
params.put("body", body);
params.put("mch_id", mch_id);
params.put("nonce_str", nonce_str);
params.put("notify_url", notify_url);
if(!trade_type.equals("APP")) {
params.put("openid", openid);
}
params.put("out_trade_no", out_trade_no);
params.put("spbill_create_ip", spbill_create_ip);
params.put("total_fee", total_fee);
params.put("trade_type", trade_type);
params.put("sign", MD5.encryptByMD5(signString()).toUpperCase());
return params;
}
組裝工具類數(shù)據(jù)
private AppWeixinPayResponse appUnifiedorderReq(Order order, Member member, HttpServletRequest request) {
// 獲取支付參數(shù)
UnifiedorderReq unifiedorderReq = new UnifiedorderReq();
unifiedorderReq.setBody(order.getOrderName().length() > 50 ? order.getOrderName().substring(0, 50) : order.getOrderName());
log.error(unifiedorderReq.getBody().length() + "--" + unifiedorderReq.getBody());
unifiedorderReq.setAttach(order.getOrderNo());
unifiedorderReq.setTotal_fee(order.getRealAmt().intValue());
unifiedorderReq.setTrade_type("APP");//此處可修改為JSAPI
unifiedorderReq.setOut_trade_no(order.getOrderNo() + RandomUtils.nextInt(100, 1000));
unifiedorderReq.setSpbill_create_ip(getIpAddr(request));
unifiedorderReq.setOpenid(member.getOpenid());
return payService.appUnifiedorderReq(unifiedorderReq, PayCategory.order.toString());
}
微信統(tǒng)一下單
public AppWeixinPayResponse appUnifiedorderReq(UnifiedorderReq unifiedorderReq, String payCategory)
throws FdServiceException {
unifiedorderReq.setAppid(FgWxConfig.appid_app);
unifiedorderReq.setMch_id(FgWxConfig.mchId);
unifiedorderReq.setNonce_str(Random2Utils.generateString(20));
if (payCategory.equals(PayCategory.order.toString())) {
unifiedorderReq.setNotify_url(fgProperties.getDomainUrl() + FgWxConfig.weixinOrderNotifyCallBack);
} else if (payCategory.equals(PayCategory.recharge.toString())) {
unifiedorderReq.setNotify_url(fgProperties.getDomainUrl() + FgWxConfig.weixinRechargeNotifyCallBack);
} else {
throw new FdServiceException(ErrorCode.ILLEGAL_ARGUMENT, "微信參數(shù)類型[" + payCategory + "]異常");
}
unifiedorderReq.setSign(MD5.encryptByMD5(unifiedorderReq.wapSignString()).toUpperCase());
logger.info("unifiedorder返回?cái)?shù)據(jù)unifiedorderReq:" + unifiedorderReq);
String unifiedorder = FgHttp.sendPost(FgWxConfig.unifiedorderUrl, unifiedorderReq.toWapXml());
logger.info("unifiedorder返回?cái)?shù)據(jù)unifiedorder:" + unifiedorder);
AppWeixinPayResponse appWeixinPayResponse = new AppWeixinPayResponse();
try {
Map<String, Object> map = XmlHelper.parseResXML(unifiedorder);
if ("SUCCESS".equals(map.get("return_code")) && "SUCCESS".equals(map.get("result_code"))) {
logger.info("微信統(tǒng)一下單返回成功:" + map);
appWeixinPayResponse.setAppid(FgWxConfig.appid_app);
appWeixinPayResponse.setNoncestr((String) map.get("nonce_str"));
appWeixinPayResponse.setPartnerid(FgWxConfig.mchId);
appWeixinPayResponse.setPrepayid((String) map.get("prepay_id"));
appWeixinPayResponse.setTimestamp((System.currentTimeMillis() + "").substring(0, 10));
appWeixinPayResponse.setSign(MD5.encryptByMD5(appWeixinPayResponse.wapSignString()).toUpperCase());
} else {
logger.info("微信統(tǒng)一下單返回失?。? + map);
throw new FdServiceException(ErrorCode.ILLEGAL_ARGUMENT, "微信統(tǒng)一下單返回失敗:" + map.get("return_msg"));
}
} catch (IOException e) {
e.printStackTrace();
} catch (ParserConfigurationException e) {
e.printStackTrace();
} catch (SAXException e) {
e.printStackTrace();
}
return appWeixinPayResponse;//直接將參數(shù)返回給前端,發(fā)起支付
}
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
Java中的Sentinel持久化規(guī)則啟動(dòng)
這篇文章主要介紹了Java中的Sentinel持久化規(guī)則啟動(dòng),本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-08-08
Java基于正則表達(dá)式實(shí)現(xiàn)查找匹配的文本功能【經(jīng)典實(shí)例】
這篇文章主要介紹了Java基于正則表達(dá)式實(shí)現(xiàn)查找匹配的文本功能,結(jié)合具體實(shí)例形式分析了java正則查找、字符串遍歷、group分組相關(guān)操作技巧,需要的朋友可以參考下2017-04-04
SpringBoot枚舉類型參數(shù)認(rèn)證的實(shí)現(xiàn)代碼
項(xiàng)目當(dāng)中經(jīng)常需要接口參數(shù)是否在一個(gè)可選的范圍內(nèi),也就是驗(yàn)證類枚舉參數(shù)的需求,所以本文我們將使用SpringBoot實(shí)現(xiàn)枚舉類型參數(shù)認(rèn)證,文中有詳細(xì)的代碼示例,需要的朋友可以參考下2023-12-12
Java中HashMap和Hashtable的區(qū)別小結(jié)
本文主要介紹了Java中HashMap和Hashtable的區(qū)別小結(jié),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07
springboot配合Thymeleaf完美實(shí)現(xiàn)遍歷功能
Thymeleaf顯然是一個(gè)開(kāi)發(fā)頁(yè)面的技術(shù),現(xiàn)在各種前端技術(shù)層出不窮,比如現(xiàn)在主流的Vue、React、AngularJS等。這篇文章主要介紹了springboot配合Thymeleaf完美實(shí)現(xiàn)遍歷,需要的朋友可以參考下2021-09-09
如何使用Spring Boot ApplicationRunner解析命令行中的參數(shù)
這篇文章主要介紹了使用Spring Boot ApplicationRunner解析命令行中的參數(shù),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2018-12-12
IDEA連接mysql報(bào)錯(cuò)的問(wèn)題及解決方法
這篇文章主要介紹了IDEA連接mysql報(bào)錯(cuò)的問(wèn)題及解決方法,本文通過(guò)圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-08-08

