Der vorherige Artikel hat die OpenId des Benutzers erhalten
In diesem Artikel wird hauptsächlich die einheitliche Bestell-API der öffentlichen WeChat-Zahlung aufgerufen
API-Adresse: https://pay.weixin.qq. wiki/doc/api/jsapi.php?chapter=9_1
Wenn man sich das Dokument ansieht, besteht der Hauptprozess darin, etwa 20 Parameter im XML-Format zu kapseln und sie an die von WeChat bereitgestellte Schnittstellenadresse und dann an Sie zu senden Der zurückgegebene Inhalt enthält bei Erfolg die für die Zahlung erforderliche Vorauszahlungs-ID
. Die Anforderungsparameter werden nicht erläutert.
Darunter zufällige Zeichenfolge: Ich verwende UUID, um den Unterstrich zu entfernen
1 2 3 | public static String create_nonce_str() {
return UUID.randomUUID().toString().replace("-","");
}
|
Nach dem Login kopieren
Bestellnummer des Händlers: Jede Bestellnummer Es kann nur einmal verwendet werden, daher wird der zur Bestellnummer des Systems hinzugefügte Zeitstempel verwendet.
Gesamtbetrag: kann nicht sein
Benachrichtigungsadresse: Die Adresse, die an das System zurückgerufen werden soll, wenn die WeChat-Zahlung erfolgreich oder fehlgeschlagen ist
Signatur:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 | 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;
}
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;
}
|
Nach dem Login kopieren
Signatur abrufen:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
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;
MessageDigest md = MessageDigest.getInstance("MD");
md.reset();
md.update(signTemp.getBytes("UTF-"));
String sign = CommonUtil.byteToStr(md.digest()).toUpperCase();
return sign;
}
|
Nach dem Login kopieren
Hinweis: Der Wert von Constants.key oben ist der API-Sicherheit API-Passwort der Händlernummer im Schlüssel.
Einige Tool-Methoden: IP-Adresse abrufen, Byte-Array in hexadezimale Zeichenfolge konvertieren, Bytes in hexadezimale Zeichenfolge konvertieren
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | public static String byteToStr(byte[] byteArray) {
String strDigest = "";
for (int i = ; i < byteArray.length; i++) {
strDigest += byteToHexStr(byteArray[i]);
}
return strDigest;
}
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;
}
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;
}
|
Nach dem Login kopieren
Auf diese Weise wird die Signatur eingeholt, die Signatur und andere Daten in PayInfo in das XML-Format umgewandelt und als Parameter an die einheitliche Bestelladresse übergeben.
1 2 3 | PayInfo pi = pu.createPayInfo(bo,"...","");
String sign = pu.getSign(pi);
pi.setSign(sign);
|
Nach dem Login kopieren
Objekt zu XML
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | private static XStream xstream = new XStream( new XppDriver() {
public HierarchicalStreamWriter createWriter(Writer out) {
return new PrettyPrintWriter(out) {
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);
}
|
Nach dem Login kopieren
XML zu Map
1 2 3 4 5 6 7 8 9 10 | @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;
}
|
Nach dem Login kopieren
Im Folgenden finden Sie die URL zum Aufrufen der einheitlichen Reihenfolge
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | log.info(MessageUtil.payInfoToXML(pi).replace("__", "_"));
Map<String, String> map = CommonUtil.httpsRequestToXML("https:
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;
}
|
Nach dem Login kopieren
httpsRequest()-Methode Kapitel 1 Im Artikel
Wenn die oben erhaltene Karte erfolgreich ist, wird
1 2 3 4 5 6 7 8 9 10 | 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");
|
Nach dem Login kopieren
darin
Diese prepay_id enthalten sein ist die Zahlungs-ID prepay_id. Sie benötigen es später zur Zahlung.
Weitere Artikel zur WeChat-Zahlung für öffentliche Konten (2) zur Realisierung einer einheitlichen Bestellschnittstelle finden Sie auf der chinesischen PHP-Website!