编程 支付宝支付接口集成——手机网站支付单文件代码

2024-11-19 01:40:15 +0800 CST views 565

支付宝支付接口集成——手机网站支付单文件代码


/*** 配置结束 ***/
$aliPay = new AlipayService();
$aliPay->setAppid($ali_appid);
$aliPay->setReturnUrl($returnurl);
$aliPay->setNotifyUrl($notifyurl);
$aliPay->setRsaPrivateKey($ali_rsaPrivateKey);
$aliPay->setTotalFee($total_fee);
$aliPay->setOutTradeNo($sdorderno);
$aliPay->setOrderName("充值");
$aliPay->setpassbackparams($remark);
$sHtml = $aliPay->doPay();
echo $sHtml;
class AlipayService
{
    protected $appId;
    protected $charset;
    protected $returnUrl;
    protected $notifyUrl;
    //私钥值
    protected $rsaPrivateKey;
    protected $totalFee;
    protected $outTradeNo;
    protected $orderName;
    protected $passbackparams;
    public function __construct()
    {
        $this->charset = 'utf-8';
    }
    public function setAppid($appid)
    {
        $this->appId = $appid;
    }
    public function setpassbackparams($str)
    {
        $this->passbackparams = $str;
    }

    public function setReturnUrl($returnUrl)
    {
        $this->returnUrl = $returnUrl;
    }


    public function setNotifyUrl($notifyUrl)
    {
        $this->notifyUrl = $notifyUrl;
    }

    public function setRsaPrivateKey($rsaPrivateKey)
    {
        $this->rsaPrivateKey = $rsaPrivateKey;
    }

    public function setTotalFee($payAmount)
    {
        $this->totalFee = $payAmount;
    }

    public function setOutTradeNo($outTradeNo)
    {
        $this->outTradeNo = $outTradeNo;
    }

    public function setOrderName($orderName)
    {
        $this->orderName = $orderName;
    }

    /**
     * 发起订单
     * @return array
     */
    public function doPay()
    {
        //请求参数
        $requestConfigs = array(
            'out_trade_no'=>$this->outTradeNo,
            'product_code'=>'QUICK_WAP_WAY',
            'total_amount'=>$this->totalFee, //单位 元
            'subject'=>$this->orderName,  //订单标题
            "passback_params"=>urldecode($this->passbackparams)
        );
        $commonConfigs = array(
            //公共参数
            'app_id' => $this->appId,
            'method' => 'alipay.trade.wap.pay',             //接口名称
            'format' => 'JSON',
            'return_url' => $this->returnUrl,
            'charset'=>$this->charset,
            'sign_type'=>'RSA2',
            'timestamp'=>date('Y-m-d H:i:s'),
            'version'=>'1.0',
            'notify_url' => $this->notifyUrl,
            'biz_content'=>json_encode($requestConfigs),
        );
        $commonConfigs["sign"] = $this->generateSign($commonConfigs, $commonConfigs['sign_type']);
        return $this->buildRequestForm($commonConfigs);
    }
    /**
     * 建立请求,以表单HTML形式构造(默认)
     * @param $para_temp 请求参数数组
     * @return 提交表单HTML文本
     */
    protected function buildRequestForm($para_temp) {
        $sHtml = "<form id='alipaysubmit' name='alipaysubmit' action='https://openapi.alipay.com/gateway.do?charset=".$this->charset."' method='POST'>";
		foreach($para_temp as $key=>$val){
            if (false === $this->checkEmpty($val)) {
                $val = str_replace("'","&apos;",$val);
                $sHtml.= "<input type='hidden' name='".$key."' value='".$val."'/>";
            }		
		}
        //submit按钮控件请不要含有name属性
        $sHtml = $sHtml."<input type='submit' value='ok' style='display:none;''></form>";
        $sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";
        return $sHtml;
    }
    public function generateSign($params, $signType = "RSA") {
        return $this->sign($this->getSignContent($params), $signType);
    }
    protected function sign($data, $signType = "RSA") {
        $priKey=$this->rsaPrivateKey;
        $res = "-----BEGIN RSA PRIVATE KEY-----\n" .
            wordwrap($priKey, 64, "\n", true) .
            "\n-----END RSA PRIVATE KEY-----";
        ($res) or die('您使用的私钥格式错误,请检查RSA私钥配置');
        if ("RSA2" == $signType) {
            openssl_sign($data, $sign, $res, version_compare(PHP_VERSION,'5.4.0', '<') ? SHA256 : OPENSSL_ALGO_SHA256); //OPENSSL_ALGO_SHA256是php5.4.8以上版本才支持
        } else {
            openssl_sign($data, $sign, $res);
        }
        $sign = base64_encode($sign);
        return $sign;
    }
    /**
     * 校验$value是否非空
     *  if not set ,return true;
     *    if is null , return true;
     **/
    protected function checkEmpty($value) {
        if (!isset($value))
            return true;
        if ($value === null)
            return true;
        if (trim($value) === "")
            return true;
        return false;
    }
    public function getSignContent($params) {
        ksort($params);
        $stringToBeSigned = "";
        $i = 0;
        foreach ($params as $k => $v) {
            if (false === $this->checkEmpty($v) && "@" != substr($v, 0, 1)) {
                // 转换成目标字符集
                $v = $this->characet($v, $this->charset);
                if ($i == 0) {
                    $stringToBeSigned .= "$k" . "=" . "$v";
                } else {
                    $stringToBeSigned .= "&" . "$k" . "=" . "$v";
                }
                $i++;
            }
        }
        unset ($k, $v);
        return $stringToBeSigned;
    }
    /**
     * 转换字符集编码
     * @param $data
     * @param $targetCharset
     * @return string
     */
    function characet($data, $targetCharset) {
        if (!empty($data)) {
            $fileType = $this->charset;
            if (strcasecmp($fileType, $targetCharset) != 0) {
                $data = mb_convert_encoding($data, $targetCharset, $fileType);
                //$data = iconv($fileType, $targetCharset.'//IGNORE', $data);
            }
        }
        return $data;
    }
}

