乐趣区

关于php:PHPLaravel支付宝支付和微信支付

<!– more –>

支付宝

注册

首先要注册两个平台账号,一个是支付宝商户平台,一个是支付宝开放平台,须要企业账号实名认证,收费。
没有条件的能够是用支付宝模仿沙箱进行测试。

开发前置
  1. 支付宝开放平台注册后,申请一个利用,取得 APPID,例如我要开发一个网站的领取,我就申请一个 网页 / 挪动利用 的利用。
  2. 支付宝商户平台注册后,取得商户 ID,而后将后面的 APPID 与商户 ID 绑定。
    3. 支付宝开放平台设置获取

    • 密钥(即:利用私钥、利用公钥、支付宝公钥),有两种,一种是公钥模式,一种是证书模式,公钥模式可不上传证书。

      • 利用网关(用来接管支付宝异步告诉信息)
        - 回调地址(领取后的回调,能够设置只验证域名)。
下载 SDK

返回官网下载 SDK,支付宝 SDK 有两种,一种是通用版,一种是 easy 版,简略来说通用版实用于非框架,easy 版实用于框架。

  1. 通用版:
    这里以 Laravel 为例,放入 /app/alipay 目录下(能够随本人喜爱换别的地位),而后 composer.json 里的 autoload 下 classmap 里退出一行 ”app/alipay” 来载入 SDK:
"classmap": ["app/alipay"]

之后在 CMD 里运行 composer dump-autoload 命令,就能够应用 SDK 了

composer dump-autoload
  1. easy 版:
    运行 composer 命令

    composer require alipaysdk/easysdk:^2.0
    配置信息

    在 config 目录里新建一个 alipay.php,在外面配置信息(在后面的支付宝开放平台都能够获取)

<?php
return [    
        // 利用 ID, 您的 APPID。'app_id' => "",

        // 商户私钥,您的原始格局 RSA 私钥
        'merchant_private_key' => "",
        
        // 异步告诉地址
        'notify_url' => "http:// 工程公网拜访地址 /alipay.trade.wap.pay-PHP-UTF-8/notify_url.php",
        
        // 同步跳转
        'return_url' => "http://mitsein.com/alipay.trade.wap.pay-PHP-UTF-8/return_url.php",

        // 编码格局
        'charset' => "UTF-8",

        // 签名形式
        'sign_type'=>"RSA2",
        
        // 接口加密 key(没有设置可不必)'screct_key' => '',

        // 支付宝网关
        'gatewayUrl' => "https://openapi.alipay.com/gateway.do",

        // 支付宝公钥, 查看地址:https://openhome.alipay.com/platform/keyManage.htm 对应 APPID 下的支付宝公钥。'alipay_public_key' => "",

        // 日志门路
        'log_path' => "",
];

ps:沙箱环境和正式环境网关不一样的

// 支付宝正式环境网关
'gatewayUrl' => "https://openapi.alipay.com/gateway.do",
// 支付宝沙箱环境网关
'gatewayUrl' => "https://openapi.alipaydev.com/gateway.do",
支付宝领取代码

