Skip to content
This repository has been archived by the owner on Jan 16, 2018. It is now read-only.

Improve prepay API to support all parameters. #214

Merged
merged 1 commit into from
Oct 14, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -671,33 +671,57 @@ public interface WxMpService {
*/
void setMaxRetryTimes(int maxRetryTimes);

/**
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
* @param openId 支付人openId
* @param outTradeNo 商户端对应订单号
* @param amt 金额(单位元)
* @param body 商品描述
* @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
* @param ip 发起支付的客户端IP
* @param notifyUrl 通知地址
* @return
*/
WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);
/**
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
* @param openId 支付人openId
* @param outTradeNo 商户端对应订单号
* @param amt 金额(单位元)
* @param body 商品描述
* @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
* @param ip 发起支付的客户端IP
* @param notifyUrl 通知地址
* @return
* @deprecated Use me.chanjar.weixin.mp.api.WxMpService.getPrepayId(Map<String, String>) instead
*/
@Deprecated
WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);

/**
* 该接口调用“统一下单”接口,并拼装JSSDK发起支付请求需要的参数
* 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82
* @param openId 支付人openId
* @param outTradeNo 商户端对应订单号
* @param amt 金额(单位元)
* @param body 商品描述
* @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
* @param ip 发起支付的客户端IP
* @param notifyUrl 通知地址
* @return
*/
Map<String, String> getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);
/**
* 统一下单(详见http://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1)
* 在发起微信支付前,需要调用统一下单接口,获取"预支付交易会话标识"
*
* @param parameters
* All required/optional parameters for weixin payment
* @return
* @throws IllegalArgumentException
*/
WxMpPrepayIdResult getPrepayId(Map<String, String> parameters);

/**
* 该接口调用“统一下单”接口,并拼装JSSDK发起支付请求需要的参数
* 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82
* @param parameters
* the required or optional parameters
* @return
*/
Map<String, String> getJSSDKPayInfo(Map<String, String> parameters);

/**
* 该接口调用“统一下单”接口,并拼装JSSDK发起支付请求需要的参数
* 详见http://mp.weixin.qq.com/wiki/7/aaa137b55fb2e0456bf8dd9148dd613f.html#.E5.8F.91.E8.B5.B7.E4.B8.80.E4.B8.AA.E5.BE.AE.E4.BF.A1.E6.94.AF.E4.BB.98.E8.AF.B7.E6.B1.82
* @param openId 支付人openId
* @param outTradeNo 商户端对应订单号
* @param amt 金额(单位元)
* @param body 商品描述
* @param tradeType 交易类型 JSAPI,NATIVE,APP,WAP
* @param ip 发起支付的客户端IP
* @param notifyUrl 通知地址
* @return
* @deprecated Use me.chanjar.weixin.mp.api.WxMpService.getJSSDKPayInfo(Map<String, String>) instead
*/
@Deprecated
Map<String, String> getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String notifyUrl);

