移动应用端的支付宝支付php开发流程

1https://openhome.alipay.com/ 支付宝开放平台并创建应用,审核通过后并签约app支付拿到pid

 

 

 

 

2按照官方文档用 RSA签名验签工具.bat】生成应用公钥和私钥

 

 

3、下载支付宝官方demohttps://docs.open.alipay.com/54/106370/根据自己的开发语言下载)包整合到项目中(说实话这个phpdemo着实有些坑)

整合好开始写支付宝支付类代码如下:

<?php
namespace data\extend;
use data\extend\alipay_app\aop\AopClient;
use data\extend\alipay_app\aop\request\AlipayTradeAppPayRequest as AlipayTradeAppPayRequest;
/**
 * 功能说明:自定义支付宝支付接入类
 */

class AliPayApp {

    protected $aop;
    /**
     * 初始化
     */
    public function __construct()
    {
        $this->aop    =    new AopClient();
        $this->aop->gatewayUrl             = "https://openapi.alipay.com/gateway.do";
        $this->aop->appId                 = "步骤一中拿到的应用appid";
        $this->aop->rsaPrivateKey         = "*******";//私有密钥(步骤二中生成的商户私有秘钥)
        $this->aop->format                 = "JSON";
        $this->aop->charset                = "utf-8";
        $this->aop->signType            = "RSA2";
        $this->aop->alipayrsaPublicKey     = "****";//商户公钥(步骤二中生成的商户公钥)
        $this->aop->alipayPublicKey        = "*****";//支付宝公钥
    }


    /**
     * 创建APP支付订单
     *
     * @param string $body 对一笔交易的具体描述信息。
     * @param string $subject 商品的标题/交易标题/订单标题/订单关键字等。
     * @param string $order_sn 商户网站唯一订单号
     * @return array 返回订单信息
     */
    public function createAppPay($order_sn,$body, $subject, $total_amount)
    {
        //实例化具体API对应的request类,类名称和接口名称对应,当前调用接口名称:alipay.trade.app.pay
        $request = new AlipayTradeAppPayRequest();
        //SDK已经封装掉了公共参数,这里只需要传入业务参数
        $bizcontent    =    [
            'body'                =>    $body,
            'subject'            =>    $subject,
            'out_trade_no'        =>    $order_sn,
            'timeout_express'    =>    '1d',//失效时间为 1天
            'total_amount'        =>    $total_amount,//价格
            'product_code'        =>    'QUICK_MSECURITY_PAY',
        ];
        //商户外网可以访问的异步地址 (异步回掉地址,根据自己需求写)
        $request->setNotifyUrl("http://".$_SERVER['HTTP_HOST']."/此处为回调通知地址");
        $request->setBizContent(json_encode($bizcontent));
        //这里和普通的接口调用不同,使用的是sdkExecute
        $response = $this->aop->sdkExecute($request);
        return $response;
        //htmlspecialchars是为了输出到页面时防止被浏览器将关键参数html转义,实际打印到日志以及http传输不会有这个问题
    }

    /**
     * 异步通知验签
     *
     * @param string $params 参数
     * @param string $signType 签名类型:默认RSA
     * @return bool 是否通过
     */
    public function rsaCheck($params, $signType)
    {
        return $this->aop->rsaCheckV1($params, NULL, $signType);
    }
   
    
}

 上面代码注意在调用 data\extend\alipay_app\aop\AopClient 这个类需要注意回调验签的过程调用 $this->aop->rsaCheckV1()这个类进行通知的sign和post回来的参数(此处需要主要验签过程按照官方要求去掉sign和sign_type后)重新组装+支付宝公钥($this->aop->alipayPublicKey切记不是应用公钥)代码稍作调整如下

 