这段代码实现了通过支付宝的 WAP 支付接口发起支付请求的过程。以下是对代码各个部分的详细解析,帮助理解支付宝支付流程的实现。

一、主要流程

  1. 实例化支付对象
    代码一开始通过 $aliPay = new AlipayService(); 实例化 AlipayService 类,用来处理支付的相关逻辑。

  2. 设置支付相关参数
    支付宝支付接口需要一些关键信息来完成支付,包括:

    • AppID:支付宝开放平台上的应用ID。
    • Return URL:支付完成后,支付宝页面重定向的URL。
    • Notify URL:支付宝异步通知结果的回调地址。
    • RSA私钥:用于签名请求参数,确保支付安全。
    • Total Fee:订单金额。
    • Out Trade No:商户订单号。
    • Order Name:订单标题。
    • Passback Params:回传给商户的附加信息。
  3. 发起支付请求
    调用 $aliPay->doPay(); 发起支付请求,最终会生成一个提交支付宝支付的HTML表单,并自动提交表单,跳转到支付宝支付页面。

二、类结构分析

1. AlipayService 类的属性

  • $appId:支付宝分配给开发者的应用ID。
  • $charset:编码格式,默认为 utf-8
  • $returnUrl:支付完成后的同步通知地址。
  • $notifyUrl:支付结果的异步通知地址。
  • $rsaPrivateKey:商户生成的RSA私钥,用于签名。
  • $totalFee:订单金额。
  • $outTradeNo:商户订单号。
  • $orderName:订单名称。
  • $passbackparams:回传参数,支付成功后支付宝会原样返回该参数。

2. set 方法
该类提供了一些 set 方法,用于设置支付请求中的各个参数,如:

  • setAppid():设置支付宝应用ID。
  • setTotalFee():设置支付金额。
  • setOutTradeNo():设置商户订单号。
  • setOrderName():设置订单标题。
  • setpassbackparams():设置附加回传参数。

这些方法使得用户能够灵活地在实例化后设置支付请求参数。

