重新对百度支付进行编写封装(百度智能小程序支付)

广告:宝塔服务器面板,一键全能部署及管理,送你10850元礼包,点我领取~~~

重新对百度支付进行编写封装(百度智能小程序支付)

最近因为项目重构的原因,对百度支付重新进行了编写封装,本次重写,添加了对签名的处理、添加用户退款,方便之后开发的使用。

因为百度电商开放平台的升级,支付功能已移至智能小程序内部,具体申请流程:百度收银台支付开通指引,(https://smartprogram.baidu.com/docs/operations/transform/pay/)

(注:在支付服务中,服务电话应填写银行预留手机号,如填写错误报【银行预留手机号码格式校验不通过】)

百度支付文档:百度收银台接口2.0(https://smartprogram.baidu.com/docs/develop/function/tune_up_2.0/)

一、申请通过后,填写百度支付相关配置:

$config = array(    'deal_id'       => '', // 百度收银台的财务结算凭证    'app_key'       => '', // 表示应用身份的唯一ID    'private_key'   => '', // 私钥原始字符串    'public_key'    => '', // 平台公钥    'notify_url'    => '', // 支付回调地址);
登录后复制

二、调用封装的支付方法,将返回信息,传递到百度小程序

<?phpinclude './BaiduPay.php';$baidupay = new \feng\BaiduPay($config);$order_sn = time().rand(1000,9999);$order = array(    'body'          => '测试商品', // 产品描述    'total_amount'  => '1', // 订单金额(分)    'order_sn'      => $order_sn, // 订单编号);$re = $baidupay->xcxPay($order);die(json_encode($re)); // JSON化直接返回小程序客户端PHP
登录后复制

小程序支付类 xcxPay:

/** * [xcxPay 百度小程序支付] * @param  [type]  $order [订单信息数组] * @return [type]         [description] * $order = array( *      'body'          => '', // 产品描述 *      'total_amount'  => '', // 订单金额(分) *      'order_sn'      => '', // 订单编号 * ); */public static function xcxPay($order){    if(!is_array($order) || count($order) < 3)        die("数组数据信息缺失!");    $config = self::$config;    $requestParamsArr = array(        'appKey'    => $config['app_key'],        'dealId'    => $config['deal_id'],        'tpOrderId' => $order['order_sn'],        'totalAmount' => $order['total_amount'],    );    $rsaSign = self::makeSign($requestParamsArr, $config['private_key']);  // 声称百度支付签名    $bizInfo = array(        'tpData' => array(            "appKey"        => $config['app_key'],            "dealId"        => $config['deal_id'],            "tpOrderId"     => $order['order_sn'],            "rsaSign"       => $rsaSign,            "totalAmount"   => $order['total_amount'],            "returnData"    => '',            "displayData"   => array(                "cashierTopBlock" => array(                    array(                        [ "leftCol" => "订单名称", "rightCol"   => $order['body'] ],                        [ "leftCol" => "数量", "rightCol" => "1" ],                        [ "leftCol" => "订单金额", "rightCol"   => $order['total_amount'] ]                    ),                    array(                        [ "leftCol" => "服务地址", "rightCol" => "北京市海淀区上地十街10号百度大厦" ],                        [ "leftCol" => "服务时间", "rightCol" => "2018/10/29 14:51" ],                        [ "leftCol" => "服务人员", "rightCol" => "百度App" ]                    )                )            ),            "dealTitle"     => $order['body'],            "dealSubTitle"  => $order['body'],            "dealThumbView" => "https://b.bdstatic.com/searchbox/icms/searchbox/img/swan-logo.png",        ),        "orderDetailData"   => ''    );    $bdOrder = array(        'dealId'        => $config['deal_id'],        'appKey'        => $config['app_key'],        'totalAmount'   => $order['total_amount'],        'tpOrderId'     => $order['order_sn'],        'dealTitle'     => $order['body'],        'signFieldsRange' => 1,        'rsaSign'       => $rsaSign,        'bizInfo'       => json_encode($bizInfo),    );    return $bdOrder;}
登录后复制

三、百度智能小程序端的使用

SWAN

<view class="wrap">    <view class="card-area">        <button bind:tap="requestPolymerPayment" type="primary" hover-stop-propagation="true">支付0.01元</button>    </view></view>HTML
登录后复制

JS

Page({    requestPolymerPayment(e) {        swan.request({            url: 'https://mbd.baidu.com/xxx', // 仅为示例,并非真实的接口地址,开发者从真实接口获取orderInfo的值            success: res => {                res.data.data.dealTitle = '百度小程序Demo支付测试';                let data = res.data;                if (data.errno !== 0) {                    console.log('create order err', data);                    return;                }                swan.requestPolymerPayment({                    orderInfo: data.data,                    success: res => {                        swan.showToast({                            title: '支付成功',                            icon: 'success'                        });                        console.log('pay success', res);                    },                    fail: err => {                        swan.showToast({                            title: err.errMsg,                            icon: 'none'                        });                        console.log('pay fail', err);                    }                });            },            fail: err => {                swan.showToast({                    title: '订单创建失败',                    icon: 'none'                });                console.log('create order fail', err);            }        });    }});
登录后复制

四、支付回调

<?phpinclude './BaiduPay.php';$baidupay = new \feng\BaiduPay($config);$re = $baidupay->notify();if ($re) {    // 这里回调处理订单操作    // 以验证返回支付成功后的信息,可直接对订单进行操作,已通知微信支付成功    $baidupay->success(); // 支付返还成功,通知结果} else {    // 支付失败    $baidupay->error(); // 支付失败,返回状态(无论支付成功与否都需要通知百度)}
登录后复制

百度完整支付类(BaiduPay.php),包含小程序支付、验签、回调、退款:

<?php/** * @Author: [FENG] <1161634940@qq.com> * @Date:   2020-09-27T16:28:31+08:00 * @Last Modified by:   [FENG] <1161634940@qq.com> * @Last Modified time: 2020-10-15T10:23:07+08:00 */namespace feng;class BaiduPay{    private static $config = array(        'deal_id'       => '', // 百度收银台的财务结算凭证        'app_key'       => '', // 表示应用身份的唯一ID        'private_key'   => '', // 私钥原始字符串        'public_key'    => '', // 平台公钥        'notify_url'    => '', // 支付回调地址    );    /**     * [__construct 构造函数]     * @param [type] $config [传递支付相关配置]     */    public function __construct($config=NULL){        $config && self::$config = $config;    }    /**     * [xcxPay 百度小程序支付]     * @param  [type]  $order [订单信息数组]     * @return [type]         [description]     * $order = array(     *      'body'          => '', // 产品描述     *      'total_amount'  => '', // 订单金额(分)     *      'order_sn'      => '', // 订单编号     * );     */    public static function xcxPay($order)    {        if(!is_array($order) || count($order) < 3)            die("数组数据信息缺失!");        $config = self::$config;        $requestParamsArr = array(            'appKey'    => $config['app_key'],            'dealId'    => $config['deal_id'],            'tpOrderId' => $order['order_sn'],            'totalAmount' => $order['total_amount'],        );        $rsaSign = self::makeSign($requestParamsArr, $config['private_key']);  // 声称百度支付签名        $bizInfo = array(            'tpData' => array(                "appKey"        => $config['app_key'],                "dealId"        => $config['deal_id'],                "tpOrderId"     => $order['order_sn'],                "rsaSign"       => $rsaSign,                "totalAmount"   => $order['total_amount'],                "returnData"    => '',                "displayData"   => array(                    "cashierTopBlock" => array(                        array(                            [ "leftCol" => "订单名称", "rightCol"   => $order['body'] ],                            [ "leftCol" => "数量", "rightCol" => "1" ],                            [ "leftCol" => "订单金额", "rightCol"   => $order['total_amount'] ]                        ),                        array(                            [ "leftCol" => "服务地址", "rightCol" => "北京市海淀区上地十街10号百度大厦" ],                            [ "leftCol" => "服务时间", "rightCol" => "2018/10/29 14:51" ],                            [ "leftCol" => "服务人员", "rightCol" => "百度App" ]                        )                    )                ),                "dealTitle"     => $order['body'],                "dealSubTitle"  => $order['body'],                "dealThumbView" => "https://b.bdstatic.com/searchbox/icms/searchbox/img/swan-logo.png",            ),            "orderDetailData"   => ''        );        $bdOrder = array(            'dealId'        => $config['deal_id'],            'appKey'        => $config['app_key'],            'totalAmount'   => $order['total_amount'],            'tpOrderId'     => $order['order_sn'],            'dealTitle'     => $order['body'],            'signFieldsRange' => 1,            'rsaSign'       => $rsaSign,            'bizInfo'       => json_encode($bizInfo),        );        return $bdOrder;    }    /**     * [refund baidu支付退款]     * @param  [type] $order [订单信息]     * @param  [type] $type  [退款类型]     * $order = array(     *      'body'          => '', // 退款原因     *      'total_amount'  => '', // 退款金额(分)     *      'order_sn'      => '', // 订单编号     *      'access_token'  => '', // 获取开发者服务权限说明     *      'order_id'      => '', // 百度收银台订单 ID     *      'user_id'       => '', // 百度收银台用户 id     * );     */    public static function refund($order=[], $type=1)    {        $config = self::$config;        $data = array(            'access_token'      => $order['access_token'], // 获取开发者服务权限说明            'applyRefundMoney'  => $order['total_amount'], // 退款金额,单位:分。            'bizRefundBatchId'  => $order['order_sn'], // 开发者退款批次            'isSkipAudit'       => 1, // 是否跳过审核,不需要百度请求开发者退款审核请传 1,默认为0; 0:不跳过开发者业务方审核;1:跳过开发者业务方审核。            'orderId'           => $order['order_id'], // 百度收银台订单 ID            'refundReason'      => $order['body'], // 退款原因            'refundType'        => $type, // 退款类型 1:用户发起退款;2:开发者业务方客服退款;3:开发者服务异常退款。            'tpOrderId'         => $order['order_sn'], // 开发者订单 ID            'userId'            => $order['user_id'], // 百度收银台用户 id        );        $array = ['errno'=>0, 'msg'=>'success', 'data'=> ['isConsumed'=>2] ];        $url = 'https://openapi.baidu.com/rest/2.0/smartapp/pay/paymentservice/applyOrderRefund';        $response = self::post_curl($url, $data);        $result = json_decode($response, true);        // // 显示错误信息        // if ($result['msg']!='success') {        //     return false;        //     // die($result['msg']);        // }        return $result;    }    /**     * [notify 回调验证]     * @return [array] [返回数组格式的notify数据]     */    public static function notify()    {        $data = $_POST; // 获取xml        $config = self::$config;        if (!$data || empty($data['rsaSign']))            die('暂无回调信息');        $result = self::checkSign($data, $config['public_key']); // 进行签名验证        // 判断签名是否正确  判断支付状态        if ($result && $data['status']==2) {            return $data;        } else {            return false;        }    }    /**     * [success 通知支付状态]     */    public static function success()    {        $array = ['errno'=>0, 'msg'=>'success', 'data'=> ['isConsumed'=>2] ];        die(json_encode($array));    }    /**     * [error 通知支付状态]     */    public static function error()    {        $array = ['errno'=>0, 'msg'=>'success', 'data'=> ['isErrorOrder'=>1, 'isConsumed'=>2] ];        die(json_encode($array));    }    /**     * [makeSign 使用私钥生成签名字符串]     * @param  array  $assocArr     [入参数组]     * @param  [type] $rsaPriKeyStr [私钥原始字符串,不含PEM格式前后缀]     * @return [type]               [签名结果字符串]     */    public static function makeSign(array $assocArr, $rsaPriKeyStr)    {        $sign = '';        if (empty($rsaPriKeyStr) || empty($assocArr)) {            return $sign;        }        if (!function_exists('openssl_pkey_get_private') || !function_exists('openssl_sign')) {            throw new Exception("openssl扩展不存在");        }        $rsaPriKeyPem = self::convertRSAKeyStr2Pem($rsaPriKeyStr, 1);        $priKey = openssl_pkey_get_private($rsaPriKeyPem);        if (isset($assocArr['sign'])) {            unset($assocArr['sign']);        }        ksort($assocArr); // 参数按字典顺序排序        $parts = array();        foreach ($assocArr as $k => $v) {            $parts[] = $k . '=' . $v;        }        $str = implode('&', $parts);        openssl_sign($str, $sign, $priKey);        openssl_free_key($priKey);        return base64_encode($sign);    }    /**     * [checkSign 使用公钥校验签名]     * @param  array  $assocArr     [入参数据,签名属性名固定为rsaSign]     * @param  [type] $rsaPubKeyStr [公钥原始字符串,不含PEM格式前后缀]     * @return [type]               [验签通过|false 验签不通过]     */    public static function checkSign(array $assocArr, $rsaPubKeyStr)    {        if (!isset($assocArr['rsaSign']) || empty($assocArr) || empty($rsaPubKeyStr)) {            return false;        }        if (!function_exists('openssl_pkey_get_public') || !function_exists('openssl_verify')) {            throw new Exception("openssl扩展不存在");        }        $sign = $assocArr['rsaSign'];        unset($assocArr['rsaSign']);        if (empty($assocArr)) {            return false;        }        ksort($assocArr); // 参数按字典顺序排序        $parts = array();        foreach ($assocArr as $k => $v) {            $parts[] = $k . '=' . $v;        }        $str = implode('&', $parts);        $sign = base64_decode($sign);        $rsaPubKeyPem = self::convertRSAKeyStr2Pem($rsaPubKeyStr);        $pubKey = openssl_pkey_get_public($rsaPubKeyPem);        $result = (bool)openssl_verify($str, $sign, $pubKey);        openssl_free_key($pubKey);        return $result;    }    /**     * [convertRSAKeyStr2Pem 将密钥由字符串(不换行)转为PEM格式]     * @param  [type]  $rsaKeyStr [原始密钥字符串]     * @param  integer $keyType   [0 公钥|1 私钥,默认0]     * @return [type]             [PEM格式密钥]     */    public static function convertRSAKeyStr2Pem($rsaKeyStr, $keyType = 0)    {        $pemWidth = 64;        $rsaKeyPem = '';        $begin = '-----BEGIN ';        $end = '-----END ';        $key = ' KEY-----';        $type = $keyType ? 'RSA PRIVATE' : 'PUBLIC';        $keyPrefix = $begin . $type . $key;        $keySuffix = $end . $type . $key;        $rsaKeyPem .= $keyPrefix . "\n";        $rsaKeyPem .= wordwrap($rsaKeyStr, $pemWidth, "\n", true) . "\n";        $rsaKeyPem .= $keySuffix;        if (!function_exists('openssl_pkey_get_public') || !function_exists('openssl_pkey_get_private')) {            return false;        }        if ($keyType == 0 && false == openssl_pkey_get_public($rsaKeyPem)) {            return false;        }        if ($keyType == 1 && false == openssl_pkey_get_private($rsaKeyPem)) {            return false;        }        return $rsaKeyPem;    }    /**     * curl post请求     * @param string $url 地址     * @param string $postData 数据     * @param array $header 头部     * @return bool|string     * @Date 2020/9/17 17:12     * @Author wzb     */    public static function post_curl($url='',$postData='',$header=[]){        $ch = curl_init($url);        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);        curl_setopt($ch, CURLOPT_POST, 1);        curl_setopt($ch, CURLOPT_HEADER, false);        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 5000);        curl_setopt($ch, CURLOPT_TIMEOUT, 5000);        if($header){            curl_setopt($ch, CURLOPT_HTTPHEADER,$header);        }        curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);        $result = curl_exec($ch);        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);        $curlErrNo = curl_errno($ch);        $curlErr = curl_error($ch);        curl_close($ch);        return $result;    }}
登录后复制

以上就是重新对百度支付进行编写封装(百度智能小程序支付)的详细内容,更多请关注9543建站博客其它相关文章!

9543建站博客
一个专注于网站开发、微信开发的技术类纯净博客。
作者头像
admin创始人

肥猫,知名SEO博客站长,14年SEO经验。

上一篇:选择yii框架的理由是什么
下一篇:详解使用Nodejs开发微信公众号后台服务功能实例(附代码)

发表评论

关闭广告
关闭广告