通联收银宝支付流程

测试账户可以去官方文档里找

官方文档

https://aipboss.allinpay.com/know/devhelp/main.php?pid=38#mid=313

流程

订单提交接口(商户网站->H5收银台)

支付请求是商户向H5收银台发起的支付请求,请求数据通过该接口传递给平台,平台根据不同的手机浏览器自动选择不同支付方式,引导用户完成支付。

注意:加签的byte[]编码为UTF-8

生产接口地址:https://syb.allinpay.com/apiweb/h5unionpay/unionorder
测试接口地址:https://test.allinpaygd.com/apiweb/h5unionpay/unionorder

 public Map<String,String> pay(long trxamt,String reqsn,String paytype,String body,String remark,String acct,String validtime,String notify_url,String limit_pay,
                                  String idno,String truename,String asinfo,String sub_appid,String goods_tag,String benefitdetail,String chnlstoreid,String subbranch,String extendparams,String cusip,String fqnum) throws Exception{
        HttpConnectionUtil http = new HttpConnectionUtil(SybConstants.SYB_APIURL+"/pay");
        http.init();
        TreeMap<String,String> params = new TreeMap<String,String>();
        params.put("cusid", SybConstants.SYB_CUSID);
        params.put("appid", SybConstants.SYB_APPID);
        params.put("version", "11");
        params.put("trxamt", String.valueOf(trxamt));
        params.put("reqsn", reqsn);
        params.put("paytype", paytype);
        params.put("randomstr", SybUtil.getValidatecode(8));
        params.put("body", body);
        params.put("remark", remark);
        params.put("validtime", validtime);
        params.put("acct", acct);
        params.put("notify_url", notify_url);
        params.put("limit_pay", limit_pay);
        params.put("sub_appid", sub_appid);
        params.put("goods_tag", goods_tag);
        params.put("benefitdetail", benefitdetail);
        params.put("chnlstoreid", chnlstoreid);
        params.put("subbranch", subbranch);
        params.put("extendparams", extendparams);
        params.put("cusip", cusip);
        params.put("fqnum", fqnum);
        params.put("idno", idno);
        params.put("truename", truename);
        params.put("asinfo", asinfo);
        params.put("signtype", SybConstants.SIGN_TYPE);
        String appkey = SybConstants.SIGN_TYPE.equals("RSA") ? SybConstants.SYB_RSACUSPRIKEY
                : SybConstants.SYB_MD5_APPKEY;
        params.put("sign", SybUtil.unionSign(params,appkey,SybConstants.SIGN_TYPE));
        byte[] bys = http.postParams(params, true);
        String result = new String(bys,"UTF-8");
        Map<String,String> map = handleResult(result);
        return map;

    }


  @SuppressWarnings({ "rawtypes", "unchecked" })
    public static Map<String,String> handleResult(String result) throws Exception{
        System.out.println("ret:"+result);
        Map map = SybUtil.json2Obj(result, Map.class);
        if(map == null){
            throw new Exception("返回数据错误");
        }
        if("SUCCESS".equals(map.get("retcode"))){
            TreeMap tmap = new TreeMap();
            tmap.putAll(map);
            String appkey = SybConstants.SIGN_TYPE.equals("RSA") ? SybConstants.SYB_RSATLPUBKEY
                    : SybConstants.SYB_MD5_APPKEY;
            if(SybUtil.validSign(tmap, appkey, SybConstants.SIGN_TYPE)){
                return map;
            }else{
                throw new Exception("验证签名失败");
            }

        }else{
            throw new Exception(map.get("retmsg").toString());
        }
    }

在这里插入图片描述

工具类

HttpConnectionUtil

public class HttpConnectionUtil {
    private HttpURLConnection conn;
    private String connectUrl;

    public HttpConnectionUtil(String connectUrl){
        this.connectUrl = connectUrl;
    }