/** rsaCheckV1 & rsaCheckV2
	 *  验证签名
	 *  在使用本方法前,必须初始化AopClient且传入公钥参数。
	 *  公钥是否是读取字符串还是读取文件,是根据初始化传入的值判断的。
	 **/
	public function rsaCheckV1($params, $rsaPublicKeyFilePath,$signType='RSA') {
		$sign = $params['sign'];
		$params['sign_type'] = null;
		$params['sign'] = null;
		return $this->verify($this->getSignContent($params), $sign, $rsaPublicKeyFilePath,$signType);
	}

    function verify($data, $sign, $rsaPublicKeyFilePath, $signType = 'RSA') {

		if($this->checkEmpty($this->alipayPublicKey)){

			$pubKey= $this->alipayrsaPublicKey;
			$res = "-----BEGIN PUBLIC KEY-----\n" .
				wordwrap($pubKey, 64, "\n", true) .
				"\n-----END PUBLIC KEY-----";
                //logWrite("商户RSA公钥".$res);
		}else {
		  //读取公钥文件(注释部分为原来)
           //$pubKey = file_get_contents($rsaPublicKeyFilePath);
           //转换为openssl格式密钥
           //$res = openssl_get_publickey($pubKey);

           //此处更改为支付宝公钥验签     $pubKey= $this->alipayPublicKey;     $res = "-----BEGIN PUBLIC KEY-----\n" .   wordwrap($pubKey, 64, "\n", true) .   "\n-----END PUBLIC KEY-----";     // logWrite("支付宝RSA公钥".$res); } ($res) or die('支付宝RSA公钥错误。请检查公钥文件格式是否正确'); //调用openssl内置方法验签,返回bool值      //logWrite("签名:".$sign); if ("RSA2" == $signType) { $result = (bool)openssl_verify($data, base64_decode($sign), $res, OPENSSL_ALGO_SHA256); } else { $result = (bool)openssl_verify($data, base64_decode($sign), $res); } if(!$this->checkEmpty($this->alipayPublicKey) && is_file($this->alipayPublicKey)) { //释放资源 openssl_free_key($res); }     //logWrite("验签结果:".var_export($result,true)); return $result; }

 

至此基本大功告成,最后一步是APP端的调用代码如下:

public function aliPayApp()
    {
        $out_trade_no = $this->GetReqArgc('out_trade_no');
        if (empty($out_trade_no)) {
            $this->error("没有获取到支付信息");
        }
        $data = $this->getPayInfo($out_trade_no);
        if($data < 0)
        {
            return $data;
        }
        $ali_pay = new AliPayApp();
        $retval = $ali_pay->createAppPay($out_trade_no, $data['pay_body'], $data['pay_detail'], $data['pay_money']);
        if($res){
            $this->ExitMessage(SUCCESS,"",array("out_trade_no"=>$out_trade_no,"retData"=>$res));
        }else{
            $this->ExitMessage(ERROR_CODE,"支付宝参数错误",0);
        }

    }

 

 以上接口返回给APP端后唤起快捷SDK创建订单并支付的参数后即可调起支付宝APP进行支付操作,最后就是通知处理支付结果的业务逻辑如下代码:

 public function payCallback(){
        $request    = input('post.');
        $pay = new AliPayApp();
        $verify = $pay->rsaCheck($params,$signType);
        if ($verify_result) { // 验证成功
            $out_trade_no = $request['out_trade_no'];
            // 支付宝交易号
            $trade_no = $request['trade_no'];
            // 交易状态
            $trade_status = $request['trade_status'];
            //logWrite("支付成功了");
            if ($trade_status == 'TRADE_FINISHED' || $trade_status == 'TRADE_SUCCESS') {

                //此处支付成功后的业务逻辑处理根据自己需求        

           	echo "success"; // 请不要修改或删除
            }
        } else {
            // 验证失败
            echo "fail";
        }
}

 ok大功告成!说实话支付宝支付还是比微信支付要好许多虽然也有坑,但微信支付的坑是比较多的! 

 

posted @ 2017-11-29 10:03  别安驹  阅读(3115)  评论(1编辑  收藏  举报