开发说明 & DEMO¶
APP+ 采用了 HTTP 协议提供各类接口,并且所有接口都是统一请求地址,方便商户简单、快速接入。本 API 包含 2 类接口,页面浏览器类和系统调用类。
- 页面浏览器类:需要从前端页面以 Form 表单的形式发起请求,浏览器会自动跳转至汇付的相关页面(一般是快捷收银台或签约页面),用户在该页面完成相关业务操作后再回跳到商户指定页面,页面方式返回的是标准的表单格式。
- 系统调用类:直接从服务端发起 HTTP 请求,API 会同步返回请求结果,返回的数据格式都是规范 JSON 格式。
参数和订单规范¶
参数规范
- 参数为可选项时,JSON 格式中可以不包含该参数,或该参数内容为空;
- 所有参数值不应该包含与 JSON 格式冲突的特殊字符,如括号,逗号,双引号,冒号等;
- 金额单位为元,精确到分,如:1200.00,359.14;
- 日期为定长 8 的字符串,格式为 YYYYMMDD,如 20140802;
- 商户客户号、用户客户号和账户号均为变长字符串;
订单规范
每个接口通过商户客户号、订单号、订单日期来标识订单的唯一性;
由于网络的不稳定性等原因,相同订单的交易应答返回给商户订单系统时,有可能会出现以下两种情况:
1.同一订单请求多次,先支付完成的订单返回参数后通知到商户;
2.同一笔订单收到多次支付结果;
处理原则:商户以订单的成功状态为终态,商户收到订单支付成功的应答后,如果再次收到订单支付失败的应答,不做处理即可。
API 调用规范¶

