简要描述
本文主要面向有一定开发基础的用户查阅对接,请仔细接口文档,如有疑问可以下载支付DEMO查看对接代码样例。 接口支持收款码类型、签约接口类型支付方式。 免签和签约接口相同,不同处为创建支付订单参数“支付方式 payType”的传值。
接口测试工具:Postmam 或 在线工具http://coolaf.com/
请求方式
接口地址:V1接口地址
请求方式:POST
参数传递:Query
Content-Type:application/x-www-form-urlencoded
query:参数在接口地址中拼接(形如:接口地址?merchantNum=1&orderNo=2……)传参post提交或form表单方式提交。
如果你的业务网站开启了https访问,请使用https开头的接口地址请求接口。否则有可能浏览器出现如下提示
请求参数值说明
参数 | 必须 | 类型 | 示例 | 说明 |
---|---|---|---|---|
merchantNum | 是 |
string | 88888888 | query商户号。在支付FM商户后台【用户中心】处可查看,该值不是用户名。 |
orderNo | 是 |
string | N001 | query商户订单号。仅允许字母或纯数字,建议不超过32字符,不能有中文 |
amount | 是 |
number | 100 | query订单金额。请求的支付金额(单位:元),最多小数点后保留2位 |
notifyUrl | 是 |
string | https://www.zhifux.com/success.txt |
query支付结果通知网址又称异步回调网址。200字符以内, http(s)开头的网址。商户业务系统用来接收数据的网址,必须为 公网可访问的 ,收到通知后请根据规范返回成功标志success ,请使用Postmam等工具测试好你的传入。开发文档: https://docs.zhifux.com/read/zhifufm/notify |
returnUrl | 否 | string | query支付完成后展示网址,有些支付方式在手机中无法跳转,所以请勿用此地址做验证或者业务强关联。200字符以内, http(s)开头的公网地址。系统自动跳转打开,常见为业务系统的支付成功提示、订单中心、会员中心网址等,又称同步跳转地址。 为了安全考虑不要和notifyUrl值传入一样。 |
|
payType | 是 |
string | alipay | query支付方式。 请根据所需对接的支付方式正确传值,需要在商户后台配置相应的收款号,参数请查看下文的支付方式payType选值说明 |
sign | 是 |
string | query签名。待签名字符串进行MD5加密得出的32位签名值,小写。待签名字符串=商户号+商户订单号+支付金额+异步通知地址+接入密钥;其中“+”表示字符串拼接,请注意拼接顺序 。接入密钥在支付FM商户后台【用户中心】处可查看。 |
|
returnType | 否 | string | query接口内容返回类型。 参数请查看下文的returnType可选值说明。 |
|
payee | 否 | string | sj1 | query指定收款号。 该值为在本平台设置的 免签类型的手机编号 或 签约类型的微信系的账号标识 或 签约类型的支付宝系的支付宝账号 的值。 |
attch | 否 | string | query附加信息,回调时候原样回传。空内容会被忽略不再回传。 | |
subject | 否 | string | query商品标题。100字符以内,签约类型会原样传到支付平台 | |
body | 否 | string | query商品描述。200字符以内,签约类型会原样传到支付平台 | |
payDuration | 否 | integer | 3 | query订单支付有效期,单位:分钟;默认值5,最大值15 。例:5 表示订单支付有效期5分钟 |
apiMode | 否 | String | 支付结果通知notifyUrl请求方式。 默认/不传值:GET请求方式回调通知; post_form:POST请求方式回调通知 |
returnType 传值说明
值 | 是否默认 | 类型 | 说明 |
---|---|---|---|
json | 是 |
string | 接口返回json数据 |
page | 否 | string | 接口直接重定向到支付页面,部分开发语言非页面form表单直接提交的有可能无法重定向,请通过json获取支付链接自行跳转。 |
payType 传值说明
支付方式的收款号配置在商户后台,分别在我们平台后台的【免签类型】和【签约类型】功能菜单下,调用接口前请确保已经配置了对应的收款账号。免签类型
:收款手机需要安装监控APP挂机。签约类型
:需要开通对应的签约商户和支付产品。
支付方式实际使用体验效果:https://docs.zhifux.com/read/zhifufm/paytype
值 | 是否默认 | 类型 | 说明 | 收款号类型 | 分派方式 | 适用端口 |
---|---|---|---|---|---|---|
否 | string | 收款码 - 微信 | 免签 | 收款号随机或轮训 | PC&WAP | |
alipay | 否 | string | 收款码 - 支付宝(上传模式和动态码模式) | 免签 | 收款号随机或轮训 | PC&WAP |
unipay | 否 | string | 收款码 - 云闪付 | 免签 | 收款号随机或轮训 | PC&WAP |
qujie.qrcode | 否 | string | 三方聚合码 - 支持付呗、收钱吧、钱到啦、京东收银哆啦宝、盛意旺、拉卡拉 商户数字钱宝、微商相册、银盛小Y APP的收款码。 | 免签 | 收款号随机或轮训 | PC&WAP |
jsnx.qrcode | 否 | string | 收款码 - 农商行收银宝 | 免签 | 收款号随机或轮训 | PC&WAP |
bankapp | 否 | string | 网银APP收款 | 免签 | 收款号随机或轮训 | PC&WAP |
alipaysign | 否 | string | 支付宝网站支付接口(电脑或手机自适应) | 直连支付宝官方签约 |
商户号轮训 | PC&WAP |
alipay.direct.pc | 否 | string | 支付宝电脑网站支付 | 直连支付宝官方签约 |
商户号轮训 | PC |
alipay.direct.wap | 否 | string | 支付宝手机网站支付 | 直连支付宝官方签约 |
商户号轮训 | WAP |
alipay-facetoface | 否 | string | 支付宝当面付,跨地区收款不推荐使用 | 直连支付宝官方签约 |
商户号轮训 | PC&WAP |
wxpayh5 | 否 | string | 微信支付H5 | 直连微信官方签约 |
商户号轮训 | WAP |
wxpaynative | 否 | string | 微信支付Native | 直连微信官方签约 |
商户号轮训 | PC |
wxpayjsapi | 否 | string | 微信支付JSAPI | 直连微信官方签约 |
商户号轮训 | PC&WAP |
fuyou-aliqr | 否 | string | 富友支付宝服务窗 | 富友间连支付宝签约 |
商户号轮训 | PC&WAP |
fuyou-wxqr | 否 | string | 富友微信支付 | 富友间连微信签约 |
商户号轮训 | PC&WAP |
fuyou-bankqr | 否 | string | 富友支付-网银APP扫码 | 富友间连银联签约 |
商户号轮训 | PC&WAP |
fuyou-pcqr | 否 | string | 富友收银台 | 富友间连签约 |
商户号轮训 | PC&WAP |
sandpayh5 | 否 | string | 杉德支付收银台 | 杉德间连签约支付宝微信 |
商户号轮训 | PC&WAP |
sand-alipay | 否 | string | 杉德支付宝 | 杉德间连签约支付宝微信 |
商户号轮训 | PC&WAP |
sand-wxpay | 否 | string | 杉德微信公众号 | 杉德间连签约支付宝微信 |
商户号轮训 | PC&WAP |
alipay-pc-all | 否 | string | 支付宝PC签约轮训,见说明 | 直连+间连支付宝签约 |
签约通道轮训+商户号轮训 |
PC |
alipay-wap-all | 否 | string | 支付宝WAP签约轮训,见说明 | 直连+间连支付宝签约 |
签约通道轮训+商户号轮训 |
WAP |
wechat-pc-all | 否 | string | 微信PC签约轮训,见说明 | 直连+间连微信签约 |
签约通道轮训+商户号轮训 |
PC |
wechat-wap-all | 否 | string | 微信WAP签约轮训,见说明 | 直连+间连微信签约 |
签约通道轮训+商户号轮训 |
WAP |
表中特殊值说明:
alipay-pc-all
包含:alipaysign,alipay.direct.pc,alipay-facetoface, fuyou-aliqr,sandpayh5alipay-wap-all
包含:alipaysign,alipay.direct.wap,alipay-facetoface, fuyou-aliqr,sandpayh5wechat-pc-all
包含:wxpaynative,wxpayjsapi,fuyou-wxqr,sandpayh5wechat-wap-all
包含:wxpayh5,wxpayjsapi,fuyou-wxqr,sandpayh5
主要用于签约类型的跨通道商户号的合理轮询分派收单使用,配置后启用状态的收款号就会参与轮训。例如:传入 alipay-pc-all调用接口时候,将轮训分派所有可以在电脑网站使用的商户号进行收单,。
返回参数值说明
支付订单创建成功后,returnType传值为json时HTTP状态码为200且返回JSON数据
;
支付订单未成功创建HTTP状态码为400且返回JSON数据
。常见返回内容说明请参考本文末“返回值说明”。
参数 | 必须 | 类型 | 说明 |
---|---|---|---|
success | 是 | boolean | 正常标志 |
code | 是 | number | 信息编码。200代表正常。此编码非HTTP状态码,别混淆了。 |
timestamp | 是 | number | 毫秒时间戳。 |
msg | 是 | string | 信息描述。 |
data | 是 | json | 数据内容,支付订单创建成功有值。 |
data内容参数:
参数 | 必须 | 类型 | 说明 |
---|---|---|---|
id | 否 | string | 平台订单号。接口请求成功有值 |
payUrl | 否 | string | 支付链接。 接口请求成功时候有值。顾客访问该网址就可以根据不同支付方式效果进行支付。如您的业务系统为APP,请调用手机浏览器访问此链接,这样支付效果更稳定,不建议在APP内直接访问 |
参考示例
请求示例
此处罗列一些常用请求的部分代码供参考,完整代码可以参考demo篇章。注意: java系统若使用老版hutool工具请求https接口可能会报错需升级到JDK11或使用http协议请求或使用demo中方法请求。
示例1:php的直接跳转到支付页面写法,page接收方式
// php 自动跳转
// 开发手册:http://docs.zhifux.com/read/zhifufm/step
$amount = "订单金额"; // 获取充值金额
$orderNo = '商户订单号'; // 商户系统创建的订单号
$merchantNum = '商户号'; // 商户号, 商户后台的用户中心页面查看
$secret = '接入密钥'; // 接入密钥, 商户后台的用户中心页面查看
$api_url = '接口地址'; // 接口地址, 商户后台的用户中心页面查看
$payType = "支付方式值"; // 前端传入的支付方式值,查看支付接口文档说明payType的取值
$notifyUrl = '通知接收接口地址'; // XXXX修改为您自己用来接收支付成功的公网地址
$returnUrl = ''; // 已支付订单状态后会跳转,一般为您想让顾客支付后看到的页面
$returnType = "page"; // 接口返回方式 page为直接跳转到支付页面,不传返回json
$sign = md5 ( $merchantNum.$orderNo.$amount.$notifyUrl.$secret); //待签名字符串=商户号+商户订单号+支付金额+异步通知地址+接入密钥
echo '<html>
<head><title>redirect...</title></head>
<body>
<form id="post_data" action="' . $api_url . '" method="post">
<input type="hidden" name="merchantNum" value="' . $merchantNum . '"/>
<input type="hidden" name="payType" value="' . $payType . '"/>
<input type="hidden" name="amount" value="' . $amount . '"/>
<input type="hidden" name="orderNo" value="' . $orderNo . '"/>
<input type="hidden" name="notifyUrl" value="' . $notifyUrl . '"/>
<input type="hidden" name="returnUrl" value="' . $returnUrl . '"/>
<input type="hidden" name="sign" value="' . $sign . '"/>
<input type="hidden" name="returnType" value="' . $returnType . '"/>
</form>
<script>document.getElementById("post_data").submit();</script>
</body>
</html>';
示例2 :form表单直接提交
如果您的网站开启了SSL,请使用https的接口地址。
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
<title>跳转支付中……</title></head>
<body>
<form style="display:none" id="fPay" method="post" action="接口地址URL">
<input name="merchantNum" type="text" value="$merchantNum"/>
<input name="amount" type="text" value="$amount"/>
<input name="payType" type="text" value="$payType"/>
<input name="returnUrl" type="text" value="$returnUrl"/>
<input name="notifyUrl" type="text" value="$notifyUrl"/>
<input name="orderNo" type="text" value="$orderID"/>
<input name="subject" type="text" value="$subject"/>
<input type="hidden" name="returnType" value="$returnType"/>
<input name="sign" type="text" value="$sign"/>
</form>
<script type="text/javascript">
// 自动提交也可以手动通过按钮触发表单提交
window.onload= function(){document.getElementById("fPay").submit();}
</script>
</body>
</html>
推荐方式
示例3:php的后台接收支付链接并跳转示例,json接收方式
<?php
$returnType = "json";
$api_url = "接口地址"; //在用户中心页面查看 接口地址
$key = "接入密钥"; //在用户中心页面查看 接入密钥
$sing = md5($merchantNum.$orderNo.$amount.$notifyUrl.$key); //待签名字符串=商户号+商户订单号+支付金额+异步通知地址+接入密钥
$native = array(
"merchantNum" => $merchantNum,
"payType" => $payType,
"amount" => $amount,
"orderNo" => $orderNo,
"notifyUrl" => $notifyUrl,
"returnUrl" => $returnUrl,
"sign" => $sign,
"returnType" => $returnType
);
$param = http_build_query($native);
$ch = curl_init ();
curl_setopt ( $ch, CURLOPT_URL, $url );
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, 1 );
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
curl_setopt ( $ch, CURLOPT_POST, 1 );
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $param );
curl_setopt ( $ch, CURLOPT_CONNECTTIMEOUT, 60 );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYHOST, FALSE );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, array (
'application/x-www-form-urlencoded;charset=utf-8',
'Content-Length: ' . strlen ( $param )
) );
$return = curl_exec ( $ch );
curl_close ( $ch );
if(strpos($return,'{') === 0){
$return = json_decode($return, true);
if($return['success']){
//json方式接收,可以跳转也可以根据你们自己框架处理支付链接
//header("location:".$return['data']['payUrl']);
header("Refresh:0.1;url=" . $return['data']['payUrl']); //会在0.1秒后执行跳转
}else{
echo "请求异常";
}
}else{
echo "请求异常";
}
exit;
?>
推荐方式
示例4:JAVA控制类核心代码,完整可参考demo
Map<String, Object> paramMap = new HashMap<>();// post请求的参数
paramMap.put("merchantNum", merchantNum);
paramMap.put("orderNo", orderNo);
paramMap.put("amount", amount);
paramMap.put("notifyUrl", notifyUrl);
paramMap.put("returnUrl", returnUrl);
paramMap.put("payType", payType);
paramMap.put("attch", attch);
paramMap.put("sign", sign);
paramMap.put("subject", "测试商品标题");
paramMap.put("body", "测试商品说明");
String paramStr = HttpUtil.toParams(paramMap);
System.out.println(paramStr);
HttpClient httpclient = HttpClientBuilder.create().build(); //httpclient-4.5.6.jar
HttpPost httpost = new HttpPost(url + "?" + paramStr); // 设置响应头信息
HttpResponse retResp; //httpcore-4.4.10.jar
String result;
JSONObject ret = new JSONObject();
try {
retResp = httpclient.execute(httpost);
result = EntityUtils.toString(retResp.getEntity(), "UTF-8");
System.out.println(result);
}
catch (ClientProtocolException e1) {
e1.printStackTrace();
}
catch (IOException e1) {
e1.printStackTrace();
}catch (ParseException e1) {
e1.printStackTrace();
}
返回示例
正确时返回:
returnType传值为json返回如下格式内容:HTTP状态码为200
{
"success": true,
"msg": "success",
"code": 200,
"timestamp": 1624553174921,
"data": {
"id": "1408103748495998976",
"payUrl": "http://XXXXX/pay?orderNo=1408103748495998976"
}
}
错误时返回:
其他返回错误代码请根据描述信息排查
HTTP状态码为400
{
"success": false,
"msg": "签名不正确",
"code": 500,
"timestamp": 1584413776852,
"data": null
}
其他说明
返回值说明
msg | 说明 |
---|---|
success | 调用接口成功 |
用户账号无权限使用 | 调用接口传入的商户号不正确或者用户账号被限制使用 |
金额格式不正确 | 金额格式要为标准数值类型 |
金额不能小于或等于0 | 订单金额不能小于或等于0,请检查金额 |
免签类型订单金额不能小于1元 | 免签类型的接口调用订单金额至少为1元 |
签名不正确 | 签名不正确,请根据API签名规则检查MD5签名参数和结果是否正确 |
发起订单失败,类型不存在 | 类型不存在,请检查支付方式传值是否正确 |
商户接口额度不足,请充值 | 商户接口额度不足,请登录支付FM充值可收款接口额度 |
XXX:must not be blank或XXX:不能为空 | 请求参数值没有按照规范传递到我们接口,一般为请求方式或请求数据不合法导致。请检查参数名是否和文档要求一致,请求方式是post,参数是param方式不是json等 |
无可用收款方式的收款账号 | 检查接口传入的PayType值对应的支付方式的收款号后台有没有正确配置 |
returnUrl保留参数说明
订单为已支付状态时,系统会根据传入的 returnUrl进行页面重定向跳转,以下参数为跳转时候系统默认携带,请勿携带传入。
携带参数初衷用于配合业务系统的页面展示,请勿用于订单已支付校验判断。回调通知参数接收请参考支付通知接口说明
参数 | 说明 |
---|---|
orderNo | 商户订单号 |
mchOrderNo | 商户订单号 |
platformOrderNo | 平台订单号 |
orderState | 跳转状态值 |
amount | 商户订单金额 |
actualPayAmount | 实际支付金额 |
MD5签名示例
支付DEMO中有完整说明和建议使用的工具包,以下只是签名示例(JAVA),其他语言可以用示例参数签名,签名结果一致表示签名函数是可用的。 供技术调试对比MD5算法用:abc123456的MD5加密串:大写:0659C7992E268962384EB17FAFE88364,小写:0659c7992e268962384eb17fafe88364
package ltd.nnt.zhifu.test;
import java.math.BigInteger;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
public class MD5Utils {
/**
* 使用md5的算法进行加密
*/
public static String md5(String plainText) {
byte[] secretBytes = null;
try {
secretBytes = MessageDigest.getInstance("md5").digest(
plainText.getBytes());
} catch (NoSuchAlgorithmException e) {
throw new RuntimeException("没有md5这个算法!");
}
String md5code = new BigInteger(1, secretBytes).toString(16);// 16进制数字
// 如果生成数字未满32位,需要前面补0
for (int i = 0; i < 32 - md5code.length(); i++) {
md5code = "0" + md5code;
}
return md5code;
}
public static void main(String[] args) {
System.out.println(md5("abc123456"));
}
}