百度小程序发起支付、回调完整版

PHP 百度小程序支付,回调处理

  • 官方文档说明
  • 小程序实际代码
  • 服务端代码
  • 服务端支付回调

最近在做百度小程序,所以涉及到了平台的支付功能。

官方文档说明

  • 首先看一下百度小程序提供的参数组装:
    百度小程序发起支付、回调完整版_第1张图片

详细可以查看官方文档:https://smartprogram.baidu.com/docs/develop/api/open/payment_swan-requestPolymerPayment/

  • 在看下核心参数获取与组装
    百度小程序发起支付、回调完整版_第2张图片
  • 开发设置参数
    百度小程序发起支付、回调完整版_第3张图片

小程序实际代码

requestPolymerPayment(e) {
  // 请求服务器,生成订单,获取支付所需参数 
  swan.request({
      url: 'https://*****/createParam',
      success: res => {
          console.log(res) 
          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'
                  });
              },
              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);
      }
  });
}

先请求服务端,生成订单,然后返回百度支付所需参数
使用百度小程序内置的requestPolymerPayment 方法发起支付
参考文档:https://smartprogram.baidu.com/docs/develop/api/open/payment_swan-requestPolymerPayment/

服务端代码

/**
 * 构造参数 - 前端请求获取参数,在发起支付
 * @param string $body  订单的名称
 * @param int $total_fee // 订单金额
 * @param string $out_trade_no 商户平台自己记录的订单ID
 * @return array
 */
public function createParam($body='订单的名称',$total_fee=0,$out_trade_no='订单号'){
    if (empty($body) || !$total_fee || empty($out_trade_no)){
          return [];
     }
    $privateKey = '';
    $data = [
            'appKey' => '****',  // 支付能力开通后分配的支付appKey,用以表示应用身份的唯一ID,在应用审核通过后进行分配,一经分配后不会发生更改,来唯一确定一个应用
            'dealId' => '****',  // 跳转百度收银台支付必带参数之一,是百度收银台的财务结算凭证,与账号绑定的结算协议一一对应,每笔交易将结算到dealId对应的协议主体
            'tpOrderId' => $out_trade_no, 	// 商户平台自己记录的订单ID
            'totalAmount' => $total_fee,    // 订单总金额,以分为单位
        ];
        $data['rsaSign'] = $this->genSignWithRsa($data,$privateKey); // 对appKey+dealId+tpOrderId+totalAmount进行RSA加密后的签名,防止订单被伪造
        $data['dealTitle'] = $body; // 订单的名称
        $data['signFieldsRange'] = 1; // 固定值1
        $bizInfoArr = [
            "tpData" => [
                "appKey" => $data['appKey'],
                "dealId" => $data['dealId'],
                "tpOrderId" => $data['tpOrderId'],
                "rsaSign" =>  $data['rsaSign'],
                "totalAmount" => $data['totalAmount'],
                "returnData"=> [
                    "bizKey1"=> "第三方的字段1取值",
                    "bizKey2"=> "第三方的字段2取值"
                ]
            ],
        ];
        $data['bizInfo'] = json_encode($bizInfoArr); // 订单详细信息,需要是一个可解析为JSON Object的字符串 可以为空 {}
    return $data;
}

/**
 * 私钥生成签名字符串
 * @param array $assocArr
 * @param $priKey
 * @param bool $rsaPriKeyStr
 * @return string
 */
private function genSignWithRsa(array $assocArr,$priKey, $rsaPriKeyStr = true){
    $sign = '';
    if (empty($rsaPriKeyStr) || empty($assocArr)) {
        return $sign;
    }
    $priKey = chunk_split($priKey, 64, "\n");
    $priKey = "-----BEGIN RSA PRIVATE KEY-----\n$priKey-----END RSA PRIVATE KEY-----\n";
    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);
    return base64_encode($sign);
}

bizInfo,如果有值,必须可解析为JSON的字符串

服务端支付回调

 /********************************************
 * 百度小程序支付回调
  ********************************************/
 function baidu_notify(){
     $data =  $_POST;
     $userId     = $data['userId']; //百度用户ID
     $orderId    = $data['orderId']; //百度平台订单ID【幂等性标识参数】(用于重入判断)
     $unitPrice  = $data['unitPrice']; //单位:分
     $count      = $data['count']; //数量
     $totalMoney = $data['totalMoney']; //订单的实际金额,单位:分
     $payMoney   = $data['payMoney']; //扣除各种优惠后用户还需要支付的金额,单位:分
     $dealId     = $data['dealId']; //百度收银台的财务结算凭证
     $payTime    = $data['payTime']; //支付完成时间,时间戳
     $payType    = $data['payType']; //支付渠道值
     $partnerId  = $data['partnerId']; //支付平台标识值
     $status     = $data['status']; //1:未支付;2:已支付;-1:订单取消
     $tpOrderId  = $data['tpOrderId']; //业务方唯一订单号
     $returnData = $data['returnData']; //业务方下单时传入的数据
     $rsaSign    = $data['rsaSign']; //全部参数参与签名

     unset($data['rsaSign']); // rsaSign 不需要参与签名
     $data['sign'] = $rsaSign;
     $check_sign = $this->checkSignWithRsa($data);
     if ($check_sign){// 验签失败
         return 'failed';
     };

     if($status == 2) {
         // 如果订单已支付,进行业务处理并返回核销信息

         // 需要返回的响应
         $ret['errno'] = 0;
         $ret['msg']   = 'success';
         $ret['data']  = json_encode(['isConsumed'=>2]);
         echo json_encode($ret);
     }

 }

 /**
  * 公钥校验签名
  * @param array $assocArr
  * @param bool $rsaPubKeyStr
  * @return bool
  */
 private function checkSignWithRsa(array $assocArr ,$rsaPubKeyStr = true){
     if (!isset($assocArr['sign']) || empty($assocArr) || empty($rsaPubKeyStr)) {
         return false;
     }

     $sign = $assocArr['sign'];
     unset($assocArr['sign']);

     if (empty($assocArr)) {
         return false;
     }

     ksort($assocArr); //按字母升序排序
     $parts = array();
     foreach ($assocArr as $k => $v) {
         $parts[] = $k . '=' . $v;
     }
     $str    = implode('&', $parts);
     $sign   = base64_decode($sign);
     $pubKey = 'bd_pub_key';  // 公钥串
     $pubKey = chunk_split($pubKey, 64, "\n");
     $pubKey = "-----BEGIN PUBLIC KEY-----\n$pubKey-----END PUBLIC KEY-----\n";
     $result = (bool)openssl_verify($str, $sign,$pubKey);
     return $result;
 }

你可能感兴趣的:(小程序,PHP)