//查询支付分是否支付
public function serviceorderServiceorder($out_order_no)
{
$setting = [];
$service_id = $setting['service_id'];
$sub_mchid = $setting['mchid'];
$ps = "/v3/payscore/partner/serviceorder?service_id=${service_id}&sub_mchid=${sub_mchid}&out_order_no=${out_order_no}";
$url = "https://api.mch.weixin.qq.com" . $ps;
$header = $this->getV3Sign('GET', $ps, "", $setting);
$res = $this->curl_post($url, [], $header, false);
$result = json_decode($res, true);
if ($result['state'] == "DONE") {
$need_collection = true;
} else {
$need_collection = false;
}
$transaction_id = $result['collection']['details'][0]['transaction_id'] ?? "";
$state = $result['state'];
return compact('state', 'need_collection', 'transaction_id');
}
//完成信用分订单
public function completeServiceorder($data)
{
$setting = [];
$data['money'] = (int)bcmul($data['money'], 100, 0);
$out_order_no = $data['order_no'];
$service_id = $setting['service_id'];
$sub_mchid = $setting['mchid'];
$post_payments = [[
'name' => '付款',
'amount' => $data['money']
]];
$time_range = [
'end_time' => date('Ymd', time())
];
$total_amount = $data['money'];
$url = "https://api.mch.weixin.qq.com/v3/payscore/partner/serviceorder/" . $out_order_no . "/complete";
$arr = [
'service_id' => $service_id,
'sub_mchid' => $sub_mchid,
'post_payments' => $post_payments,
'total_amount' => $total_amount,
'time_range' => $time_range
];
$arr = json_encode($arr);
$header = $this->getV3Sign('POST', "/v3/payscore/partner/serviceorder/" . $out_order_no . "/complete", $arr, $setting);
$res = $this->curl_post($url, $arr, $header);
$result = json_decode($res, true);
if (isset($result['message']) && $result['message']) {
\think\Log::error($result['message'] . "_" . $data['order_no']);
return false;
}
return true;
}
//取消信用分订单
public function cancelServiceorder($out_order_no)
{
$setting = [];
$service_id = $setting['service_id'];
$sub_mchid = $setting['mchid'];
$reason = "用户取消";
$arr = [
'service_id' => $service_id,
'sub_mchid' => $sub_mchid,
'reason' => $reason
];
$url = "https://api.mch.weixin.qq.com/v3/payscore/partner/serviceorder/{$out_order_no}/cancel";
$arr = json_encode($arr);
$header = $this->getV3Sign('POST', "/v3/payscore/partner/serviceorder/{$out_order_no}/cancel", $arr, $setting);
$res = $this->curl_post($url, $arr, $header);
$result = json_decode($res, true);
return $result;
}
//创建信用分订单
public function addServiceorder($data)
{
$setting = [];//数组数据
$service_id = $setting['service_id'];
$appid = $setting['main_gzh_app_id'];
$sub_appid = $setting['gzh_app_id'];
$sub_mchid = $setting['mchid'];
$out_order_no = $data['order_no'];
$service_introduction = "付款";//描述
$risk_fund = [
'name' => 'ESTIMATE_ORDER_COST',
'amount' => 10000
];
$time_range = [
'start_time' => date('Ymd', time())
];
$notify_url = $setting['zfj_notify_url'] ?? "";
$arr = [
'sub_appid' => $sub_appid,
'service_id' => $service_id,
'appid' => $appid,
'sub_mchid' => $sub_mchid,
'out_order_no' => $out_order_no,
'service_introduction' => $service_introduction,
'risk_fund' => $risk_fund,
'time_range' => $time_range,
'notify_url' => $notify_url,
'need_user_confirm' => true
];
$url = "https://api.mch.weixin.qq.com/v3/payscore/partner/serviceorder";
$arr = json_encode($arr);
$header = $this->getV3Sign('POST', '/v3/payscore/partner/serviceorder', $arr, $setting);
$res = $this->curl_post($url, $arr, $header);
$result = json_decode($res, true);
if (isset($result['message']) && $result['message']) {
throw new BaseException(['msg' => 'message: ' . $result['message']]);
}
$timestamp = time();
$nonce_str = getRandom(32);//随机串
$js_arr = [
'sign_type' => 'HMAC-SHA256',
'mch_id' => $result['mchid'],
'package' => $result['package'],
'timestamp' => $timestamp,
'nonce_str' => $nonce_str
];
$sign = $this->makeSign($js_arr, $setting['v3_apikey']);
$js_arr['sign'] = $sign;
ksort($js_arr);
$js_arr = $this->toUrlParams($js_arr);
$a_s = [
'order_id' => $result['order_id'],
'out_order_no' => $result['out_order_no'],
'package' => $result['package'],
'cont' => $js_arr
];
return $a_s;
}
/**
* 格式化参数格式化成url参数
* @param $values
* @return string
*/
public function toUrlParams($values)
{
$buff = '';
foreach ($values as $k => $v) {
if ($k != 'sign' && $v != '' && !is_array($v)) {
$buff .= $k . '=' . $v . '&';
}
}
return trim($buff, '&');
}
/**
* 生成签名
* @param $values
* @return string 本函数不覆盖sign成员变量,如要设置签名需要调用SetSign方法赋值
*/
public function makeSign($values, $key = null)
{
//签名步骤一:按字典序排序参数
ksort($values);
$string = $this->toUrlParams($values);
//签名步骤二:在string后加入KEY
$string = $string . '&key=' . $key;
$string = md5($string);
$string = hash_hmac("sha256", $string, $key);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
public function getV3Sign($http_method = 'POST', $url = '', $body = '', $config)
{
$mch_private_key = $config['key_pem'];
$timestamp = time();//时间戳
$nonce = getRandom(32);//随机串
//构造签名串
$message = $http_method . "\n" . $url . "\n" . $timestamp . "\n" . $nonce . "\n" . $body . "\n";
//计算签名值
openssl_sign($message, $raw_sign, $mch_private_key, 'SHA256');
$sign = base64_encode($raw_sign);
// echo $message;
// echo "
";
// echo $sign;exit;
//设置HTTP头
$token = sprintf('WECHATPAY2-SHA256-RSA2048 mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',
$config['main_mchid'], $nonce, $timestamp, $config['serial_no'], $sign);
$headers = [
'Accept: application/json',
'User-Agent: */*',
'Content-Type: application/json; charset=utf-8',
'Authorization: ' . $token,
];
return $headers;
}
Index.php
//免密自动支付
public function index()
{
$order_no = "订单号";
$rts = (new WxGzhPay())->addServiceorder([
'order_no' => $order_no
]);
$wx_js = "";//微信js参数
$this->assign('wx_js', $wx_js);
$this->assign('queryString', $rts);
return view();
}
html部分代码
wx.config({
debug: false, // 开启调试模式,调用的所有api的返回值会在客户端alert出来,若要查看传入的参数,可以在pc端打开,参数信息会通过log打出,仅在pc端时才会打印。
appId: '{$wx_js["appID"]}', // 必填,公众号的唯一标识
timestamp: '{$wx_js["timestamp"]}', // 必填,生成签名的时间戳
nonceStr: '{$wx_js["noncestr"]}', // 必填,生成签名的随机串
signature: '{$wx_js["signature"]}',// 必填,签名
jsApiList: ['openBusinessView'] // 必填,需要使用的JS接口列表
});
let wechatInfo = navigator.userAgent.match(/MicroMessenger\/([\d\.]+)/i);
let wechatVersion = wechatInfo[1];
if (compareVersion(wechatVersion, '7.0.5') >= 0) {
goToWXScore();
} else {
// 提示用户升级微信客户端版本
window.href = 'https://support.weixin.qq.com/cgi-bin/readtemplate?t=page/common_page__upgrade&text=text005&btn_text=btn_text_0'
}
let az_type = 1
if(/android/i.test(navigator.userAgent)){
az_type = 1
}
if(/(iPhone|iPad|iPod|iOS)/i.test(navigator.userAgent)){
az_type = 2
}
function goToWXScore() {
wx.ready(()=>{
wx.checkJsApi({
jsApiList: ['openBusinessView'], // 需要检测的JS接口列表
success: function (res) {
if (res.checkResult.openBusinessView) {
wx.invoke(
'openBusinessView', {
businessType: 'wxpayScoreUse',
queryString: 'package={$queryString["package"]}'
},
function (res) {
if(az_type==1){
if (parseInt(res.err_code) === 0) {
let r = JSON.parse(res.extraData)
if(!r.query_id){
//成功
}else {
//失败
}
} else {
//失败
}
}else{
let the_code = JSON.stringify(res['err_code'])
// 从微信侧小程序返回时会执行这个回调函数
if (parseInt(the_code) === 0) {
let r = JSON.stringify(res.extraData)
if(r=="{}"){
//失败
}else {
//成功
}
} else {
//失败
}
}
});
}
}
});
})
}