这里以网站领取为例,可参考 SDK 文档

  1. 通用版

     $config = config("alipay");
     // 商户订单号,商户网站订单零碎中惟一订单号,必填
     $out_trade_no = time() . mt_rand(1111, 9999);
     // 订单名称,必填
     $subject = trim("Q 币订单领取");
    
     // 付款金额,必填
     $total_amount = 499;
    
     // 商品形容,可空
     $body = "EDG 皮肤大礼包";
    
     // 结构参数
     $payRequestBuilder = new AlipayTradePagePayContentBuilder();
     $payRequestBuilder->setBody($body);
     $payRequestBuilder->setSubject($subject);
     $payRequestBuilder->setTotalAmount($total_amount);
     $payRequestBuilder->setOutTradeNo($out_trade_no);
    
     $aop = new AlipayTradeService($config);
    
     /**
     * pagePay 电脑网站领取申请
     * @param $builder 业务参数,应用 buildmodel 中的对象生成。* @param $return_url 同步跳转地址,公网能够拜访
     * @param $notify_url 异步告诉地址,公网能够拜访
     * [[@return](https://learnku.com/users/31554)](https://learnku.com/users/31554) $response 支付宝返回的信息
     */
     return $aop->pagePay($payRequestBuilder,$config['return_url'],$config['notify_url']);
  2. easy 版

    //1. 设置参数(全局只需设置一次)$config = config('alipay');
             $options = new Config();
             $options->protocol = 'https';
             $options->gatewayHost = 'openapi.alipay.com';
             $options->signType = 'RSA2';
    
             $options->appId = $config['app_id'];
    
             // 为防止私钥随源码泄露,举荐从文件中读取私钥字符串而不是写入源码中
             $options->merchantPrivateKey = $config['merchant_private_key'];
             $options->gatewayHost = "openapi.alipaydev.com";
    
             $options->alipayPublicKey = $config['alipay_public_key'];
             // 可设置异步告诉接管服务地址(可选)$options->notifyUrl = $config['notify_url'];
    
             // 可设置 AES 密钥,调用 AES 加解密相干接口时须要(可选)// $options->encryptKey = $config['screct_key'];
             Factory::setOptions($options);
             try {
                 //2. 发动 API 调用(以领取能力下的对立收单交易创立接口为例)$result = Factory::payment()->page()->pay("iPhone6 16G", "2020423435526001", "88.88", $config['return_url']);
                 return $result->body;
             } catch (Exception $e) {echo "调用失败,". $e->getMessage(). PHP_EOL;;
             }

    其余调用办法能够在 alipaysdk 里找到 API 文档进行调用,例如手机网站 H5 领取:

    $result = Factory::payment()->wap()->pay("Q 币充值题目", "订单号", 88.88, "领取失败跳转 URL", "领取胜利同步跳转 URL");
    return $result->body;
    领取

    领取胜利后会跳转到之前配置的同步 GET 跳转 URL,而后支付宝会发送一个 POST 申请到异步告诉 URL。

    $params = $request->all();
    echo '购买胜利!';
    领取回调

    非必须,避免数据泄露被歹意调用接口。支付宝验签要将所有参数拼接成字符串验签,所以不要带入多余的参数。

  3. 通用版

     $params = $request->all();
     $config = config("alipay");
     $aop = new AlipayTradeService($config);
     $config = config("alipay");
      // 记得去除多余参数 params
     if($aop->check($params))
     {echo '验签胜利';}
  4. easy 版

     $config = config('alipay');
     $params = $request->all();
     $Signer = new Signer();
     // 记得去除多余参数 params
    $v = $Signer->verifyParams($params, $config['alipay_public_key']);
    if($v)
    {echo '验签胜利';}

    微信

    注册

    注册微信开放平台和微信商户平台。微信商户须要微信认证(领取 300 块钱)。
    注册实现后获取信息

下载 SDK

这里咱们间接应用 easywechat 工具来进行开发,因为咱们应用的是 Laravel,能够下载 easywechat 的 laravel 版本

composer require "overtrue/laravel-wechat:~5.0"
配置文件

运行命令

php artisan vendor:publish --provider="Overtrue\LaravelWeChat\ServiceProvider"

会在 config 目录生成 wechat.php
批改 wechat.php

 /*
     * 微信领取
     */
    'payment' => [
        'default' => ['sandbox'            => env('WECHAT_PAYMENT_SANDBOX', false),
            'app_id'             => env('WECHAT_PAYMENT_APPID', '你的 appid'),
            'mch_id'             => env('WECHAT_PAYMENT_MCH_ID', '你的商户 ID'),
            'key'                => env('WECHAT_PAYMENT_KEY', '你的 key'),
            'cert_path'          => env('WECHAT_PAYMENT_CERT_PATH', '/cert/apiclient_cert.pem'),    // XXX: 绝对路径!!!!'key_path'           => env('WECHAT_PAYMENT_KEY_PATH', '/cert/apiclient_key.pem'),      // XXX: 绝对路径!!!!'notify_url'         => 'http://www.baidu.com',                           // 默认领取后果告诉地址
        ],
        // ...
    ],
领取代码
类型

留神金额字段 total_fee 的数是要 *100 的,比方 1 块钱应该写 100,trade_type 类型是领取形式,其余形式为:

JSAPI–JSAPI 领取(或小程序领取)、NATIVE–Native 领取、APP–app 领取,MWEB–H5 领取,不同 trade_type 决定了调起领取的形式,请依据领取产品正确上传

扫码领取
$config = config('wechat.payment.default');
        $app = Factory::payment($config);
        $result = $app->order->unify([
            'body' => 'Q 币微信领取',
            'out_trade_no' => 随机生成的订单号,
            'total_fee' => 1 * 100,
            'trade_type' => 'NATIVE', // 请对应换成你的领取形式对应的值类型
        ]);
        $result['total'] = $data['total'];

        return $result;

这里我应用的是 Native 领取,会返回一个二维码,SDK 并不内置二维码生成库,应用你相熟的工具创立二维码即可,比方 PHP 局部有以下工具能够抉择

  • https://github.com/endroid/qr…
  • https://github.com/SimpleSoft…
  • https://github.com/aferrandin…
