/**html**/
/**
*JSAPI支付
**/
function onBridgeReady(result) {
alert( result.appId );
alert( result.timeStamp );
alert( result.nonceStr );
alert( result.package );
alert( result.signType );
alert( result.paySign );
WeixinJSBridge.invoke('getBrandWCPayRequest', {
"appId" : result.appId, //公众号ID,由商户传入
"timeStamp": result.timeStamp, //时间戳,自1970年以来的秒数
"nonceStr" : result.nonceStr, //随机串
"package" : result.package,
"signType" : result.signType, //微信签名方式:
"paySign" : result.paySign, //微信签名
},
function (res) {
alert( JSON.parse(res) );
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
}
});
}
//****?
<?php
/**
* WeChat pay
* 库和SDK wechatpay-guzzle-middleware
* User:wang jian
* Date:2021.12.24
*/
namespace App\Library;
use GuzzleHttp\Exception\RequestException;
use WechatPay\GuzzleMiddleware\WechatPayMiddleware;
use WechatPay\GuzzleMiddleware\Util\PemUtil;
use GuzzleHttp\HandlerStack;
class WeChatTwo
{
private static $merchantId; //微信_商户号
private static $appid; //微信开放平台_appid
private static $appkey; //微信开放平台_appkey
private static $merchantCertificateSerial; //微信_商户API证书序列号
private static $apiv3key; //微信_APIV3密钥
private static $merchantPrivateKeyFilePath; //微信_商户API证书私钥
private static $platformCertificateFilePath; //微信_支付平台证书_初始生成——其它加载
private static $upload_img_api; //图片上传接APIurl
private static $client;
public function __construct()
{
WeChatTwo::$merchantId = config('wechat.merchantId'); //微信_商户号
WeChatTwo::$appid = config('wechat.appid'); //微信开放平台_appid
WeChatTwo::$appkey = config('wechat.appkey'); //微信开放平台_appkey
WeChatTwo::$apiv3key = config('wechat.apiv3key'); //微信开放平台_appkey
WeChatTwo::$merchantCertificateSerial = config('wechat.merchantCertificateSerial'); //微信_商户API证书序列号
WeChatTwo::$merchantPrivateKeyFilePath = storage_path('cert'.DIRECTORY_SEPARATOR.'wechat'.DIRECTORY_SEPARATOR.'4C1BBE189365B735FF1B7AE9A63EDCB7CDA49093'.DIRECTORY_SEPARATOR.'apiclient_key.pem');//商户API证书私钥
WeChatTwo::$platformCertificateFilePath = storage_path('cert'.DIRECTORY_SEPARATOR.'wechat'.DIRECTORY_SEPARATOR.'4C1BBE189365B735FF1B7AE9A63EDCB7CDA49093'.DIRECTORY_SEPARATOR.'wechatpay_67BD0BB346B4ABD494092F0F7FCF507A42E48A1E.pem');//微信_支付平台证书_初始生成——其它加载
WeChatTwo::$upload_img_api = 'https://api.mch.weixin.qq.com/v3/merchant/media/upload'; //图片上传接API url
WeChatTwo::$client = WeChatTwo::instanceWeChatPay();
}
/**
* 构建一个客户端实例
* wechatpay-guzzle-middleware,适用于PHP开发者
*/
public static function instanceWeChatPay(){
// 商户相关配置,
$merchantId = WeChatTwo::$merchantId; // 商户号
$merchantSerialNumber = WeChatTwo::$merchantCertificateSerial; // 商户API证书序列号
$merchantPrivateKey = PemUtil::loadPrivateKey(WeChatTwo::$merchantPrivateKeyFilePath); // 商户私钥文件路径
// 微信支付平台配置
$wechatpayCertificate = PemUtil::loadCertificate(WeChatTwo::$platformCertificateFilePath); // 微信支付平台证书文件路径
// 构造一个WechatPayMiddleware
$wechatpayMiddleware = WechatPayMiddleware::builder()
->withMerchant($merchantId, $merchantSerialNumber, $merchantPrivateKey) // 传入商户相关配置
->withWechatPay([ $wechatpayCertificate ]) // 可传入多个微信支付平台证书,参数类型为array
->build();
// 将WechatPayMiddleware添加到Guzzle的HandlerStack中
$stack =\GuzzleHttp\HandlerStack::create();
$stack->push($wechatpayMiddleware, 'wechatpay');
// 创建Guzzle HTTP Client时,将HandlerStack传入,接下来,正常使用Guzzle发起API请求,WechatPayMiddleware会自动地处理签名和验签
//WeChatTwo::$client = new \GuzzleHttp\Client(['handler' => $stack]);
return new \GuzzleHttp\Client(['handler' => $stack]);
}
/**
* JSAPI支付下单
* 同步请求
* @param $out_trade_no
* @param $description
* @param $total
*/
public function JsapiSyncWeChatPay($total,$description,$notify_url,$out_trade_no,$openid,$attach ='')
{
$data = [];
try {
if(!$total || !$description || !$notify_url || !$out_trade_no || !$openid){
$data['statusCode'] = 400;
$data['msg'] = '缺少必要参数,稍后再试';
return $data;
}
$time_expire = date("Y-m-d\TH:i:s\Z",strtotime("30*60 seconds") );
$order = [
"time_expire" => $time_expire, //交易结束时间--订单失效时间
"mchid" => WeChatTwo::$merchantId, //直连商户号 Required
"appid" => WeChatTwo::$appid, //应用ID Required
"notify_url" => $notify_url, //通知地址 Required
"out_trade_no"=> $out_trade_no, //商户订单号 Required
"amount" => ["total" => $total,"currency" => "CNY"], //订单金额信息 Required
"description" => $description, //商品描述 Required
"payer" => [
"openid" => $openid, //获取微信用户的$openid
],
//"attach" => "自定义数据说明", //附加数据
];
$timestamp = time();
$nonce = WeChatTwo::getNonceStr();
$url ="https://api.mch.weixin.qq.com/v3/pay/transactions/jsapi";
$resp = WeChatTwo::$client->request(
'POST',
$url, //请求URL
[
// JSON请求体
'json' => $order,
'headers' => [
'Accept' => 'application/json',
'Authorization' => 'WECHATPAY2-SHA256-RSA2048'.WeChatTwo::SignatureGenerate ($url, "POST", "",$timestamp,$nonce),
]
]
);
$statusCode = $resp->getStatusCode();
if ($statusCode == 200) { //处理成功
$getContents = json_decode($resp->getBody()->getContents());
$body['appId'] = WeChatTwo::$appid; //公众号ID,由商户传入
$body['timeStamp'] = $timestamp; //时间戳
$body['nonceStr'] = $nonce; //随机串
$body['package'] = "prepay_id=" . $getContents->prepay_id;
$body['signType'] = "RSA"; //微信签名方式:
$body['paySign'] = WeChatTwo::paySign($url, "POST", $body['package'],$timestamp,$nonce); //微信签名
$data['msg'] = '处理成功';
$data['statusCode'] = 200;
$data['body'] = $body;
} else if ($statusCode == 204) { //处理成功,无返回Body
$data['msg'] = '微信支付统一下单失败';//'处理成功,无返回Body,请刷新后再试';
$data['statusCode'] = 204;
}
return $data;
} catch (RequestException $e) {
$data['msg'] = $e->getMessage();
$data['statusCode'] = 400;
return $data;
/*// 进行错误处理
echo $e->getMessage()."\n";
if ($e->hasResponse()) {
echo "failed,resp code = " . $e->getResponse()->getStatusCode() . " return body = " . $e->getResponse()->getBody() . "\n";
}*/
}
}
/**
* 生成签名
* @param $appId
* @param $timeStamp
* @param $nonceStr
* @param $package
* @return string
*/
public static function paySign($url = "", $http_method = "POST", $body = "", $timestamp = "", $nonce="")
{
if (!in_array('sha256WithRSAEncryption', openssl_get_md_methods(true))) {
throw new RuntimeException("当前PHP环境不支持SHA256withRSA");
}
$url_parts = parse_url($url);
$canonical_url = ($url_parts['path'] . (!empty($url_parts['query']) ? "?${url_parts['query']}" : ""));
//当前时间戳
$timestamp = empty($timestamp) ? time() : $timestamp;
//随机字符串
$nonce = empty($nonce) ? WeChatTwo::getNonceStr() : $nonce;
//POST请求时 需要 转JSON字符串
$message = $http_method."\n".
$canonical_url."\n".
$timestamp."\n".
$nonce."\n".
$body."\n";
//生成签名
openssl_sign($message, $raw_sign, openssl_get_privatekey(file_get_contents( WeChatTwo::$merchantPrivateKeyFilePath )), 'sha256WithRSAEncryption');
$sign = base64_encode($raw_sign);
return $sign;
}
/**
* 生成 Authorization
* @param string $url
* @param string $http_method
* @param string $body
* @return string
*/
public static function SignatureGenerate ($url = "", $http_method = "POST", $body = "", $timestamp = "", $nonce="")
{
//当前时间戳
$timestamp = empty($timestamp) ? time() : $timestamp;
//随机字符串
$nonce = empty($nonce) ? WeChatTwo::getNonceStr() : $nonce;
$sign = WeChatTwo::paySign($url, $http_method, $body,$timestamp,$nonce);
//$schema = 'WECHATPAY2-SHA256-RSA2048'; ////Authorization 类型
$token = sprintf('mchid="%s",nonce_str="%s",timestamp="%d",serial_no="%s",signature="%s"',WeChatTwo::$merchantId, $nonce, $timestamp, WeChatTwo::$merchantCertificateSerial, $sign);
return $token;
}
// 解密数据
public function decryptSign($ciphertext, $associatedData, $nonceStr)
{
$ciphertext = base64_decode($ciphertext);
if (function_exists('\sodium_crypto_aead_aes256gcm_is_available') && \sodium_crypto_aead_aes256gcm_is_available()) {
//$APIv3_KEY就是在商户平台后端设置是APIv3秘钥
$orderData = \sodium_crypto_aead_aes256gcm_decrypt($ciphertext, $associatedData, $nonceStr, WeChatTwo::$apiv3key);
$orderData = json_decode($orderData, true);
return $orderData;
}else{
//exit('缺乏PHP扩展:sodium,请安装该扩展或切换到PHP7.3+版本');
}
return false;
}
/**将字符串安全编码
*
* @param $string
*
* @return string
*/
public function urlsafe_b64encode($string)
{
$data = base64_encode($string);
$data = str_replace(array('+', '/', '='), array('-', '_', ''), $data);
return $data;
}
/**将字符串安全解码
*
* @param $string
*
* @return string
*/
public function urlsafe_b64decode($string)
{
$data = str_replace(array('-', '_'), array('+', '/'), $string);
$mod4 = strlen($data) % 4;
if ($mod4) {
$data .= substr('====', $mod4);
}
return base64_decode($data);
}
/*
* 产生随机字符串,不长于32位
* @param int $length
* @return string
*/
public static function getNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
}
什么问题呀
已解决