回调说明
<hr />
<h4>为保证回调来源真实可靠 请您对 服务器ip 8.154.42.61 进行加白 除此之外全部拦截。我们系统会进行五次回调 如果五次都请求不同 将拉黑对应回调地址。 收到通知后记得返回 success 如果不返回会继续通知</h4>
<hr />
<h3>记账本安全发银行卡转账回调</h3>
<pre><code>//失败回调内容
{
&quot;biz_scene&quot;: &quot;ENTRUST_TRANSFER&quot;,
&quot;action_type&quot;: &quot;FINISH&quot;,
&quot;error_code&quot;: &quot;Ali_Err_111034&quot;,
&quot;origin_interface&quot;: &quot;alipay.fund.trans.uni.transfer&quot;,
&quot;out_biz_no&quot;: &quot;zfbe99caef3fc2f42ae828e7acb878247b1&quot;, //转账接口成功后的订单号
&quot;trans_amount&quot;: &quot;2000.00&quot;, //金额
&quot;product_code&quot;: &quot;SINGLE_TRANSFER_NO_PWD&quot;,
&quot;fail_reason&quot;: &quot;该银行账户不存在&quot;, //失败说明 只有失败才会有失败原因
&quot;order_id&quot;: &quot;20240903110070xxxxxx43991537&quot;, //支付宝订单号
&quot;timestamp&quot;: &quot;1735442319605&quot;, //时间戳
&quot;sign&quot;:&quot;f6cf4f05605defea8589c828a85657a1be447d0709081a26b1f0629638caffae&quot; ,//签名
&quot;status&quot;: &quot;FAIL&quot; //状态代表失败
}
//成功回调内容
{
&quot;pay_date&quot;: &quot;2024-09-03 18:08:10&quot;, //转账时间
&quot;biz_scene&quot;: &quot;ENTRUST_TRANSFER&quot;,
&quot;action_type&quot;: &quot;FINISH&quot;,
&quot;pay_fund_order_id&quot;: &quot;20240903xxxxxxx067988330&quot;,//支付宝交易号
&quot;origin_interface&quot;: &quot;alipay.fund.trans.uni.transfer&quot;,
&quot;out_biz_no&quot;: &quot;zfb8a32xxxxxxxeb7f6edee6&quot;, //转账接口成功后的订单号
&quot;trans_amount&quot;: &quot;100.00&quot;, //转账金额
&quot;product_code&quot;: &quot;SINGLE_TRANSFER_NO_PWD&quot;,
&quot;order_id&quot;: &quot;2024xxxxxxxx60043754024&quot;, //支付宝订单号
&quot;timestamp&quot;: &quot;1735442319605&quot;, //时间戳
&quot;sign&quot;:&quot;f6cf4f05605defea8589c828a85657a1be447d0709081a26b1f0629638caffae&quot;,//签名
&quot;status&quot;: &quot;SUCCESS&quot; //SUCCESS状态代表成功 DEALING 处理中(表示银行还在处理中) 处理中的订单也会回调
}
------</code></pre>
<h3>记账本安全发支付宝转账回调</h3>
<pre><code class="language-json"> {
&quot;code&quot;: &quot;10000&quot;,
&quot;msg&quot;: &quot;Success&quot;,
&quot;order_id&quot;: &quot;2024111112159884&quot;, //支付宝订单号
&quot;out_biz_no&quot;: &quot;n113131327536&quot;, //第三方单号
&quot;pay_fund_order_id&quot;: &quot;20241111112159884&quot;, //支付宝交易号
&quot;status&quot;: &quot;SUCCESS&quot;, //状态 只有成功的会返回 失败的在结果直接通知了
&quot;timestamp&quot;: &quot;1735442319605&quot;, //时间戳
&quot;sign&quot;:&quot;f6cf4f05605defea8589c828a85657a1be447d0709081a26b1f0629638caffae&quot;,//签名
&quot;trans_date&quot;: &quot;2024-12-29 20:26:25&quot; //支付时间
}</code></pre>
<h3>回调校验签名示例</h3>
<pre><code class="language-java">//校验回调签名
@SuppressWarnings(&quot;all&quot;)
@Test
public void t1() throws NoSuchAlgorithmException, IOException {
//回调的数据
JSONObject entries = JSONUtil.parseObj(callbackContent);
String apiSign=entries.getStr(&quot;sign&quot;);
entries.remove(&quot;sign&quot;); //移除签名
Map&lt;String, Object&gt; params = new TreeMap&lt;&gt;();
String sign = this.generateSignature(
&quot;您的appid&quot;,
&quot;您的appkey&quot;
,entries.getstr(&quot;timestamp&quot;) // 回调的时间戳
, entries.getstr(&quot;out_biz_no&quot;), // 回调的第三方单号
entries.toString(), params);
if (sign.equals(apiSign)){
//业务逻辑处理
return &quot;success&quot;; //返回succes 不会在通知 返回其他的任何还会通知4次
}
}
/\*\*
\* 生成签名
\* 构建待签名字符串:
\* 将所有签名参数按照一定规则(如字典序)进行排序。
\* 将排序后的参数按照“key=value”的格式拼接成一个字符串,参数之间用“&amp;”符号连接。
\* 例如:appid=xxx&amp;appkey=yyy×tamp=zzz¶m1=value1¶m2=value2。
\* 生成签名:
\* 使用哈希算法(如SHA-256对待签名字符串进行加密处理。
\* 将加密后的结果作为签名。
\*/
@SuppressWarnings(&quot;all&quot;)
public static String generateSignature(String appId, String appKey, String timestamp, String clientTransId, String data, Map&lt;String, Object&gt; params) throws NoSuchAlgorithmException{
//转换为json
JSONObject entries = JSONUtil.parseObj(data);
//排序data数据
TreeMap&lt;String, Object&gt; sortedParams1 = new TreeMap&lt;&gt;(entries);
//排序后转成json 并且转换成string
JSONObject entries1 = JSONUtil.parseObj(sortedParams1);
System.out.println(&quot;sortedParams1:&quot;+entries1);
// 构建待签名字符串
StringBuilder sb = new StringBuilder();
TreeMap&lt;String, Object&gt; sortedParams = new TreeMap&lt;&gt;(params);
sortedParams.put(&quot;appId&quot;, appId);
sortedParams.put(&quot;appKey&quot;, appKey);
sortedParams.put(&quot;timestamp&quot;, timestamp);
sortedParams.put(&quot;data&quot;, entries1.toString());
sortedParams.put(&quot;clientTransId&quot;, clientTransId);
for (Map.Entry&lt;String, Object&gt; entry : sortedParams.entrySet()) {
sb.append(entry.getKey()).append(&quot;=&quot;).append(entry.getValue()).append(&quot;&amp;&quot;);
}
// 去除最后一个&#039;&amp;&#039;字符
String unsignedString = sb.toString().substring(0, sb.length() - 1);
// 使用SHA-256算法生成签名
MessageDigest digest = MessageDigest.getInstance(&quot;SHA-256&quot;);
byte\[\] hashBytes = digest.digest(unsignedString.getBytes());
// 将字节数组转换为十六进制字符串
StringBuilder hashString = new StringBuilder();
for (byte b : hashBytes) {
hashString.append(String.format(&quot;%02x&quot;, b));
}
return hashString.toString();
}</code></pre>