    public void init() throws Exception{
        URL url = new URL(connectUrl);
        System.setProperty("java.protocol.handler.pkgs", "javax.net.ssl");
        HostnameVerifier hv = new HostnameVerifier() {
            public boolean verify(String urlHostName, SSLSession session) {
                return urlHostName.equals(session.getPeerHost());
            }
        };
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
        URLConnection conn = url.openConnection();
        conn.setDoInput(true);
        conn.setDoOutput(true);
        conn.setReadTimeout(60000);
        conn.setConnectTimeout(30000);
        if (conn instanceof HttpsURLConnection){
            HttpsURLConnection httpsConn = (HttpsURLConnection)conn;
           // httpsConn.setSSLSocketFactory(SSLUtil.getInstance().getSSLSocketFactory());
        } else if (conn instanceof HttpURLConnection){
            HttpURLConnection httpConn = (HttpURLConnection)conn;
        } else {
            throw new Exception("不是http/https协议的url");
        }
        this.conn = (HttpURLConnection)conn;
        initDefaultPost();
    }

    public void destory(){
        try{
            if(this.conn!=null){
                this.conn.disconnect();
            }
        }catch(Exception e){

        }
    }

    private void initDefaultPost() throws Exception{
        conn.setDoOutput(true);
        conn.setDoInput(true);
        conn.setRequestMethod("POST");
        conn.setUseCaches(false);
        conn.setInstanceFollowRedirects(true);
        conn.setRequestProperty("Content-Type", "application/x-www-form-urlencoded");
    }

    public byte[] postParams(Map<String, String> params,boolean readreturn) throws IOException {
        StringBuilder outBuf = new StringBuilder();
        boolean isNotFirst = false;
        for (Map.Entry<String, String> entry: params.entrySet()){
            if (isNotFirst)
                outBuf.append('&');
            isNotFirst = true;
            outBuf
                    .append(entry.getKey())
                    .append('=')
                    .append(URLEncoder.encode(entry.getValue(), "UTF-8"));
        }
        System.out.println("参数:"+outBuf.toString());
        return postParams(outBuf.toString(),readreturn);
    }

    public byte[] postParams(String message,boolean readreturn) throws IOException {
        DataOutputStream out = new DataOutputStream(conn.getOutputStream());
        out.write(message.getBytes("UTF-8"));
        out.close();
        if(readreturn){
            return readBytesFromStream(conn.getInputStream());
        }else{
            return null;
        }
    }

    public byte[] postParams(byte[] message,boolean readreturn) throws IOException {
        DataOutputStream out = new DataOutputStream(conn.getOutputStream());
        out.write(message);
        out.close();
        if(readreturn){
            return readBytesFromStream(conn.getInputStream());
        }else{
            return null;
        }
    }

    private byte[] readBytesFromStream(InputStream is) throws IOException{
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        int readLen;
        byte[] tmpBuf = new byte[4096];
        while ((readLen = is.read(tmpBuf)) > 0)
            baos.write(tmpBuf, 0, readLen);
        is.close();
        return baos.toByteArray();
    }

    public HttpURLConnection getConn() {
        return conn;
    }
}

SybUtil

public class SybUtil {
    /**
     * js转化为实体
     *
     * @param <T>
     * @param jsonstr
     * @param cls
     * @return
     */
    public static <T> T json2Obj(String jsonstr, Class<T> cls) {
        JSONObject jo = JSONObject.fromObject(jsonstr);
        T obj = (T) JSONObject.toBean(jo, cls);
        return obj;
    }

