欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

支付宝接入流程

程序员文章站 2022-07-13 17:08:15
...

主要接入支付的支付功能,包括电脑网站支付、手机网站支付、APP支付、当面付。
使用语言:PHP
官方文档:https://doc.open.alipay.com/docs/doc.htm?treeId=193&articleId=105899&docType=1
支付宝接入流程


一、开发前的准备,参考官方文档

https://doc.open.alipay.com/docs/doc.htm?treeId=193&articleId=105894&docType=1


二、下载服务端SDK

https://doc.open.alipay.com/doc2/detail?treeId=54&articleId=103419&docType=1

三、沙箱环境调试
上线前先在沙箱环境下进行测试,支付宝提供了专门的沙箱APP,可以任意充值测试。

注意:使用沙箱环境测试时,需要使用沙箱环境中的相关参数。

四、服务端代码

>>>下载SDK后,删除不要的文件,放入自己的目录中,即可直接使用
支付宝接入流程

五、注意
>>>沙箱环境时有专门的key
>>>程序中使用的公钥是支付的公钥,不是自己生存的公钥。


>>>支付宝类,直接调用SDK中的代码,提供各种支付能力接口。
电脑网站支付:pay函数
手机完整支付:jsPay函数
APP接口:appApi函数,主要用于获取APP支付的相关参数(由于私钥存储在服务端,需要通过私钥加密相关参数)
当面付:generateQrCode函数,内部系统使用,生成当面付的支付二维码,发给客户让客户进行支付。

<?php

class Dg_Pay_Zhifubao
{

    /**
     * 支付网关
     *
     * @var string
     */
    private $gatewayUrl = 'https://openapi.alipay.com/gateway.do';

    /**
     * 异步通知URL
     * 
     * @var string
     */
    private $notifyUrl = 'https://www.baidu.com';

    /**
     * 支付后跳转地址
     * 
     * @var string
     */
    private $returnUrl = 'https://www.baidu.com';
    private $returnUrlM = 'https://www.baidu.com';

    /**
     * 支付宝分配的应用ID
     * 
     * @var string
     */
    private $appId = 'xxx';

    /**
     * 收款支付宝账号
     *
     * @var string
     */
    private $sellerEmail = '';

    /**
     * 卖家支付宝用户号
     *
     * @var string
     */
    private $sellerId = 'xxx';

    /**
     * 商户私钥
     * 
     * @var string
     */
    private $privateKey;
    private $privateKeyPath;

    /**
     * 支付宝公钥(此处是支付宝生成的公钥)
     * 
     * @var string
     */
    private $publicKey;
    private $publicKeyPath;

    /**
     * 签名方式
     *
     * @var string
     */
    private $signType = 'RSA2';

    /**
     * 返回值数据类型
     * 
     * @var string
     */
    private $format = 'json';

    /**
     * 请求编码
     * 
     * @var string
     */
    private $charset = 'utf-8';

    /**
     * 初始化支付参数
     *
     * @param string $out_trade_no
     *            订单号
     * @param double $total_fee
     *            交易金额
     * @param string $subject
     *            商品名称
     * @param string $body
     *            商品描述
     */
    public function __construct()
    {
        $this->privateKeyPath = dirname(__FILE__) . DS . 'zhifubao_private_key.pem';
        $this->publicKey = 'xxx';        
        //ToDo 沙箱测试参数
        if ( false ) {
            $this->gatewayUrl = 'https://openapi.alipaydev.com/gateway.do';
            $this->appId = 'xxx';
            $this->sellerId = 'xxx';
            $this->notifyUrl = 'https://www.baidu.com';
            $this->returnUrl = 'https://www.baidu.com';
            $this->returnUrlM = 'https://www.baidu.com';
            $this->publicKey = 'xxx';
        }
        //引入支付宝SDK
        include_once("alipay/AopSdk.php");
    }

    /**
     * 生成支付地址
     *
     * @return string
     */
    public function pay($out_trade_no, $total_fee, $subject = '缴费', $body = '缴费')
    {
        $client = new AopClient;
        $client->gatewayUrl = $this->gatewayUrl;
        $client->appId = $this->appId;
        $client->rsaPrivateKeyFilePath = $this->privateKeyPath;
        $client->alipayrsaPublicKey = $this->publicKey;
        $client->apiVersion = '1.0';
        $client->signType = $this->signType;
        $client->postCharset= $this->charset;
        $client->format = $this->format;
        
        $request = new AlipayTradePagePayRequest();
        $bizParam = array(
            'product_code' => 'FAST_INSTANT_TRADE_PAY',
            'out_trade_no' => $out_trade_no,
            'total_amount' => $total_fee,
            'subject'      => $subject,
            'body'         => $body,
            'seller_id'    => $this->sellerId,
        );
        $bizContent = json_encode($bizParam, JSON_UNESCAPED_UNICODE);
        $request->setBizContent($bizContent);
        $request->setNotifyUrl($this->notifyUrl);
        $request->setReturnUrl($this->returnUrl);
        $response = $client->pageExecute($request);
        //指定编码,360、qq浏览器下,浏览器没有设置为自动检测编码,会有问题。
        header("Content-type: text/html; charset=utf-8");
        echo $response;
    }

