2020-02-10 18:02:13
围观(4539)
去年写过一篇文章:PHP开发微信支付功能
但是那篇文章用的是 NATIVE 支付方式,就是扫码支付,请求微信后返回的是一段 weixin:// 协议的链接,然后手机扫码调起微信支付.
其实微信小程序支付也差不多,只是支付方式用的是 JSAPI ,区别就是小程序支付 比 扫码支付 多了个openid的参数.
直接上代码:
public function pay() { // 支付数据 $data['out_trade_no'] = '这里需要生成订单号 可用 md5 函数生成当前时间 + 随机数 比如 md5(time . rand(100, 999))'; // 当然还有很多其他生成订单号的方法 博主仅仅是举例 $data['total_fee'] = 100; // 这个就是支付金额 此金额单位为分 比如 100 调起支付后是支付 1 分钱 $data['spbill_create_ip'] = $_SERVER["REMOTE_ADDR"]; // 客服端的 IP 可以使用其他方式获取,本文仅演示 $data['attach'] = '附加数据,在查询API和支付通知中原样返回'; $data['body'] = '产品名称 在支付的时候显示的'; $data['appid'] = '公众号的 APPID'; $data['mch_id'] = '微信支付的商户号'; $data['nonce_str'] = md5(time() . rand(0, 999)); // 这个是随机字串 具体看官方文档吧 $data['trade_type'] = 'JSAPI'; // 支付方式 扫码用 NATIVE 小程序用 JSAPI 也是本文的内容. $data['openid'] = '用户的openid 比如是A用户调用充值功能 就需要传A用户的openid 谁支付就用谁的'; // 异步回调地址 回调地址就不多说了... $data['notify_url'] = ($_SERVER['HTTPS'] ?? 'http' == 'on' ? "https://" : "http://") . $_SERVER["HTTP_HOST"] . '/api/wechat_callback'; // 将参数签名 $sign = $this->get_param($data); $data_xml = "<xml> <appid>".$data['appid']."</appid> <attach>".$data['attach']."</attach> <body>".$data['body']."</body> <mch_id>".$data['mch_id']."</mch_id> <nonce_str>".$data['nonce_str']."</nonce_str> <notify_url>".$data['notify_url']."</notify_url> <openid>".$data['openid']."</openid> <out_trade_no>".$data['out_trade_no']."</out_trade_no> <spbill_create_ip>".$data['spbill_create_ip']."</spbill_create_ip> <total_fee>".$data['total_fee']."</total_fee> <trade_type>".$data['trade_type']."</trade_type> <sign>".$sign."</sign> </xml>"; // 微信统一下单接口地址 $url = 'https://api.mch.weixin.qq.com/pay/unifiedorder'; // 发起HTTP请求 因为用的是 Laravel 框架,所以可以使用 GuzzleHttp 类 // 如果报错 Guzzle\Http 不存在,可以装一下 GuzzleHttp 包. $http = new GuzzleHttpClient; $response = $http->request('POST', $url, ['body' => $data_xml]); $wechat_pay_res = $this->xml_to_array($response->getBody()); if($wechat_pay_res['return_code'] !== 'SUCCESS' && $wechat_pay_res['return_msg'] !== 'OK') { // 开启数据库事务 在这里需要抛出异常 回滚数据 // 微信支付请求失败了 } // 需要给前端那边 小程序用到的数据 $mini_program_pay_params['appId'] = $gzh_config['appid']; $mini_program_pay_params['timeStamp'] = time(); $mini_program_pay_params['nonceStr'] = $data['nonce_str']; $mini_program_pay_params['package'] = 'prepay_id=' . $wechat_pay_res['prepay_id']; $mini_program_pay_params['signType'] = 'MD5'; $sign = $this->get_param($mini_program_pay_params); $mini_program_pay_params['paySign'] = $sign; $mini_program_pay_params['prepay_id'] = $wechat_pay_res['prepay_id']; $mini_program_pay_params['out_trade_no'] = $data['out_trade_no']; $mini_program_pay_params['total_fee'] = $data['total_fee']; return $mini_program_pay_params; // 可以这样传 // return response()->json(['mini_program_pay_params' => $mini_program_pay_params]); } private function get_param($param_array, $isencode = false) { $paramStr = ''; ksort($param_array); $i = 0; foreach($param_array as $key => $value){ if ($key == 'Signature'){ continue; } if ($i == 0){ $paramStr .= ''; }else{ $paramStr .= '&'; } $paramStr .= $key . '=' . ($isencode ? urlencode($value) : $value); ++$i; } $api_key = '微信支付密钥'; $stringSignTemp = $paramStr."&key={$api_key}"; return strtoupper(md5($stringSignTemp)); } private function xml_to_array($xml) { libxml_disable_entity_loader(true); $xml_string = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA); return json_decode(json_encode($xml_string), true); }
这样就完成了后端请求微信接口,拿到提供给前端那边调起支付的参数了.
前端开发调起小程序支付看这个文档:https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=7_7&index=5
示例代码:
wx.requestPayment({ 'timeStamp': '', 'nonceStr': '', 'package': '', 'signType': 'MD5', 'paySign': '', 'success':function(res){}, 'fail':function(res){}, 'complete':function(res){} })
还有就是后端的异步回调,拿微信支付结果通知的,看博主之前发布的那篇文章就好了:PHP开发微信支付功能
本文地址 : bubaijun.com/page.php?id=164
版权声明 : 未经允许禁止转载!
上一篇文章: PHP使用地址获取附近小区信息
下一篇文章: PHP使用经纬度获取两个位置的距离及范围查询