业务流程
- 抗辩服务覆盖范围
- 除信用卡外,还可以处理Paypal、Klarna等钱包类工具的争议案件
- 支持欺诈类拒付抗辩,但需要传输额外的字段
- 抗辩服务时间要求:
- 信用卡:一般为16天
- paypal等钱包支付方式:一般为12天
- T1: 接收到拒付消息后,给到商家准备材料的时间: 建议为5天
- T2: 上传材料后,跨拒通的初审时间: 3天时间
- T3: 跨拒通给出补充意见后,商户补充材料的时间:建议为2天时间
- T4: 跨拒通最后的审核时间:建议为2天
收单机构给到商户的时间:
跨拒通时效设置:
- 商户沟通需求(为提高胜率,建议允许跨拒通在以下情况下直接联系商家):
- 商家未在规定时间内补充材料
- 商家补充材料后仍然不符合抗辩要求
- 以下4类拒付建议放弃抗辩:
- 未采用3D验证的欺诈类拒付
- 拒付时商家尚未发货
- 买家已将货物退回
- 低于拒付处理费&抗辩成本的低金额交易(例如15USD以下)
安全与加密方式
- 要使用我们的 API,您将需要某些凭据,我们将使用这些凭据来识别和授权使用拒付抗辩 API服务。请通过 support@tradefensor.com 联系我们 以获取您的凭据。您应该从我们这里获得以下凭据才能开始使用 API
接口参数
- 通讯方式:
https+JSON
- 字符集:
UTF-8
- 加密方式:
MD5 Salt
- Request Body
- Content Type
application/json
- API 域名
- 生产环境:
https://mer.tradefensor.com
- 加密方式
- 加密:MD5 (参与签名的参数按照ASCII码从小到大排序,将参数按固定顺序组装成签名原始串以“&”拼接,最后在拼接上商户密钥。签名的参数顺序和格式如下:key1=value1&key2=value2...keyn=valuen*****)
javaimport com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONArray; import com.alibaba.fastjson.JSONObject; import org.apache.commons.lang3.StringUtils; import org.apache.http.HttpException; import java.io.IOException; import java.io.UnsupportedEncodingException; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.util.*; public class TestSign { public static String sign(Map<String, Object> paramValues, String secret) { StringBuilder sb = new StringBuilder(); List<String> paramNames = new ArrayList<String>(paramValues.size()); paramNames.addAll(paramValues.keySet()); Collections.sort(paramNames); for (String key : paramNames) { Object value = paramValues.get(key); if (value == null || StringUtils.isBlank(value.toString())) { continue; } String value_inner = value.toString(); if (value_inner.startsWith("[")) { sb.append("&").append(key).append("=").append(parseJsonArray(value_inner)); } else if (value_inner.startsWith("{")) { Map requestMap = JSON.parseObject(value_inner); sb.append("&").append(key).append("=").append(sign(requestMap, secret)); } else { sb.append("&").append(key).append("=").append(value.toString()); } } sb.append("&").append(secret); String str = sb.substring(1,sb.length()); return disguiseMD5(str,"UTF-8"); } private static JSONArray parseJsonArray(String jsonArrayString) { List<Map<String, Object>> list = (List<Map<String, Object>>) JSONArray.parse(jsonArrayString); List<JSONObject> result = new LinkedList<JSONObject>(); for (Map<String, Object> map : list) { List<String> paramNames = new ArrayList<String>(map.size()); paramNames.addAll(map.keySet()); Collections.sort(paramNames); //JSONObject.toJSONString(json, SerializerFeature.SortField) JSONObject jsonObject = new JSONObject(true); for (String key : paramNames) { Object value = map.get(key); if (value == null || StringUtils.isBlank(value.toString())) { continue; } jsonObject.put(key, value); } result.add(jsonObject); } // logger.info("\nJSONArray 内JSONObject排序:{}\n", result); Collections.sort(result, (JSONObject o1, JSONObject o2) -> { Integer o1_index = o1.getInteger("index"); Integer o2_index = o2.getInteger("index"); if (o1_index == null || o2_index == null) { throw new IllegalArgumentException("参数明细中需要指定INDEX"); } return o1_index.compareTo(o2_index); }); // logger.info("\nJSONArray 排序:{}\n", result.toString()); JSONArray jsonArray = new JSONArray(); for (JSONObject jsonObject : result) { jsonArray.add(jsonObject); } return jsonArray; } public static String disguiseMD5(String message, String encoding) { if (null == message || null == encoding) { return null; } message = message.trim(); byte value[]; try { value = message.getBytes(encoding); } catch (UnsupportedEncodingException e) { value = message.getBytes(); } MessageDigest md = null; try { md = MessageDigest.getInstance("MD5"); } catch (NoSuchAlgorithmException e) { return null; } return toHex(md.digest(value)); } public static String toHex(byte input[]) { if (input == null) { return null; } StringBuffer output = new StringBuffer(input.length * 2); for (int i = 0; i < input.length; i++) { int current = input[i] & 0xff; if (current < 16) { output.append("0"); } output.append(Integer.toString(current, 16)); } return output.toString(); } public static void main(String[] args) throws IOException, HttpException { Map<String, Object> paramValues = new HashMap<>(); paramValues.put("test","222"); System.out.println(sign(paramValues,"Hr2JXE5mHjUL3vopraYZrZWDzfMaA0OLAvs5QxsIdJc=")); } }
合作清单
协助我们的新合作伙伴进行 API 集成、开发和测试的清单。
Item | Description |
在生产中将 IP/s 列入白名单 | eg. 111.222.333.444 |
接收加密生产 API_KEY等信息的电子邮件地址。 |
流程图
- 当发起抗辩,提供完善的材料时,虚线处 step3和 step4则不会发生
接口文档
👉 点击此处
数据结构&释义
- 支付、拒付、订单之间的关系:
- 1 笔【拒付】对应 1 笔【支付】
- 1 笔【支付】对应 N 笔【订单】
- 1 笔【订单】对应 N 个【商品】、N个【物流】、N个【交易历史】、1个【买卖家】、1笔【退款】、1笔【质量证明】、1笔【售后】 、1笔【商家陈述】
xml一笔拒付任务的示例: chargeback1 payment1 (第1笔订单数据) - contract1 - Seller&buyer1 - Products1_1 | Products1_2 - Quality1 - Shipping1_1 | Shipping1_2 - Return&Refund1 - Aftersales1 - History1 | History1 - Statement (第2笔订单数据) - contract2 - Seller&buyer2 - Products2_1 | Products2_2 - Quality2 - Shipping2_1 | Shipping2_2 - Return&Refund2 - Aftersales2 - History2_1 | History2_2 - Statement