    /**
     * JS支付
     * 
     * @return array
     */
    public function jsPay($out_trade_no, $total_fee, $body, $wx_app = 'APP' , $platform = 'ios')
    {
        $client = new AopClient;
        $client->gatewayUrl = $this->gatewayUrl;
        $client->appId = $this->appId;
        $client->rsaPrivateKeyFilePath = $this->privateKeyPath;
        $client->alipayrsaPublicKey = $this->publicKey;
        $client->apiVersion = '1.0';
        $client->signType = $this->signType;
        $client->postCharset= $this->charset;
        $client->format = $this->format;

        $request = new AlipayTradeWapPayRequest();
        $bizParam = array(
            'product_code' => 'QUICK_WAP_PAY',
            'seller_id'    => $this->sellerId,
            'out_trade_no' => $out_trade_no,
            'total_amount' => $total_fee,
            'subject'      => $body,
            'body'         => $body,
        );
        $bizContent = json_encode($bizParam, JSON_UNESCAPED_UNICODE);
        $request->setBizContent($bizContent);
        $request->setNotifyUrl($this->notifyUrl);
        $request->setReturnUrl($this->returnUrlM);
        $response = $client->pageExecute($request);
        header("Content-type: text/html; charset=utf-8");
        echo $response;
    }

    /**
     * APP获得支付参数
     * 
     * @return array
     */
    public function appApi($out_trade_no, $total_fee, $body, $wx_app = 'APP' , $platform = 'ios')
    {
        $client = new AopClient;
        $client->gatewayUrl = $this->gatewayUrl;
        $client->appId = $this->appId;
        $client->rsaPrivateKeyFilePath = $this->privateKeyPath;
        $client->alipayrsaPublicKey = $this->publicKey;
        $client->format = $this->format;
        $client->charset = $this->charset;
        $client->signType = $this->signType;

        $request = new AlipayTradeAppPayRequest();
        $bizParam = array(
            'product_code' => 'QUICK_MSECURITY_PAY',
            'seller_id'    => $this->sellerId,
            'out_trade_no' => $out_trade_no,
            'total_amount' => $total_fee,
            'subject'      => $body,
            'body'         => $body,
        );
        $request->setNotifyUrl($this->notifyUrl);
        $bizContent = json_encode($bizParam, JSON_UNESCAPED_UNICODE);
        $request->setBizContent($bizContent);
        $response = $client->sdkExecute($request);
        //解析参数,此处返回字符串,APP需要json
        parse_str($response, $responseJson);
        //私钥
        $responseJson['private_key'] = $this->_getPrivateKey();
        return Dg_Helper_Common::initReturn(NO_ERROR, NO_ERROR, $responseJson);
    }

    /**
     * 生成支付二维码
     * 
     * @return array
     */
    public function generateQrCode($out_trade_no, $total_fee, $subject = '缴费', $body = '缴费')
    {
        $client = new AopClient;
        $client->gatewayUrl = $this->gatewayUrl;
        $client->appId = $this->appId;
        $client->rsaPrivateKeyFilePath = $this->privateKeyPath;
        $client->alipayrsaPublicKey = $this->publicKey;
        $client->apiVersion = '1.0';
        $client->format = $this->format;
        $client->postCharset = $this->charset;
        $client->signType = $this->signType;

        $request = new AlipayTradePrecreateRequest();
        $bizParam = array(
            'seller_id'    => $this->sellerId,
            'out_trade_no' => $out_trade_no,
            'total_amount' => $total_fee,
            'subject'      => $body,
            'body'         => $body,
        );
        $request->setNotifyUrl($this->notifyUrl);
        $bizContent = json_encode($bizParam, JSON_UNESCAPED_UNICODE);
        $request->setBizContent($bizContent);
        try {
            $response = $client->execute($request); //返回的是对象
            $response = json_decode(json_encode($response), true);
            if ( isset($response['alipay_trade_precreate_response']) && $response['alipay_trade_precreate_response']['code'] == '10000' ) {
                return Dg_Helper_Common::initReturn(NO_ERROR, NO_ERROR, $response['alipay_trade_precreate_response']);
            } else {
                return Dg_Helper_Common::initReturn(ERROR_COMMON , NO_ERROR , $response['alipay_trade_precreate_response']['msg'].' '.$response['alipay_trade_precreate_response']['sub_msg']);
            }
        } catch (Exception $e) {
            return Dg_Helper_Common::initReturn(ERROR_COMMON , NO_ERROR , $e->getMessage());
        }
    }

    /**
     * 验证签名
     * 
     * @param  array $data 支付宝返回的参数
     * @return bool
     */
    public function verify($data)
    {
        if ( $data['seller_id'] != $this->sellerId ) {
            return false;
        }
        if ( $data['app_id'] != $this->appId ) {
            return false;
        }

        $client = new AopClient;
        $client->alipayrsaPublicKey = $this->publicKey;
        $result = $client->rsaCheckV1($data, '', $this->signType);
        return $result;
    }

    /**
     * 获得私钥
     * 
     * @return string
     */
    private function _getPrivateKey()
    {
        $privateKey = '';
        if ( file_exists($this->privateKeyPath) ) {
            $privateKey = file_get_contents($this->privateKeyPath);
            $privateKey = str_replace(array('-----BEGIN RSA PRIVATE KEY-----','-----END RSA PRIVATE KEY-----'), '', $privateKey);
            $privateKey = str_replace("\r\n", '', $privateKey);
        }
        return $privateKey;
    }
}
?>