微信App支付开发历程
微信开放平台账号配置

查看详情得到对应的AppID和AppSecret(不可再次查看,创建App应用时保存好),对应的接口信息中注意开通微信支付

app支付核心代码如下:
//微信支付
String now_ip=Utils.getIP(request); //得到用户ip
String nonce_str=Utils.getCharAndNum(32); //得到32位随机数
int inputIntFee=1;
String total_fee=inputIntFee+"";
//total_fee="1";//
String prepay_id=null;
Map<String,String> paraMap=new HashMap<>();
paraMap.put("appid", PayConfigUtils.getWx_app_id());
paraMap.put("attach", description);
paraMap.put("body", body);
paraMap.put("mch_id", PayConfigUtils.getWx_mch_id());
paraMap.put("nonce_str", nonce_str);
paraMap.put("notify_url", PayConfigUtils.getWx_pay_notify_url());
paraMap.put("out_trade_no", passengerOrder.getPay_num());
paraMap.put("spbill_create_ip", now_ip);
paraMap.put("total_fee", total_fee);
paraMap.put("trade_type", "APP");
List<String> keys =new ArrayList<>(paraMap.keySet());
Collections.sort(keys);
StringBuilder authInfo = new StringBuilder();
for (int i=0;i<keys.size()-1; i++) {
String value = paraMap.get(keys.get(i));
authInfo.append(keys.get(i)+"="+value+"&");
}
authInfo.append(keys.get(keys.size()-1)+"="+paraMap.get(keys.get(keys.size()-1)));
String stringA=authInfo.toString()+"&key="+PayConfigUtils.getWx_app_secret_key();
String sign=Utils.encode("MD5",stringA).toUpperCase();
//封装xml
String paras="<xml>\n" +
" <appid>"+PayConfigUtils.getWx_app_id()+"</appid>\n" +
" <attach>"+description+"</attach>\n" +
" <body>"+body+"</body>\n" +
" <mch_id>"+PayConfigUtils.getWx_mch_id()+"</mch_id>\n" +
" <nonce_str>"+nonce_str+"</nonce_str>\n" +
" <notify_url>"+PayConfigUtils.getWx_pay_notify_url()+"</notify_url>\n" +
" <out_trade_no>"+passengerOrder.getPay_num()+"</out_trade_no>\n" +
" <spbill_create_ip>"+now_ip+"</spbill_create_ip>\n" +
" <total_fee>"+total_fee+"</total_fee>\n" +
" <trade_type>APP</trade_type>\n" +
" <sign>"+sign+"</sign>\n" +
"</xml>";
try {
String content=senPost(paras);
if(content!=null){
prepay_id=Utils.readStringXml(content);
}
if(prepay_id!=null){
String current_noncestr=Utils.getCharAndNum(32);
String current_sign=null;
long current_timestamp=System.currentTimeMillis()/1000;
result.put("appid",PayConfigUtils.getWx_app_id());
result.put("partnerid",PayConfigUtils.getWx_mch_id());
result.put("prepayid",prepay_id);
result.put("package","Sign=WXPay");
result.put("noncestr",current_noncestr);
result.put("timestamp",current_timestamp);
//加密算法
String nowStringA="appid="+PayConfigUtils.getWx_app_id()+"&noncestr="+current_noncestr+"&package=Sign=WXPay&partnerid="+PayConfigUtils.getWx_mch_id()+"&prepayid="+prepay_id+"×tamp="+current_timestamp+"&key="+PayConfigUtils.getWx_app_secret_key();
current_sign=Utils.encode("MD5",nowStringA).toUpperCase();
result.put("sign",current_sign);
}
} catch (Exception e) {
e.printStackTrace();
}
工具类Utils具体代码如下:
package com.now.do.utilities;
import org.apache.commons.lang.StringUtils;
import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.stereotype.Component;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;
import redis.clients.jedis.Jedis;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.security.MessageDigest;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
public class Utils {
public static String getCurrentTime() {
Date inputDate = new Date();
SimpleDateFormat outputFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String datetime = outputFormat.format(inputDate);
return datetime;
}
public static String getTimestamp() {
Long timestamp = System.currentTimeMillis();
return timestamp.toString();
}
public static long getCurrenTimeStamp(){
long time = System.currentTimeMillis();
return time;
}
//加密算法
public static String encode(String algorithm, String str) {
String ALGORITHM = "MD5";
char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
if (str == null) {
return null;
}
try {
MessageDigest messageDigest = MessageDigest.getInstance(algorithm);
messageDigest.update(str.getBytes("utf-8"));
return getFormattedText(messageDigest.digest());
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private static String getFormattedText(byte[] bytes) {
int len = bytes.length;
StringBuilder buf = new StringBuilder(len * 2);
char[] HEX_DIGITS = {'0', '1', '2', '3', '4', '5',
'6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};
// 把密文转换成十六进制的字符串形式
for (int j = 0; j < len; j++) {
buf.append(HEX_DIGITS[(bytes[j] >> 4) & 0x0f]);
buf.append(HEX_DIGITS[bytes[j] & 0x0f]);
}
return buf.toString();
}
public static String getIP(HttpServletRequest request) {
String ip = request.getHeader("X-Forwarded-For");
if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
//多次反向代理后会有多个ip值,第一个ip才是真实ip
int index = ip.indexOf(",");
if(index != -1){
return ip.substring(0,index);
}else{
return ip;
}
}
ip = request.getHeader("X-Real-IP");
if(StringUtils.isNotEmpty(ip) && !"unKnown".equalsIgnoreCase(ip)){
return ip;
}
return request.getRemoteAddr();
}
//产生8位随机数
public static String random(int n){
int[] i=new int[n];
int count=0;
String randomNum="";
while(count<n){
int t=(int)(Math.random()*9);//抽取的数值小于char类型的“z”(122)
if((t>=0&t<=9)){
i[count]=t;
count++;
}
}for(int k=0;k<n;k++){
if(i[k]>=0&i[k]<=9)
randomNum=randomNum+i[k];
else
randomNum=randomNum+(char)i[k];
}
return randomNum;
}
public static String getCharAndNum(int length) {
String val = "";
Random random = new Random();
for (int i = 0; i < length; i++) {
// 输出字母还是数字
String charOrNum = random.nextInt(2) % 2 == 0 ? "char" : "num";
// 字符串
if ("char".equalsIgnoreCase(charOrNum)) {
// 取得大写字母还是小写字母
int choice = random.nextInt(2) % 2 == 0 ? 65 : 97;
val += (char) (choice + random.nextInt(26));
} else if ("num".equalsIgnoreCase(charOrNum)) { // 数字
val += String.valueOf(random.nextInt(10));
}
}
return val;
}
public static void getUpperWord(){
String key="851wordW";
System.out.println(key.toUpperCase());
}
//随机生成一个在一定范围内的随机数
public static int getRandomNum(int limit){
int randomNum=(int)(Math.random()*(limit+1));//抽取的数值小于char类型的“z”(122)
return randomNum;
}
public static String readStringXml( String xml) {
Document doc ;
String result=null;
try {
doc = DocumentHelper.parseText(xml); // 将字符串转为XML
Element rootElt = doc.getRootElement(); // 获取根节点
Iterator return_code = rootElt.elementIterator("return_code"); // 获取根节点下的子节点return_code
// 获取根节点下的子节点return_code
String is_success=null;
// 遍历head节点
while (return_code.hasNext()) {
Element recordEle = (Element) return_code.next();
is_success = recordEle.getText(); // 拿到return_code返回值
//System.out.println("return_code:" + is_success);
}
if(is_success!=null&&is_success.equals("SUCCESS")){
Iterator prepay_id = rootElt.elementIterator("prepay_id");
while (prepay_id.hasNext()) {
Element recordEle = (Element) prepay_id.next();
result = recordEle.getText(); // 拿到prepay_id返回值
//System.out.println("prepay_id:" + result);
}
}
} catch (DocumentException e) {
e.printStackTrace();
} catch (Exception e) {
e.printStackTrace();
}
return result;
}
public static void getDoubleValue(){
String time=Utils.getCurrentTime();
System.out.println(time.substring(0,time.length()-3));
}
}
剩下的工作就是把得到的吊起微信支付的参数,即上面的JsonObject(result)发送到前台就ok了!

浙公网安备 33010602011771号