支付宝App支付全解析
2016-07-11 本文已影响17562人
Tsy远
简单介绍了支付宝App支付的申请、接入、使用、确认支付结果等相关流程
0 系列文章
系列一 微信App支付全解析
系列二 支付宝App支付全解析
系列三 微信公众号支付全解析
系列四 微信扫码支付全解析
系列五 支付宝即时到账支付全解析
系列六 微信退款全解析
系列七 支付宝退款全解析
系列八 支付宝开放平台支付更新升级全解析
1 申请
登录支付宝商家服务,进入移动支付。签约。
签约通过后,一共需要以下参数可以完成支付:
- partnerid
- sellerid
- rsa私钥
- 支付宝公钥
1.1 partnerid
商户合作者身份。
进入我的商家服务
获取pid
注:支付宝还有一个开放平台,每个应用一个appid,一个pid可以有多个appid,但是移动支付、即时到账收款、手机网站支付这三种支付渠道属于只需要pid即可支付的支付方式,不需要申请应用
1.2 sellerid
登录支付宝账户,一般为邮箱或者手机号
1.3 rsa私钥和支付宝公钥
rsa私钥公钥是自己生成,然后将公钥上传支付宝,私钥自己保存。
详见官网文档
Paste_Image.png2 接入流程
主要几个步骤:
- 生成支付参数(放在服务端,需要生成签名)
- 调用客户端SDK发起支付
- 服务端异步接收支付结果
2.1 生成支付参数
$partner = ""; //你的pid
$seller_id = ""; //seller_id
$subject = "支付宝移动支付测试"; //交易主题
$body = "支付宝移动支付测试detail"; //交易详细说明
$total_fee = "0.01"; //支付金额 单位是元
$out_trade_no = ""; //自己业务系统生成的交易no,可以唯一标识
$rsa_path = ""; //rsa私钥路径
$notify_url = ""; //接收支付结果通知url
$data = array();
$data['service'] = "mobile.securitypay.pay";
$data['partner'] =$partner;
$data['_input_charset'] = "utf-8";
$data['notify_url'] = $notify_url;
$data['out_trade_no'] = $out_trade_no;
$data['subject'] = $subject;
$data['payment_type'] = "1";
$data['seller_id'] = seller_id;
$data['total_fee'] = $total_fee;
$data['body'] = $body;
//签名
$unsign_str =createLinkString(argSort($data));
$sign =rsaSign($unsign_str, $rsa_path);
$sign = urlencode(mb_convert_encoding($sign, "UTF-8")); //需要进行utf8格式转换
$pay_params = $unsign_str . "&sign=" . $sign . "&sign_type=RSA";
一些函数:
/**
* 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
* @param $para mixed 需要拼接的数组
* @return string 拼接完成以后的字符串
*/
public static function createLinkString($para) {
$arg = "";
while (list ($key, $val) = each ($para)) {
if($val == "") {
continue;
}
$arg.=$key."=".$val."&";
}
//去掉最后一个&字符
$arg = substr($arg,0,count($arg)-2);
//如果存在转义字符,那么去掉转义
if(get_magic_quotes_gpc()){
$arg = stripslashes($arg);
}
return $arg;
}
/**
* 数组排序 按照ASCII字典升序
* @param $para mixed 排序前数组
* @return mixed 排序后数组
*/
public static function argSort($para) {
ksort($para);
reset($para);
return $para;
}
/**
* RSA签名
* @param $data string 待签名数据
* @param $private_rsa_path string 用户私钥地址
* @return mixed
* 失败:false
* 成功:签名结果
*/
public static function rsaSign($data, $private_rsa_path) {
$private_rsa = file_get_contents($private_rsa_path);
$res = openssl_get_privatekey($private_rsa);
if(!$res) {
return false;
}
openssl_sign($data, $sign, $res);
openssl_free_key($res);
//base64编码
$sign = base64_encode($sign);
return $sign;
}
3. 调用支付
3.1 Android
可以直接参考调用我二次封装过的Android SDK。将生成的pay_param直接传入支付宝支付即可发起支付。
Github地址:https://github.com/tsy12321/PayAndroid
3.2 iOS
二次封装过的iOS SDK。
Github地址:https://github.com/tsy12321/PayiOS
4 异步结果通知
注:尤其要注意通知结果验证成功后要能正确处理重复通知,放置多次发货造成资金损失
验证签名可以直接下载支付宝sdk例子,进行直接调用。
下载地址:https://doc.open.alipay.com/doc2/detail.htm?treeId=54&articleId=104509&docType=1
打开其中服务端Demo将里面验证通知部分取出来使用。
$$alipay_partnerid = ""; //你的pid
$$alipay_public_key_path = ""; //支付宝公钥路径
$alipayNotify = new AlipayNotify($alipay_partnerid, $alipay_public_key_path);
$verify_result = $alipayNotify->verifyNotify();
if(!$verify_result) {
//签名验证失败 todo
die("fail");
}
//成功接收并验证了通知
echo("success");
if($_POST['trade_status'] !== "TRADE_SUCCESS" && $_POST['trade_status'] !== "TRADE_FINISHED") {
if($_POST['trade_status'] === "WAIT_BUYER_PAY") {
//wait bueyer pay通知可以忽略
die("success");
} else if($_POST['trade_status'] === "TRADE_CLOSED" && $_POST['refund_status'] === "REFUND_SUCCESS") { //全额退款也是成功
//当退款成功时 可能会触发通知closed的通知,也可以算作成功支付
} else { //支付失败
//支付失败处理 todo
}
}
//支付成功处理 发货
//todo
5 其他
- 客户端收到同步支付结果后建议一段时间内轮询检查服务端,获取服务端的结果,支付最终状态以服务端为准
结尾
更多文章关注我的公众号
我的公众号