小程序php支付功能开发,php开发实现微信小程序支付功能

/**

* 构建微信支付

* @return \Response

*/

public function WxPay()

{

$input = Request::all();

$openId = $input['openId'] ?? null;

//判断金额是否为正整数

$input['total_fee'] = $input['total_fee']*100;

if (!preg_match("/^[1-9][0-9]*$/", $input['total_fee'])) {

return '金额错误';

}

//验证订单

$order_id = intval($input['order_id']);

$order = Order::where('id',$order_id)->first();

if(!$order){

return '订单不存在';

}

$notify_url = "回调地址";

$data = [

'out_trade_no' => $order->order_code,

'total_fee' => $input['total_fee'],

'openid' => $input['openId'],

'body' => $input['body'] ?? null,

'created_at' => Carbon::now(),

'updated_at' => Carbon::now(),

];

$data['notify_url'] = $notify_url;

//调用微信支付统一下单

$result = $this->unifiedOrder($data);

// 请求失败

if (!$result) {

//请求失败

}

if ($result['return_code'] === 'FAIL' || $result['result_code'] === 'FAIL') {

//调用出错

}

//调起支付数据签名字段

$timeStamp = time();

$appid = $result['appid'];

$nonce_pay = str_shuffle($result['nonce_str']);//随机字符串

$package = $result['prepay_id'];

$signType = "MD5";

$key = Common::KEY;

$stringPay = "appId=" . $appid . "&nonceStr=" . $nonce_pay . "&package=prepay_id=" . $package . "&signType=" . $signType . "&timeStamp=" . $timeStamp . "&key=" . $key;

$paySign = strtoupper(md5($stringPay));

//这些参数需要返回给小程序组件使用,弹出支付页面

$pay_data = array(

'nonceStr' => $nonce_pay,

'package' => "prepay_id=" . $package,

'timeStamp' => (string)$timeStamp,

'paySign' => $paySign,

'signType' => $signType

);

return $pay_data;

}

/**

* 小程序 统一下单方法

* @param $data

* array(

* 'out_trade_no' => 商户订单号,

* 'total_fee' => 总金额,

* 'openid' => 用户标识,

* 'body' => 商品描述,

* )

* @return bool|mixed

*/

public function unifiedOrder(array $data)

{

$common = (new Common);

$params['appid'] = $common::SHOP_ID;

$params['mch_id'] = $common::MCH_ID;

$params['nonce_str'] = $common->GenRandomString();//随机字符串

$params['body'] = $data['body'];//商品描述

$params['out_trade_no'] = $data['out_trade_no'];//商户订单号

$params['total_fee'] = $data['total_fee'];//总金额

$params['spbill_create_ip'] = $_SERVER['REMOTE_ADDR'];//终端IP

$params['notify_url'] = $data['notify_url'];//通知地址

$params['trade_type'] = 'JSAPI';//交易类型

$params['openid'] = $data['openid'];//用户标识

//$this->params['detail'] = $data['detail'] ?? null;//商品详情

//$this->params['attach'] = $data['attach'] ?? null;//附加数据

ksort($params);

//获取签名数据

$sign = $common->Sign($params);

$params['sign'] = $sign;//签名

$xml = $common->DataToXml($params);

$response = $common->PostXmlCurl($xml, 'https://api.mch.weixin.qq.com/pay/unifiedorder');

if (!$response) {

return false;

}

return $common->XmlToData($response);

}

common.php 文件内容入下:

/**

* 产生一个指定长度的随机字符串,并返回给用户

* @param $len //产生字符串的长度

* @return string 随机字符串

*/

public function GenRandomString($len = 32)

{

$chars = array(

"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k",

"l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v",

"w", "x", "y", "z", "A", "B", "C", "D", "E", "F", "G",

"H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R",

"S", "T", "U", "V", "W", "X", "Y", "Z", "0", "1", "2",

"3", "4", "5", "6", "7", "8", "9"

);

$charsLen = count($chars) - 1;

// 将数组打乱

shuffle($chars);

$output = "";

for ($i = 0; $i < $len; $i++) {

$output .= $chars[mt_rand(0, $charsLen)];

}

return $output;

}

/**

* 签名 $data要先排好顺序

* @param $data

* @return string

*/

public function Sign($data)

{

ksort($data);

$stringA = '';

foreach ($data as $key => $value) {

if (!$value) continue;

if ($stringA) $stringA .= '&' . $key . "=" . $value;

else $stringA = $key . "=" . $value;

}

$wx_key = $this::KEY;//申请支付后有给予一个商户账号和密码,登陆后自己设置的key

$stringSignTemp = $stringA . '&key=' . $wx_key;

return strtoupper(md5($stringSignTemp));

}

/**

* 将xml转为array

* @param string $xml

* return array

* @return bool|mixed

*/

public function XmlToData($xml)

{

if (!$xml) {

return false;

}

//将XML转为array

//禁止引用外部xml实体

libxml_disable_entity_loader(true);

$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);

return $data;

}

/**

* 输出xml字符

* @param $params //参数名称

* return string 返回组装的xml

*

* @return bool|string

*/

public function DataToXml($params)

{

if (!is_array($params) || count($params) <= 0) {

return false;

}

$xml = "";

foreach ($params as $key => $val) {

if (is_numeric($val)) {

$xml .= "" . $val . "" . $key . ">";

} else {

$xml .= "" . $key . ">";

}

}

$xml .= "";

return $xml;

}

/**

* 以post方式提交xml到对应的接口url

*

* @param string $xml 需要post的xml数据

* @param string $url url

* @param bool $useCert 是否需要证书,默认不需要

* @param int $second url执行超时时间,默认30s

* @return bool|string

* @throws

*/

public function PostXmlCurl($xml, $url, $useCert = false, $second = 30)

{

$ch = curl_init();

//设置超时

curl_setopt($ch, CURLOPT_TIMEOUT, $second);

curl_setopt($ch, CURLOPT_URL, $url);

//

curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, $useCert);

curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, $useCert ? 2 : 0);

//设置header

curl_setopt($ch, CURLOPT_HEADER, FALSE);

//要求结果为字符串且输出到屏幕上

curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);

if ($useCert == true) {

//TODO 以下两种方式需选择一种

/*------- --第一种方法,cert 与 key 分别属于两个.pem文件--------------------------------*/

//使用证书:cert 与 key 分别属于两个.pem文件

//默认格式为PEM,可以注释

curl_setopt($ch, CURLOPT_SSLCERTTYPE, 'PEM');

curl_setopt($ch, CURLOPT_SSLCERT, '绝对路径');

//默认格式为PEM,可以注释

curl_setopt($ch, CURLOPT_SSLKEYTYPE, 'PEM');

curl_setopt($ch, CURLOPT_SSLKEY, '绝对路径');

/**

* 补充 当找不到ca根证书的时候还需要rootca.pem文件

* TODO 注意,微信给出的压缩包中,有提示信息:

* 由于绝大部分操作系统已内置了微信支付服务器证书的根CA证书,

* 2018年3月6日后, 不再提供CA证书文件(rootca.pem)下载

*/

//curl_setopt($ch, CURLOPT_CAINFO,self::APICLIENT_CA);

/*----------第二种方式,两个文件合成一个.pem文件----------------------------------------*/

//curl_setopt($ch,CURLOPT_SSLCERT,getcwd().'/all.pem');

}

//post提交方式

curl_setopt($ch, CURLOPT_POST, TRUE);

curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);

//运行curl

$data = curl_exec($ch);

//返回结果

if ($data) {

curl_close($ch);

return $data;

} else {

$error = curl_errno($ch);

curl_close($ch);

return false;

}

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值