微信App支付开发历程

与微信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+"&timestamp="+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了!

posted @ 2017-02-23 14:06  流年飞逝  阅读(524)  评论(0编辑  收藏  举报