聚合支付 - 接口开发文档 SDK示例下载

支付下单接口

请求API地址

国内:https://18pay.net/pay.html

海外:http://www.18pay.net/pay.html

提示:安全起见,提交方式推荐使用 POST ,请不要用 GET 方式提交。
请求参数列表
参数名称 参数含义 类型 示例值 是否必填 参与签名 描述
appid 商户编号 string 20206491 平台分配商户编号
payid 唯一标识 string 202305310100203715872 订单编号或者用户ID(必须确保是唯一的)
money 订单金额 string 10 订单提交的金额(单位:元)
type 支付方式 string 1 传入数字(1为支付宝,2为微信支付)
notify_url 异步通知地址 string http://296o.com/notify_url.php 接收平台通知的URL,需给绝对路径,并确保平台能通过互联网访问该地址
return_url 同步跳转地址 string http://296o.com/return_url.php 前端页面跳转的URL(支付成功后会跳转到这个地址),
该地址只作为前端页面的一个跳转,须使用notify_url通知作为支付最终结果
subject 商品名称 string 购买商品 商品说明,游戏充值可传玩家账号或者角色名
client_ip 客户端IP string 114.114.114.114 请正确提交用户的真实IP,否则会出现"支付IP地址异常"问题
param 自定义参数 string 没有请留空 原封返回,避免特殊字符
account 充值账号 string qq1234 接口用于游戏充值时,可传入玩家账号
contact 联系方式 string 79899080 接口用于游戏充值时,可传入玩家联系方式
native 原生接口 string true native不为空时,接口返回原生支付结果,比如支付宝和微信的官方二维码链接
hidetitle 隐藏标题 string true hidetitle不为空时,自动隐藏支付页面上的"支付中心"标题栏
codesize 二维码大小 int 150 二维码大小默认200px
agent 代理账号 string 88888 支持三级代理分销,直接传入代理的登录账号
sign 数据签名 string fa7337122f6082b6ac14433ecf8ec73a 对数据进行签名,请参考签名算法
sign_type 签名类型 string rsa 默认md5(V1.0),可选rsa(V2.0)
charset 编码 string utf-8 utf-8或gb2312,默认utf-8
签名算法
重要提示:平台现已支持两种签名算法版本!
  • MD5签名(V1.0):传统签名方式,默认使用;
  • RSA签名(V2.0)强烈推荐使用,更安全、更高效;
  使用V2.0需要在基本资料中配置RSA密钥,并将 sign_type 参数设为 rsa

▍ MD5签名算法(V1.0 - 默认)

  • 第一步

    设所有发送或者接收到的数据为集合,将集合内非空参数值的参数按照参数名从小到大排序(ASCII码字典序),使用 URL 键值对的格式(即key1=value1&key2=value2…)拼接成字符串 str 。

    
    $postDatas = array(
        "appid" => '20206491',
        "money" => '10',
        "payid" => '202305310100203715872',
        "type" => '1',
        "subject" => '购买商品',
        "notify_url" => 'http://296o.com/notify_url.php',
        "return_url" => 'http://296o.com/return_url.php'
    );
    //ksort()对数组按照键名进行升序排序
    ksort($postDatas);
    //reset()内部指针指向数组中的第一个元素
    reset($postDatas);
    $str = ASCII($postDatas);
    function ASCII($postDatas = array()){
    	$str = '';//初始化
    	foreach ($postDatas AS $key => $val) { //遍历参数数组
    		if ($val == ''||$key == 'sign') continue; //跳过这些不签名
    		if ($str) $str .= '&'; //第一个字符串签名不加& 其他加&连接起来参数
    		$str .= "$key=$val"; //拼接为url参数形式
    	}
    	return $str;
    }
    
  • 第二步

    然后在字符串 str 后面拼接上 appkey(平台商户密钥),得到 stringSignTemp 字符串,最后对stringSignTemp 进行 MD5 运算,得到 sign 值

    
    $str = "appid=20206491&money=10&notify_url=http://296o.com/notify_url.php&payid=202305310100203715872&return_url=http://296o.com/return_url.php&subject=购买商品&type=1";
    $stringSignTemp = $str.$appkey;
    $sign = md5($stringSignTemp);
    

