话说接支付宝的故事已经有几个回合了,30年河东,30年河西,之前的支付宝已经不再是之前的支付宝啦,从技术上来讲,变得越来越古怪了。接口都被当成产品,各种需要签约啦。今天的重点在于支付宝网银直连、转账到银行卡两个接口,故事的来来回回已经越约了技术层面,俨然成了一场非技术层面拉锯。读完本故事,您应该懂得怎么开通支付宝网银直连、转账到支付宝,故事写于2019年9月29日下午16点46分。如果支付宝变来变去,故事也可能成为历史传奇,不再有效。
一、捉摸不透的官方客服
向官方客服进行咨询的话,先是机器人伺候,再到人工客服,统一都是说网银直连下线了、转账到银行卡下线了,无在线签约入口。蹊跷的是,在线客服提供可至电xxxx咨询,联系业务经理云云。
二、线下业务经理的快速通道
原来被当成无解的支付宝网银直连&转账到银行卡,竟然在支付宝业务经理BD的线下邮件开通方式下,可以开通。这已经不再是技术领域的问题了。看接口路径中的pre-open,文档顶部标明了定向开放文档。这些接口不签约,统统是不生效了,参考文档开发,也调不通。能走线下就不要去走线上,感觉线下就像一个绿色通道,无所不能。
2.1 支付宝网银直连
网银直连的文档看起比较老旧,像是之前的支付宝对接文档。demo也不难,不过,不签约的话,照着demo做,也无法直接跳到网银。官方提供的demo是java jsp版本,有点小小的不适应。
依据官方demo,转了一份Spring MCV版本
"api") (value =
public String api(Model model, HttpServletRequest request) throws Exception {
// 支付类型
String payment_type = "1";
// 必填,不能修改
// 服务器异步通知页面路径
String notify_url = "https://i.zuime.com/create_direct_pay_by_user-JAVA-UTF-8/notify_url.jsp";
// 需http://格式的完整路径,不能加?id=123这类自定义参数
// 页面跳转同步通知页面路径
String return_url = "https://i.zuime.com/create_direct_pay_by_user-JAVA-UTF-8/return_url.jsp";
// 需http://格式的完整路径,不能加?id=123这类自定义参数,不能写成http://localhost/
// 商户订单号
String out_trade_no = new String(request.getParameter("WIDout_trade_no").getBytes("ISO-8859-1"), "UTF-8");
// 商户网站订单系统中唯一订单号,必填
// 订单名称
String subject = new String(request.getParameter("WIDsubject").getBytes("ISO-8859-1"), "UTF-8");
// 必填
// 付款金额
String total_fee = new String(request.getParameter("WIDtotal_fee").getBytes("ISO-8859-1"), "UTF-8");
// 必填
// 订单描述
String body = new String(request.getParameter("WIDbody").getBytes("ISO-8859-1"), "UTF-8");
// 默认支付方式
String paymethod = "bankPay";
// 必填
// 默认网银
String defaultbank = new String(request.getParameter("WIDdefaultbank").getBytes("ISO-8859-1"), "UTF-8");
// 必填,银行简码请参考接口技术文档
// 商品展示地址
String show_url = new String(request.getParameter("WIDshow_url").getBytes("ISO-8859-1"), "UTF-8");
// 需以http://开头的完整路径,例如:http://www.商户网址.com/myorder.html
// 防钓鱼时间戳
String anti_phishing_key = "";
// 若要使用请调用类文件submit中的query_timestamp函数
// 客户端的IP地址
String exter_invoke_ip = "";
// 非局域网的外网IP地址,如:221.0.0.1
//////////////////////////////////////////////////////////////////////////////////
// 把请求参数打包成数组
Map<String, String> sParaTemp = new HashMap<String, String>();
sParaTemp.put("service", "create_direct_pay_by_user");
sParaTemp.put("partner", AlipayConfig.partner);
sParaTemp.put("seller_email", AlipayConfig.seller_email);
sParaTemp.put("_input_charset", AlipayConfig.input_charset);
sParaTemp.put("payment_type", payment_type);
sParaTemp.put("notify_url", notify_url);
sParaTemp.put("return_url", return_url);
sParaTemp.put("out_trade_no", out_trade_no);
sParaTemp.put("subject", subject);
sParaTemp.put("total_fee", total_fee);
sParaTemp.put("body", body);
sParaTemp.put("paymethod", paymethod);
sParaTemp.put("defaultbank", defaultbank);
sParaTemp.put("show_url", show_url);
sParaTemp.put("anti_phishing_key", anti_phishing_key);
sParaTemp.put("exter_invoke_ip", exter_invoke_ip);
// 建立请求
String sHtmlText = AlipaySubmit.buildRequest(sParaTemp, "get", "确认");
model.addAttribute("page", sHtmlText);
return "pay/alipay/mapi/api";
重点参数在paymethod、defaultbank。
String paymethod = "bankPay";//网银直连
String defaultbank= "CMB";//银行简码,参考支付宝对接文档详细说明
PS:敲黑板画重点,没有签约的话,是无法跳过去的,这些参数都不会生效,依旧会跳到支付宝的支付界面,而不是网银。
2.2 转账到银行卡
支付宝转账到银行卡
https://docs.alipay.com/pre-open/api_pre/alipay.fund.trans.tobank.transfer
发起转账到银行卡后,支付宝会返回很详细的错误信息。
错误码 | 错误描述 | 解决方案 |
---|---|---|
INVALID_PARAMETER | 参数有误。 | 请根据入参说明检查请求参数合法性。 |
SYSTEM_ERROR | 系统繁忙 | 可能发生了网络或者系统异常,导致无法判定准确的转账结果。此时,商户不能直接当做转账成功或者失败处理,可以考虑采用相同的out_biz_no重发请求,或者通过调用“(alipay.fund.trans.order.query)”来查询该笔转账订单的最终状态。 |
EXCEED_LIMIT_SM_AMOUNT | 单笔额度超限 | 请根据接入文档检查amount字段 |
EXCEED_LIMIT_DM_AMOUNT | 日累计额度超限 | 请根据接入文档说明检查本日请求总金额+本次请求金额是否超限。 |
EXCEED_LIMIT_MM_AMOUNT | 月累计金额超限 | 请根据接入文档说明检查本月请求总金额+本次请求金额是否超限。 |
PAYCARD_UNABLE_PAYMENT | 付款账户余额支付功能不可用 | 请付款账户登录支付宝账户开启余额支付功能。 |
PAYER_STATUS_ERROR | 付款账号状态异常 | 请检查付款方是否进行了自助挂失,如果无,请联系支付宝客服检查用户状态是否正常。 |
PAYER_CERTIFY_CHECK_FAIL | 付款方人行认证受限 | 付款方请升级认证等级。 |
PAYER_STATUS_ERROR | 付款方用户状态不正常 | 请检查付款方是否进行了自助挂失,如果无,请联系支付宝客服检查用户状态是否正常。 |
PAYER_BALANCE_NOT_ENOUGH | 付款方余额不足 | 支付时间点付款方余额不足,请向付款账户余额充值后再原请求重试。 |
PAYER_USER_INFO_ERROR | 付款用户姓名或其它信息不一致 | 检查付款用户姓名payer_real_name与真实姓名一致性。 |
PAYMENT_INFO_INCONSISTENCY | 两次请求商户单号一样,但是参数不一致 | 如果想重试前一次的请求,请用原参数重试,如果重新发送,请更换单号。 |
CARD_BIN_ERROR | 收款人银行账号不正确 | 请确认收款人银行账号正确性,要求为借记卡卡号。 |
PAYEE_CARD_INFO_ERROR | 收款方卡信息错误 | 请联系收款方确认卡号与姓名一致性。 |
INST_PAY_UNABLE | 资金流出能力不具备 | 可能由于银行渠道在维护或无T0渠道,与联系支付宝客服确认。 |
PAYER_ACC_OCUPIED | 付款人登录账号存在多个重复账户,无法确认唯一 | 如果未传输payer_account_name,请传入payer_account_name; 如果传入了payer_account_name,则是由于登录账号对应的多个重复账户的真实姓名一致,请更换登录号。 |
MEMO_REQUIRED_IN_TRANSFER_ERROR | 根据监管部门的要求,单笔转账金额达到50000元时,需要填写付款理由 | 请填写remark或memo字段。 |
PERMIT_CHECK_PERM_IDENTITY_THEFT | 您的账户存在身份冒用风险,请进行身份核实解除限制 | 您的账户存在身份冒用风险,请进行身份核实解除限制 |
依据官方提示,状态可以通过alipay.fund.trans.order.query接口进行查询核实。而官方的接口描述,又给出了神奇的描述。
https://docs.open.alipay.com/api_28/alipay.fund.trans.order.query
* 转账单据状态。
SUCCESS:成功(配合"单笔转账到银行账户接口"产品使用时, 同一笔单据多次查询有可能从成功变成退票状态);
FAIL:失败(具体失败原因请参见error_code以及fail_reason返回值);
INIT:等待处理;
DEALING:处理中;
REFUND:退票(仅配合"单笔转账到银行账户接口"产品使用时会涉及, 具体退票原因请参见fail_reason返回值);
UNKNOWN:状态未知。
*/
private String status;
经典问题
SUCCESS:成功(配合"单笔转账到银行账户接口"产品使用时, 同一笔单据多次查询有可能从成功变成退票状态);
请告诉我,什么时候才能一个转账的状态能最终定下来
不能说多次查询,又从成功变成了退票
请告之你们的转账到银行卡状态,在什么时候才能明确的认定为成功状态,而不是有可能从成功状态变成退票状态
感觉接口死循环了。发起转账状态要查询,查询状态又可能从成功变成退款,很是尴尬的局面。支付宝客服一直未给一个明确的答复,一个下午都在等答复。
写在收尾处
对接蚂蚁金服支付宝的网银直连、转账到银行卡,不是一个技术问题,而商务签约问题,不签约,不给文档,不给文档没有下文。对于技术人来讲,收藏一份网银直连、转账到银行卡文档,是很有必要的。估计签名还没有签约,功能都可以提前开发好了。
让天底下没有难接的支付
关注公众号【Yuema约吗】回复alipay,获取支付网银直连、转账到银行卡技术文档
ps:不签约接口不生效,但是可以提前开发