支付宝+银联统一支付功能实现

原创
2016-06-07 11:40:54 1230浏览

这个model将支付宝和银行支付统一到一起,摆脱了对SDK的依赖,我尽量封在了这一个model里面,可根据自己项目需求修改。

应一些朋友要求,我把发起支付以及支付回调部分也放上来,我去掉了一些内容只留下了流程。

2015-8-14更新:很久没上这里了,发现好多消息说想要模板,我这里发出来。
PayAction: class PayAction extends Action{
//支付跳转
function do_pay(){
//构造参数
$payment = array(
'money'=>12,
'deal_name'=>'充值',
//支付银行,对应银行ID我在后面贴出来
'bank_id'=>'',
'notice_sn'=>'20140920123456',
);
echo D('Payment')->get_payment_code($payment);
}

//支付结果同步回调
function response(){
$request = $_GET;
unset($request['_URL_']);
$pay_res = D('Payment')->notify($request);

if($pay_res['status']){
//支付成功业务逻辑
}else{
$this->error('支付失败');
}
}

//支付结果异步回调
function notify(){
$request = $_POST;
$pay_res = D('Payment')->notify($request);

if($pay_res['status']){
//支付成功业务逻辑
echo 'success';
}else{
echo 'fail';
}
}
}

//银行ID
$bank_id = array(
'ICBCB2C' => '中国工商银行',
'CMB' => '招商银行',
'CCB' => '中国建设银行',
'ABC' => '中国农业银行',
'SPDB' => '上海浦东发展银行',
'SDB' => '深圳发展银行',
'CIB' => '兴业银行',
'BJBANK' => '北京银行',
'CEBBANK' => '中国光大银行',
'CMBC' => '中国民生银行',
'CITIC' => '中信银行',
'GDB' => '广东发展银行',
'SPABANK' => '平安银行',
'BOCB2C' => '中国银行',
'COMM' => '交通银行',
'ALIPAY' => '支付宝',
);

?>
出现调试错误一般是参数传错了
1、配置model里面的config,model里其他东西根本不用看
2、构造请求参数$payment
money、deal_name和订单号notice_sn是你随便给的,bank_id在页面用 radio传过来的其值是我给的那些银行ID,比如工行就是ICBCB2C