    /**
     * md5
     *
     * @param b
     * @return
     */
    public static String md5(byte[] b) {
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.reset();
            md.update(b);
            byte[] hash = md.digest();
            StringBuffer outStrBuf = new StringBuffer(32);
            for (int i = 0; i < hash.length; i++) {
                int v = hash[i] & 0xFF;
                if (v < 16) {
                    outStrBuf.append('0');
                }
                outStrBuf.append(Integer.toString(v, 16).toLowerCase());
            }
            return outStrBuf.toString();
        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
            return new String(b);
        }
    }

    /**
     * 判断字符串是否为空
     *
     * @param s
     * @return
     */
    public static boolean isEmpty(String s) {
        if (s == null || "".equals(s.trim()))
            return true;
        return false;
    }

    /**
     * 生成随机码
     *
     * @param n
     * @return
     */
    public static String getValidatecode(int n) {
        Random random = new Random();
        String sRand = "";
        n = n == 0 ? 4 : n;// default 4
        for (int i = 0; i < n; i++) {
            String rand = String.valueOf(random.nextInt(10));
            sRand += rand;
        }
        return sRand;
    }



    public static boolean validSign(TreeMap<String, String> param,
                                    String appkey, String signType) throws Exception {
        if (param != null && !param.isEmpty()) {
            if (!param.containsKey("sign"))
                return false;
            String sign = param.remove("sign");
            if ("MD5".equals(signType)) {// 如果是md5则需要把md5的key加入到排序
                param.put("key", appkey);
            }
            StringBuilder sb = new StringBuilder();
            for (Map.Entry<String, String> entry : param.entrySet()) {
                if (entry.getValue() != null && entry.getValue().length() > 0) {
                    sb.append(entry.getKey()).append("=")
                            .append(entry.getValue()).append("&");
                }
            }
            if (sb.length() > 0) {
                sb.deleteCharAt(sb.length() - 1);
            }
            if ("MD5".equals(signType)) {
                return sign.toLowerCase().equals(
                        md5(sb.toString().getBytes("UTF-8")).toLowerCase());
            } else {
                return rsaVerifyPublickey(sb.toString(), sign, appkey, "UTF-8");
            }
        }
        return false;
    }

    public static boolean rsaVerifyPublickey(String content, String sign,
                                             String publicKey, String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509("RSA",
                    Base64.decodeBase64(publicKey.getBytes()));
            return rsaVerifyPublickey(content, sign, pubKey, charset);
        } catch (Exception e) {
            e.printStackTrace();
            throw new Exception("RSAcontent = " + content + ",sign=" + sign
                    + ",charset = " + charset, e);
        }
    }

    public static boolean rsaVerifyPublickey(String content, String sign,
                                             PublicKey pubKey, String charset) throws Exception {
        try {
            java.security.Signature signature = java.security.Signature
                    .getInstance("SHA1WithRSA");

            signature.initVerify(pubKey);

            if (charset == null || "".equals(charset)) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }

            return signature.verify(Base64.decodeBase64(sign.getBytes()));
        } catch (Exception e) {
            throw e;
        }
    }
    public static String unionSign(TreeMap<String, String> params,String appkey,
                                   String signType) throws Exception {
        // TODO Auto-generated method stub

        params.remove("sign");
        if ("MD5".equals(signType)) {// 如果是md5则需要把md5的key加入到排序
            params.put("key", appkey);
        }
        StringBuilder sb = new StringBuilder();
        for (Map.Entry<String, String> entry : params.entrySet()) {
            if (entry.getValue() != null && entry.getValue().length() > 0) {
                sb.append(entry.getKey()).append("=").append(entry.getValue())
                        .append("&");
            }
        }
        if (sb.length() > 0) {
            sb.deleteCharAt(sb.length() - 1);
        }
        String sign = "";
        if ("MD5".equals(signType)) {
            System.out.println(sb.toString());
            sign = md5(sb.toString().getBytes("UTF-8"));// 记得是md5编码的加签
            params.remove("key");
        } else {
            System.out.println(sb.toString());
            sign = rsaSign(sb.toString(), appkey, "UTF-8");
        }
        return sign;
    }

    public static String rsaSign(String content, String privateKey,
                                 String charset) throws Exception {
        PrivateKey priKey = getPrivateKeyFromPKCS8("RSA",
                Base64.decodeBase64(privateKey.getBytes()));
        return rsaSign(content, priKey, charset);
    }

    public static String rsaSign(String content, byte[] privateKey,
                                 String charset) throws Exception {
        PrivateKey priKey = getPrivateKeyFromPKCS8("RSA", privateKey);
        return rsaSign(content, priKey, charset);
    }

    public static String rsaSign(String content, PrivateKey priKey,
                                 String charset) throws Exception {
        java.security.Signature signature = java.security.Signature
                .getInstance("SHA1WithRSA");
        signature.initSign(priKey);
        if (charset == null || "".equals(charset)) {
            signature.update(content.getBytes());
        } else {
            signature.update(content.getBytes(charset));
        }
        byte[] signed = signature.sign();

        return new String(Base64.encodeBase64(signed));
    }

    public static PrivateKey getPrivateKeyFromPKCS8(String algorithm,
                                                    byte[] encodedKey) throws Exception {

        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);

        return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
    }

    public static PublicKey getPublicKeyFromX509(String algorithm,
                                                 byte[] encodedKey) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);

        return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    }
}

总结

我是把数据打印到控制台上了,这只是一个Damo 可以作为操作加入到项目中 支付成功后的回调地址是自己设置的需要注意必须是外网的端口

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值