盘盈分账系统

盘盈分账系统


接入指南

准备工作:

  • 每个商户拥有独立应用id(appId),每个支付通道拥有独立的收款编码(paymentCode),请联系工作人员获取
  • 每个商户拥有独立的参数加密私钥,请联系工作人员获取
  • 接口参数名大小写敏感
  • 接口返回为JSON格式
  • 每次调用接口时都需要传参数签名

    生产环境:
    测试环境:http://payment.test.payol.cn/

    项目登录密码: test/123456 可配置分账用户、分账比例、订单查询、支付撤销等

参数名 必选 类型 说明 备注
data String 请求参数 JSON数据序列化字符串
sign String 参数签名 RSA方式,使用私钥对请求参数签名

请求参数签名Sample:

public static String PRIVATE_KEY = "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDXYbSt91JOnZZaJXrt2CRM+TWsT/qx4ypJFx3lWXshcrS1KdJTJQv//lEEtluO9poQCRs0UAGLuCGlxGvZTVHtxSIPbPA36ITEVipekZ9FCugRZ8oIADsxdS4QnS8M8BDd3Qtl519kfs16fev7qNbf6tkMu/kPC8wO3VzBVOLUq3rRgCntTBfzyQBiH0ZEKGm3DefAynchvXy2MWKHfdgILF/x80TqYbv7LAub5hfsAasw4J05psXzNebRzugpoqDbfpNs8nkpz6U+QLJzdjKc9PMWw4S9ReCQnotNAaIp9RX8cxT6S8U1U0x33fERSYzYaGYVl5/x46rCOPCC7HVzAgMBAAECggEACmNrDI0GSkZtjxGJuVkYfyHyBcqhw9y6GGZmCb7kInve3XIT8/CwgHtquvh0uBOK4MUfq8lEGdIaxV0Q+p0xG2/LscTGXVv4s2OYjZEmhnT9NoG0C+i+8ia9vw1lzJDzr0/PEe4z+qvnC0ZxkGTXYFt6dpPGcoRWJk1lAOowOqOoEExcwsZhBkvGTWTv6AyBASBNhE2WAHzqRuF+Du4aEOirTyCfcgxb6hLVVVZWX2T5jRyq8lgn1RLg5ickVjtaWQBsPig32TImy0HKnRQa6WnKTNBaVOaDbsJzpxAq4OITgFjEg0L7QBjBJM1nVIh1kU73ixPCe1asqWTD7YutGQKBgQD0hGDxLe4Sm4IPkz/IStwJQpfUEskfPVbSGQS+KTMEPs2m2dB4mEV5x1JACekPxpUNe6KDt2YHYT9zRmxXGoJstuJ7C6qNAyxQB7jG0fxp20kweym81pBf7m9nSajw4i1Zq4axDTzLQ7YjF0dmdgR5BcJX8u5w3yj81sNFRuS4VwKBgQDhfw5z22Cg8n4gF0GLA4zrS/FeOD3lnQ7lQ91Hmp1ad5g0xyeHq53r/0+Ecyi1E0FK2el2pJVH0xmFW+xd7Q4teS3FZv5iw23NHyjFalipSqTmRjAAATRNGopMdwKwYqvtCTpkaNj/XRVTsDwmMA9f+C7vcA9YICkQjnOy++uqRQKBgDD/uiF6j8PAz+5pFpX/klp0stI3tYACHbzacJ3eya9nGnT+Hw2bjgiaTbwxgDe+Fq5uASIeBV8jOMDT8u/9ivdYKsh3jQTXBvE+quOEvu1DmUYS2ElUQfhHYqGzHByxZl8axVIDkhQ1jHE5wAAjVEAgTFKthuStg5wvOVBPpZPfAoGAawnJzXsUKjIRZqBDb3529PYuk7/0ubrM6E1Hi4a8LMZaTKtAe2keZHjjwQZ9Cz8hnitEZBoJ9nchRSl2ULuHIFTGQk76b90+kMC6tMMfZPTWw6wLeuUXc4YmoddYQmwEGldoDWOrpcQErJ4aXzIvCiof9W5nCjjx5TcJequUG7H2pQh3w==";
public static void main(String[] args) {
    try {
    // {"orderNo": "GK20231101123334817bS","payType": "wx_pub", "orderAmount" : 0.02, "paymentCode": "LSFPG5At5", "code": "071xVaGa1NGokG0OM4Ja149Vzo4xVaGJ"}
    PaymentInfoRequest payment = new PaymentInfoRequest();
    payment.setOrderNo("GK20231101123334817b1");
    payment.setPayType("wx_pub");
    payment.setOrderAmount(BigDecimal.valueOf(0.02));
    payment.setPaymentCode("LSFPG5At5");
    payment.setCode("071xVaGa1NGokG0OM4Ja149Vzo4xVaGJ");

    String payInfo = JSON.toJSONString(payment);

    // 请求参数签名
    String sign = PanySign.sign(payInfo, PRIVATE_KEY);

    //验签标记
    //boolean checkSign = PanySign.verifySign(payInfo, sign, PUBLIC_KEY);

    System.out.println("payInfo = " + payInfo);
    System.out.println("sign = " + sign);

    } catch (Exception e) {
    throw new RuntimeException(e);
    }
}

签名Util

/**
 * Pany签名工具类
 */
public class PanySign {

    public static String sign(String content, String privateKey) throws Exception {
        return sign(content, privateKey, "UTF-8");
    }

