在UniApp中封装H5实现微信支付,并使用FastAdmin作为后端服务,你需要完成以下几个步骤:
-
配置微信支付参数:
- 在微信公众平台获取商户号、API密钥等参数。
- 在FastAdmin中配置这些参数。
-
FastAdmin后端接口:
- 创建一个接口用于生成预支付订单。
- 创建一个接口用于处理支付结果通知。
-
UniApp前端调用:
- 调用FastAdmin的预支付订单接口获取支付参数。
- 使用微信H5支付API进行支付。
详细步骤
1. 配置微信支付参数
- 在微信公众平台注册并获取商户号、API密钥等参数。
- 在FastAdmin中配置这些参数,通常在配置文件中设置。
2. FastAdmin后端接口
生成预支付订单接口
// application/api/controller/Pay.php
namespace app\api\controller;
use think\Controller;
use think\Request;
use think\Log;
class Pay extends Controller
{
public function unifiedorder(Request $request)
{
$orderNo = $request->post('order_no'); // 订单号
$amount = $request->post('amount'); // 金额,单位为分
$openId = $request->post('openid'); // 用户的OpenID
// 这里需要调用微信支付统一下单接口
$result = $this->weixinUnifiedOrder($orderNo, $amount, $openId);
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
return json(['code' => 0, 'data' => $result]);
} else {
return json(['code' => 1, 'msg' => $result['err_code_des']]);
}
}
private function weixinUnifiedOrder($orderNo, $amount, $openId)
{
$appid = 'your_appid';
$mch_id = 'your_mch_id';
$key = 'your_api_key';
$notify_url = 'https://your-fastadmin-domain/api/pay/notify';
$data = [
'appid' => $appid,
'mch_id' => $mch_id,
'nonce_str' => $this->createNonceStr(),
'body' => '商品描述',
'out_trade_no' => $orderNo,
'total_fee' => $amount,
'spbill_create_ip' => $_SERVER['REMOTE_ADDR'],
'notify_url' => $notify_url,
'trade_type' => 'MWEB',
'openid' => $openId,
];
$data['sign'] = $this->makeSign($data, $key);
$xml = $this->arrayToXml($data);
$url = 'https://api.mch.weixin.qq.com/pay/unifiedorder';
$response = $this->curlPost($url, $xml);
return $this->xmlToArray($response);
}
private function createNonceStr($length = 32)
{
$chars = "abcdefghijklmnopqrstuvwxyz0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
private function makeSign($data, $key)
{
ksort($data);
$stringA = '';
foreach ($data as $k => $v) {
if ($k != 'sign' && $v != '' && !is_array($v)) {
$stringA .= "$k=$v&";
}
}
$stringSignTemp = $stringA . "key=$key";
return strtoupper(md5($stringSignTemp));
}
private function arrayToXml($data)
{
$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;
}
private function xmlToArray($xml)
{
libxml_disable_entity_loader(true);
$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $data;
}
private function curlPost($url, $data)
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$response = curl_exec($ch);
curl_close($ch);
return $response;
}
}
处理支付结果通知接口
// application/api/controller/Pay.php
public function notify()
{
$xml = file_get_contents('php://input');
$result = $this->parseXml($xml);
if ($result['return_code'] == 'SUCCESS' && $result['result_code'] == 'SUCCESS') {
// 处理支付结果,更新订单状态等
// ...
$response = '<xml><return_code><![CDATA[SUCCESS]]></return_code><return_msg><![CDATA[OK]]></return_msg></xml>';
} else {
$response = '<xml><return_code><![CDATA[FAIL]]></return_code><return_msg><![CDATA[签名失败]]></return_msg></xml>';
}
echo $response;
}
private function parseXml($xml)
{
libxml_disable_entity_loader(true);
$data = json_decode(json_encode(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA)), true);
return $data;
}
3. UniApp前端调用
调用预支付订单接口
// pages/pay/index.vue
export default {
methods: {
async createOrder() {
const orderNo = 'your_order_no';
const amount = 1; // 金额,单位为元
const openid = 'user_openid'; // 用户的OpenID
const response = await uni.request({
url: 'https://your-fastadmin-domain/api/pay/unifiedorder',
method: 'POST',
data: {
order_no: orderNo,
amount: amount * 100, // 转换为分
openid: openid
}
});
if (response.data.code === 0) {
this.redirectToWxPay(response.data.data);
} else {
uni.showToast({
title: response.data.msg,
icon: 'none'
});
}
},
redirectToWxPay(data) {
const mweb_url = data.mweb_url + '&redirect_url=' + encodeURIComponent('https://your-domain.com/pay/success');
window.location.href = mweb_url;
}
}
}
总结
以上步骤涵盖了从配置微信支付参数到实现FastAdmin后端接口和UniApp前端调用的全过程。请根据实际情况调整代码中的具体实现细节。特别是openid
的获取,通常需要通过微信授权获取。