/**
* 该接口提供所有微信支付订单的查询,当支付通知处理异常戒丢失的情冴,商户可以通过该接口查询订单支付状态。
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.TreeMap;
import java.util.UUID;
Expand Down Expand Up @@ -777,43 +778,45 @@ public void setMaxRetryTimes(int maxRetryTimes) {

@Override
public WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String callbackUrl) {
String nonce_str = System.currentTimeMillis() + "";

SortedMap<String, String> packageParams = new TreeMap<String, String>();
Map<String, String> packageParams = new HashMap<String, String>();
packageParams.put("appid", wxMpConfigStorage.getAppId());
packageParams.put("mch_id", wxMpConfigStorage.getPartnerId());
packageParams.put("nonce_str", nonce_str);
packageParams.put("body", body);
packageParams.put("out_trade_no", outTradeNo);

packageParams.put("total_fee", (int) (amt * 100) + "");
packageParams.put("spbill_create_ip", ip);
packageParams.put("notify_url", callbackUrl);
packageParams.put("trade_type", tradeType);
packageParams.put("openid", openId);

return getPrepayId(packageParams);
}

public WxMpPrepayIdResult getPrepayId(final Map<String, String> parameters) {
String nonce_str = System.currentTimeMillis() + "";

final SortedMap<String, String> packageParams = new TreeMap<String, String>(parameters);
packageParams.put("appid", wxMpConfigStorage.getAppId());
packageParams.put("mch_id", wxMpConfigStorage.getPartnerId());
packageParams.put("nonce_str", nonce_str);
checkParameters(packageParams);

String sign = WxCryptUtil.createSign(packageParams, wxMpConfigStorage.getPartnerKey());
String xml = "<xml>" +
"<appid>" + wxMpConfigStorage.getAppId() + "</appid>" +
"<mch_id>" + wxMpConfigStorage.getPartnerId() + "</mch_id>" +
"<nonce_str>" + nonce_str + "</nonce_str>" +
"<sign>" + sign + "</sign>" +
"<body><![CDATA[" + body + "]]></body>" +
"<out_trade_no>" + outTradeNo + "</out_trade_no>" +
"<total_fee>" + packageParams.get("total_fee") + "</total_fee>" +
"<spbill_create_ip>" + ip + "</spbill_create_ip>" +
"<notify_url>" + callbackUrl + "</notify_url>" +
"<trade_type>" + tradeType + "</trade_type>" +
"<openid>" + openId + "</openid>" +
"</xml>";
packageParams.put("sign", sign);

StringBuilder request = new StringBuilder("<xml>");
for (Entry<String, String> para : packageParams.entrySet()) {
request.append(String.format("<%s>%s</%s>", para.getKey(), para.getValue(), para.getKey()));
}
request.append("</xml>");

HttpPost httpPost = new HttpPost("https://api.mch.weixin.qq.com/pay/unifiedorder");
if (httpProxy != null) {
RequestConfig config = RequestConfig.custom().setProxy(httpProxy).build();
httpPost.setConfig(config);
}

StringEntity entity = new StringEntity(xml, Consts.UTF_8);
StringEntity entity = new StringEntity(request.toString(), Consts.UTF_8);
httpPost.setEntity(entity);
try {
CloseableHttpResponse response = getHttpclient().execute(httpPost);
Expand All @@ -828,9 +831,39 @@ public WxMpPrepayIdResult getPrepayId(String openId, String outTradeNo, double a
return new WxMpPrepayIdResult();
}

final String[] REQUIRED_ORDER_PARAMETERS = new String[] { "appid", "mch_id", "body", "out_trade_no", "total_fee", "spbill_create_ip", "notify_url",
"trade_type", };

private void checkParameters(Map<String, String> parameters) {
for (String para : REQUIRED_ORDER_PARAMETERS) {
if (!parameters.containsKey(para))
throw new IllegalArgumentException("Reqiured argument '" + para + "' is missing.");
}
if ("JSAPI".equals(parameters.get("trade_type")) && !parameters.containsKey("openid"))
throw new IllegalArgumentException("Reqiured argument 'openid' is missing when trade_type is 'JSAPI'.");
if ("NATIVE".equals(parameters.get("trade_type")) && !parameters.containsKey("product_id"))
throw new IllegalArgumentException("Reqiured argument 'product_id' is missing when trade_type is 'NATIVE'.");
}

@Override
public Map<String, String> getJSSDKPayInfo(String openId, String outTradeNo, double amt, String body, String tradeType, String ip, String callbackUrl) {
WxMpPrepayIdResult wxMpPrepayIdResult = getPrepayId(openId, outTradeNo, amt, body, tradeType, ip, callbackUrl);
Map<String, String> packageParams = new HashMap<String, String>();
packageParams.put("appid", wxMpConfigStorage.getAppId());
packageParams.put("mch_id", wxMpConfigStorage.getPartnerId());
packageParams.put("body", body);
packageParams.put("out_trade_no", outTradeNo);
packageParams.put("total_fee", (int) (amt * 100) + "");
packageParams.put("spbill_create_ip", ip);
packageParams.put("notify_url", callbackUrl);
packageParams.put("trade_type", tradeType);
packageParams.put("openid", openId);

return getJSSDKPayInfo(packageParams);
}

@Override
public Map<String, String> getJSSDKPayInfo(Map<String, String> parameters) {
WxMpPrepayIdResult wxMpPrepayIdResult = getPrepayId(parameters);
String prepayId = wxMpPrepayIdResult.getPrepay_id();
if (prepayId == null || prepayId.equals("")) {
throw new RuntimeException("get prepayid error");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ public class WxMpPrepayIdResult implements Serializable {
private String result_code;
private String prepay_id;
private String trade_type;
private String err_code;
private String err_code_des;
private String code_url;

public String getReturn_code() {
return return_code;
Expand Down Expand Up @@ -94,4 +97,28 @@ public String getTrade_type() {
public void setTrade_type(String trade_type) {
this.trade_type = trade_type;
}

public String getErr_code() {
return err_code;
}

public void setErr_code(String err_code) {
this.err_code = err_code;
}

public String getErr_code_des() {
return err_code_des;
}

public void setErr_code_des(String err_code_des) {
this.err_code_des = err_code_des;
}

public String getCode_url() {
return code_url;
}

public void setCode_url(String code_url) {
this.code_url = code_url;
}
}