赞
踩
1、下载官方提供的sdk(https://github.com/wechatpay-apiv3/wechatpay-php)
2、创建订单
use WeChatPay\Builder; use WeChatPay\Crypto\AesGcm; use WeChatPay\Crypto\Rsa; use WeChatPay\Formatter; use WeChatPay\Util\PemUtil; /** * @param $out_trade_no 订单号 * @param $total_fee 支付金额 * @param $attach 扩展字段 * @param $body 描述 * @return mixed */ public static function h5($out_trade_no, $total_fee, $attach, $body){ // 商户号 $merchantId = 'xxx'; // 从本地文件中加载「商户API私钥」,「商户API私钥」会用来生成请求的签名 $merchantPrivateKeyFilePath = 'file://这里写apiclient_key.pem文件地址绝对路径'; $merchantPrivateKeyInstance = Rsa::from($merchantPrivateKeyFilePath, Rsa::KEY_TYPE_PRIVATE); // 「商户API证书」的「证书序列号」 $merchantCertificateSerial = 'xxx'; // 从本地文件中加载「微信支付平台证书」,用来验证微信支付应答的签名(php需要用工具或者时接口获取,见我的另一篇文章记录) $platformCertificateFilePath = 'file://这里写平台证书地址绝对路径'; $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, ], ]); try { $resp = $instance ->chain('v3/pay/transactions/h5') ->post(['json' => [ 'mchid' => '', 'attach' => $attach, 'out_trade_no' => $out_trade_no, 'appid' => '', 'description' => $body, 'notify_url' => '', 'amount' => [ 'total' => $total_fee, 'currency' => 'CNY' ], 'scene_info' => [ 'payer_client_ip' => '', 'h5_info' => [ 'type' => 'Wap', ], ], ]]); $res = json_decode($resp->getBody(),true); return $res['h5_url']; // 返回给前端,前端在浏览器跳转该地址就可以唤起微信支付 } 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; } } /** * 微信支付回调 * @param $input 获取的body数据 * @param $header 获取的请求头数据 * @return bool */ public function notify($input,$header) { $inWechatpaySignature = $header['wechatpay-signature'];// 请根据实际情况获取 $inWechatpayTimestamp = $header['wechatpay-timestamp'];// 请根据实际情况获取 $inWechatpaySerial = $header['wechatpay-serial'];// 请根据实际情况获取 $inWechatpayNonce = $header['wechatpay-nonce'];// 请根据实际情况获取 $inBody = $input;// 请根据实际情况获取,例如: file_get_contents('php://input'); $apiv3Key = '';// 在商户平台上设置的APIv3密钥 // 根据通知的平台证书序列号,查询本地平台证书文件, // 假定为 `/path/to/wechatpay/inWechatpaySerial.pem` $platformPublicKeyInstance = Rsa::from('file://平台证书地址', Rsa::KEY_TYPE_PUBLIC); // 检查通知时间偏移量,允许5分钟之内的偏移 $timeOffsetStatus = 300 >= abs(Formatter::timestamp() - (int)$inWechatpayTimestamp); $verifiedStatus = Rsa::verify( // 构造验签名串 Formatter::joinedByLineFeed($inWechatpayTimestamp, $inWechatpayNonce, $inBody), $inWechatpaySignature, $platformPublicKeyInstance ); if ($timeOffsetStatus && $verifiedStatus) { // 转换通知的JSON文本消息为PHP Array数组 $inBodyArray = (array)json_decode($inBody, true); // 使用PHP7的数据解构语法,从Array中解构并赋值变量 ['resource' => [ 'ciphertext' => $ciphertext, 'nonce' => $nonce, 'associated_data' => $aad ]] = $inBodyArray; // 加密文本消息解密 $inBodyResource = AesGcm::decrypt($ciphertext, $apiv3Key, $nonce, $aad); // 把解密后的文本转换为PHP Array数组 $inBodyResourceArray = (array)json_decode($inBodyResource, true); if ($inBodyResourceArray['trade_state'] == 'SUCCESS') { // 这里写业务逻辑 $result = [ 'code'=>'SUCCESS', 'message'=>'成功', ]; echo json_encode($result);exit; } } } // 获取header头的方法 public function get_all_header() { // 忽略获取的header数据。这个函数后面会用到。主要是起过滤作用 $ignore = array('host','accept','content-length','content-type','connection','accept-encoding'); $headers = array(); //这里大家有兴趣的话,可以打印一下。会出来很多的header头信息。咱们想要的部分,都是‘http_'开头的。所以下面会进行过滤输出。/* var_dump($_SERVER); foreach($_SERVER as $key=>$value){ if(substr($key, 0, 5)==='HTTP_'){ //这里取到的都是'http_'开头的数据。 //前去开头的前5位 $key = substr($key, 5); //把$key中的'_'下划线都替换为空字符串 $key = str_replace('_', ' ', $key); //再把$key中的空字符串替换成‘-’ $key = str_replace(' ', '-', $key); //把$key中的所有字符转换为小写 $key = strtolower($key); //这里主要是过滤上面写的$ignore数组中的数据 if(!in_array($key, $ignore)){ $headers[$key] = $value; } } }//输出获取到的header return $headers; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。