php支付宝sdk
‘壹’ php支付宝验签失败
1可能是编码问题,看所有文件是不是都使用了统一编码,比如utf8; 2检查申请的SDK是否输入正确,是否完整输入了申请的SDK; 3如果是支付宝帐号密码的问题,那就不说了 4建议启动服务器后稍等几分钟,再做验证。
‘贰’ php自动抓取淘宝订单号和支付宝交易号存入数据库的代码
你这个想法很好,但是实现起来很麻烦,首先你需要淘宝对你开放API接口才行,然后写代码有事一个难事,不过我知道有一个软件是可以实现的,甩手掌柜,只需要绑定你的淘宝账号就可以,因为他们一个公司,和淘宝合作,淘宝对其开放API,然后一个团队写代码,所以是可以实现的。不光可以自动下载订单,还可以轻松管理商品,打印发货单,进销存管理等等!
‘叁’ php 后台怎么把多种支付方式集成在一起 可以先择性安装
本文将介绍如何快速通过PHP类库来集成、整合支付宝来实现充值功能。如果你的系统想要扩充积分、账户余额等功能,那么就要选择一个第三方支付系统来充值。
支付宝集成时,需要三大步:
1、通过表单提交信息,系统整合信息,提交信息到支付宝;
2、用户进行支付后,支付宝后台通知系统处理;
3、支付宝后台通知完成后,支付宝前台跳转到系统返回地址;
支付宝PHP类
PHP 类alipay_notify,主要功能是付款过程中服务器通知处理。
PHP 类alipay_service,根据支付宝外部服务接口生成支付宝地址。
我把这2个类,集中到一个文件alipay.class.inc中,点击这里查看并下载PHP支付宝类源码。
下面主要主要讲解通过支付宝的PHP类来实现整合。
PHP支付宝集成
第一步,建立提交充值的基本信息:
fubao-chong PHP支付宝集成 建立提交充值的基本信息
第二步,验证用户提交的金额正确,通过表单验证后,通过支付宝alipay_service类生成支付宝链接,然后跳转到支付宝链接。
function index() {
$total = intval($_POST['total']);
if (!$total) {
$total = 1;
}
$pay_bank = trim($_POST['pay_bank']);
$account = $_POST['_account'];
$base_path = ‘http://’.$_SERVER['HTTP_HOST'].base_path();
$order_id = date(‘YmdHis’, time()); //时间值作为唯一的订单ID号
$subject = $body = ‘LixiPHP充值’.$total.’元’;
$out_trade_no = date(‘YmdHis’, time()).’-’.$account->student['sid'];
//合作身份者ID,以2088开头的16位纯数字
$partner = ’20887015**9*7**’;
//安全检验码,以数字和字母组成的32位字符
$security_code = ‘gc2qxh4**ab***3jp8*****2ptxewks4′;
//签约支付宝账号或卖家支付宝帐户
$seller_email = ‘[email protected]’;
$_input_charset = "UTF-8";
$sign_type = "MD5"; //签名方式
$transport = ‘https’;//字符编码格式
$parameter = array(
"service" => "create_direct_pay_by_user", //交易类型
"partner" => $partner, //合作商户号
"return_url" => $base_path.’alipay/return’, //同步返回
"notify_url" => $base_path.’alipay/notify’, //异步返回
"_input_charset" => ‘UTF-8′, //字符集,默认为GBK
"subject" => $subject, //商品名称,必填
"body" => $subject, //商品描述,必填
"out_trade_no" => $out_trade_no, //商品外部交易号,必填(保证唯一性)
"price" => $total, //商品单价,必填(价格不能为0)
"payment_type" => "1", //默认为1,不需要修改
"quantity" => "1", //商品数量,必填
"paymethod" => ‘directPay’,
"defaultbank" => $pay_bank,
"logistics_fee" =>’0.00′, //物流配送费用
"logistics_payment" =>’BUYER_PAY’, //物流费用付款方式:SELLER_PAY(卖家支付)、BUYER_PAY(买家支付)、BUYER_PAY_AFTER_RECEIVE(货到付款)
"logistics_type" =>’EXPRESS’, //物流配送方式:POST(平邮)、EMS(EMS)、EXPRESS(其他快递)
//"receive _mobile" => ”, //收货人手机
"show_url" => $base_path, //商品相关网站
"seller_email" => $seller_email, //卖家邮箱,必填
);
require("../libraries/payment/alipay.class.inc");
$alipay = new alipay_service($parameter, $security_code, $sign_type);
$link = $alipay->create_url();
header("Location: ".$link);
}
用户跳转到支付宝支付界面后,默认的支付银行是在提交表单前选择的网上银行,选择支付宝的话就是使用支付宝余额支付。然后就是等待用户支付了。用户完成支付后,请会发生下面的几个步骤,当然如果用户放弃支付的话,就没有后面的处理了。
第三步,用户进行支付后,支付宝后台通知系统处理。系统处理页面主要是根据生成支付宝链接是使用的notify_url来决定的。它处理完成后,成功返回success,失败返回fail,如果支付宝收到的是fail,那么支付宝还会在隔1小时,1天,1周等周期再次通知服务器处理,这里的周期需求向支付宝询问。如果支付宝收到的是success,注意支付宝好像在一个月后要发送一次TRADE_FINISHED表示交易完成,这个一定不要再给用户加一次充值了。
function alipay_notify() {
$out_trade_no = date(‘YmdHis’, time()).’-’.$account->student['sid'];
//合作身份者ID,以2088开头的16位纯数字
$partner = ’20887015**9*7**’;
//安全检验码,以数字和字母组成的32位字符
$security_code = ‘gc2qxh4**ab***3jp8*****2ptxewks4′;
//签约支付宝账号或卖家支付宝帐户
$seller_email = ‘[email protected]’;
$sign_type = "MD5";
$_input_charset = ‘UTF-8′;
$transport = ‘https’;
require("../libraries/payment/alipay.class.inc");
$alipay = new alipay_notify($partner,$security_code,$sign_type,$_input_charset,$transport);
$verify_result = $alipay->notify_verify();
//支付宝 Notice verify
if($verify_result) {
//认证合格
//获取支付宝的反馈参数
//获取支付宝传递过来的订单号
$order_id = $_POST['out_trade_no'];
//获取支付宝传递过来的总价格
$total_fee = $_POST['total_fee'];
//拆分订单号为订单和学员ID
$txn_id = explode(‘-’, $order_id);
$real_orderid = $txn_id[0]; //get the real order
$sid = $txn_id[1];
if($_POST['trade_status'] == ‘TRADE_SUCCESS’) {
//这里放入你自定义代码,比如根据不同的trade_status进行不同操作
mysql_query("UPDATE {student} set balance = balance+%d where sid = %d", (int) $total_fee, $sid);
mysql_query("INSERT INTO {payment_receipts} (sid, order_id, amount, received) VALUES (%d, ‘%s’, %f, %d)", $sid, $real_orderid, (int) $total_fee, time());
echo "success";
}
else {
echo "fail";
}
}
else {
echo "fail";
}
}
第四步,用户完成支付后,支付宝前台跳转到系统返回地址。这个页面其实可以只做一个非常简单页面,不用做任何验证。但是为了安全建议也做一下返回验证。但是最后不要在返回页面做数据库操作。
function alipay_return() {
$out_trade_no = date(‘YmdHis’, time()).’-’.$account->student['sid'];
//合作身份者ID,以2088开头的16位纯数字
$partner = ’20887015**9*7**’;
//安全检验码,以数字和字母组成的32位字符
$security_code = ‘gc2qxh4**ab***3jp8*****2ptxewks4′;
//签约支付宝账号或卖家支付宝帐户
$seller_email = ‘[email protected]’;
$sign_type = "MD5";
$_input_charset = ‘UTF-8′;
$transport = ‘https’;
require("../libraries/payment/alipay.class.inc");
$alipay = new alipay_notify($partner,$security_code,$sign_type,$_input_charset,$transport);
$verify_result = $alipay->return_verify();
$order_id = $_GET['out_trade_no']; //获取订单号
$total_fee = (int) $_GET['total_fee']; //获取总价格
$txn_id = explode(‘-’, $order_id);
$real_orderid = $txn_id[0]; //get the real order
$sid = $txn_id[1];
//认证合格
if($verify_result) {
$output = ‘<h2>恭喜您,学员ID’.$sid.’充值’.$total_fee.’元成功!</h2>’;
$student = mysql_query("SELECT uid, balance FROM {student} WHERE sid = %d", $sid);
$output .= ‘<p>您目前的余额’.$student->balance.’元。</p>’;
$output .= l(‘查看记录’, ‘user/’.$student->uid.’/depositlogs’);
return $output;
}
else {
$output = ‘<h2>你的订单支付过程出现故障!</h2>’;
$output .= ‘<p>您的交易信息是无效的,如果你使用的是已有的返回信息的话,那么交易已经成立,你可以查看我的订单历史。<br>如果你是黑客的话,俺是守法的好公民,希望你能饶了我这个小店。’;
$output .= ‘</p><p><a href="/">返回首页</a></p>’;
return $output;
}
}
如果用户是恶意修改网址参数,将会看到:
callback return failed 如果用户是恶意修改网址参数
如果用户正常通过支付宝自动跳转回来的,将会看到:
callback return success 如果用户正常通过支付宝自动跳转回来的
好的,赶快将以上方法和代码应用到你的积分、账户余额系统把!
‘肆’ php 支付宝接口官方给的md5签名版本和rsa签名版本的区别
虽然支付宝官方还未提供相关SDK,PHP确实可以实现RSA方式的签名,这点其实很重要,由于不熟悉,在遇到困难的时候,经常会不由自主地想到是否PHP不支持RSA签名,干脆用MD5得了,这样就没有了前进的动力。其实说穿了MD5和RSA签名,不同的只是签名方式的区别,其他的都一样,因此我这里主要说一下如何用RSA进行签名和验签。
首先你需要准备下面的东西:
php的openssl扩展里已经封装好了验签的方法openssl_verify。
如果在Windows下的php.ini需要开启Openssl模块: extension=php_openssl.dll
商户私钥:
即RSA私钥,按照手册,按以下方式生成:
openssl genrsa -out rsa_private_key.pem 1024
商户公钥:
即RSA私钥,按照手册,按以下方式生成:
openssl rsa -in rsa_private_key.pem -pubout -out rsa_public_key.pem
生成之后,按照手册的说明,需要在签约平台上传公钥,需要注意的是,上传的时候需要把所有的注释和换行都去掉。
另外手册中还有如下命令:
openssl pkcs8 -topk8 -inform PEM -in rsa_private_key.pem -outform PEM -nocrypt
该命令将RSA私钥转换成PKCS8格式,对于PHP来说,不需要。
支付宝公钥:
根据手册,在签约平台获得。
如果你直接复制下来的话,会得到一个字符串,需要进行下面的转换;
1)把空格变成换行
2)添加注释
比如你复制下来的公钥是:
ztPFg0D3tu7jLqCacgqL+lbshIaItDGEXAMZmKa3DV6Wxy+l48YMo0RyS+dWze4M
UmuxHU/v6tiT0ZTXJN3EwrjCtCyyttdv/ROB3CkheXnTKB76reTkQqg57OWW+m9j
TCoccYMDXEIWYTs3CwIDAQAB,那转换之后为:
-----BEGIN PUBLIC KEY-----
ztPFg0D3tu7jLqCacgqL+lbshIaItDGEXAMZmKa3DV6Wxy+l48YMo0RyS+dWze4M
UmuxHU/v6tiT0ZTXJN3EwrjCtCyyttdv/ROB3CkheXnTKB76reTkQqg57OWW+m9j
TCoccYMDXEIWYTs3CwIDAQAB
-----END PUBLIC KEY-----
把公钥保存在文件里。
注意这个是2048位的公钥应该是9行或者10行,不能为1行,不然PHP的openssl_pkey_get_public无法读取,pub_key_id的结果为false,如果没有-----BEGIN PUBLIC KEY----- 和 -----END PUBLIC KEY----- 可以自己加上,最后保存到一个rsa_public_key.pem文件中。
好了,现在已经有了所有的东西,先看签名函数:
复制代码
1 <?php
2 /**
3 * 签名字符串
4 * @param $prestr 需要签名的字符串
5 * return 签名结果
6 */
7 function rsaSign($prestr) {
8 $public_key= file_get_contents('rsa_private_key.pem');
9 $pkeyid = openssl_get_privatekey($public_key);
10 openssl_sign($prestr, $sign, $pkeyid);
11 openssl_free_key($pkeyid);
12 $sign = base64_encode($sign);
13 return $sign;
14 }
15 ?>
复制代码
注意点:
1.$prestr的内容和MD5一样(参见手册,但不包含最后的MD5密码)
2.签名用商户私钥
3.最后的签名,需要用base64编码
4.这个函数返回的值,就是这次请求的RSA签名。
验签函数:
复制代码
1 <?php
2 /**
3 * 验证签名
4 * @param $prestr 需要签名的字符串
5 * @param $sign 签名结果
6 * return 签名结果
7 */
8 function rsaVerify($prestr, $sign) {
9 $sign = base64_decode($sign);
10 $public_key= file_get_contents('rsa_public_key.pem');
11 $pkeyid = openssl_get_publickey($public_key);
12 if ($pkeyid) {
13 $verify = openssl_verify($prestr, $sign, $pkeyid);
14 openssl_free_key($pkeyid);
15 }
16 if($verify == 1){
17 return true;
18 }else{
19 return false;
20 }
21 }
22 ?>
复制代码
注意点:
1.$prestr的内容和MD5一样(参见手册)
2.$sign是支付宝接口返回的sign参数用base64_decode解码之后的二进制
3.验签用支付宝公钥
4.这个函数返回一个布尔值,直接告诉你,验签是否通过
支付宝官方提供的PHP版SDK demo中只对MD5加密方式进行了处理,但android 端和ios端 请求支付宝加密方式只能用RSA加密算法,这时服务端PHP就无法验证签名了,所以需要对demo进行一些修改。
1、修改alipay_notify.class.php文件
verifyNotify 函数第46行
$isSign = $this->getSignVeryfy($_POST, $_POST["sign"]);
改成
$isSign = $this->getSignVeryfy($_POST, $_POST["sign"], $_POST["sign_type"]);
verifyReturn 函数第83行
$isSign = $this->getSignVeryfy($_GET, $_GET["sign"]);
改成
$isSign = $this->getSignVeryfy($_GET, $_GET["sign"], $_GET["sign_type"]);
getSignVeryfy 函数 116行
function getSignVeryfy($para_temp, $sign) {
改成
function getSignVeryfy($para_temp, $sign, $sign_type) {
getSignVeryfy 函数 127行
switch (strtoupper(trim($this->alipay_config['sign_type']))) {
case "MD5" :
$isSgin = md5Verify($prestr, $sign, $this->alipay_config['key']);
break;
default :
$isSgin = false;
}
改成
switch (strtoupper(trim($sign_type))) {
case "MD5" :
$isSgin = md5Verify($prestr, $sign, $this->alipay_config['key']);
break;
case "RSA" :
$isSgin = rsaVerify($prestr, $sign);
break;
default :
$isSgin = false;
}
2、新建一个alipay_rsa.function.php文件
复制代码
1 <?php
2 /* *
3 * RSA
4 * 详细:RSA加密
5 * 版本:3.3
6 * 日期:2014-02-20
7 * 说明:
8 * 以下代码只是为了方便商户测试而提供的样例代码,商户可以根据自己网站的需要,按照技术文档编写,并非一定要使用该代码。
9 * 该代码仅供学习和研究支付宝接口使用,只是提供一个参考。
10 */
11 /**
12 * 签名字符串
13 * @param $prestr 需要签名的字符串
14 * return 签名结果
15 */
16 function rsaSign($prestr) {
17 $public_key= file_get_contents('rsa_private_key.pem');
18 $pkeyid = openssl_get_privatekey($public_key);
19 openssl_sign($prestr, $sign, $pkeyid);
20 openssl_free_key($pkeyid);
21 $sign = base64_encode($sign);
22 return $sign;
23 }
24 /**
25 * 验证签名
26 * @param $prestr 需要签名的字符串
27 * @param $sign 签名结果
28 * return 签名结果
29 */
30 function rsaVerify($prestr, $sign) {
31 $sign = base64_decode($sign);
32 $public_key= file_get_contents('rsa_public_key.pem');
33 $pkeyid = openssl_get_publickey($public_key);
34 if ($pkeyid) {
35 $verify = openssl_verify($prestr, $sign, $pkeyid);
36 openssl_free_key($pkeyid);
37 }
38 if($verify == 1){
39 return true;
40 }else{
41 return false;
42 }
43 }
44 ?>