手动实现支付宝手机支付

可以看到小破站的底部多了一个打赏的区域,点击支付后能够唤起支付宝实现打赏功能。
(暗示打钱)

功能介绍

当用户通过手机访问网站生成订单时,浏览器会跳转到支付宝网关,通过支付宝网关唤起APP来支付订单,支付完成后再跳转回原来的站点。

手机支付流程图

其中1.3发送支付请求官方有提供能快速实现功能的sdk,但只要了解请求的实现过程,完全可以自己手动实现。

前置工作

先到蚂蚁金服开放平台的沙箱环境注册一个应用,通过支付宝开放平台开发助手生成一对密钥,将公钥放到开放平台的密钥设置中。

请求实现过程

  1. 构建参数
  2. 生成签名
    2.1 去除参数名和值的前后空格
    2.2 去除空值参数
    2.3 去除sign参数
    2.4 参数排序
    2.5 参数签名
  3. 跳转页面

一、构建参数

将公共的参数写到公共类里,如:gatewayUrl(网关地址)、appId等。

<?php


class Aop
{
  public $gatewayUrl = 'https://openapi.alipay.com/gateway.do'; // 网关地址
  public $appId; // 应用id
  public $format = 'json'; // 请求参数格式,固定json
  public $charset = 'utf-8'; // 请求使用的编码格式
  public $signType = 'RSA2'; // 签名算法类型,官方推荐RSA2
  public $version = '1.0'; // 调用接口的版本号,固定1.0
  public $timestamp; // 请求的时间
  public $privateKey; // 私钥
}

每个订单不同的参数写到手机支付请求类里,如:methodbizContent等。

<?php


class AlipayTradeWapPay
{
  public $method = 'alipay.trade.wap.pay'; // 调用接口的名城,手机支付固定为这个
  public $productCode = 'QUICK_WAP_WAY'; // biz_content里面的参数,手机支付固定为这个
  public $bizContent; // 订单信息
  public $returnUrl; // 完成支付后跳转的页面
}

php对私钥的格式有一定的要求,并不是将工具生成的私钥复制过来就能用,需要稍微格式化一下,因此设置私钥写成函数。

<?php


class Aop
{
  // ...

  public function setPrivateKey ($privateKey) {
    $this->privateKey = "-----BEGIN RSA PRIVATE KEY-----\n" .
      chunk_split($privateKey, 64, "\n") .
      "-----END RSA PRIVATE KEY-----";
  }
}

同样,bizContent传入一个数组,需要加上productCode参数后转为json字符串。

<?php


class AlipayTradeWapPay
{
  // ...

  public function setBizContent ($bizContent) {
    $this->bizContent = json_encode(array_merge($bizContent, [
      'product_code' => $this->productCode
    ]));
  }
}

在公共类里面加一个函数,用来解析订单参数。

<?php


class Aop
{
  // ...

  /**
   * 解析请求
   * @param $request 订单参数
   */
  public function execute ($request) {
    // ...
  }
}

二、生成签名

首先要获取请求的参数。

<?php


class Aop
{
  // ...

  /**
   * 获取请求参数数据数组
   * @param $request 订单参数
   * @return array 请求数据
   */
  public function getData ($request) {
    return [
      'app_id' => $this->appId,
      'format' => $this->format,
      'charset' => $this->charset,
      'sign_type' => $this->signType,
      'timestamp' => $this->timestamp,
      'version' => $this->version,
      'method' => $request->method,
      'biz_content' => $request->bizContent,
      'return_url' => $request->returnUrl
    ];
  }
}

然后要将参数按照指定规则序列化。

<?php


class Aop
{
  // ...