举例说明:假设接口参数为:version=10,cmd_id=101,mer_cust_id=6666000000011499,user_name=张三,bg_ret_url=http://mertest.chinapnr.com/npay
第一步:将接口参数转换成 JSON 格式字符串。
{“version”:”10”,”cmd_id”:”101”,”mer_cust_id”:”6666000000011499”,”user_name”:”张三”,”bg_ret_url”:”http://mertest.chinapnr.com/npay”}
第二步:使用 pfx 证书和密码进行加密,生成 check_value。
java
SignResult signResult = CFCASignature.signature(pfxFile, pfxFilePwd,params, "utf-8");
String check_value = signResult.getSign();
第三步:组装请求参数 version、cmd_id、mer_cust_id 和 check_value,以 post 方式请求接口。
java
String postStr = "cmd_id=101&version=10&mer_cust_id=6666000000011499&check_value=第二步生成的加签串";
HttpRequest httpRequest = HttpRequest.post("https://apptrade.testpnr.com/api/merchantRequest").charset("UTF-8");
HttpResponse httpResponse = httpRequest.contentType("application/x-www-form-urlencoded").body(postStr).send();
注意:组装请求参数时 version、cmd_id 和 mer_cust_id 必须和第一步的接口参数中的 version、cmd_id 和 mer_cust_id 值保持一致。
API 应答接收规范

举例说明(以交易状态查询接口返回的数据为例):
第一步:从应答报文中取得 check_value
假设返回数据如下:
{"check_value":"B170E66B00D344F8CEA68C3A84F0ED2207805147793F806CBD3D3E166B57F511ABEB7D5D7A725ECEFDC640FDC2F7102CD8D470CB0BE18A3B4ADE870689D7FCBD4CA55DD5C2E1D6BFC3F30514B0813D8E680708B44A1C1637780CA0D998EF22C10B7E4B8954F304F226BB50F091A60C939F7C4DB513261FC47667757550C7911E"}
第二步:解签 check_value,并取得返回参数
将第一步取得的 check_value,使用 cer 证书文件和汇付的商户号(100001)进行解签,得到返回参数的 JSON 格式字符串,例如:
{"extension":"extension","trans_stat":"","cmd_id":"301","div_detail":"","resp_code":"301000","mer_priv":"mer_priv","trans_amt":"","trans_type":"01","order_date":"20160801","order_id":"600001","mer_cust_id":"6666000000024878","resp_desc":"查询成功"}
API 特点
- 为保证接口的安全性,每笔交易都通过 CFCA 进行签名,篡改签名将导致验签失败,交易无法正常进行;
- 商户可以动态地将每笔交易的返回地址指向不同的交易网站,适合于多网站和多应用的商户;
- 商户在接口中可以自定义域,本平台返回时,会将该域原样返回,供商户实现特定的功能;
- 本平台通过后台方式向商户发送交易结果,通过分析商户的返回页面,可以准确地知道商户是否收到交易应答结果,从而对发送失败的交易采取自动重发;
结果返回机制¶
接口中提供“商户前台应答地址ret_url”,“商户后台应答地址bg_ret_url”,向用户反馈接口处理结果
- 商户前台应答地址ret_url,商户通过此参数传入商户侧的页面展示页面,汇付交易受理完跳转到该地址展示受理结果。
- 商户后台应答地址bg_ret_url,对于交易异步产生终态结果的,商户通过此参数传入后台结果回调地址,汇付在交易处理完毕后通过调用该地址通知商户交易的终态结果。
异步回调接收规范¶
本平台除了查询交易外所有交易,都同时提供异步回调通知,当请求HTTP或HTTPS,5秒内未收到交易应答,或者应答的状态码非200,该交易即进入重发队列,本平台会尝试将该交易应答重发给商户,重试3次 。如若由于网络或商户系统异常导致返回均无法接收,需线下请求重发。
为了表示商户订单系统已经收到交易应答,商户必须在应答接收页面输出一段特殊的字符串,组成规则为:固定字符串RECV_ORD_ID_加上交易接口的订单号order_id。
例如:商户收到一笔订单号为order_id=20180101ABCD 的交易应答,则应在该页面输出 RECV_ORD_ID_20180101ABCD 的字符串。 代码示例:resp.getWriter().print(“RECV_ORD_ID_” + orderId);
我司本系统生产环境出口IP为:139.224.111.237,若贵司系统对外网访问有IP限制,烦请将该IP加入白名单,以确保异步回调能收到。
加解签 & DEMO¶
本 API 对商户与汇付之间请求数据采用的是 CFCA 证书加解签方式。目前支持JAVA、PHP、C#、Python四种语言。
JAVA 代码示例及完整DEMO¶
加签示例
java
private static String sign(String valueObj) {
// 加签用 pfx 文件,请换成商户自己导出的证书
String pfxFile = "/app/etc/product/888888-汇付测试商户.pfx";
// 加签用密码,导出 pfx 证书时的密码
String pfxFilePwd = "888888";
// 加签
SignResult signResult = CFCASignature.signature(pfxFile, pfxFilePwd,valueObj, "utf-8");
if ("000".equals(signResult.getCode())) {
return signResult.getSign();
} else {
return "加签失败";
}
}
验签示例
java
public static String parseResult(String responseJson) throws Exception {
JSONObject jsonObject = JSON.parseObject(responseJson);
String sign = jsonObject.getString("check_value");
// 解签用的证书,请换成商户自己下载的证书
String cerFile = "/app/etc/product/CFCA_ACS_OCA31.cer";
VerifyResult verifyResult = CFCASignature.verifyMerSign("100001", sign, "utf-8", cerFile);
if ("000".equals(verifyResult.getCode())) {
String content = new String(verifyResult.getContent(), Charset.forName("utf-8"));
return content;
} else {
return "验签失败";
}
}
JAVA版完整DEMO说明
DEMO 分别提供了页面浏览器调用方式的快捷支付 APP 版接口和后台系统调用方式的 APP 支付接口调用示例。使用 DEMO 之前商户需要申请 CFCA 加解签证(商户在汇付开户后,会有邮件通知下载)
硬件需求
服务可以部署在 linux 和 windows 等具有 JVM 环境的服务容器内,比如 jboss,tomcat 等(暂提供 jboss)。安装 JDK1.7 并配置好 JDK 的环境变量。
部署服务
将证书文件放到服务器 $path 目录下,上传 war 包到服务器。
上传测试证书888888-NEW.pfx,CFCA_ACS_TEST_OCA31.cer,到/app/etc/目录下。
启动服务器
- Windows服务器下执行**/jboss/bin/standalone.bat
如:**/jboss/bin/standalone.bat
- Linux服务器下,执行**/jboss/bin/standalone.sh
如:**/jboss/bin/standalone.sh
接口 | 调用方式 | 访问地址 | 说明 |
---|---|---|---|
快捷支付 APP 版接口 | 页面浏览器提交 | http://ip:port/service-demo/quickPay/pay.json | 请求后跳转快捷支付页面 |
APP 支付接口 | 后台系统调用 | http://ip:port/service-demo/appPay/pay?pay_type=10 | 请求后返回APP支付参数 |
PHP 代码示例( Linux 版)¶
Demo 运行
一、安装对应版本的PHP
二、安装运行时环境(glibc库等)
三、修改PHP的配置文件php.ini
- 修改php.ini,使php允许加载扩展,并将当前扩展添加到其扩展列表中
- enable_dl = On
- extension=libSADKExtension.so
四、在DemoRSA目录下替换证书和cer文件
- pfx为私钥文件请妥善保管不要泄露给他人,cer文件为颁发者公钥,用来验证汇付公钥
五、配置 cfcalog.conf cfca日志文件
六、通过命令行终端运行Demo文件
- php huifuCFCALinuxDemo.php
PHP demo运行常见问题
- Message:cfca_Initialize error:24578,请检查下证书权限、日志权限,证书路径是否正确
- Message:cfca_signData_PKCS7Attached error:24578,请检查下证书权限、日志权限,证书路径是否正确
- 具体错误可通过cfca.log日志中判断排查问题
- 注:cfca_verifyCertificate 参数 $nCertVerifyFlag 是数值类型的
Msg PKCS7-attached Sign | 为使用 pfx 证书加签 |
PKCS7-attached-Verify | 为验证汇付的签名 |
cfca_verifyCertificate | 为验证证书链合法性 |
cfca_getCertificateInfo | 为获取证书信息(非必要) |
php
<?php
class HuifuCFCA
{
private $apiUrl = 'http://mertest.chinapnr.com/npay/merchantRequest'; //app+ 商户交易接口,此处使用的是联调环境地址
private $strSignAlg = 'RSA'; //RSA证书类型
private $strPfxPassword = '888888'; //导出时设置的密码
private $strHashAlg = 'SHA-256'; //加签算法
private $strPfxFilePath = './RSA/AS0381.pfx'; //汇付下发的证书,此处换成商户自己的证书 .pfx 格式 加签使用
private $strTrustedCACertFilePath = './RSA/CFCA_ACS_TEST_OCA31.cer|./RSA/CFCA_ACS_TEST_CA.cer'; //汇付下发的.cer证书 ,需要一对证书 解签使用
private $strLogCofigFilePath = './cfcalog.conf'; //CFCA log 目录
public function __construct()
{
$this->getCFCAInitialize(); //CFCA工具初始化
}
/**
* CFCA工具初始化
*/
private function getCFCAInitialize()
{
$nResult = cfca_initialize($this->strLogCofigFilePath);
if (0 != $nResult) {
//记录log
echo new Exception("\n cfca_Initialize error:".$nResult."\n");
}
}
/**
* 调用接口 此处是APP + 的接口请求
*
* @return string
*/
public function apiRequest(){
//请求参数,依据商户自己的参数为准
$requestParam['version'] = '10';
$requestParam['cmd_id'] = '202';
$requestParam['mer_cust_id'] = '6666000000002619';
$requestParam['user_cust_id'] = '6666000000054387';
$requestParam['order_date'] = '20180918';
$requestParam['order_id'] = '201809189000001';
$requestParam['trans_amt'] = '1.00';
$requestParam['cash_bind_card_id'] = '76247';
$requestParam['fee_obj'] = '';
$requestParam['fee_acct_id'] = '';
$requestParam['cash_type'] = '02030000';
$requestParam['bg_ret_url'] = 'http://192.168.0.74:8001/npayCallBack/asyncHandle.json';
$requestParam['mer_priv'] = 'test_mer_priv';
$requestParam['extension'] = 'test_extension';
//加签
$strSignSourceData = json_encode($requestParam);
$cfcaSign = $this->CFCASignature($strSignSourceData);
//接口请求参数
$param = [
'requestData' => [
'cmd_id' => $requestParam['cmd_id'],
'mer_cust_id' => $requestParam['mer_cust_id'],
'version' => $requestParam['version'],
'check_value' => $cfcaSign,
],
'headers' => ['Content-type' => 'application/x-www-form-urlencoded;charset=UTF-8']
];
$requestData = $this->requestData($param);
$checkValue = json_decode($requestData['body'],1)['check_value'];
//验证接口返回的签名数据
$sourceData = $this->getCFCASignSourceData($checkValue);
$SignCertContent = !empty($sourceData['strMsgP7AttachedSignCertContent']) ? $sourceData['strMsgP7AttachedSignCertContent'] : '';
//验证返回数据的CFCA证书有效性
$verifyCertificat = $this->verifyCertificat($SignCertContent);
$signSourceData = '';
if(!empty($sourceData['strMsgP7AttachedSource']) && $verifyCertificat){ //校验证书有效性
$signSourceData = $sourceData['strMsgP7AttachedSource'];
}
return $signSourceData;
}
/**
* CFCA 加签方法
*
* @param $strSignSourceData base64 encode 加签原串
* @return string base64 encode 加签串
*/
private function CFCASignature($strSignSourceData){
$strMsgPKCS7AttachedSignature = '';//加签生成串 ,输出变量,无需传值
try{
//调用加签方法
$nResult = cfca_signData_PKCS7Attached($this->strSignAlg, $strSignSourceData,
$this->strPfxFilePath, $this->strPfxPassword, $this->strHashAlg,$strMsgPKCS7AttachedSignature);
//加签方法异常判断及记录
if (0 != $nResult) {
//记录log
echo new Exception("\n cfca_signData_PKCS7Attached error:".$nResult."\n");
}
}catch (Exception $e){
throw new Exception("\n cfca_verifyCertificate error:".$e."\n");
}
return base64_encode($strMsgPKCS7AttachedSignature);
}
/**
* CFCA 验证签名数据
*
* @param $signature
* @return array
*/
private function getCFCASignSourceData($signature){
$strMsgP7AttachedSignCertContent = ''; //PKCS#7 中的签名证书 输出变量,无需传值
$strMsgP7AttachedSource = ''; //签名原文字符串 输出变量,无需传值
try{
//调用验证签名数据方法
$nResult = cfca_verifyDataSignature_PKCS7Attached($this->strSignAlg, base64_decode($signature),
$strMsgP7AttachedSignCertContent,$strMsgP7AttachedSource);
//验证签名方法异常判断及记录
if (0 != $nResult) {
//记录log
echo new Exception("cfca_verifyDataSignature error:".$nResult);
}
}catch (Exception $e){
//记录log
throw new Exception("cfca_verifyDataSignature_PKCS7Attached error:".$e);
}
return array(
'strMsgP7AttachedSource' => $strMsgP7AttachedSource,
'strMsgP7AttachedSignCertContent' => $strMsgP7AttachedSignCertContent,
);
}
/**
* CFCA 证书有效性验证
*
* @param $strMsgP7AttachedSignCertContent PKCS#7 中的签名证书 base64
* @return int
*/
private function verifyCertificat($strMsgP7AttachedSignCertContent = ''){
$nCertVerifyFlag = '4'; //验证证书链完整性
$strTrustedCACertFilePath = $this->strTrustedCACertFilePath;
$isVerify = false;
try{
//调用验证方法
$nResult = cfca_verifyCertificate($strMsgP7AttachedSignCertContent, $nCertVerifyFlag, $strTrustedCACertFilePath,"");
if (0 == $nResult) { // 0 为验证通过 ,其他验证失败
$isVerify = true;
}else{
//记录log
echo new Exception("cfca_verifyCertificate error:".$nResult);
}
}catch (Exception $e){
//记录log
throw new Exception("cfca_verifyCertificate error:".$e);
}
return $isVerify;
}
/**
* 请求接口返回数据
* @param $param
* @return array
*/
private function requestData($param)
{
try{
// 请求接口所以参数初始化
$data = [
'url' => $this->apiUrl, // 接口 url
'requestData' => $param['requestData'], // 请求接口参数
'headers' =>$param['headers']
];
$res = $this->httpPostRequest($data['url'],$data['headers'],$data['requestData']);
} catch (\Exception $e) {
//记录log
throw new Exception("api requestData error :".$e);
}
return [
'status' => $res['info']['http_code'],
'body' => $res['body']
];
}
/**
* curl post 请求方法
*
* @param string $url
* @param array $header
* @param array $requestData
* @return array
*/
private function httpPostRequest($url = '',$header = array(),$requestData = array()){
$curl = curl_init();
curl_setopt ( $curl, CURLOPT_HTTPHEADER,$header);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS,http_build_query($requestData));
$res = curl_exec($curl);
$info = curl_getinfo($curl);
$error = curl_error($curl);
curl_close($curl);
return [
'body' => $res,
'info' => $info,
'error' => $error,
];
}
/**
*CFCA工具结束
*/
public function __destruct()
{
cfca_uninitialize();
}
}
//调用
$demoObj = new HuifuCFCA();
$data = $demoObj->apiRequest();
print_r('<pre/>');
print_r($data);
PHP 代码示例( Windows 版)¶
Demo 运行
环境要求:WinServer2008 64bit、 WinServer2012 64bit 1. 配置php.ini php -i|findstr ini ,找到php.ini所在路径 将重命名后的 php.ini 文件内的“; extension_dir = “ext””行,修改为 “extension_dir = “./ext””。然后,在 php.ini 文件末尾,添加以下两行内容: [COM_DOT_NET] extension=php_com_dotnet.dll
2. 注册com组件 64位下执行 regsvr32 CryptoKit.Standard.x64.dll 32位下执行 regsvr32 CryptoKit.Standard.x86.dll
3. 在DemoRSA目录下替换证书和cer文件 pfx为私钥文件请妥善保管不要泄露给他人 cer文件为颁发者公钥,用来验证汇付公钥
4. 在Demo目录下执行 php huifuCFCAWindowsDemo.php
SignData_PKCS7Attached | 为使用 pfx 证书加签 |
VerifyDataSignature_PKCS7Attached | 为验证汇付的签名 |
VerifyCertificate | 为验证证书链合法性 |
GetCertificateInfo | 为获取证书信息(非必要) |
php
<?php
class HuifuCFCA
{
private $apiUrl = 'http://mertest.chinapnr.com/npay/merchantRequest'; // app+ 商户交易接口,此处使用的是联调环境地址
private $strSignAlg = 'RSA'; //RSA证书类型
private $strPfxPassword = '888888'; //导出时设置的密码
private $strHashAlg = 'SHA-256'; //加签算法
private $strPfxFilePath = './RSA/AS0381.pfx'; //汇付天下发的证书,此处换成商户自己的证书 此处换成商户自己的证书 .pfx 格式 加签使用
private $strTrustedCACertFilePath = './RSA/CFCA_ACS_TEST_OCA31.cer|./RSA/CFCA_ACS_TEST_CA.cer'; //汇付下发的.cer证书 ,需要一对证书 验签使用
private $cryptoAgentServerObj = ''; //CFCA obj
public function __construct()
{
// Create the object of COM by its ProgID
// If your php is compiled with x64, you need to use CryptoKit.standard.x64.dll, its ProgID is:CryptoKit.CryptoAgent.Server.Standard.x64.1
// If your php is compiled with x86, you need to use CryptoKit.standard.x86.dll, its ProgID is:CryptoKit.CryptoAgent.Server.Standard.x86.1
// Change next line according to your php
//注册windows com 服务,依据自己PHP编译版本选择对应参数,此处使用的是32位编译版本的PHP
$this->cryptoAgentServerObj = new \COM("CryptoKit.CryptoAgent.Server.Standard.x86.1", NULL, CP_UTF8);
}
/**
* 调用接口 此处是APP + 的接口请求
*
* @return string
*/
public function apiRequest(){
//请求参数,依据商户自己的参数为准
$requestParam['version'] = '10';
$requestParam['cmd_id'] = '202'; //取现接口
$requestParam['mer_cust_id'] = '6666000000002619';
$requestParam['user_cust_id'] = '6666000000054387';
$requestParam['order_date'] = '20180918';
$requestParam['order_id'] = '201809189000001';
$requestParam['trans_amt'] = '1.00';
$requestParam['cash_bind_card_id'] = '76247';
$requestParam['fee_obj'] = '';
$requestParam['fee_acct_id'] = '';
$requestParam['cash_type'] = '02030000';
$requestParam['bg_ret_url'] = 'http://192.168.0.74:8001/npayCallBack/asyncHandle.json';
$requestParam['mer_priv'] = 'test_mer_priv';
$requestParam['extension'] = 'test_extension';
//加签
$strSignSourceData = json_encode($requestParam);
$cfcaSign = $this->CFCASignature($strSignSourceData);
//取现接口请求
$param = [
'requestData' => [
'cmd_id' => $requestParam['cmd_id'],
'mer_cust_id' => $requestParam['mer_cust_id'],
'version' => $requestParam['version'],
'check_value' => $cfcaSign,
],
'headers' => ['Content-type' => 'application/x-www-form-urlencoded;charset=UTF-8']
];
$requestData = $this->requestData($param);
$checkValue = json_decode($requestData['body'],1)['check_value'];
//验证接口返回的签名数据
$strBase64CertContent = $this->verifyDataSignature($checkValue);
//验证返回数据的CFCA证书有效性
$verifyCertificat = $this->verifyCertificat($strBase64CertContent);
//获取解签数据
$signSourceData = '';
if($verifyCertificat){ //校验证书有效性
$signSourceData = $this->getCFCASignSourceData($checkValue);
}
return $signSourceData;
}
/**
* cfca 加签方法
*
* @param $strSignSourceData 待签名字符串
* @return string
*/
private function CFCASignature($strSignSourceData){
$strMsgPKCS7AttachedSignature = '';
try{
$strMsgPKCS7AttachedSignature = $this->cryptoAgentServerObj->SignData_PKCS7Attached($this->strSignAlg, $strSignSourceData,
$this->strPfxFilePath, $this->strPfxPassword, $this->strHashAlg);
}catch (Exception $e){
$strErrorMsg = $this->cryptoAgentServerObj->GetLastErrorDesc();
return $strErrorMsg;
}
return base64_encode($strMsgPKCS7AttachedSignature);
}
/**
* CFCA 验证签名数据
* @param $signature Base64编码的签名
* @return string
*/
private function verifyDataSignature($signature){
$strBase64CertContent = "";
try{
$strBase64CertContent = $this->cryptoAgentServerObj->VerifyDataSignature_PKCS7Attached($this->strSignAlg,base64_decode($signature));
}catch (Exception $e){
$strErrorMsg = $this->cryptoAgentServerObj->GetLastErrorDesc();
//记录log
throw new Exception("\n verifyDataSignature error:".$strErrorMsg."\n");
}
return $strBase64CertContent;
}
/**
* CFCA 解签获取签名数据
* @param $signature
* @return string
*/
private function getCFCASignSourceData($signature){
$strMsgP7AttachedSource = '';
try{
$strMsgP7AttachedSource = $this->cryptoAgentServerObj->GetSignSourceData(base64_decode($signature));
}catch (Exception $e){
$strErrorMsg = $this->cryptoAgentServerObj->GetLastErrorDesc();
return $strErrorMsg;
}
return $strMsgP7AttachedSource;
}
/**
* CFCA 证书有效性验证
*
* @param $strBase64CertContent 签名证书内容 base64
* @return bool
*/
private function verifyCertificat($strBase64CertContent = ''){
$nCertVerifyFlag = '4'; //验证证书链完整性
$strTrustedCACertFilePath = $this->strTrustedCACertFilePath;
try{
//调用验证方法
$nResult = $this->cryptoAgentServerObj->VerifyCertificate($strBase64CertContent, $nCertVerifyFlag, $strTrustedCACertFilePath,"");
if (!$nResult) { // true 为验证通过 ,其他验证失败
//记录log
echo new Exception("verifyCertificat error:".$nResult);
}
}catch (Exception $e){
//记录log
throw new Exception("verifyCertificat error:".$e);
}
return $nResult;
}
/**
* 请求接口返回数据
* @param $param
* @return array
*/
private function requestData($param)
{
try{
// 请求接口所以参数初始化
$data = [
'url' => $this->apiUrl, // 接口 url
'requestData' => $param['requestData'], // 请求接口参数
'headers' =>$param['headers']
];
$res = $this->httpPostRequest($data['url'],$data['headers'],$data['requestData']);
} catch (\Exception $e) {
//记录log
throw new Exception("api requestData error :".$e);
}
return [
'status' => $res['info']['http_code'],
'body' => $res['body']
];
}
/**
* curl post 请求方法
*
* @param string $url
* @param array $header
* @param array $requestData
* @return array
*/
private function httpPostRequest($url = '',$header = array(),$requestData = array()){
$curl = curl_init();
curl_setopt ( $curl, CURLOPT_HTTPHEADER,$header);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS,http_build_query($requestData));
$res = curl_exec($curl);
$info = curl_getinfo($curl);
$error = curl_error($curl);
curl_close($curl);
return [
'body' => $res,
'info' => $info,
'error' => $error,
];
}
}
//调用接口
$demoObj = new HuifuCFCA();
$data = $demoObj->apiRequest();
print_r('<pre/>');
print_r($data);
Python 代码示例¶
Demo 运行环境要求:Linux 64bit
1、Python要求:Python2.7/Python3.x
2、使用 pip 安装 cfcasign, 安装命令: pip install cfcasign-0.0.1.tar.gz
3、参考demo完成cfca加解签
python
"""CFCA Python SDK version Demo"""
from cfcasign import CFCASignature
import os
if __name__ == '__main__':
cfca_signature = CFCASignature()
# 加签
_return_code, sign = cfca_signature.get_sign(algorithm='rsa',
source_data=__doc__,
pfx_file_path=os.path.join('rsasigncert.pfx'),
pfx_password='111111',
hash_alg='sha-256'
)
print("sign return code: {0}".format(_return_code))
print("sign value: {0}".format(sign))
# 验签
signature_base64 = b"TUlJR0pRWUpLb1pJaHZjTkFRY0NvSUlHRmpDQ0JoSUNBUUV4RHpBTkJnbGdoa2dCWlFNRUFnRUZBREFYQmdrcWhraUc5dzBCQndHZ0NnUUlWR1Z6ZEVSaGRHR2dnZ1JNTUlJRVNEQ0NBekNnQXdJQkFnSUZRQUtaZDNVd0RRWUpLb1pJaHZjTkFRRUxCUUF3WFRFTE1Ba0dBMVVFQmhNQ1EwNHhNREF1QmdOVkJBb1RKME5vYVc1aElFWnBibUZ1WTJsaGJDQkRaWEowYVdacFkyRjBhVzl1SUVGMWRHaHZjbWwwZVRFY01Cb0dBMVVFQXhNVFEwWkRRU0JCUTFNZ1ZFVlRWQ0JQUTBFek1UQWVGdzB4T0RBeE1UVXdORFE1TkRCYUZ3MHlNekF4TVRVd05EUTVOREJhTUhFeEN6QUpCZ05WQkFZVEFrTk9NUlV3RXdZRFZRUUtFd3hEUmtOQklGUkZVMVFnUTBFeEVUQVBCZ05WQkFzVENFeHZZMkZzSUZKQk1Sa3dGd1lEVlFRTEV4QlBjbWRoYm1sNllYUnBiMjVoYkMweE1SMHdHd1lEVlFRREZCUXdOVEZBUVZNd016Z3hRRTR4TVRFeE16QkFNVENDQVNJd0RRWUpLb1pJaHZjTkFRRUJCUUFEZ2dFUEFEQ0NBUW9DZ2dFQkFOMlN3T0MyeDUwQkRMSXpHWGNJOFlUQ0VMTEVsTG5VUFNBZndNQi9zYXN0eWZ1WjFLQnQ5YlFSOEhhTkRVM0I4S0o2RVdEYTlYYUcyMStmT0hvViszOW1vV3E2Vm1jL2pHRDJMaUdneGJCWWgyUkkwakZFODdZQjIvZE1iT3JyT3E5SjViVHc5bVQ0L3BCbHF1Q0RLdlkwclpUdlVVb3loRW5TcWlaQ0lFY1hBall3T2l0UlovS0tkbU9pTUhrOXJ3ZTJhekhjZ1R5TGJiMzVDL2dIUjViZWRCVWNPbEhuUnh1N2pNSlgwbWxEaEFXOUo4c3E2ZHJ0eTVIRkxoTTR0VjVuUW1ES1JteEo5Ylk0WmRuaXpvdlg0NTJmNFJOYUs2TE4vQ1RYUWcvSkpmYzMxM3k3YitQSFJjSHFINlh6dnBXRHJhczNhbEtRMlBqVlhwQnRwcThDQXdFQUFhT0IrakNCOXpBL0JnZ3JCZ0VGQlFjQkFRUXpNREV3THdZSUt3WUJCUVVITUFHR0kyaDBkSEE2THk5dlkzTndkR1Z6ZEM1alptTmhMbU52YlM1amJqbzRNQzl2WTNOd01COEdBMVVkSXdRWU1CYUFGSm85dEs1bFdQdk9XZ1Y0SnFCdEt3U0d1c2JzTUF3R0ExVWRFd0VCL3dRQ01BQXdOd1lEVlIwZkJEQXdMakFzb0NxZ0tJWW1hSFIwY0Rvdkx6SXhNQzQzTkM0ME1pNHpMMDlEUVRNeEwxSlRRUzlqY213eU9TNWpjbXd3RGdZRFZSMFBBUUgvQkFRREFnYkFNQjBHQTFVZERnUVdCQlR0Szk2V2w4aTlDaThaV3ZEeUpZSWpuaStCMWpBZEJnTlZIU1VFRmpBVUJnZ3JCZ0VGQlFjREFnWUlLd1lCQlFVSEF3UXdEUVlKS29aSWh2Y05BUUVMQlFBRGdnRUJBRGE2cVpuS1Ryak9HSWpoWXdMelY2N3VqMFJYbDMzcXNsNFpMSVY1Ym1BQ0dRWUVPSlpuaDZLcjhHNnI1TXBZK0k0S2ptNCtUNXlrSmNlRHoyMGJNa0lDMnlXREpoQW1kWjIrTEdXcE9wdnlka1hVaE5QNzZ5aFc2RzdSdGVUZllDSSsrYmhTdUd1TWRGSUNPN3VOSDN4d0lUUGhabjliWVR4dGxVbWh3MnU5U0ZXOG5oQVphdHd0VExJVUxXYmcwZ2lXbU5tcXNENVhiNG45U2xRVk9tTDBDd3o0Zkd3d2FoVG9Tait5aU82QmhwbFlyeWJuNHc2cXhtU0htMXhOYkJqSW05djYrV2EwcHFRbldGZ3VwZCtFMGYxYVphSmxYQi9wWkMyNzBGZEZyZ0hYdTBBNEFOZ0lTZjNJYU5RNk1mbUFDTm5BRGpSQVd2dFVZWTFCaEhVeGdnR1JNSUlCalFJQkFUQm1NRjB4Q3pBSkJnTlZCQVlUQWtOT01UQXdMZ1lEVlFRS0V5ZERhR2x1WVNCR2FXNWhibU5wWVd3Z1EyVnlkR2xtYVdOaGRHbHZiaUJCZFhSb2IzSnBkSGt4SERBYUJnTlZCQU1URTBOR1EwRWdRVU5USUZSRlUxUWdUME5CTXpFQ0JVQUNtWGQxTUEwR0NXQ0dTQUZsQXdRQ0FRVUFNQTBHQ1NxR1NJYjNEUUVCQVFVQUJJSUJBRGphRFEvUTduWnV0M041TUUvN2dQa1QyeG5aUS9tTERMTFVnWGhFSmRTUjg2RlkzaEd0TmE3SEVFb2tFbFF1MERPWHZEbFp3YU4xV0NmTHFCM3kraW4zazhTNzdOT2ZnNnVxcE1ENFc0YjdpZEgvR0hDTHQ5eWozYWMzdUNmQ3Ixc3doOW43QUxZYitMbGM3Sjd6TFJVajdFZ1pDc0NCd1VPTkZCRmkwVWg0c0d5VWhZM3NWN0tsV01saVpFSVhzV3YwT0VJODE4QVlYL1ErdFpvalEramZEYktRMkpVSVlNaC93UXA4WWE5Ty9oT3RVMTZIQUh5RWJTZXVML1o5QnFpVUYxQ2RZY3dVb3lWL1Nzend3eHR2eDlDRFB4YjI1dVhzMDBhdmFOZ1VKdElUZFlEazNObENhaXhvdy9nQkQ0V3VSZW9Sa3hxMGpVU3pIS1FLTXkwPQ=="
_return_code, value = cfca_signature.check_sign(base64_signature=signature_base64, algorithm='rsa')
print("check sign return code: {0}".format(_return_code))
print("value: {0}".format(value))
# 验证证书
_return_code = cfca_signature.verify_certificate(certificate_path='CFCA_ACS_TEST_CA.cer|CFCA_ACS_TEST_OCA31.cer',
verify_level=4)
print("check cer code: {0}".format(_return_code))
# 验签 + 证书
value, _return_code = cfca_signature.check_sign_cer(base64_signature=signature_base64,
algorithm='rsa',
certificate_path='CFCA_ACS_TEST_CA.cer|CFCA_ACS_TEST_OCA31.cer',
verify_level=4)
print("value: {0}".format(value))
print("check cer code: {0}".format(_return_code))
C# 代码示例¶
Demo 运行环境要求:Windows Server 2008、 Windows Server 2012
SADK.Standard.x64.dll 为 CFCA 加解签 SDK,888888-NEW.pfx 为测试的加签证书(使用前请替换成商户的加签证书),将这两个文件拷贝到运行程序的根目录后运行 Demo。
项目中使用这两个文件时可以将 Sign.cs 文件中这两个文件的位置替换成实际文件的绝对路径。
c#
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Text;
using System.Threading.Tasks;
namespace app_plus
{
class Program
{
static void Main(string[] args)
{
// mt();
// Test122();
Test202();
}
static void mt()
{
string s = "{\"ordAmt\":\"420.00\",\"apiVersion\":\"2.0.0.1\",\"payChannelType\":\"W1\",\"appId\":\"wxa403cbc1ea66ee73\",\"isRaw\":\"1\",\"openId\":\"oVW8pwBOgVDD9fN0JNr4v69mP81M\",\"buyerLogonId\":\"\",\"buyerId\":\"\",\"merOperId\":\"shangshi01\",\"merPriv\":{\"merNoticeUrl\":\"https://pay.xiaogj.com/notify/chinapnrpay\"},\"termOrdId\":\"100054731905071000107418740333\",\"outOrdId\":\"100054731905071000107418740333\",\"goodsDesc\":\"网上商城订单\",\"memberId\":\"310000016000334222\",\"longitude\":\"\",\"latitude\":\"\",\"imei\":\"\",\"macIp\":\"\",\"softVersion\":\"\",\"osVersion\":\"\",\"bgRetURL\":\"\"}";
for (int i=0; i<10; i++)
{
new System.Threading.Thread(o =>
{
Sign sg = new Sign();
for (int j = 0; j < 100000; j++)
{
sg.sign(s);
}
Console.WriteLine("thread: completed");
}).Start();
}
while (true) ;
}
//122 文件上传demo
static void Test122()
{
string url = "https://apptrade.testpnr.com/api/fileMerchantRequest";
string version = "10";
string cmd_id = "122";
string mer_cust_id = "6666000000002619";
string attach_no = "abcd" + DateTime.Now.Ticks.ToString("x");
string file_name = "test.png";
string file_path = "C:\\" + file_name;
Dictionary<string, string> info = new Dictionary<string, string>();
info.Add("version", version);
info.Add("cmd_id", cmd_id);
info.Add("mer_cust_id", mer_cust_id);
info.Add("attach_no", attach_no);
info.Add("trans_type", "01");
info.Add("attach_type", "05");
info.Add("extension", "1");
string json_string = JsonConvert.SerializeObject(info, Formatting.None);
Sign sg = new Sign();
string check_value = sg.sign(json_string);
string boundary = "ABCD" + DateTime.Now.Ticks.ToString("x");
byte[] firstBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("--" + boundary + "\r\n");
byte[] boundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "\r\n");
byte[] endBoundaryBytes = System.Text.Encoding.ASCII.GetBytes("\r\n--" + boundary + "--");
string url_with_param = url;
bool concat_start = true;
foreach (var key in info.Keys)
{
if (concat_start)
{
url_with_param += "?";
concat_start = false;
}
else
{
url_with_param += "&";
}
url_with_param += key + "=" + info[key];
}
url_with_param += "&check_value=" + check_value;
HttpWebRequest request = request = (HttpWebRequest)WebRequest.Create(url_with_param);
request.Method = "post";
request.ContentType = "multipart/form-data; boundary=" + boundary;
string formItem;
byte[] formItemBytes;
Stream memStream = new System.IO.MemoryStream();
memStream.Write(firstBoundaryBytes, 0, firstBoundaryBytes.Length);
formItem = "Content-Disposition: form-data; " +
"name=\"attach_file\"; " +
"filename=\"" + file_name + "\"\r\n" +
"Content-Type: image/png\r\n\r\n";
formItemBytes = System.Text.Encoding.UTF8.GetBytes(formItem);
memStream.Write(formItemBytes, 0, formItemBytes.Length);
using (var fileStream = new FileStream(file_path, FileMode.Open, FileAccess.Read))
{
byte[] buffer = new byte[1024];
int bytesRead = 0;
while ((bytesRead = fileStream.Read(buffer, 0, buffer.Length)) != 0)
{
memStream.Write(buffer, 0, bytesRead);
}
}
memStream.Write(endBoundaryBytes, 0, endBoundaryBytes.Length);
request.ContentLength = memStream.Length;
using (var requestStream = request.GetRequestStream())
{
memStream.Position = 0;
byte[] tempBuffer = new byte[memStream.Length];
memStream.Read(tempBuffer, 0, tempBuffer.Length);
memStream.Close();
requestStream.Write(tempBuffer, 0, tempBuffer.Length);
}
string responseText = null;
try
{
HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse();
using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
responseText = streamReader.ReadToEnd();
Dictionary<string, string> responseJson = (Dictionary<string, string>)JsonConvert.DeserializeObject<Dictionary<string, string>>(responseText);
responseText = responseJson["check_value"];
responseText = sg.unsign(responseText);
}
}
catch (WebException e)
{
if (e.Response != null)
{
using (var errorResponse = (HttpWebResponse)e.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
responseText = reader.ReadToEnd();
}
}
}
}
Console.WriteLine(responseText);
while (true) ;
}
//122 取现demo
static void Test202()
{
string url = "https://apptrade.testpnr.com/api/merchantRequest";
string version = "10";
string cmd_id = "202";
string mer_cust_id = "6666000000002619";
Dictionary<string, string> info = new Dictionary<string, string>();
info.Add("version", version);
info.Add("cmd_id", cmd_id);
info.Add("mer_cust_id", mer_cust_id);
info.Add("user_cust_id", "6666000000002959");
info.Add("order_date", "20181026");
info.Add("order_id", "201673233703");
info.Add("trans_amt", "0.39");
info.Add("cash_bind_card_id", "65334");
info.Add("fee_obj", "02050200");
info.Add("fee_acct_id", "2744");
info.Add("cash_type", "02030000");
info.Add("bg_ret_url", "http://192.168.0.74:8001/npayCallBack/asyncHandle.json");
info.Add("mer_priv", "test_mer_priv");
info.Add("extension", "test_extension");
string json_string = JsonConvert.SerializeObject(info, Formatting.None);
Sign sg = new Sign();
string check_value = sg.sign(json_string);
json_string = sg.unsign(check_value);
HttpWebRequest request = request = (HttpWebRequest)WebRequest.Create(url);
request.Method = "post";
request.ContentType = "application/x-www-form-urlencoded";
using (var streamWriter = new StreamWriter(request.GetRequestStream()))
{
string requestText = "version=" + version + "&" +
"cmd_id=" + cmd_id + "&" +
"mer_cust_id=" + mer_cust_id + "&" +
"check_value=" + check_value;
streamWriter.Write(requestText);
streamWriter.Flush();
streamWriter.Close();
}
string responseText = null;
try
{
HttpWebResponse httpResponse = (HttpWebResponse)request.GetResponse();
using (StreamReader streamReader = new StreamReader(httpResponse.GetResponseStream()))
{
responseText = streamReader.ReadToEnd();
Dictionary<string, string> responseJson = (Dictionary<string, string>)JsonConvert.DeserializeObject<Dictionary<string, string>>(responseText);
responseText = responseJson["check_value"];
responseText = sg.unsign(responseText);
}
} catch (WebException e) {
if (e.Response != null) {
using (var errorResponse = (HttpWebResponse)e.Response)
{
using (var reader = new StreamReader(errorResponse.GetResponseStream()))
{
responseText = reader.ReadToEnd();
}
}
}
}
Console.WriteLine(responseText);
while (true) ;
}
}
}
证书下载操作指引¶
安装证书控件
非IE浏览器下,点击邮件中的申请链接,登录安全证书下载控台。首次登录需要安装证书控件,系统提示如下图。点击【确定】,下载保存证书控件到本地,并安装。

