本项目用zend framework框架实现的
modules/default/controllers/IndexControllerphp
IndexControllerphp
复制代码 代码如下:
<?php
class IndexController extends Zend_Controller_Action
{
public function init()
{
/* Initialize action controller here */
}
public function indexAction()
{
/*模拟订单
*$MockOrder是从数据库取出来的信息
它包含一些块钱Request的信息
这里我写死了
*orderId订单号
数据库表的主键(唯一)
//必要字段
*usr_idtype证件类型
根据自己需要
*usr_idcode证件号
根据自己需要
*etx_status是否优惠
根据自己需要
*time_create验证是否符合优惠的时间
根据自己需要
*ets_license套餐代码如同商品类别
根据自己需要
*contact_type联系方式类型
固定选择值
电子邮件
手机号
根据自己需要
块钱那边可以为空
*contact_text联系方式
根据contact_type来填写
根据自己需要
块钱那边可以为空
*etsPrice套餐价格及商品价格
根据自己需要
*orderPrice实际价格
根据自己需要
*orderAmount订单实际支付金额
这个要加手续费的
//必要字段
*orderTime订单时间
//必要字段
*paySuccess订单是否支付成功
//必要字段
*buySuccess账号是否生成功
根据自己需要
*payTime订单支付成功时间
//必要字段
*总之凡是跟订单有关的都是必要字段
*orderId
orderAmount
orderTime为 Request所需字段
*paySuccess
payTime为Response所需字段
*/
$MockOrder = array();
$MockOrder[
orderId
] =
;//订单号
必要
$MockOrder[
usr_idtype
] =
;//证件类型
身份证
$MockOrder[
usr_idcode
] =
;//身份证号
$MockOrder[
etx_status
] =
;//是否优惠
否
$MockOrder[
time_create
] =
;//验证是否优惠时间
$MockOrder[
ets_license
] =
;//套餐代码及商品类别
$MockOrder[
contact_type
] =
;//联系方式类型
邮箱
$MockOrder[
contact_text
] =
x@
com
;//联系方式
邮箱
$MockOrder[
etsPrice
] =
;//套餐价格及商品价格
$MockOrder[
orderPrice
] =
;//实际价格
$MockOrder[
orderAmount
] =
;//订单实际支付价格
加手续费的
必要
$MockOrder[
orderTime
] =
;//订单生成时间
必要
$MockOrder[
paySuccess
] =
;//订单是否支付成功
必要
$MockOrder[
buySuccess
] =
;//账号是否生成成功
$MockOrder[
payTime
] =
;//订单支付时间
必要
//BillRequest就是快钱那边需要的的一些参数
$this
>view
>BillRequest = new Application_Model_BillRequest($MockOrder);
Zend_Debug::dump($this
>view
>BillRequest);exit;
}
//bgUrl地址指向这里
public function receiveAction()
{
//receive数据库设计
/*用$MockReceive数组模拟
* $MockReceive = array();
* $MockReceive[
id
]主键;
* $MockReceive[
orderId
]商户订单号;
* $MockReceive[
receiveTime
]接受时间;
* $MockReceive[
queryString
]http_build_encode($_REQUEST);
* $MockReceive[
dealId
]快钱交易号;
* $MockReceive[
bankDealId
]银行交易号;
* $MockReceive[
payResult
]处理结果
支付成功
支付失败;
* $MockReceive[
dealTime
]快钱交易时间;
* $MockReceive[
payAmount
]订单实际支付金额;
* $MockReceive[
fee
]费用;
* $MockReceive[
errCode
]错误代码;
*/
/*$_REQUEST是快钱那边返回来的数据
* merchantAcctId人民币账号
与提交订单时的块钱账号保持一致
* version网关版本
固定值
v
与提交订单时的网关版本号保持一致
* language网页显示语言种类
中文显示
与提交订单时的网页显示语言种类保持一致
* signType签名类型
PKI签名
与提交订单时的签名类型保持一致
* payType支付方式
全部
与提交订单时的支付方式保持一致
* bankId银行代码
* orderId商户订单号
与提交订单时的商户订单号保持一致
* orderTime商户订单提交时间
与提交订单时的商户订单提交时间保持一致
* orderAmount商户订单金额
与提交订单时的商户订单金额保持一致
* dealId快钱交易号
* bankDealId银行交易号
* dealTime快钱交易时间
* payAmount订单实际支付金额
* fee费用
* ext
扩展字段
与提交订单时的扩展字段
保持一致
* ext
扩展字段
与提交订单时的扩展字段
保持一致
* payResult处理结果
支付成功
支付失败
* errCode错误代码
可为空
* signMsg签名字符串
*/
$BillResponse = new Application_Model_BillResponse($_REQUEST);
//$BillResponse
>checkSignMsg验证签名字符串是否正确
防止bug漏洞等
if($BillResponse
>checkSignMsg){
//判断订单支付是否成功
if($BillResponse
>isSuccess){
//返回给快钱
快钱会按照redirecturl地址跳到新页面
这里是成功页面
return "<result>
</result><redirecturl>http://
bill/default/index/sucess</redirecturl>";exit;
}else{
//返回给快钱
快钱会按照redirecturl地址跳到新页面
这个是失败页面
return "<result>
</result><redirecturl>http://
bill/default/index/fail</redirecturl>";exit;
}
}
//返回给快钱
快钱会按照redirecturl地址跳到新页面
这个是失败页面
return "<result>
</result><redirecturl>http://
bill/default/index/fail</redirecturl>";exit;
}
//redirecturl地址
//成功
public function success()
{
}
//失败
public function fail()
{
}
}
modules/default/views/scripts/index/indexphtml
复制代码 代码如下:
<?php $BillRequest = (array)$this
>BillRequest;?>
<div style="display:none;">
<form name="kqPay" action="
<?php foreach($BillRequest as $key => $val):?>
<input type="hidden" name="<?php echo $key;?>" value="<?php echo $val;?>"/>
<?php endforeach;?>
<input type="submit" name="submit" value="提交到快钱" id="kqPay">
</form>
</div>
<script>
document
getElementById(
kqPay
)
click();
</script>
models/BillRequestphp
BillRequestphp
复制代码 代码如下:
<?php
class Application_Model_BillRequest
{
public function __construct($MockOrder){
/*
* 人民币网关账号
*第一种方式
该账号为
位人民币网关商户编号+
该参数必填
对应工商银行
*第二种方式
该账号为
位人民币网关商户
*/
$this
>merchantAcctId = "
";
//服务器接收支付结果的后台地址
该参数务必填写
绝对路径//不能为空
$this
>bgUrl = "http://
bill/default/index/receive";
//商户订单号
以下采用时间来定义订单号
商户可以根据自己订单号的定义规则来定义该值//不能为空
$this
>orderId =
TOLPC
sprintf("%
d"
$MockOrder[
orderId
]);
//订单金额
金额以“分”为单位
商户测试以
分测试即可
切勿以大金额测试
该参数必填//不能为空
$this
>orderAmount =$MockOrder[
orderAmount
];
//订单提交时间
格式
yyyyMMddHHmmss
如
//不能为空
$this
>orderTime = date("YmdHis"
$MockOrder[
orderTime
]);
//支付人姓名
可以为空
$this
>payerName= "";
//支付人联系类型
代表电子邮件方式
代表手机联系方式
可以为空
$this
>payerContactType = "";
//支付人联系方式
与payerContactType设置对应
payerContactType为
则填写邮箱地址
payerContactType为
则填写手机号码
可以为空
$this
>payerContact = "";
//商品名称
可以为空
$this
>productName= "TOLPC";
//商品数量
可以为空
$this
>productNum = "
";
//商品代码
可以为空
$this
>productId = $MockOrder[
ets_license
];
//商品描述
可以为空
$this
>productDesc = "";
//支付方式
一般为
代表所有的支付方式
如果是银行直连商户
该值为
必填//不能为空
$this
>payType = "
";
//编码方式
代表 UTF
;
代表 GBK;
代表 GB
默认为
该参数必填//不能为空
$this
>inputCharset = "
";
//网关版本
固定值
v
该参数必填//不能为空
$this
>version = "v
";
//语言种类
代表中文显示
代表英文显示
默认为
该参数必填//不能为空
$this
>language = "
";
//签名类型
该值为
代表PKI加密方式
该参数必填//不能为空
$this
>signType = "
";
//接收支付结果的页面地址
该参数一般置为空即可
$this
>pageUrl = "";
//扩展字段
商户可以传递自己需要的参数
支付完快钱会原值返回
可以为空
$this
>ext
= $MockOrder[
orderId
];
//扩展自段
商户可以传递自己需要的参数
支付完快钱会原值返回
可以为空
$this
>ext
= $MockOrder[
orderTime
];
//银行代码
如果payType为
该值可以为空
如果payType为
该值必须填写
具体请参考银行列表
$this
>bankId = "";
//同一订单禁止重复提交标志
实物购物车填
虚拟产品用
代表只能提交一次
代表在支付不成功情况下可以再提交
可为空
$this
>redoFlag = "";
//快钱合作伙伴的帐户号
即商户编号
可为空
$this
>pid = "";
//快钱提供的request参数
$KeyOrders = array(
inputCharset
pageUrl
bgUrl
version
language
signType
merchantAcctId
payerName
payerContactType
payerContact
orderId
orderAmount
orderTime
productName
productNum
productId
productDesc
ext
ext
payType
bankId
redoFlag
pid
);
//判断快钱提供的request参数的值是否为空
把非空的参数及值重新组建数组
foreach($KeyOrders as $key){
if(
==$this
>{$key}){continue;}
$params[$key] = $this
>{$key};
}
//http_build_query()生成URL
encode之后的请求字符串
//urldecode()还原未编码的字符串
//getSignMsg() PKI加密
也可使用MD
加密
//MD
加密方式 strtoupper(md
(urldecode(http_build_query($params))));这种不常用了
//常用PKI加密
$this
>signMsg = $this
>getSignMsg(urldecode(http_build_query($params)));
}
//PKI加密技术
public function getSignMsg($param){
//
bill
rsa
pem是快钱的一个CA证书
//本地随机生成一个KEY
用此KEY加密数据 KEY为$priv_key_id
$priv_key_id = openssl_get_privatekey(file_get_contents("
bill
rsa
pem"
"r"));
//用$priv_key_id给$param数据加密
//计算一个签名字符串$param通过使用SHA
哈希加密
随后$priv_key_id私钥加密
数据本身是不加密的
openssl_sign($param
$signMsg
$priv_key_id
OPENSSL_ALGO_SHA
);
//从存储器上释放$priv_key_id
openssl_free_key($priv_key_id);
//使用base
对数据进行编码
return base
_encode($signMsg);
}
}
models/BillResponsephp
BillResponsephp
复制代码 代码如下:
<?php
class Application_Model_BillResponse
{
/*
* __construct()构造函数
* 生成
个参数及值
可能有一个参数的值为空
$this
>errCode的值可能为空
*/
public function __construct($response){
$KeyOrders = array(
merchantAcctId
version
language
signType
payType
bankId
orderId
orderTime
orderAmount
dealId
bankDealId
dealTime
payAmount
fee
ext
ext
payResult
errCode
signMsg
);
foreach($KeyOrders as $key){
$this
>{$key} = $response[$key];
}
}
/*
* 检查签名字符串
* 快钱返回的签名字符串是$this
>signMsg
* 使用base
对前面字符串进行解码
* 验证使用快钱给的公钥验证
* 快钱那边他们把返回来的参数值不为空的使用私钥加密生成了$this
>signMsg
* 快钱给了我们私钥对应的公钥
我们使用这个公钥来验证
成功
失败
错误
*/
public function checkSignMsg(){
$KeyOrders = array(
merchantAcctId
version
language
signType
payType
bankId
orderId
orderTime
orderAmount
dealId
bankDealId
dealTime
payAmount
fee
ext
ext
payResult
errCode
);
foreach($KeyOrders as $key){
if(
==$this
>{$key}){continue;}
$params[$key] = $this
>{$key};
}
//$pub_key_id 公钥
$pub_key_id = openssl_get_publickey(file_get_contents("
bill
rsa
cer"
"r"));
return openssl_verify(urldecode(http_build_query($params))
base
_decode($this
>signMsg)
$pub_key_id);
}
public function isSuccess(){
//$this
>payResult成功时
失败时
return
==$this
>payResult;
}
public function getOrderId(){
return str_replace(
XXX
$this
>orderId);
}
}
需要一个公钥和一个私钥这个不是一对的
都是一半
billrsacer
billrsapem