    public static boolean verifySign(String content, String sign, String publicKey) throws Exception {
        return verifySign(content, sign, publicKey, "UTF-8");
    }

    public static String sign(String content, String privateKey, String charset) throws Exception {
        try {
            PrivateKey priKey = getPrivateKeyFromPKCS8("RSA", new ByteArrayInputStream(privateKey.getBytes()));
            Signature signature = Signature.getInstance("SHA1withRSA");
            signature.initSign(priKey);
            if (charset != null && charset.length() != 0) {
                signature.update(content.getBytes(charset));
            } else {
                signature.update(content.getBytes());
            }

            byte[] signed = signature.sign();
            return new String(Base64.encodeBase64(signed));
        } catch (Exception var6) {
            throw new Exception("RSAcontent = " + content + "; charset = " + charset, var6);
        }
    }

    public static boolean verifySign(String content, String sign, String publicKey, String charset) throws Exception {
        try {
            PublicKey pubKey = getPublicKeyFromX509("RSA", new ByteArrayInputStream(publicKey.getBytes()));
            Signature signature = Signature.getInstance("SHA1withRSA");
            signature.initVerify(pubKey);
            if (charset != null && charset.length() != 0) {
                signature.update(content.getBytes(charset));
            } else {
                signature.update(content.getBytes());
            }

            return signature.verify(Base64.decodeBase64(sign.getBytes()));
        } catch (Exception var6) {
            throw new Exception("RSAcontent = " + content + ",sign=" + sign + ",charset = " + charset, var6);
        }
    }

    public static PrivateKey getPrivateKeyFromPKCS8(String algorithm, InputStream ins) throws Exception {
        boolean validKey = ins != null && algorithm != null || algorithm.length() != 0;
        if (validKey) {
            KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
            byte[] encodedKey = StreamUtil.readText(ins).getBytes();
            encodedKey = Base64.decodeBase64(encodedKey);
            return keyFactory.generatePrivate(new PKCS8EncodedKeySpec(encodedKey));
        } else {
            return null;
        }
    }

    public static PublicKey getPublicKeyFromX509(String algorithm, InputStream ins) throws Exception {
        KeyFactory keyFactory = KeyFactory.getInstance(algorithm);
        StringWriter writer = new StringWriter();
        StreamUtil.io(new InputStreamReader(ins), writer);
        byte[] encodedKey = writer.toString().getBytes();
        encodedKey = Base64.decodeBase64(encodedKey);
        return keyFactory.generatePublic(new X509EncodedKeySpec(encodedKey));
    }

    public static String getOriginalStr(Map<String, Object> map) {
        List<String> listKeys = new ArrayList(map.keySet());
        Collections.sort(listKeys);
        StringBuilder stringBuilder = new StringBuilder();

        for(int i = 0; i < listKeys.size(); ++i) {
            if (map.get(listKeys.get(i)) != null && map.get(listKeys.get(i)).toString().length() != 0) {
                stringBuilder.append((String)listKeys.get(i)).append("=").append(map.get(listKeys.get(i))).append("&");
            }
        }

        return stringBuilder.length() == 0 ? "" : stringBuilder.toString().substring(0, stringBuilder.length() - 1);
    }
}

StreamUtil:

public class StreamUtil {
    private static final int DEFAULT_BUFFER_SIZE = 8192;

    public StreamUtil() {
    }

    public static void io(InputStream in, OutputStream out, int bufferSize) throws IOException {
        if (bufferSize == -1) {
            bufferSize = 8192;
        }

        byte[] buffer = new byte[bufferSize];

        int amount;
        while((amount = in.read(buffer)) >= 0) {
            out.write(buffer, 0, amount);
        }

    }

    public static void io(Reader in, Writer out) throws IOException {
        io((Reader)in, (Writer)out, -1);
    }

    public static void io(Reader in, Writer out, int bufferSize) throws IOException {
        if (bufferSize == -1) {
            bufferSize = 4096;
        }

        char[] buffer = new char[bufferSize];

        int amount;
        while((amount = in.read(buffer)) >= 0) {
            out.write(buffer, 0, amount);
        }

    }

    public static String readText(InputStream in) throws IOException {
        return readText(in, (String)null, -1);
    }

    public static String readText(InputStream in, String encoding) throws IOException {
        return readText(in, encoding, -1);
    }

    public static String readText(InputStream in, String encoding, int bufferSize) throws IOException {
        Reader reader = encoding == null ? new InputStreamReader(in) : new InputStreamReader(in, encoding);
        return readText(reader, bufferSize);
    }

    public static String readText(Reader reader, int bufferSize) throws IOException {
        StringWriter writer = new StringWriter();
        io((Reader)reader, (Writer)writer, bufferSize);
        return writer.toString();
    }

    public static void closeQuietly(Reader input) {
        try {
            if (input != null) {
                input.close();
            }
        } catch (IOException var2) {
        }

    }

    public static void closeQuietly(Writer output) {
        try {
            if (output != null) {
                output.close();
            }
        } catch (IOException var2) {
        }

    }

    public static void closeQuietly(InputStream input) {
        try {
            if (input != null) {
                input.close();
            }
        } catch (IOException var2) {
        }

    }

    public static void closeQuietly(OutputStream output) {
        try {
            if (output != null) {
                output.close();
            }
        } catch (IOException var2) {
        }

    }
}

页面列表

ITEM_HTML