Baidu Payment (Baidu Smart Mini Program Payment) を書き換えてカプセル化する

藏色散人
リリース: 2021-09-12 16:16:50
転載
2789 人が閲覧しました

最近、プロジェクトの再構築により、Baidu Payment が書き換えられ、カプセル化されました。この書き換えでは、その後の開発と使用を容易にするために、署名処理とユーザー返金が追加されました。

Baidu 電子商取引オープン プラットフォームのアップグレードにより、支払い機能はスマート ミニ プログラムに移行されました。具体的な申請プロセスは次のとおりです: Baidu Cashier Payment Activation Guide (https://smartprogram.baidu) .com/docs/operations /transform/pay/)

(注: 決済サービスでは、サービスの電話番号に銀行が予約した携帯電話番号を入力する必要があります。入力が間違っている場合は、 、[銀行が予約した携帯電話番号形式の検証に失敗しました] が報告されます)

Baidu 支払いドキュメント: Baidu Cashier Interface 2.0 (https://smartprogram.baidu.com/docs/develop/function/tune_up_2.0/) )

1. アプリケーションが承認されたら、Baidu の支払い関連情報を入力します。構成:

$config = array(
    'deal_id'       => '', // 百度收银台的财务结算凭证
    'app_key'       => '', // 表示应用身份的唯一ID
    'private_key'   => '', // 私钥原始字符串
    'public_key'    => '', // 平台公钥
    'notify_url'    => '', // 支付回调地址
);
ログイン後にコピー

2. カプセル化された支払い方法を呼び出し、返された情報を Baidu ミニ プログラム

に渡します。
<?php
include &#39;./BaiduPay.php&#39;;
$baidupay = new \feng\BaiduPay($config);
$order_sn = time().rand(1000,9999);
$order = array(
    &#39;body&#39;          => &#39;测试商品&#39;, // 产品描述
    &#39;total_amount&#39;  => &#39;1&#39;, // 订单金额(分)
    &#39;order_sn&#39;      => $order_sn, // 订单编号
);
$re = $baidupay->xcxPay($order);
die(json_encode($re)); // JSON化直接返回小程序客户端
PHP
ログイン後にコピー

ミニ プログラム支払いクラス xcxPay:

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

3. Baidu Intelligence ミニ プログラムの使用

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: &#39;https://mbd.baidu.com/xxx&#39;, // 仅为示例,并非真实的接口地址,开发者从真实接口获取orderInfo的值
            success: res => {
                res.data.data.dealTitle = &#39;百度小程序Demo支付测试&#39;;
                let data = res.data;
                if (data.errno !== 0) {
                    console.log(&#39;create order err&#39;, data);
                    return;
                }
                swan.requestPolymerPayment({
                    orderInfo: data.data,
                    success: res => {
                        swan.showToast({
                            title: &#39;支付成功&#39;,
                            icon: &#39;success&#39;
                        });
                        console.log(&#39;pay success&#39;, res);
                    },
                    fail: err => {
                        swan.showToast({
                            title: err.errMsg,
                            icon: &#39;none&#39;
                        });
                        console.log(&#39;pay fail&#39;, err);
                    }
                });
            },
            fail: err => {
                swan.showToast({
                    title: &#39;订单创建失败&#39;,
                    icon: &#39;none&#39;
                });
                console.log(&#39;create order fail&#39;, err);
            }
        });
    }
});
ログイン後にコピー

4. 支払いコールバック

<?php
include &#39;./BaiduPay.php&#39;;
$baidupay = new \feng\BaiduPay($config);
$re = $baidupay->notify();
if ($re) {
    // 这里回调处理订单操作
    // 以验证返回支付成功后的信息,可直接对订单进行操作,已通知微信支付成功
    $baidupay->success(); // 支付返还成功,通知结果
} else {
    // 支付失败
    $baidupay->error(); // 支付失败,返回状态(无论支付成功与否都需要通知百度)
}
ログイン後にコピー

Baidu 完全な支払いクラス (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(
        &#39;deal_id&#39;       => &#39;&#39;, // 百度收银台的财务结算凭证
        &#39;app_key&#39;       => &#39;&#39;, // 表示应用身份的唯一ID
        &#39;private_key&#39;   => &#39;&#39;, // 私钥原始字符串
        &#39;public_key&#39;    => &#39;&#39;, // 平台公钥
        &#39;notify_url&#39;    => &#39;&#39;, // 支付回调地址
    );
    /**
     * [__construct 构造函数]
     * @param [type] $config [传递支付相关配置]
     */
    public function __construct($config=NULL){
        $config && self::$config = $config;
    }
    /**
     * [xcxPay 百度小程序支付]
     * @param  [type]  $order [订单信息数组]
     * @return [type]         [description]
     * $order = array(
     *      &#39;body&#39;          => &#39;&#39;, // 产品描述
     *      &#39;total_amount&#39;  => &#39;&#39;, // 订单金额(分)
     *      &#39;order_sn&#39;      => &#39;&#39;, // 订单编号
     * );
     */
    public static function xcxPay($order)
    {
        if(!is_array($order) || count($order) < 3)
            die("数组数据信息缺失!");
        $config = self::$config;
        $requestParamsArr = array(
            &#39;appKey&#39;    => $config[&#39;app_key&#39;],
            &#39;dealId&#39;    => $config[&#39;deal_id&#39;],
            &#39;tpOrderId&#39; => $order[&#39;order_sn&#39;],
            &#39;totalAmount&#39; => $order[&#39;total_amount&#39;],
        );
        $rsaSign = self::makeSign($requestParamsArr, $config[&#39;private_key&#39;]);  // 声称百度支付签名
        $bizInfo = array(
            &#39;tpData&#39; => array(
                "appKey"        => $config[&#39;app_key&#39;],
                "dealId"        => $config[&#39;deal_id&#39;],
                "tpOrderId"     => $order[&#39;order_sn&#39;],
                "rsaSign"       => $rsaSign,
                "totalAmount"   => $order[&#39;total_amount&#39;],
                "returnData"    => &#39;&#39;,
                "displayData"   => array(
                    "cashierTopBlock" => array(
                        array(
                            [ "leftCol" => "订单名称", "rightCol"   => $order[&#39;body&#39;] ],
                            [ "leftCol" => "数量", "rightCol" => "1" ],
                            [ "leftCol" => "订单金额", "rightCol"   => $order[&#39;total_amount&#39;] ]
                        ),
                        array(
                            [ "leftCol" => "服务地址", "rightCol" => "北京市海淀区上地十街10号百度大厦" ],
                            [ "leftCol" => "服务时间", "rightCol" => "2018/10/29 14:51" ],
                            [ "leftCol" => "服务人员", "rightCol" => "百度App" ]
                        )
                    )
                ),
                "dealTitle"     => $order[&#39;body&#39;],
                "dealSubTitle"  => $order[&#39;body&#39;],
                "dealThumbView" => "https://b.bdstatic.com/searchbox/icms/searchbox/img/swan-logo.png",
            ),
            "orderDetailData"   => &#39;&#39;
        );
        $bdOrder = array(
            &#39;dealId&#39;        => $config[&#39;deal_id&#39;],
            &#39;appKey&#39;        => $config[&#39;app_key&#39;],
            &#39;totalAmount&#39;   => $order[&#39;total_amount&#39;],
            &#39;tpOrderId&#39;     => $order[&#39;order_sn&#39;],
            &#39;dealTitle&#39;     => $order[&#39;body&#39;],
            &#39;signFieldsRange&#39; => 1,
            &#39;rsaSign&#39;       => $rsaSign,
            &#39;bizInfo&#39;       => json_encode($bizInfo),
        );
        return $bdOrder;
    }
    /**
     * [refund baidu支付退款]
     * @param  [type] $order [订单信息]
     * @param  [type] $type  [退款类型]
     * $order = array(
     *      &#39;body&#39;          => &#39;&#39;, // 退款原因
     *      &#39;total_amount&#39;  => &#39;&#39;, // 退款金额(分)
     *      &#39;order_sn&#39;      => &#39;&#39;, // 订单编号
     *      &#39;access_token&#39;  => &#39;&#39;, // 获取开发者服务权限说明
     *      &#39;order_id&#39;      => &#39;&#39;, // 百度收银台订单 ID
     *      &#39;user_id&#39;       => &#39;&#39;, // 百度收银台用户 id
     * );
     */
    public static function refund($order=[], $type=1)
    {
        $config = self::$config;
        $data = array(
            &#39;access_token&#39;      => $order[&#39;access_token&#39;], // 获取开发者服务权限说明
            &#39;applyRefundMoney&#39;  => $order[&#39;total_amount&#39;], // 退款金额,单位:分。
            &#39;bizRefundBatchId&#39;  => $order[&#39;order_sn&#39;], // 开发者退款批次
            &#39;isSkipAudit&#39;       => 1, // 是否跳过审核,不需要百度请求开发者退款审核请传 1,默认为0; 0:不跳过开发者业务方审核;1:跳过开发者业务方审核。
            &#39;orderId&#39;           => $order[&#39;order_id&#39;], // 百度收银台订单 ID
            &#39;refundReason&#39;      => $order[&#39;body&#39;], // 退款原因
            &#39;refundType&#39;        => $type, // 退款类型 1:用户发起退款;2:开发者业务方客服退款;3:开发者服务异常退款。
            &#39;tpOrderId&#39;         => $order[&#39;order_sn&#39;], // 开发者订单 ID
            &#39;userId&#39;            => $order[&#39;user_id&#39;], // 百度收银台用户 id
        );
        $array = [&#39;errno&#39;=>0, &#39;msg&#39;=>&#39;success&#39;, &#39;data&#39;=> [&#39;isConsumed&#39;=>2] ];
        $url = &#39;https://openapi.baidu.com/rest/2.0/smartapp/pay/paymentservice/applyOrderRefund&#39;;
        $response = self::post_curl($url, $data);
        $result = json_decode($response, true);
        // // 显示错误信息
        // if ($result[&#39;msg&#39;]!=&#39;success&#39;) {
        //     return false;
        //     // die($result[&#39;msg&#39;]);
        // }
        return $result;
    }
    /**
     * [notify 回调验证]
     * @return [array] [返回数组格式的notify数据]
     */
    public static function notify()
    {
        $data = $_POST; // 获取xml
        $config = self::$config;
        if (!$data || empty($data[&#39;rsaSign&#39;]))
            die(&#39;暂无回调信息&#39;);
        $result = self::checkSign($data, $config[&#39;public_key&#39;]); // 进行签名验证
        // 判断签名是否正确  判断支付状态
        if ($result && $data[&#39;status&#39;]==2) {
            return $data;
        } else {
            return false;
        }
    }
    /**
     * [success 通知支付状态]
     */
    public static function success()
    {
        $array = [&#39;errno&#39;=>0, &#39;msg&#39;=>&#39;success&#39;, &#39;data&#39;=> [&#39;isConsumed&#39;=>2] ];
        die(json_encode($array));
    }
    /**
     * [error 通知支付状态]
     */
    public static function error()
    {
        $array = [&#39;errno&#39;=>0, &#39;msg&#39;=>&#39;success&#39;, &#39;data&#39;=> [&#39;isErrorOrder&#39;=>1, &#39;isConsumed&#39;=>2] ];
        die(json_encode($array));
    }
    /**
     * [makeSign 使用私钥生成签名字符串]
     * @param  array  $assocArr     [入参数组]
     * @param  [type] $rsaPriKeyStr [私钥原始字符串,不含PEM格式前后缀]
     * @return [type]               [签名结果字符串]
     */
    public static function makeSign(array $assocArr, $rsaPriKeyStr)
    {
        $sign = &#39;&#39;;
        if (empty($rsaPriKeyStr) || empty($assocArr)) {
            return $sign;
        }
        if (!function_exists(&#39;openssl_pkey_get_private&#39;) || !function_exists(&#39;openssl_sign&#39;)) {
            throw new Exception("openssl扩展不存在");
        }
        $rsaPriKeyPem = self::convertRSAKeyStr2Pem($rsaPriKeyStr, 1);
        $priKey = openssl_pkey_get_private($rsaPriKeyPem);
        if (isset($assocArr[&#39;sign&#39;])) {
            unset($assocArr[&#39;sign&#39;]);
        }
        ksort($assocArr); // 参数按字典顺序排序
        $parts = array();
        foreach ($assocArr as $k => $v) {
            $parts[] = $k . &#39;=&#39; . $v;
        }
        $str = implode(&#39;&&#39;, $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[&#39;rsaSign&#39;]) || empty($assocArr) || empty($rsaPubKeyStr)) {
            return false;
        }
        if (!function_exists(&#39;openssl_pkey_get_public&#39;) || !function_exists(&#39;openssl_verify&#39;)) {
            throw new Exception("openssl扩展不存在");
        }
        $sign = $assocArr[&#39;rsaSign&#39;];
        unset($assocArr[&#39;rsaSign&#39;]);
        if (empty($assocArr)) {
            return false;
        }
        ksort($assocArr); // 参数按字典顺序排序
        $parts = array();
        foreach ($assocArr as $k => $v) {
            $parts[] = $k . &#39;=&#39; . $v;
        }
        $str = implode(&#39;&&#39;, $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 = &#39;&#39;;
        $begin = &#39;-----BEGIN &#39;;
        $end = &#39;-----END &#39;;
        $key = &#39; KEY-----&#39;;
        $type = $keyType ? &#39;RSA PRIVATE&#39; : &#39;PUBLIC&#39;;
        $keyPrefix = $begin . $type . $key;
        $keySuffix = $end . $type . $key;
        $rsaKeyPem .= $keyPrefix . "\n";
        $rsaKeyPem .= wordwrap($rsaKeyStr, $pemWidth, "\n", true) . "\n";
        $rsaKeyPem .= $keySuffix;
        if (!function_exists(&#39;openssl_pkey_get_public&#39;) || !function_exists(&#39;openssl_pkey_get_private&#39;)) {
            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=&#39;&#39;,$postData=&#39;&#39;,$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;
    }
}
ログイン後にコピー

以上がBaidu Payment (Baidu Smart Mini Program Payment) を書き換えてカプセル化するの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:fengkui.net
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート
私たちについて 免責事項 Sitemap
PHP中国語ウェブサイト:福祉オンライン PHP トレーニング,PHP 学習者の迅速な成長を支援します!