위챗 공중번호 지불(二) 통합 주문 인터페이스 실현
이 글은 주로 위챗 공중 결제의 통일된 주문 API를 호출하는 것이다
API 주소:https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_1
문서를 보면 주요 절차는 20개 정도의 매개 변수를 XML 형식으로 봉하여 위챗에서 보낸 인터페이스 주소로 보내면 되돌아오는 내용을 얻을 수 있다. 성공하면 지불에 필요한 선불 ID가 있다
요청 매개 변수는 설명하지 않습니다.
여기서 랜덤 문자열: UUID를 사용하여 중간선을 그립니다
public static String create_nonce_str() {
return UUID.randomUUID().toString().replace("-","");
}
상점 주문 번호: 매 주문 번호는 한 번만 사용할 수 있기 때문에 시스템의 주문 번호에 시간 스탬프를 추가합니다.총 금액:
알림 주소: 위챗 결제 성공 또는 실패가 시스템에 전송된 주소
서명:
import java.io.Serializable;
public class PayInfo implements Serializable{
private static final long serialVersionUID = L;
private String appid;
private String mch_id;
private String device_info;
private String nonce_str;
private String sign;
private String body;
private String attach;
private String out_trade_no;
private int total_fee;
private String spbill_create_ip;
private String notify_url;
private String trade_type;
private String openid;
// get,set
}
/**
* xml java
* @param bizOrder
* @param ip ip
* @param openId openId
* @return
*/
public PayInfo createPayInfo(BizOrder bizOrder,String ip,String openId) {
PayInfo payInfo = new PayInfo();
payInfo.setAppid(Constants.appid);
payInfo.setDevice_info("WEB");
payInfo.setMch_id(Constants.mch_id);
payInfo.setNonce_str(CommonUtil.create_nonce_str().replace("-", ""));
payInfo.setBody(" body");
payInfo.setAttach(bizOrder.getId());
payInfo.setOut_trade_no(bizOrder.getOrderCode().concat("A").concat(DateFormatUtils.format(new Date(), "MMddHHmmss")));
payInfo.setTotal_fee((int)bizOrder.getFeeAmount());
payInfo.setSpbill_create_ip(ip);
payInfo.setNotify_url(Constants.notify_url);
payInfo.setTrade_type("JSAPI");
payInfo.setOpenid(openId);
return payInfo;
}
서명 가져오기:
/**
*
* @param payInfo
* @return
* @throws Exception
*/
public String getSign(PayInfo payInfo) throws Exception {
String signTemp = "appid="+payInfo.getAppid()
+"&attach="+payInfo.getAttach()
+"&body="+payInfo.getBody()
+"&device_info="+payInfo.getDevice_info()
+"&mch_id="+payInfo.getMch_id()
+"&nonce_str="+payInfo.getNonce_str()
+"¬ify_url="+payInfo.getNotify_url()
+"&openid="+payInfo.getOpenid()
+"&out_trade_no="+payInfo.getOut_trade_no()
+"&spbill_create_ip="+payInfo.getSpbill_create_ip()
+"&total_fee="+payInfo.getTotal_fee()
+"&trade_type="+payInfo.getTrade_type()
+"&key="+Constants.key; // key
MessageDigest md = MessageDigest.getInstance("MD");
md.reset();
md.update(signTemp.getBytes("UTF-"));
String sign = CommonUtil.byteToStr(md.digest()).toUpperCase();
return sign;
}
참고: 위의 Constants.key 값은 상호 API 보안 API 키에 있습니다.일부 도구 방법: IP 주소를 가져와 바이트 그룹을 16진 문자열로 변환하고, 바이트를 16진 문자열로 변환합니다.
/**
*
*
* @param byteArray
* @return
*/
public static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = ; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
/**
*
*
* @param btyes
* @return
*/
public static String byteToHexStr(byte bytes) {
char[] Digit = { '', '', '', '', '', '', '', '', '', '', 'A', 'B', 'C', 'D', 'E', 'F' };
char[] tempArr = new char[];
tempArr[] = Digit[(bytes >>> ) & XF];
tempArr[] = Digit[bytes & XF];
String s = new String(tempArr);
return s;
}
/**
* ip
* @param request
* @return
*/
public static String getIpAddr(HttpServletRequest request) {
InetAddress addr = null;
try {
addr = InetAddress.getLocalHost();
} catch (UnknownHostException e) {
return request.getRemoteAddr();
}
byte[] ipAddr = addr.getAddress();
String ipAddrStr = "";
for (int i = ; i < ipAddr.length; i++) {
if (i > ) {
ipAddrStr += ".";
}
ipAddrStr += ipAddr[i] & xFF;
}
return ipAddrStr;
}
이렇게 하면 서명을 얻고 서명과 PayInfo의 다른 데이터를 XML 형식으로 바꾸어 매개 변수로 통일된 주문 주소에 전달합니다.
PayInfo pi = pu.createPayInfo(bo,"...","");
String sign = pu.getSign(pi);
pi.setSign(sign);
객체 전환 XML
/**
* xstream CDATA
*/
private static XStream xstream = new XStream(new XppDriver() {
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
// CDATA
boolean cdata = true;
@SuppressWarnings("rawtypes")
public void startNode(String name, Class clazz) {
super.startNode(name, clazz);
}
protected void writeText(QuickWriter writer, String text) {
if (cdata) {
writer.write("<![CDATA[");
writer.write(text);
writer.write("]]>");
} else {
writer.write(text);
}
}
};
}
});
public static String payInfoToXML(PayInfo pi) {
xstream.alias("xml", pi.getClass());
return xstream.toXML(pi);
}
xml 턴맵
@SuppressWarnings("unchecked")
public static Map<String, String> parseXml(String xml) throws Exception {
Map<String, String> map = new HashMap<String, String>();
Document document = DocumentHelper.parseText(xml);
Element root = document.getRootElement();
List<Element> elementList = root.elements();
for (Element e : elementList)
map.put(e.getName(), e.getText());
return map;
}
다음은 통합 주문 URL 호출입니다.
log.info(MessageUtil.payInfoToXML(pi).replace("__", "_"));
Map<String, String> map = CommonUtil.httpsRequestToXML("https://api.mch.weixin.qq.com/pay/unifiedorder", "POST", MessageUtil.payInfoToXML(pi).replace("__", "_").replace("<![CDATA[", "").replace("]]>", ""));
log.info(map);
public static Map<String, String> httpsRequestToXML(String requestUrl, String requestMethod, String outputStr) {
Map<String, String> result = new HashMap<>();
try {
StringBuffer buffer = httpsRequest(requestUrl, requestMethod, outputStr);
result = MessageUtil.parseXml(buffer.toString());
} catch (ConnectException ce) {
log.error(" :"+ce.getMessage());
} catch (Exception e) {
log.error("https :"+ece.getMessage());
}
return result;
}
httpsRequest() 이 방법은 1편에서위에서 얻은 맵이 성공하면 안에
String return_code = map.get("return_code");
if(StringUtils.isNotBlank(return_code) && return_code.equals("SUCCESS")){
String return_msg = map.get("return_msg");
if(StringUtils.isNotBlank(return_msg) && !return_msg.equals("OK")) {
return " !";
}
}else{
return " !";
}
String prepay_Id = map.get("prepay_id");
이 prepay_ID가 바로 선불 ID입니다.후불은 그것을 필요로 한다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
위챗 결제 자바 버전 V3 데이터 합법성 확인(Deom)1.1 위챗 리셋 데이터 분석 result 결과는 위챗에서 반환된 XML 데이터입니다. 1.2 위챗에서 반환된 XML 데이터 분석 smap으로 값을 가져온 질서정연한 맵 형식의 데이터를 되돌려줍니다.get (필드 이...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.