▍ RSA签名算法(V2.0 - 强烈推荐

RSA签名流程(2密钥模式):
1. 商户自行生成RSA密钥对,将商户公钥配置到平台,商户私钥自己保管
2. 从平台"基本资料"获取平台RSA公钥,用于验证异步通知签名
3. 发起请求时,用商户私钥进行RSA签名
4. 异步通知时,平台用平台私钥签名,商户用平台公钥验签
5. 私钥各自保管,安全性更高!
  • 第一步:生成商户RSA密钥对

    推荐方式:在平台"基本资料"页面点击 "生成商户RSA密钥对" 按钮,一键生成:

    商户私钥:弹窗展示,请立即复制保存(平台不保存,丢失无法找回)

    商户公钥:自动保存到平台,无需手动配置

    平台公钥:从平台"基本资料"复制,用于验证异步通知签名

    也可使用OpenSSL命令自行生成:

    
    # 使用OpenSSL生成商户RSA密钥对(可选)
    openssl genpkey -algorithm RSA -out merchant_private_key.pem -pkeyopt rsa_keygen_bits:2048
    openssl rsa -pubout -in merchant_private_key.pem -out merchant_public_key.pem
    
  • 第二步:使用商户私钥签名(PHP示例)

    
    //构造待签名字符串(与MD5签名第一步相同)
    $postDatas = array(
        "appid" => '20206491',
        "money" => '10',
        "payid" => '202305310100203715872',
        "type" => '1',
        "subject" => '购买商品',
        "notify_url" => 'http://296o.com/notify_url.php',
        "return_url" => 'http://296o.com/return_url.php',
        "sign_type" => 'rsa'
    );
    ksort($postDatas);
    reset($postDatas);
    $str = ASCII($postDatas);
    
    //使用商户RSA私钥进行RSA签名
    $privateKey = "-----BEGIN PRIVATE KEY-----
    你的商户RSA私钥
    -----END PRIVATE KEY-----";
    $res = openssl_get_privatekey($privateKey);
    openssl_sign($str, $sign, $res, OPENSSL_ALGO_SHA256);
    openssl_free_key($res);
    $sign = base64_encode($sign);
    
  • 第三步:验证异步通知签名(PHP示例)

    
    $platformPublicKey = "-----BEGIN PUBLIC KEY-----
    平台RSA公钥
    -----END PUBLIC KEY-----";
    
    $postDatas = $_POST;
    ksort($postDatas);
    reset($postDatas);
    $str = ASCII($postDatas);
    $sign = base64_decode($_POST['sign']);
    
    $res = openssl_get_publickey($platformPublicKey);
    $verifyResult = openssl_verify($str, $sign, $res, OPENSSL_ALGO_SHA256);
    openssl_free_key($res);
    
    if($verifyResult === 1 && !empty($_POST['pay_no'])){
        exit('success');
    }else{
        exit('fail');
    }
    
签名失败怎么办?
  • 常见问题排查

    1、可以使用signArray参数,提交参与签名的数组字符串,然后对比前后计算签名的数组参数有什么区别;

    2、param参数值里包含逗号(,)等符号,http请求提交到平台时,会被检测层过滤掉符号,从而导致签名不一致;

    解决方案:
    如果你的param参数里必须携带符号,那么可以先进行base64编码转换,异步通知和同步跳转接收param参数时,再转换回来即可。

    3、如果参与签名的数组字符串里存在转义字符,那么要先去掉转义,再进行签名,参考代码如下:

    
    function createSignArray($postDatas) {
        ksort($postDatas);
        reset($postDatas);
    	$str  = "";
    	while (list ($key, $val) = each ($postDatas)) {
    		$str.=$key."=".urlencode($val)."&";
    	}
    	$str = substr($str,0,count($str)-2);
    	if(get_magic_quotes_gpc()){
    	    $str = stripslashes($str);
    	}
    	return $str;
    }
    

支付回调通知

提交native参数时,以json格式返回原生支付结果:
参数名称 参数含义 参数说明
status 返回状态 status为1表示成功,status为0表示失败
pay_no 交易流水号 平台生成的交易流水号
pay_money 支付金额 买家需要支付的实际金额
pay_url 支付链接 商户可用此参数自定义创建支付页面,或者跳转到支付宝、微信等第三方平台
code_url 二维码链接 商户可用此参数自定义去生成二维码后展示出来进行扫码支付
code_img 二维码图片 此参数的值即是根据code_url生成的可以扫码支付的二维码图片地址
订单支付成功时,系统会以POST请求方式通知到异步通知地址(notify_url),以GET请求方式跳转到同步跳转地址(return_url),通知结果参数如下表:
参数名称 参数含义 类型 示例值 参与签名 参数说明
pay_id 唯一标识 string admin 商户提交的的唯一标识(订单编号或者用户ID)
pay_money 订单金额 string 100.00 实际付款金额
pay_no 交易流水号 string 20200217200042408995 平台生成的交易流水号
pay_time 交易时间 int 1487597795 付款的时间戳
pay_type 支付方式 int 1 1:支付宝 2:微信支付 3:QQ钱包
param 扩展返回 string 没有则不返回 商户附加数据,原封返回,提交什么就返回什么。注意:值为空时不参与签名
sign 数据签名 string c47f3cba123456b6b24542110a8928af 加密签名,验证订单是否为合法,请参考签名算法
sign_type 签名类型 string rsa 默认md5(V1.0),如果下单时使用rsa,通知也会使用rsa

通知返回的参数示例如下:

MD5签名(V1.0)通知示例:


pay_id=admin&pay_money=100.00&pay_no=20200217200042408995&pay_time=1487597795&pay_type=1&sign=c47f3cba123456b6b24542110a8928af

RSA签名(V2.0)通知示例:


pay_id=admin&pay_money=100.00&pay_no=20200217200042408995&pay_time=1487597795&pay_type=1&sign_type=rsa&sign=e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855...
业务处理返回
返回类型 返回数据
业务处理完成返回 ok 或者 success
业务处理失败还需要下次继续通知返回 fail

1、业务处理完成返回:ok 或者 success

2、业务处理失败还需要下次继续通知返回:fail

3、注意:一定要验证是否有pay_no参数值,因为只有该值存在,才是付款成功 。

  • notify_url异步通知示例(Thinkphp):

    
    $appkey="平台的商户密钥";
    //平台RSA公钥(使用RSA签名时需要)
    $platformPublicKey = "-----BEGIN PUBLIC KEY-----
    平台RSA公钥
    -----END PUBLIC KEY-----";
    
    if (empty($_POST)) $_POST = $_GET; //如果为GET方式访问 
    //ksort()对数组按照键名进行升序排序 
    ksort($_POST); 
    //reset()内部指针指向数组中的第一个元素 
    reset($_POST); 
    $sign = '';//初始化 
    foreach ($_POST AS $key => $val) { //遍历POST参数 
    if ($val == ''||$key == 'sign'||$key == 'sign_type') continue; //跳过这些不签名 
    if ($sign) $sign .= '&'; //第一个字符串签名不加& 其他加&连接起来参数 
    $sign .= "$key=$val"; //拼接为url参数形式 
    } 
    $pay_id = $_POST['pay_id']; //需要充值的ID 或订单号 或用户名 
    $pay_money = (float)$_POST['pay_money']; //实际付款金额
    $pay_no = $_POST['pay_no']; //交易流水号 
    $pay_time = $_POST['pay_time']; //付款的时间戳 
    $pay_type = (int)$_POST['pay_type']; //支付方式 1:支付宝 2:微信支付 3:QQ钱包 
    $param = isset($_POST['param'])?$_POST['param']:'';//自定义参数 
    
    //验证签名(根据sign_type选择验证方式)
    $signValid = false;
    if(isset($_POST['sign_type']) && strtolower($_POST['sign_type']) == 'rsa'){
        $res = openssl_get_publickey($platformPublicKey);
        $signValid = openssl_verify($sign, base64_decode($_POST['sign']), $res, OPENSSL_ALGO_SHA256) === 1;
        openssl_free_key($res);
    }else{
        $signValid = (md5($sign . $appkey) == $_POST['sign']);
    }
    
    if (!$_POST['pay_no'] || !$signValid) { //不合法的数据 
    exit('fail'); //返回失败 继续补单 
    } else { //合法的数据 
    /** 
    * 业务处理在这里写 
    */ 
    exit('success'); //返回成功,业务处理完成,下面不再执行了
     } 
    
  • return_url同步跳转示例(Thinkphp):

    
    $appkey="平台的商户密钥";
    //平台RSA公钥(使用RSA签名时需要)
    $platformPublicKey = "-----BEGIN PUBLIC KEY-----
    平台RSA公钥
    -----END PUBLIC KEY-----";
    
    if (empty($_POST)) $_POST = $_GET; //如果为GET方式访问 
    //ksort()对数组按照键名进行升序排序 
    ksort($_POST); 
    //reset()内部指针指向数组中的第一个元素 
    reset($_POST); 
    $sign = '';//初始化 
    foreach ($_POST AS $key => $val) { //遍历POST参数 
    if ($val == ''||$key == 'sign'||$key == 'sign_type') continue; //跳过这些不签名 
    if ($sign) $sign .= '&'; //第一个字符串签名不加& 其他加&连接起来参数 
    $sign .= "$key=$val"; //拼接为url参数形式 
    } 
    $pay_id = $_POST['pay_id']; //需要充值的ID 或订单号 或用户名 
    $pay_money = (float)$_POST['pay_money']; //实际付款金额 
    $pay_no = $_POST['pay_no']; //交易流水号 
    $pay_time = $_POST['pay_time']; //付款的时间戳 
    $pay_type = (int)$_POST['pay_type']; //支付方式 1:支付宝 2:微信支付 3:QQ钱包
    $param = isset($_POST['param'])?$_POST['param']:'';//自定义参数 
    
    //验证签名
    $signValid = false;
    if(isset($_POST['sign_type']) && strtolower($_POST['sign_type']) == 'rsa'){
        $res = openssl_get_publickey($platformPublicKey);
        $signValid = openssl_verify($sign, base64_decode($_POST['sign']), $res, OPENSSL_ALGO_SHA256) === 1;
        openssl_free_key($res);
    }else{
        $signValid = (md5($sign . $appkey) == $_POST['sign']);
    }
    
    if (!$_POST['pay_no'] || !$signValid) { //不合法的数据 
    $result = '支付失败';
    } else { //合法的数据 
    /** 
    * 业务处理在这里写 
    */ 
    $result = '支付成功'; 
    } 
    $this->assign('pay_id',$pay_id);
    $this->assign('pay_no',$pay_no);
    $this->assign('pay_money',$pay_money);
    $this->assign('pay_type',$pay_type);
    $this->assign('pay_time',date("Y-m-d H:i:s",$pay_time));
    $this->assign('param',$param);
    $this->assign('result',$result);
    return view();
    

订单查询接口

查询API地址
https://18pay.net/pay/query.html
查询参数列表
参数名称 参数含义 类型 示例值 是否必填 参与签名 参数说明
appid 商户编号 string 20206491 平台分配商户编号
pay_no 交易流水号 string 20200217200042408995 平台生成的交易流水号,pay_no和pay_id必须提交其中一个,否则查询不到订单,同时提交2个参数时,pay_no优先
pay_id 唯一标识 string admin 商户提交的的唯一标识(订单编号或者用户ID)
sign 数据签名 string d7242db1748f4baef9ecec43b4106553 对数据进行签名,请参考签名算法
sign_type 签名类型 string rsa 默认md5,可选rsa(推荐)
charset 编码 string utf-8 utf-8或gb2312,默认utf-8
查询结果返回

系统会以json格式返回查询的结果(数据签名类型和提交的一样),可根据code的值来判断订单是否支付成功

返回类型 返回数据
支付成功 {"code":1,"type":"success","pay_no":"平台订单交易流水号","msg":"订单支付成功","sign_type":"md5","sign":"c47f3cba123456b6b24542110a8928af"}
未支付 {"code":0,"type":"error","pay_no":"平台订单交易流水号","msg":"订单未支付","sign_type":"md5","sign":"c47f3cba123456b6b24542110a8928af"}
其他情况 {"code":0,"type":"error","title":"提示","msg":"订单不存在","sign_type":"md5","sign":"c47f3cba123456b6b24542110a8928af"}

SDK接口示例

语言类型 接口介绍 SDK下载
易支付 彩虹易支付的接口插件 点击下载
发货100 发货100系统的接口示例 点击下载
Java Java的聚合支付接口示例 点击下载
ASP ASP的聚合支付接口示例 点击下载
PHP PHP的聚合支付接口示例 点击下载
Thinkphp5 Thinkphp5的聚合支付接口示例 点击下载