支付完成后通知

本接口用于支付成功之后的通知,支付完成后采宝会将如下参数post到相关地址。

收到本接口的回调数据后,请异步处理订单逻辑,支付完成后的通知采用的是RSA签名算法,具体生成sign签名逻辑请看RSA请求签名规则, 并返回success字符串(必须完全相同,不能有任何其他字符),否则采宝会尝试进行重试,重试时间会不断加长,具体重试时间间隔为:15S、30S、300S、1800S、3600S、(24 * 3600 - 1800)S,共重试6次,超过时间后,不再进行通知,请自行通过订单查询接口同步支付状态。

需要注意的是:

1. 当接入方收到通知后,请立刻返回success,自己的业务请异步进行处理,通知超时时间为5S,超过5S会超时,超时后会记录异常一次。
2. 为了保障系统的问题定性,我们队外部通知采取了保护机制,如果发现一段时间(20分钟)内,大量订单通知异常(通知异常80次),那我们会将停止这个服务器订单的通知,停止通知20分钟,20分钟之后自动恢复通知,如果再在20分钟内发现还是通知失败超过80次,则重复之前停止通知的逻辑。

参数简介

参数名 参数介绍
cbOrderNo 采宝的订单号,最长64位
appOrderNo 调用方自己生成的订单号
outOrderNo 微信或支付宝产生的订单号
orderStatus 订单状态,详情参照:订单状态详解
totalAmount 订单总额,以分为单位
receiveAmount 实收金额,以分为单位
paymentChannel 支付渠道, 详情参照:支付渠道详解
subject 订单简介
discountAmount 优惠金额,以分为单位
paymentWay 支付方式,详情参照:支付方式详解
payTime 支付时间,数字格式,值为距离1970.1.1日的毫秒数
sign 签名值,具体参照: 接口验签规则

Rsa验证签名方法示例(java)

/**
     * 排序需要签名的字段
     * @param sortedParams 参数Map
     * @return
     */
    public static String getSignContent(Map<String, String> sortedParams) {
        StringBuffer content = new StringBuffer();
        ArrayList keys = new ArrayList(sortedParams.keySet());
        Collections.sort(keys);
        int index = 0;

        for(int i = 0; i < keys.size(); ++i) {
            String key = (String)keys.get(i);
            String value = (String)sortedParams.get(key);
            if (StringUtils.isNotEmpty(value)) {
                content.append((index == 0 ? "" : "&") + key + "=" + value);
                ++index;
            }
        }

        return content.toString();
    }


    /**
     * 验证签名
     * @param content 签证签名内容串
     * @param sign 签名
     * @param publicKey 公钥
     * @param charset 字符集
     * @param signType 签名类型
     * @return
     * @throws RsaSignException
     */
    public static boolean rsaCheck(String content, String sign, String publicKey, String charset, String signType) throws RsaSignException {
        if ("RSA".equals(signType)) {
            return rsaCheckContent(content, sign, publicKey, charset);
        } else if ("RSA2".equals(signType)) {
            return rsa256CheckContent(content, sign, publicKey, charset);
        } else {
            throw new RsaSignException("Sign Type is Not Support : signType=" + signType);
        }
    }

    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 boolean rsaCheckContent(String content, String sign, String publicKey, String charset) throws RsaSignException {
        try {
            PublicKey e = getPublicKeyFromX509("RSA", new ByteArrayInputStream(publicKey.getBytes()));
            Signature signature = Signature.getInstance("SHA1WithRSA");
            signature.initVerify(e);
            if (CheckUtil.isEmpty(charset)) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }

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

    public static boolean rsa256CheckContent(String content, String sign, String publicKey, String charset) throws RsaSignException {
        try {
            PublicKey e = getPublicKeyFromX509("RSA", new ByteArrayInputStream(publicKey.getBytes()));
            Signature signature = Signature.getInstance("SHA256WithRSA");
            signature.initVerify(e);
            if (CheckUtil.isEmpty(charset)) {
                signature.update(content.getBytes());
            } else {
                signature.update(content.getBytes(charset));
            }

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

results matching ""

    No results matching ""