H5 领取
$config = config('wechat.payment.default');
        $app = Factory::payment($config);
        $result = $app->order->unify([
            'body' => 'Q 币微信领取',
            'out_trade_no' => 随机生成的订单号,
            'total_fee' => 1 * 100,
            'trade_type' => 'MWEB', // 请对应换成你的领取形式对应的值类型
        ]);
        $result['total'] = $data['total'];

        return redirect($result['mweb_url']);

这个是在非微信浏览器下进行的 H5 领取,如果要进行微信外部浏览器 H5 领取,须要应用 JSSDK 领取。

JSSDK 领取
  1. 先申请公众号,而后配置公众号信息
 /*
     * 公众号
     */
    'official_account' => [
        'default' => ['app_id'  => env('WECHAT_OFFICIAL_ACCOUNT_APPID', '你的 AppID'),         // AppID
            'secret'  => env('WECHAT_OFFICIAL_ACCOUNT_SECRET', '你的 secret'),    // AppSecret
            'token'   => env('WECHAT_OFFICIAL_ACCOUNT_TOKEN', '你的 token'),           // Token
            'aes_key' => env('WECHAT_OFFICIAL_ACCOUNT_AES_KEY', '你的 aes 加密 key')
            ]
    ]
  1. 用接口获取 openid。这里应用 easywechat 封装好的 user() 办法获取 openid,先通过 authorize 接口获取 code,而后通过 code 获取 openid,之后能够思考将 openid 存在 session 里,或者数据库等其余中央。
if ($request->has('code'))
{$config = config('wechat.official_account.default');
    $c = \EasyWeChat\Factory::officialAccount($config);
    $rs = $c->oauth->user();
    return redirect("你的订单页面?openid=" . $rs['original']['openid']);
}
// 获取 code
$currentUrl = urlencode(url()->current());
$url = "https://open.weixin.qq.com/connect/oauth2/authorize?appid=wxe96b27ac2a780cb1&redirect_uri={$currentUrl}&response_type=code&scope=snsapi_base&state=STATE&connect_redirect=1#wechat_redirect";
return redirect($url);
  1. 用后面获取的 openid 去下单,而后这里有三种 js 领取形式:WeixinJSBridge, JSSDK, 小程序
$config = config('wechat.payment.default');
$app = \EasyWeChat\Factory::payment($config);

$result = $app->order->unify([
    'body' => 'Q 币订单微信领取',
    'out_trade_no' => 随机生成的订单号,
    'total_fee' => 1 * 100,
    'trade_type' => 'JSAPI', // 请对应换成你的领取形式对应的值类型
    'openid' => $openid,
]);
// 未完待续 
  1. WeixinJSBridge
    PHP

    $json = $jssdk->bridgeConfig($prepayId); // 返回 json 字符串,如果想返回数组,传第二个参数 false

    JavaScript

    
    WeixinJSBridge.invoke(
           'getBrandWCPayRequest', $json,
           function(res){if(res.err_msg == "get_brand_wcpay_request:ok") {
                    // 应用以上形式判断前端返回, 微信团队郑重提醒:// res.err_msg 将在用户领取胜利后返回
                    // ok,但并不保障它相对牢靠。}
           }
       );
  2. JSSDK
    PHP

    $config = $jssdk->sdkConfig($prepayId); // 返回数组 

    JavaScript

    wx.chooseWXPay({timestamp: <?= $config['timestamp'] ?>,
        nonceStr: '<?= $config['nonceStr'] ?>',
        package: '<?= $config['package'] ?>',
        signType: '<?= $config['signType'] ?>',
        paySign: '<?= $config['paySign'] ?>', // 领取签名
        success: function (res) {// 领取胜利后的回调函数}
    });
  3. 小程序

    PHP

    $config = $jssdk->bridgeConfig($prepayId, false); // 返回数组 

    JavaScript

    wx.requestPayment({timeStamp: <?= $config['timeStamp'] ?>, // 留神 timeStamp 的格局
        nonceStr: '<?= $config['nonceStr'] ?>',
        package: '<?= $config['package'] ?>',
        signType: '<?= $config['signType'] ?>',
        paySign: '<?= $config['paySign'] ?>', // 领取签名
        success: function (res) {// 领取胜利后的回调函数}
    });
领取回调

微信领取胜利后会有一个领取回调,这里返回的是 XML,须要解析能力应用

$xml = $request->getContent();
$param = (array)simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA);
echo 'Q 币充值胜利';
退出移动版