PaymentModel:
class PaymentModel extends Model{
private $config;
function _initialize(){
$this->config = array(
'alipay_partner'=>C('ALIPAY_PARTNER'),
'alipay_account'=>C('ALIPAY_ACCOUNT'),
'alipay_key'=>C('ALIPAY_KEY'),
'return_url' => 'http://'.HOST_NAME.U('Pay/response'),
'notify_url' => 'http://'.HOST_NAME.U('Pay/notify'),
);
}
function get_payment_code($form){
$link = $form['bank_id'] == 'ALIPAY' ? $this->alipay_link($form) : $this->bank_link($form);
return $link;
}
// 银联接连
function bank_link($form){
$payment_notice = array(
'money'=>$form['money'],
'deal_name'=>$form['order_name'],
'bank_id'=>$form['bank_id'],
'notice_sn'=>$form['order_sn'],
);
$money = round($payment_notice['money'],2);
$payment_info = $this->config;

$subject = $payment_notice['deal_name'];

$data_return_url = $payment_info['return_url'];
$data_notify_url = $payment_info['notify_url'];

$service = 'create_direct_pay_by_user';
/* 银行类型 */
$bank_type = $payment_notice['bank_id'];

$parameter = array(
'service' => $service,
'partner' => $payment_info['alipay_partner'],
//'partner' => ALIPAY_ID,
'_input_charset' => 'utf-8',
'notify_url' => $data_notify_url,
'return_url' => $data_return_url,
/* 业务参数 */
'subject' => $subject,
'out_trade_no' => $payment_notice['notice_sn'],
'price' => $money,
'quantity' => 1,
'payment_type' => 1,
/* 物流参数 */
'logistics_type' => 'EXPRESS',
'logistics_fee' => 0,
'logistics_payment' => 'BUYER_PAY_AFTER_RECEIVE',
'extend_param' => 'changjianghu',
/* 买卖双方信息 */
'seller_email' => $payment_info['alipay_account'],
'defaultbank' => $bank_type,
'payment' => 'bankPay'
);

$parameter = $this->argSort($parameter);

$param = '';
$sign = '';

foreach ($parameter AS $key => $val){
$param .= "$key=" .urlencode($val). "&";
$sign .= "$key=$val&";
}

$param = substr($param, 0, -1);
$sign = substr($sign, 0, -1). $payment_info['alipay_key'];
$sign_md5 = md5($sign);


$payLinks = '

正在连接支付接口...';
$payLinks.='';

return $payLinks;
}
// 支付宝链接
function alipay_link($form){
$payment_notice = array(
'money'=>$form['money'],
'deal_name'=>$form['order_name'],
'bank_id'=>$form['bank_id'],
'notice_sn'=>$form['order_sn'],
);
$money = round($payment_notice['money'],2);
$payment_info = $this->config;

$subject = $payment_notice['deal_name'];

$data_return_url = $payment_info['return_url'];
$data_notify_url = $payment_info['notify_url'];

$parameter = array(
'service' => 'create_direct_pay_by_user',
'partner' => $payment_info['alipay_partner'],
//'partner' => ALIPAY_ID,
'_input_charset' => 'utf-8',
'notify_url' => $data_notify_url,
'return_url' => $data_return_url,
/* 业务参数 */
'subject' => $subject,
'out_trade_no' => $payment_notice['notice_sn'],
'price' => $money,
'quantity' => 1,
'payment_type' => 1,
/* 物流参数 */
'logistics_type' => 'EXPRESS',
'logistics_fee' => 0,
'logistics_payment' => 'BUYER_PAY_AFTER_RECEIVE',
'extend_param' => 'changjianghu',
/* 买卖双方信息 */
'seller_email' => $payment_info['alipay_account']
);
// print_r($parameter);exit;
$parameter = $this->argSort($parameter);

$param = '';
$sign = '';

foreach ($parameter AS $key => $val)
{
$param .= "$key=" .urlencode($val). "&";
$sign .= "$key=$val&";
}

$param = substr($param, 0, -1);
$sign = substr($sign, 0, -1). $payment_info['alipay_key'];
$sign_md5 = md5($sign);


$payLinks = '
正在连接支付接口...
';
$payLinks.='';

return $payLinks;
}

/*结果*/
function notify($request){
$return_res = array(
'info'=>'',
'status'=>false,
);
$payment = $this->config;

$request = $this->argSort($request);

/* 检查数字签名是否正确 */
$isSign = $this->getSignVeryfy($request);
if (!$isSign){//签名验证失败
$return_res['info'] = '签名验证失败';
return $return_res;
}

if ($request['trade_status'] == 'TRADE_SUCCESS' || $request['trade_status'] == 'TRADE_FINISHED' || $request['trade_status'] == 'WAIT_SELLER_SEND_GOODS' || $request['trade_status'] == 'WAIT_BUYER_CONFIRM_GOODS'){

$return_res['status'] = true;

}
return $return_res;
}

// 获取返回时的签名验证结果
function getSignVeryfy($para_temp) {
//除去待签名参数数组中的空值和签名参数
$para_filter = $this->paraFilter($para_temp);
//对待签名参数数组排序
$para_sort = $this->argSort($para_filter);
//把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
$prestr = $this->createLinkstring($para_sort);

$isSgin = false;
$isSgin = $this->md5Verify($prestr, $para_temp['sign'], $this->config['alipay_key']);
return $isSgin;
}
// 验证签名
function md5Verify($prestr, $sign, $key) {
$prestr = $prestr . $key;
$mysgin = md5($prestr);

if($mysgin == $sign) {
return true;
}
else {
return false;
}
}
// 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
function createLinkstring($para) {
$arg = "";
while (list ($key, $val) = each ($para)) {
$arg.=$key."=".$val."&";
}
//去掉最后一个&字符
$arg = substr($arg,0,count($arg)-2);

//如果存在转义字符,那么去掉转义
if(get_magic_quotes_gpc()){$arg = stripslashes($arg);}

return $arg;
}
// 除去数组中的空值和签名参数
function paraFilter($para) {
$para_filter = array();
while (list ($key, $val) = each ($para)) {
if($key == "sign" || $key == "sign_type" || $val == "")continue;
else $para_filter[$key] = $para[$key];
}
return $para_filter;
}
// 对数组排序
function argSort($para) {
ksort($para);
reset($para);
return $para;
}

}

?>
HTML模板:nbsp;html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">





预购一个梦想 - 唱江湖音乐众筹网



















专为音乐人设计的便携式监听音箱iLoud


支持金额 ¥1990.00

邮费:¥15.00

应付总额 ¥2002.00





















支付宝即时到帐支付:





确定,去付款

























90%剩余

9剩余份数

1990价格





















来自唱江湖的信息:



声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn核实处理。