<?php
namespace app\index\controller;
use think\Controller;
use think\Db;
use think\Loader;
Loader::import('WxPay.WxPay', EXTEND_PATH, '.Api.php');
class Index extends Controller
{
//登陆
public function getLogin($code)
{
这两个填写的是小程序的,不需要填商户号
填写appid
$appid = '';
填写appsercert
$appsercert = '';
$url = 'https://api.weixin.qq.com/sns/jscode2session?appid=' . $appid . '&secret=' . $appsercert . '&js_code=' . $code . '&grant_type=authorization_code';
$res = json_decode(my_request($url), true);
$use = \db('user');
$userinfo = $use->where(['openid' => $res['openid']])->find();
if (!$userinfo) {
$use->insert(['openid' => $res['openid']]);
return json(['openid' => $res['openid'], 'phone' => '']);
} else {
return json($userinfo);
}
}
//这里调用支付,传openid
public function pay($openid)
{
return json($this->makeWxPreOrder(0.01, $openid));
}
//处理支付结果 这个是微信通知支付结果的
public function notify()
{
// 获取xml
$xml = file_get_contents('php://input', 'r');
$result = $this->toArray($xml);
file_put_contents('test.txt', json_encode($result));
if ($result['result_code'] == 'SUCCESS' && $result['return_code'] == 'SUCCESS') {
# out_trade_no是单号
# total_fee 是金额 以分为单位
echo exit('<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>');
}
}
//在这里生成订单,下面的方法是给他调用的
private function makeWxPreOrder($totalPrice, $openid)
{
//传递过来的参数为订单商品总价格
/**
*
* 统一下单,WxPayUnifiedOrder中out_trade_no、body、total_fee、trade_type必填
* appid、mchid、spbill_create_ip、nonce_str不需要填入
* @param WxPayUnifiedOrder $inputObj
* @param int $timeOut
* @throws WxPayException
* @return 成功时返回,其他抛异常
*/
$orderNo = date('ymdhis') . round('1111', '9999');
$wxOrderData = new \WxPayUnifiedOrder();
//唯一订单号
$wxOrderData->SetOut_trade_no($orderNo);
//代表JSAPI模式,不要修改,公众号支付,H5,小程序都是这个
$wxOrderData->SetTrade_type('JSAPI');
//价格,单位为分
$wxOrderData->SetTotal_fee($totalPrice * 100);
//商品简介
$wxOrderData->SetBody('零食商贩');
//使用小程序用户的openid
$wxOrderData->SetOpenid($openid);
//异步回调验证路径,开发者自定义
$wxOrderData->SetNotify_url(__SITE__.'/index/index/notify');
//一个生成签名的方法
return $this->getPaySignature($wxOrderData);
}
private function getPaySignature($wxOrderData)
{
$wxOrder = \WxPayApi::unifiedOrder($wxOrderData);
// 失败时不会返回result_code
if ($wxOrder['return_code'] != 'SUCCESS' || $wxOrder['result_code'] != 'SUCCESS') {
Log::record($wxOrder, 'error'); //修改成自己的异常处理
Log::record('获取预支付订单失败', 'error');
}
$signature = $this->sign($wxOrder);
return $signature;
}
//按照文档要求生成签名,传递给小程序,让小程序拉起支付
private function sign($wxOrder)
{
$jsApiPayData = new \WxPayJsApiPay();
//传入小程序appid
//appid
$jsApiPayData->SetAppid(\WxPayConfig::APPID);
//按照文档,要求是字符串类型
$jsApiPayData->SetTimeStamp((string) time());
//生成随机字符串
$rand = md5(time() . mt_rand(0, 1000));
$jsApiPayData->SetNonceStr($rand);
//拼接prepay_id,要注意拼接
$jsApiPayData->SetPackage('prepay_id=' . $wxOrder['prepay_id']);
//签名方式md5
$jsApiPayData->SetSignType('md5');
//然后调用sdk自带的MakeSign方法生成签名
$sign = $jsApiPayData->MakeSign();
//然后在使用sdk自带方法获取到上面的我们赋值到成员属性生成的数组
$rawValues = $jsApiPayData->GetValues();
//然后我们在数组上加上生成的签名
$rawValues['paySign'] = $sign;
//删除appid,因为返回给客户端没有用,所以消除
unset($rawValues['appId']);
//返回
return $rawValues;
}
/**
* 将xml转为array
* @param string $xml xml字符串
* @return array 转换得到的数组
*/
public function toArray($xml)
{
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$result = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $result;
}
}
本文为连浩勇原创文章,欢迎转载,但请注明来自连浩勇博客http://lhyong.cn