簡單介紹了支付寶即時到賬支付-即PC端支付的申請、接入、使用、確認支付結果等相關流程
0 系列文章
系列一 微信App支付全解析
系列二 支付寶App支付全解析
系列三 微信公眾號支付全解析
系列四 微信掃碼支付全解析
系列五 支付寶即時到賬支付全解析
系列六 微信退款全解析
系列七 支付寶退款全解析
系列八 支付寶開放平臺支付更新升級全解析
1 申請
登入支付寶商家服務,進入即時到賬支付。簽約。
簽約通過後,一共需要以下引數可以完成支付:
- partnerid
- sellerid
- rsa私鑰
- 支付寶公鑰
1.1 partnerid
商戶合作者身份。
進入我的商家服務
獲取pid
注:支付寶還有一個開放平臺,每個應用一個appid,一個pid可以有多個appid,但是移動支付、即時到賬收款、手機網站支付這三種支付渠道屬於只需要pid即可支付的支付方式,不需要申請應用
1.2 sellerid
登入支付寶賬戶,一般為郵箱或者手機號
1.3 rsa私鑰和支付寶公鑰
rsa私鑰公鑰是自己生成,然後將公鑰上傳支付寶,私鑰自己儲存。
詳見官網文件
2 接入流程
主要幾個步驟:
- 生成支付地址(放在服務端,需要生成簽名)
- 開啟地址跳轉支付寶收銀臺進行掃碼或者輸入密碼支付
- 服務端非同步接收支付結果
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例子,進行直接呼叫。
下載地址:doc.open.alipay.com/doc2/detail…
開啟其中服務端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 其他
- 客戶端收到同步支付結果後建議一段時間內輪詢檢查服務端,獲取服務端的結果,支付最終狀態以服務端為準
結尾
更多文章關注我的公眾號