最近在做百度小程序,所以涉及到了平台的支付功能。
详细可以查看官方文档:https://smartprogram.baidu.com/docs/develop/api/open/payment_swan-requestPolymerPayment/
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;
}