
所有的操作都来自参考:https://github.com/wechatpay-apiv3/wechatpay-php,包括安装等。
第一步安装wechatpay-php
composer require wechatpay/wechatpay //注意安装目录,最好先cd到你的项目下再运行该安装命令
第二步:下载微信支付平台证书
具体请参考另一篇文章“windows系统下PHP版微信支付 wechatpay-php APIv3 平台证书下载(composer)”
第三步:所有功能实现代码
use WeChatPay\Formatter;
use WeChatPay\Builder;
use WeChatPay\Crypto\AesGcm;
use WeChatPay\Crypto\Rsa;
use WeChatPay\Util\PemUtil;
class Pay
{
private $appid=''; //微信公众号ID,唯一标识
private $secret=''; //微信公众号的appsecret
private $mchid=''; // 商户号
private $keyCert='apiclient_key.pem'; //商户API私钥
private $serialNo=''; // 「商户API证书」的「证书序列号」
private $wechatpayCert='wechatpay_cert.pem'; //微信支付平台证书
//JSAPI下单,同时获取相关参数,包括:code、access_token、openid、prepay_id
public function toCode(){
$url='https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$this->appid.'&redirect_uri='.urlencode('http://www.shiyunkj.com/wx/pay/getCode').'&response_type=code&scope=snsapi_base&state=syno'.time().'#wechat_redirect';
return redirect($url);
}
public function getCode(){
$gv=input('get.'); //获取code、state参数
if(isset($gv['code']) && $gv['code']!=''){
$url='https://api.weixin.qq.com/sns/oauth2/access_token?appid='.$this->appid.'&secret='.$this->secret.'&code='.$gv['code'].'&grant_type=authorization_code';
$res=$this->curlContents($url); //正常返回 access_token、openid等参数
if(isset($res['openid'])){
$data=[
'appid'=>$this->appid, //公众号的服务号APPID
'mchid'=>$this->mchid, //商户号
'description'=>哈喽吧1分礼品-1号', //商品描述
'out_trade_no'=>'20221005003252001', //商户订单号
'attach'=>'ceshi_'.time(), //附加数据,在查询API和支付通知中原样返回
'notify_url'=>'http://www.hilo8.com/wx/pay/notify', //异步接收微信支付结果通知的回调地址
'amount'=>['total'=>0.1*100], //订单总金额,单位为分
'payer'=>['openid'=>$res['openid']] //用户标识,用户在直连商户appid下的唯一标识
];
$instance=$this->APIv3();
try {
$resp = $instance->chain('v3/pay/transactions/jsapi')->post(['json' => $data]); //jsapi下单
$prepay_id=json_decode($resp->getBody(),true)['prepay_id'];
if(isset($prepay_id)){
echo '下单成功:prepay_id='.$prepay_id;
}else{
echo $resp->getStatusCode(), PHP_EOL;
echo $resp->getBody(), PHP_EOL;
}
} catch (\Exception $e) {
// 进行错误处理
echo $e->getMessage(), PHP_EOL;
if ($e instanceof \GuzzleHttp\Exception\RequestException && $e->hasResponse()) {
$r = $e->getResponse();
echo $r->getStatusCode() . ' ' . $r->getReasonPhrase(), PHP_EOL;
echo $r->getBody(), PHP_EOL, PHP_EOL, PHP_EOL;
}
echo $e->getTraceAsString(), PHP_EOL;
}
}else{
echo '获取openid失败,错误信息:'.json_encode($res,JSON_UNESCAPED_UNICODE);
}
}else{
echo '授权获取code失败,错误信息:'.json_encode($gv,JSON_UNESCAPED_UNICODE);
}
}
//异步接收微信支付结果通知,自行编写数据处理
public function notify(){
}
//获取支付参数
public function payConfig(){
$config=$this->sign('prepay_id值');
return json($config);
}
//微信支付订单号查询
public function cxTransactionId(){
$id='420000***93';
$resp = $this->APIv3()
->chain('v3/pay/transactions/id/'.$id)
->get(['query' => ['mchid' => $this->mchid]]);
echo $resp->getBody();
}
//商户订单号查询
public function cxOutTradeNo(){
$out_trade_no='20221004***02';
$resp = $this->APIv3()
->chain('v3/pay/transactions/out-trade-no/'.$out_trade_no)
->get(['query' => ['mchid' => $this->mchid]]);
echo $resp->getBody();
}
//关闭订单
public function closeOutTradeNo(){
$out_trade_no='20221004***02';
$resp = $this->APIv3()
->chain('v3/pay/transactions/out-trade-no/'.$out_trade_no.'/close')
->post(['json' => ['mchid' => $this->mchid]]);
echo $resp->getBody(); //正常无返回数据
}
//=============================================================================
//构造 APIv3 客户端实例
private function APIv3(){
$merchantId = $this->mchid; // 商户号
// 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名
$merchantPrivateKeyFilePath = $this->certPath().$this->keyCert;
$merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE);
// 「商户API证书」的「证书序列号」
$merchantCertificateSerial = $this->serialNo;
// 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名
$platformCertificateFilePath = $this->certPath().$this->wechatpayCert;
$platformPublicKeyInstance = Rsa::from($platformCertificateFilePath, Rsa::KEY_TYPE_PUBLIC);
// 从「微信支付平台证书」中获取「证书序列号」
$platformCertificateSerial = PemUtil::parseCertificateSerialNo($platformCertificateFilePath);
// 构造一个 APIv3 客户端实例
$instance = Builder::factory([
'mchid' => $merchantId,
'serial' => $merchantCertificateSerial,
'privateKey' => $merchantPrivateKeyInstance,
'certs' => [$platformCertificateSerial => $platformPublicKeyInstance],
]);
return $instance;
}
//签名
private function sign($prepay_id)
{
$merchantPrivateKeyFilePath = $this->certPath().$this->keyCert;
$merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath);
$params = [
'appId' => $this->appid,
'timeStamp' => (string)Formatter::timestamp(),
'nonceStr' => Formatter::nonce(),
'package' => 'prepay_id='.$prepay_id,
];
$params += ['paySign' => Rsa::sign(
Formatter::joinedByLineFeed(...array_values($params)),
$merchantPrivateKeyInstance
), 'signType' => 'RSA'];
return $params;
}
}
说明:以上的一些参数需要换成自己的,curlContents()需要自己编写,实际就是curl方式获取内容,如不会可以使用file_get_contents()。
支付调用:
//<a href="javascript:onBridgeReady();">支付订单</a>
function onBridgeReady() {
$.get('/wx/pay/payConfig', function(sign){
WeixinJSBridge.invoke('getBrandWCPayRequest', sign, function(res) {
if (res.err_msg == "get_brand_wcpay_request:ok") {
// 使用以上方式判断前端返回,微信团队郑重提示:
//res.err_msg将在用户支付成功后返回ok,但并不保证它绝对可靠。
alert('支付成功');
}else{
alert(JSON.stringify(res));
}
});
})
}
上一篇:windows系统下PHP版微信支付 wechatpay-php APIv3 平台证书下载(composer)
下一篇:PHP将十六进制颜色值转RGB/RGBA颜色值的方法
讨论数量:2
$gv=input('get.'); 就是获取code和state参数。
code说明:code作为换取access_token的票据,每次用户授权带上的code将不一样,code只能使用一次,5分钟未被使用自动过期。
state说明:state值为toCode()里链接上state参数的值,重定向后会带上state参数,开发者可以填写a-zA-Z0-9的参数值,最多128字节。
更多说明请参数官方文档:https://developers.weixin.qq.com/doc/offiaccount/OA_Web_Apps/Wechat_webpage_authorization.html