- 安装过程中如果弹出如下的提示框,一定要选择允许。

- 安装完成后,重起浏览器。

IE 浏览器下,进入邮件中的申请链接地址,输入联系人手机号,获取验证码(下载测试证书时,验证码随便输入4位,不做校验)。

- 点击【下载证书】,系统会自动下载安装。

- 安装成功后提示。(注意不要忘记下载右边的【用户指南cer文件】来获取cer证书哦!)

导出加签证书
- 点击浏览器菜单栏“工具”菜单,单击“Internet选项”。

- 在弹出的对话框中点击【内容】选项卡,单击【证书】按钮。

- 选中之前安装的证书,点击【导出】。

- 选择导出私钥,点击【下一步】。

- 选择“个人信息交换”,下属二级选项可根据实际需要勾选,建议全选。点击【下一步】。

- 输入并确认密码,点击【下一步】。
注意:请记下这里输入的密码,调用加签方法时需要用到这个密码

- 指定文件名和存放路径。点击【浏览】可更改存放路径,选择完成后点击【下一步】。

- 点击【完成】,获得 pfx 文件。

下载解签证书

点击【用户指南 cer 文件】,系统会自动下载解签证书。
CFCA_ACS_TEST_OCA31.cer 为测试环境用的解签证书,CFCA_ACS_OCA31.cer 为生产环境用的解签证书。
手机 SDK¶
APP+ SDK 提供了多种主流支付渠道,商户只需要一次接入即可完成多个渠道的接入。APP+ SDK 适配了 Android、iOS 移动端平台。
相关组件下载
流程说明¶