  /**
   * 序列化请求参数数据
   * @param $data 请求参数数据
   * @return string 序列化后的参数
   */
  public function serData ($data) {
    $newData = [];
    foreach ($data as $k => $v) {
//      1、去除参数名和值前后的空格
      $key = trim($k);
      $value = trim($v);
//      2、去除空值参数
      if ($key && $value) {
        $newData[$key] = $value;
      }
    }
//    3、去除sign参数
    unset($newData['sign']);
//    4、按参数名排序
    ksort($newData);
//    5、拼凑序列化参数
    $para = '';
    foreach ($newData as $k => $v) {
      $para .= $k . "=$v&";
    }
    $para = substr($para, 0, -1);
    return $para;
  }
}

序列化后就可以对参数数据进行签名了。

<?php


class Aop
{
  // ...

  /**
   * 根据序列化参数数据进行签名
   * @param $para 序列化的参数数据
   * @return bool|string
   */
  public function getSign ($para) {
    openssl_sign($para, $sign, $this->privateKey, OPENSSL_ALGO_SHA256);
    return urlencode(base64_encode($sign));
  }
}

三、跳转页面

以上三个函数应用在execute中,将序列化参数和签名拼成get参数跳转到网关即可。

<?php


class Aop
{
  // ...

  /**
   * 解析请求
   * @param $request 订单参数
   */
  public function execute ($request) {
    $data = $this->getData($request);
    $para = $this->serData($data);
    $sign = $this->getSign($para);
//    跳转到支付宝网关
    $url = $this->gatewayUrl . '?' . $para . '&sign=' . $sign;
    header("Location:$url");
  }
}

如何使用

引入公共类和手机支付请求类,设置好参数后调用execute方法。

<?php

require_once 'Aop.php';
require_once 'requests/AlipayTradeWapPay.php';
require_once 'config.php';

$aop = new Aop();
$aop->gatewayUrl = $config['gatewayUrl'];
$aop->appId = $config['appId'];
$aop->timestamp = date('Y-m-d H:i:s');
$aop->setPrivateKey($config['privateKey']);

$request = new AlipayTradeWapPay();
$request->setBizContent([
  'out_trade_no' => microtime(true) * 10000,
  'subject' => '测试订单',
  'total_amount' => 9.99
]);
$request->returnUrl = 'http://.../paid.php';

$aop->execute($request);
手机支付效果

最后:

加入对话

4条评论

  1.   手动实现支付宝手机支付是怎么回事呢?手动实现支付宝相信大家都很熟悉,但是手动实现支付宝手机支付是怎么回事呢,下面就让小编带大家一起了解吧。
      手动实现支付宝手机支付,其实就是手动实现支付宝手机支付,大家可能会很惊讶手动实现支付宝怎么会手机支付呢?但事实就是这样,小编也感到非常惊讶。
      这就是关于手动实现支付宝手机支付的事情了,大家有什么想法呢,欢迎在评论区告诉小编一起讨论哦!

    1.   问题的关键究竟为何? 现在,解决手动实现支付宝手机支付的问题,是非常非常重要的。 所以, 莎士比亚曾经提到过,那脑袋里的智慧,就像打火石里的火花一样,不去打它是不肯出来的。带着这句话,我们还要更加慎重的审视这个问题: 既然如何, 一般来讲,我们都必须务必慎重的考虑考虑。 手动实现支付宝手机支付,到底应该如何实现。 所谓手动实现支付宝手机支付,关键是手动实现支付宝手机支付需要如何写。 洛克曾经说过,学到很多东西的诀窍,就是一下子不要学很多。这不禁令我深思。 俾斯麦说过一句富有哲理的话,对于不屈不挠的人来说,没有失败这回事。这句话语虽然很短,但令我浮想联翩。 就我个人来说,手动实现支付宝手机支付对我的意义,不能不说非常重大。 既然如此, 生活中,若手动实现支付宝手机支付出现了,我们就不得不考虑它出现了的事实。

  2. Yang老师,我看不懂哦,但这是不是和这个网站可以打赏关联支付宝一个原理呢?

    1. 是的,本破站打赏功能就是按这个流程实现的支付宝接入

留下评论

邮箱地址不会被公开。 必填项已用*标注

给博主打赏

2元 5元 10元