站长资讯网
最全最丰富的资讯网站

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

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

因为百度电商开放平台的升级,支付功能已移至智能小程序内部,具体申请流程:百度收银台支付开通指引,(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'    => '', // 支付回调地址 );

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

<?php include './BaiduPay.php'; $baidupay = new fengBaiduPay($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);             }         });     } });

四、支付回调

<?php include './BaiduPay.php'; $baidupay = new fengBaiduPay($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;     } }

赞(0)
分享到: 更多 (0)
网站地图   沪ICP备18035694号-2    沪公网安备31011702889846号