接入步骤¶
- 第一步:下载SDK,并按照SDK中的接入说明文档集成SDK;
- 第二步:联系商务申请配置SDK密钥;
- 第三步:SDK中更换成贵司获取的商户客户号、SDK密钥、以及其他必要的参数,然后进行交易。
快捷支付接口¶
商户服务端提供此接口给客户端 SDK 调用。当商户 APP 发起快捷支付时,客户端 SDK 会调用此接口,跳转到汇付的快捷支付页面,用户完成支付后跳转支付结果页面。
调用方式:页面提交方式
请求参数
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
设备号 | device_info | 变长32位 | 可选 | |
IP地址 | ip_addr | 变长20位 | 可选 | |
经纬度 | location_val | 变长20位 | 可选 | |
设备信息 | dev_info_json | 变长2000位 | 可选 | 该字段是由客户端 SDK 调用商户此接口时,传过来的。服务端请将该参数透传给快捷支付( APP 版)接口 |
支付参数 | self_param_info | 可选 | 该字段是商户的 APP 调用 客户端 SDK 时传的参数,再由客户端 SDK 透传给此接口。此字段内容商户可以自定义 | |
扩展域 | extension | 变长512位 | 可选 | 用于扩展请求参数 |
返回参数
返回结果页面
注:如果商户服务端请求支快捷支付时传的 ret_url 不为空,则跳转到商户的 ret_url,由商户解签处理快捷支付结果。否则跳转到 APP+ 的结果页面,商户不需要处理快捷支付同步接口,只需要接收并处理异步消息。
APP 支付接口¶
商户服务端提供此接口给客户端 SDK 调用。当商户 APP 发起微信或者支付宝支付时,客户端 SDK 会调用此接口,获取微信或者支付宝的支付参数,然后再唤起微信或者支付宝支付。
调用方式:系统调用
请求参数
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
设备号 | device_info | 变长32位 | 可选 | |
IP地址 | ip_addr | 变长20位 | 可选 | |
经纬度 | location_val | 变长20位 | 可选 | |
设备信息 | dev_info_json | 变长2000位 | 可选 | 该字段是由客户端 SDK 调用商户此接口时,传过来的。服务端请将该参数透传给 APP 支付接口 |
支付类型 | pay_type | 定长2位 | 必须 | 15:支付宝;10 : 微信APP支付; |
支付参数 | self_param_info | 可选 | 该字段是商户的 APP 调用 客户端 SDK 时传的参数,再由客户端 SDK 透传给此接口。此字段内容商户可以自定义 | |
扩展域 | extension | 变长512位 | 可选 | 用于扩展请求参数 |
返回参数
参数中文名称 | 参数名称 | 数据格式 | 是否必须 | 说明 |
---|---|---|---|---|
应答返回码 | resp_code | 定长6位String | 必须 | 218002:请求已受理;218003:交易失败;218098:系统超时;其他请参考 APP支付返回码 |
应答返回描述 | resp_desc | 变长String | 必须 | 返回码的对应中文描述 |
支付地址 | pay_url | 变长1024位 | 必须 | 用于支付宝支付 |
支付信息 | pay_info | 定长16位String | 必须 | 用于微信APP支付 |
扩展域 | extension | 变长512位的String | 可选 |
注意事项:
1、请将返回参数以 json 格式写入到 response 对象的 body 区,且 body 区只有返回参数,如果是 java 开发则可以添加注解@ResponseBody
body区格式:
%7B%22pay_url%22%3A%22%22%2C%22resp_desc%22%3A%22%E4%BA%8C%E7%BA%A7%E5%95%86%E6%88%B7%E5%8F%B7%E4%B8%8D%E5%AD%98%E5%9C%A8%22%2C%22platform_seq_id%22%3A%22%22%2C%22resp_code%22%3A%22218748%22%2C%22pay_info%22%3A%22%22%2C%22token_id%22%3A%22%22%2C%22order_id%22%3A%22TEST1513827504986%22%2C%22order_date%22%3A%2220171221%22%7D
2、为了防止乱码,返回参数需要做URLEncoder转码
更新记录¶
2021.11.03 v3.4.6
- 新增省市县地区代码
2021.10.27 v3.4.5
- 218银联正扫优化
2021.05.27 v3.4.4
- 122上传文件新增类型:19-活体验证
2021.04.06 v3.4.3
- 冻结比例优化
2021.03.25 v3.4.2
- 交易类增加相关字段
2021.03.18 v3.4.1
- 开户类增加相关字段
2021.02.02 v3.4.0
- 156 新增申请商户接口
- 155 新增手机pos交易结果通知
2021.01.28 v3.3.9
- 154 碰一碰交易结果通知字段可选优化
2020.11.30 v3.0.3.6
- 新增161 快捷绑卡cvv2版聚合版一阶段短信发送
- 新增162 快捷绑卡cvv2版聚合版二阶段绑卡+支付
2020.11.26 v3.3.7
- 160 快捷小额免密支付接口新增请参:tm_type,remark1,remark2
2020.11.04 v3.3.6
- 160 新增快捷小额免密支付接口
2020.06.30 v3.3.5
- 154 碰一碰交易结果通知新增返参标签id:nfc_tag_id
2020.06.19 v3.3.4
- 150 新增申请标签数据接口
- 151 新增停用标签数据接口
- 152 新增修改标签数据接口
- 153 新增标签数据查询接口
- 154 新增碰一碰交易结果通知
2020.06.04 v3.3.3
- 129 新增银行卡四要素验证接口
- 106 删除独立验卡接口
- 134 新增个人用户信息修改接口
2020.05.14 v3.3.2
- 128 新增短信验证接口
- 211 新增刷脸支付后台版接口
2020.05.08 v3.3.1
- 企业网银支持列表增加兰州银行和甘肃银行
2020.04.08 v3.3.0
- 210 新增刷脸支付接口
- 301 交易状态查询接口增加刷脸交易查询类型trans_type:28
2019.12.13 v3.2.9
- 218 APP支付接口新增支付类型14:APPLE PAY
2019.11.28 v3.2.8
- 下线 215 反扫消费接口和223 反扫撤销接口
2019.10.28 v3.2.7
- 参数规范新增说明
2019.07.31 v3.2.6
- 104 取现绑卡/811 取现绑卡代开户请参银行代号bank_id设置可选
- 111 绑卡短信发送接口请参银行代号bank_id设置定长8位
2019.07.17 v3.2.5
- 203、301接口返回参数新增手续费金额字段
2019.06.29 v3.2.4
- 更新所有涉及设备信息的接口
2019.06.25 v3.2.3
- 更新 设备静态信息
2019.03.27 v3.2.2
- 204 接口新增 pay_type 交易类型返回参数
2019.03.21 v3.2.1
- 209、218接口新增 limit_pay 是否禁用贷记卡字段
2019.03.14 v3.2.0
- 102、125、120 接口更新股东信息说明
2019.02.01 v3.1.9
- 120 接口请求参数新增结算卡标志 card_type 参数
2019.01.22 v3.1.8
- 新增 批量生成电子回执单 接口
2019.01.17 v3.1.7
- 812接口请求参数说明修改
- 118接口功能说明优化,以及参数描述优化
- 附件中新增网银支付接口参数gate_id网关列表
- 证书下载指引图片更换
- 102、125接口控股股东参数描述修改
2019.01.10 v3.1.6
- 企业开户后台版接口股东信息改为必传
- 849接口名称改为签约代扣支付接口以及sign_seq_id参数说明修改
- 102、125、124、122添加企业用户、个体户上传附件材料的要求说明
- 316接口参数描述修改
- 101个人开户接口增加个人职业分类信息
- 102、125企业开户接口增加行业列表信息
2019.01.03 v3.1.5
2018.12.29 v3.1.4
2018.12.21 v3.1.3
- 120接口部分参数改为必传
- 850、849、825、847、814、811接口bg_ret_url描述修改
- 接入指南新增 自助联调开放平台
2018.12.20 v3.1.2
- 216接口补加tm_type字段
- 847接口去掉充值类型中的个人网银 和 交易类型中的免注册网银支付
- 增加接入指南中 调用接口url中的描述信息
2018.12.14 v3.1.1
- 新增接入指南 对接过程中常见问题
- 整合 开发说明和 SDK&DEMO
- 各个接口功能说明细化
2018.12.07 v3.1.0
- 新增 接口调用顺序适合不同场景
- 整合 网银/转账/退款接口
- 整合 取现类接口和代发类接口
- 接入流程说明优化
2018.11.20 v3.0.9
2018.10.23 v3.0.6
- 新增 无卡收款绑卡短信接口
- 新增 无卡收款绑卡接口
- 新增 无卡收款短信发送接口
- 新增 无卡收款接口
- 新增 批量生成代发回执单接口
- 商户文件上传接口 去除更新模式
- 扫码支付接口、APP支付接口、网银支付接口 同步异步增加返回字段,手续费金额,手续费账户,手续费客户号
2018.09.28 v3.0.5
- 新增 企业开户申请接口
2018.09.11 v3.0.3.1
2018.09.06 v3.0.3
2018.09.04 v3.0.2
- 消费金融类代扣签约接口 返回参数添加绑卡 ID
- 前台快捷绑卡代开户接口 返回参数添加绑卡 ID
- 快捷绑卡代开户接口 返回参数添加绑卡 ID
- APP支付接口 请求参数订单超时时间改为定长 14 位
- 取现绑卡代开户接口 返回参数增加绑卡 ID
- 纯通道代扣签约接口 请求参数产品订单号改为非必填
- 新增 直接代扣支付接口
- 个人开户省份地区可选,企业开户部分字段长度变更
2018.08.16 v3.0.1
- 新增 银行限额列表查询接口
- 快捷支付接口 新增上送设备信息
- 快捷支付统合版支付接口 新增上送设备信息
2018.08.13 v1.1.8
- 银行卡解绑接口 短信验证码日期、短信验证码订单号和短信验证码修改为非必传
2018.07.19 v1.1.7
2018.04.02 v1.1.4
2018.02.02 v1.1.3
- 新增 生利宝理财开通接口、 生利宝理财关闭接口、 申购接口、 赎回接口、 交易明细查询接口 和 收益查询接口
- 扫码支付接口、 反扫接口、 APP支付接口 和 交易状态查询接口 返回参数添加外部订单流水号
2018.01.24 v1.1.1
2017.12.27 v1.1.0
- 快捷支付接口 和 快捷支付统合版短信发送接口 请求参数银行代码、省份和地区修改为可选
- 扫码支付接口 、 反扫接口 、 快捷支付WEB版接口 、 快捷支付APP版接口 和 APP支付接口 增加二级商户号字段