配置微信支付信息
小程序
function wxPay(order) {
let token = wx.getStorageSync('token')
wx.request({
url: '**/api/wxpay/index',
data: {
order: order,
token: token,
shop_id:shop_id
},
success: (res) => {
//返回微信支付所有参数
let dataArr = res.data
if (dataArr.code == 200) {
wx.requestPayment({
timeStamp: dataArr.data.timeStamp + "",
nonceStr: dataArr.data.nonceStr,
package: dataArr.data.package,
signType: 'MD5',
paySign: dataArr.data.paySign,
success(res) {
ui.navigateTo('../order/order')
},
fail(res) {
console.log(res)
}
})
}
}
后台接口
<?php
namespace appapicontrollerv1;
use thinkRequest;
use thinkController;
use appapicontrollerBaseController;
use appcommoncontrollerWeChatPay as WeChatPayCommon;
class WeChat extends BaseController
{
public function getData()
{
$param = $this->request->param();
try {
$wechat = new WeChatPayCommon($param['shop_id']);
return $wechat->getData($param);
} catch (Exception $e) {
return $this->r_json(400,$e->getMessage());
}
}
}
支付模型
这边参数全部保存到数据库了
<?php
namespace appcommoncontroller;
use thinkRequest;
use thinkController;
use appcommonmodelUser as UserModel;
use appcommonmodelOrders as OrdersModel;
use appcommonmodelShopList as ShopListModel;
use appcommonvalidateWeChatPay as WeChatPayValidate;
class WeChatPay extends Controller
{
private $appid = '';
private $mch_id = '';
private $key = '';
function __construct($shop_id)
{
$shop = (new ShopListModel())->get($shop_id);//重数据库获取参数
$this->appid = $shop['wx_appid'];
$this->mch_id = $shop['wx_mch_id'];
$this->key = $shop['wx_key'];
$this->spbill_create_ip = $shop['spbill_create_ip'];
$this->notify_url = $shop['notify_url'];
}
public function getData($param){
$this->param = $param;
$validate = new WeChatPayValidate();//TP5验证其验证返回的参数
if (!$validate->check($this->param)) return $this->msg(400,$validate->getError());
//查看订单状态 是否满足条件
$this->orders = (new OrdersModel())->get(['orders_number' => $param['orders_number'] , 'orders_status' => 1]);
if (empty($this->orders )) return $this->msg(400,"订单错误");
$this->user = (new UserModel())->get($param['uid']);
//调起支付
return $this->msg(200,'ok',$this->getSign());
}
/**
* JSAPI调起支付
*/
private function getSign()
{
$this->getOrders();
$config = [];
$config['appId'] = $this->appid;
$config['timeStamp'] = time();
$config['nonceStr'] = 'x'.time().'x';
$config['package'] = "prepay_id=".$this->getOrders();
$config['signType'] = "MD5";
$config['paySign'] = $this->MakeSign($config);
return $config;
}
/**
* 统一下单
*/
private function getOrders()
{
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$msg = [];
$msg['appid'] = $this->appid;
$msg['mch_id'] = $this->mch_id;
$msg['nonce_str'] = 'o'.time().'o';
$msg['body'] = $this->orders['orders_number'];
$msg['out_trade_no'] = $this->orders['orders_number'];
$msg['total_fee'] = $this->orders['orders_money']*100;
$msg['spbill_create_ip'] = $this->spbill_create_ip;
$msg['notify_url'] = $this->notify_url;
$msg['trade_type'] = 'JSAPI';
$msg['openid'] = $this->user['openid'];
$msg['sign'] = $this->MakeSign($msg);
$xml = $this->ToXml($msg);
$data = $this->https_request($url,$xml);
$data = $this->FromXml($data);
if (!empty($data['return_msg']) && !empty($data['return_code'])){
if ($data['return_code'] == "FAIL") {
throw new Exception($data['return_msg']);
}
}
return $data['prepay_id'];
}
/**
* 生成签名
* @return 签名
*/
private function MakeSign($data)
{
//签名步骤一:按字典序排序参数
ksort($data);
$string = $this->ToUrlParams($data);
//签名步骤二:在string后加入KEY
$string = $string . "&key=".$this->key;
//签名步骤三:MD5加密或者HMAC-SHA256
$string = md5($string);
//签名步骤四:所有字符转为大写
$result = strtoupper($string);
return $result;
}
/**
* 格式化参数格式化成url参数
*/
private function ToUrlParams($data)
{
$buff = "";
foreach ($data as $k => $v)
{
if($k != "sign" && $v != "" && !is_array($v)){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
/**
* 输出xml字符
* @throws Exception
**/
private function ToXml($data)
{
if(!is_array($data) || count($data) <= 0)
{
throw new Exception("数组数据异常!");
}
$xml = "<xml>";
foreach ($data as $key=>$val)
{
if (is_numeric($val)){
$xml.="<".$key.">".$val."</".$key.">";
}else{
$xml.="<".$key."><![CDATA[".$val."]]></".$key.">";
}
}
$xml.="</xml>";
return $xml;
}
/**
* 将xml转为array
* @param string $xml
* @throws WxPayException
*/
private function FromXml($xml)
{
if(!$xml){
throw new WxPayException("xml数据异常!");
}
//将XML转为array
//禁止引用外部xml实体
libxml_disable_entity_loader(true);
$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $data;
}
/**
* curl请求
*/
private function https_request($url,$data=null,$time_out=60,$out_level="s",$headers=array())
{
$curl = curl_init();
curl_setopt($curl, CURLOPT_NOSIGNAL, 1);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
if (!empty($data)){
curl_setopt($curl, CURLOPT_POST, 1);
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
}
if($out_level=="s") {
//超时以秒设置
curl_setopt($curl, CURLOPT_TIMEOUT,$time_out);//设置超时时间
}elseif ($out_level=="ms"){
curl_setopt($curl, CURLOPT_TIMEOUT_MS,$time_out); //超时毫秒,curl 7.16.2中被加入。从PHP 5.2.3起可使用
}
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
if($headers){
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);//如果有header头 就发送header头信息
}
$output = curl_exec($curl);
curl_close($curl);
return $output;
}
private function msg($code,$msg,$data=[]){
return json_encode(['code' => $code , 'msg' => $msg , 'data' => $data]);
}
}