码无界前端码无界IOS And Android程序员

支付宝即时到账支付全解析

2016-07-11  本文已影响1963人  Tsy远

简单介绍了支付宝即时到账支付-即PC端支付的申请、接入、使用、确认支付结果等相关流程

0 系列文章

系列一 微信App支付全解析
系列二 支付宝App支付全解析
系列三 微信公众号支付全解析
系列四 微信扫码支付全解析
系列五 支付宝即时到账支付全解析
系列六 微信退款全解析
系列七 支付宝退款全解析
系列八 支付宝开放平台支付更新升级全解析

1 申请

登录支付宝商家服务,进入即时到账支付。签约。

签约通过后,一共需要以下参数可以完成支付:

  1. partnerid
  2. sellerid
  3. rsa私钥
  4. 支付宝公钥

1.1 partnerid

商户合作者身份。

进入我的商家服务
获取pid

Paste_Image.png

注:支付宝还有一个开放平台,每个应用一个appid,一个pid可以有多个appid,但是移动支付、即时到账收款、手机网站支付这三种支付渠道属于只需要pid即可支付的支付方式,不需要申请应用

1.2 sellerid

登录支付宝账户,一般为邮箱或者手机号

1.3 rsa私钥和支付宝公钥

rsa私钥公钥是自己生成,然后将公钥上传支付宝,私钥自己保存。

详见官网文档

Paste_Image.png

2 接入流程

参考支付宝移动支付接入文档

主要几个步骤:

  1. 生成支付地址(放在服务端,需要生成签名)
  2. 打开地址跳转支付宝收银台进行扫码或者输入密码支付
  3. 服务端异步接收支付结果

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

$MAPI_GATEWAY = "https://mapi.alipay.com/gateway.do";    //mapi 入口 路由

$data = array();
$data['service'] = "create_direct_pay_by_user"; 
$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);

$params = createLinkstringUrlencode($data);

$url = $MAPI_GATEWAY . '?' . $params;

一些函数:

/**
 * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串
 * @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;
  }

/**
 * 把数组所有元素,按照“参数=参数值”的模式用“&”字符拼接成字符串 并对字符串做urlencode编码
 * @param $para mixed 需要拼接的数组
 * @return string 拼接完成以后的字符串
 */
public static function createLinkstringUrlencode($para) {    
  $arg  = "";    
  while (list ($key, $val) = each ($para)) {        
    if($val == "") {            
      continue;        
    }        
    $arg.=$key."=".urlencode($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 异步结果通知

注:尤其要注意通知结果验证成功后要能正确处理重复通知,放置多次发货造成资金损失

验证签名可以直接下载支付宝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 其他

  1. 客户端收到同步支付结果后建议一段时间内轮询检查服务端,获取服务端的结果,支付最终状态以服务端为准

结尾

更多文章关注我的公众号


我的公众号
上一篇下一篇

猜你喜欢

热点阅读