3. doPay() 方法
这个方法是发起支付请求的核心,它构建了支付请求的参数,并调用了支付宝接口:

  • $requestConfigs:包含订单的主要信息,如订单号、金额、标题和回传参数。
  • $commonConfigs:包含支付宝支付接口的公共参数,如应用ID、接口方法、通知地址等。
  • generateSign():为请求参数生成签名,保证数据的完整性和安全性。

4. buildRequestForm() 方法
该方法生成了一个HTML表单,将请求参数通过表单的方式提交到支付宝支付网关,并通过JavaScript自动提交表单。这是WAP支付的一种常见方式。

5. generateSign()sign() 方法
这两个方法负责生成支付请求的签名:

  • generateSign():首先将参数排序并生成待签名的字符串。
  • sign():使用RSA私钥对字符串进行签名。

6. getSignContent() 方法
该方法将请求参数按字典序排序并生成待签名的字符串,确保签名的内容是有序的,符合支付宝的签名规范。

7. checkEmpty() 方法
这是一个工具方法,用来检查参数值是否为空,以避免提交空值的参数影响签名和支付请求。

8. characet() 方法
该方法用于转换字符集编码,确保提交给支付宝的参数符合 charset 要求(默认是 utf-8)。

三、关键代码详解

  1. 签名生成
    支付宝的支付请求必须经过签名,以确保数据的安全性和完整性。代码中的 generateSign() 方法通过将请求参数进行排序并拼接成字符串,再用商户的RSA私钥进行签名来完成这一过程。

    public function generateSign($params, $signType = "RSA") {
         return $this->sign($this->getSignContent($params), $signType);
    }
    
  2. 自动提交支付表单
    代码中 buildRequestForm() 方法构建了支付请求的表单,并且通过以下代码自动提交表单,跳转到支付宝支付页面:

    $sHtml = $sHtml."<script>document.forms['alipaysubmit'].submit();</script>";
    
  3. 回传参数处理
    支付宝在支付成功后会将商户传入的 passback_params 原样返回给商户,这对于支付后处理业务逻辑非常有用。代码通过 urldecode() 对该参数进行了处理。

    "passback_params"=>urldecode($this->passbackparams)
    

四、总结

这段代码展示了如何通过支付宝WAP支付接口实现支付功能。它通过设置一系列参数,构建签名,生成表单并自动提交到支付宝支付网关。整个流程的核心在于生成请求参数并对其进行签名,以确保安全性。通过异步通知或同步通知,商户能够获得支付结果并进行进一步的业务处理。

这段代码设计得较为清晰,分工明确,扩展性强。

复制全文 生成海报 支付 支付宝 接口集成

推荐文章

介绍Vue3的Tree Shaking是什么?
2024-11-18 20:37:41 +0800 CST
Nginx 如何防止 DDoS 攻击
2024-11-18 21:51:48 +0800 CST
一些好玩且实用的开源AI工具
2024-11-19 09:31:57 +0800 CST
15 个 JavaScript 性能优化技巧
2024-11-19 07:52:10 +0800 CST
thinkphp分页扩展
2024-11-18 10:18:09 +0800 CST
批量导入scv数据库
2024-11-17 05:07:51 +0800 CST
Linux 常用进程命令介绍
2024-11-19 05:06:44 +0800 CST
微信小程序热更新
2024-11-18 15:08:49 +0800 CST
在 Nginx 中保存并记录 POST 数据
2024-11-19 06:54:06 +0800 CST
Vue3中如何处理组件间的动画?
2024-11-17 04:54:49 +0800 CST
Golang Select 的使用及基本实现
2024-11-18 13:48:21 +0800 CST
php常用的正则表达式
2024-11-19 03:48:35 +0800 CST
html一些比较人使用的技巧和代码
2024-11-17 05:05:01 +0800 CST
Hypothesis是一个强大的Python测试库
2024-11-19 04:31:30 +0800 CST
CSS 奇技淫巧
2024-11-19 08:34:21 +0800 CST
markdowns滚动事件
2024-11-19 10:07:32 +0800 CST
Vue3中的JSX有什么不同?
2024-11-18 16:18:49 +0800 CST
thinkphp swoole websocket 结合的demo
2024-11-18 10:18:17 +0800 CST
程序员茄子在线接单