在Fastadmin中使用epay插件开发微信支付
目录
使用epay开发微信支付
准备工作
注册公众号
在微信公众平台注册小程序/服务号等,注册后申请微信认证。
获取公众号appid,appsecret
并且配置ip白名单,js接口安全域名。设置为你的服务器,需要公网可以访问。
目前改为在微信开放平台相应公众号中进行管理配置。
如果是前后端分离的项目,js安全域名需要配置两个。
如果前后端不在一个服务器的,需要配置两个ip白名单。

开通微信商家平台
微信商户平台:https://pay.weixin.qq.com/
扫码注册申请商家,获取以下配置内容:

说明:
公钥证书是使用V3支付接口时使用的,默认是V2接口不需要获取公钥证书。
支付模式是指:小程序支付、H5支付、JsApi支付、App支付等。
微信商户平台关联
就是把公众号与商家平台进行关联,这样才能在该公众号中使用商家支付。
在商家平台中新增完授权(需要超级管理员权限)。还需要在公众号中同意授权。
新增授权
在商户平台的主界面,进入 “产品中心”,在左侧菜单选择 “APPID 账号管理”,点击右侧的 “关联 APPID”。


微信公众号同意
登录微信公众平台,在左侧菜单选择 “微信支付”,按照指示进行确认操作。操作完毕,微信商户平台可以看到关联成功。

安装插件
在插件管理中搜索支付
在列表中找到微信支付宝整合插件进行下载。

配置插件
因为我是使用公众号的所以:公众号app_id、app_secret必填。
支付商户号、ApiV2密钥必填。
V3的可以不填,因为默认使用v2支付。

然后API证书cert和API证书key证书必填。
回调通知地址可以不填,在代码中请求时传参即可。

开发
支付与支付回调
发起支付和回调示例
可以根据epay/controller下的Index.php中的experience和notifyx在
自己的控制器中编写支付方法和回调处理,如下:

/**
* 体验,仅供开发测试
*/
public function experience()
{
$amount = $this->request->post('amount');
$type = $this->request->post('type');
$method = $this->request->post('method');
$openid = $this->request->post('openid', "");
if (!$amount || $amount < 0) {
$this->error("支付金额必须大于0");
}
if (!$type || !in_array($type, ['alipay', 'wechat'])) {
$this->error("支付类型不能为空");
}
if (in_array($method, ['miniapp', 'mp']) && !$openid) {
$this->error("openid不能为空");
}
//订单号
$out_trade_no = date("YmdHis") . mt_rand(100000, 999999);
//订单标题
$title = '测试订单';
//回调链接
$notifyurl = $this->request->root(true) . '/addons/epay/index/notifyx/paytype/' . $type;
$returnurl = $this->request->root(true) . '/addons/epay/index/returnx/paytype/' . $type . '/out_trade_no/' . $out_trade_no;
$response = Service::submitOrder($amount, $out_trade_no, $type, $title, $notifyurl, $returnurl, $method, $openid);
return $response;
}
/**
* 支付成功,仅供开发测试
*/
public function notifyx()
{
$paytype = $this->request->param('paytype');
$pay = Service::checkNotify($paytype);
if (!$pay) {
return json(['code' => 'FAIL', 'message' => '失败'], 500, ['Content-Type' => 'application/json']);
}
// 获取回调数据,V3和V2的回调接收不同
$data = Service::isVersionV3() ? $pay->callback() : $pay->verify();
try {
//微信支付V3返回和V2不同
if (Service::isVersionV3() && $paytype === 'wechat') {
$data = $data['resource']['ciphertext'];
$data['total_fee'] = $data['amount']['total'];
}
\think\Log::record($data);
//获取支付金额、订单号
$payamount = $paytype == 'alipay' ? $data['total_amount'] : $data['total_fee'] / 100;
$out_trade_no = $data['out_trade_no'];
\think\Log::record("回调成功,订单号:{$out_trade_no},金额:{$payamount}");
//你可以在此编写订单逻辑
} catch (Exception $e) {
\think\Log::record("回调逻辑处理错误:" . $e->getMessage(), "error");
}
//下面这句必须要执行,且在此之前不能有任何输出
if (Service::isVersionV3()) {
return $pay->success()->getBody()->getContents();
} else {
return $pay->success()->send();
}
}
按照此改好后,也就是直接使用Service中的submitOrder提交支付,返回prepay_id【预支付交易会话标识】预支付交易会话标识,JSAPI或小程序调起支付时需要使用的参数,有效期为2小时,失效后需要重新请求该接口以获取新的prepay_id。
支付方法调用
我在trait中封装了支付方法,在别的控制器中直接use trait后传参调用支付方法即可。
如下:
/**
* 微信支付
*/
public function wxPay($data)
{
$openid = \addons\epay\library\Service::getOpenid();
if (!$openid) {
return '请绑定微信账号';
}
$params = [
'amount' => $data['amount'],
'orderid' => $data['order_no'],
'type' => "wechat",
'title' => $data['title'],
'notifyurl' => local_url(self::$callbackUrls[$data['pay_type']]), // 域名 + 路径
'method' => "mp",
'openid' => $openid
];
try {
$response = \addons\epay\library\Service::submitOrder($params);
return json_decode($response, true);
} catch (\Exception $e) {
return $e->getMessage();
}
}
微信退款
封装微信退款
当用户不想用买这个商品时,可以取消订单或者申请取消订单,所以要调用微信的退款方法。
在service中没有封装退款方法的调用,自己加一个,如下:
/**
* 微信退款
* @param $params
* @return array
*/
public static function submitRefunds($params)
{
$total_amount = $params['total_amount'] ?? 1;
$refund_amount = $params['refund_amount'] ?? 1;
//自定义微信支付宝相关配置
$custom = $params['custom'] ?? [];
//默认回调和跳转
$config = Service::getConfig('wechat', array_merge($custom, ['notify_url' => $params['notifyurl']]));
//单位分
$total_fee = function_exists('bcmul') ? bcmul($total_amount, 100) : $total_amount * 100;
$refund_fee = function_exists('bcmul') ? bcmul($refund_amount, 100) : $refund_amount * 100;
//创建支付对象
$pay = Pay::wechat($config);
$params = [
'out_trade_no' => $params['out_trade_no'],
'out_refund_no' => $params['out_refund_no'],
'total_fee' => (int)$total_fee,
'refund_fee' => (int)$refund_fee,
'reason' => $params['reason'] ?? '用户申请退款',
'notify_url' => $config['notify_url'], // 退款结果通知地址
];
$result = $pay->refund($params);
return $result->toArray();
}
调用微信退款
还是在支付trait文件中添加,如下方法:
/**
* 微信退款操作
* @param $data
* @return mixed|string
*/
public function wxRefund($data)
{
$params = [
'out_trade_no' => $data['order_no'], // 订单编号
'out_refund_no' => $data['out_refund_no'], // 退款订单编号
'total_amount' => $data['total_amount'], // 总金额
'refund_amount' => $data['amount'], //退款金额
'reason' => $data['reason'], //退款原因
'notifyurl' => local_url(self::$callbackUrls[$data['pay_type']]), // 退款结果通知地址
//'notifyurl' => 'http://你的域名self::$callbackUrls[$data['pay_type']], // 退款结果通知地址
];
try {
$response = \addons\epay\library\Service::submitRefunds($params);
return $response;
} catch (\Exception $e) {
return $e->getMessage();
}
}
关闭微信订单
当用户只是调用了微信支付,但是没有输入密码时就关闭了窗口,选择取消订单时,可以调用关闭微信订单。不关闭也可以,一定时间后微信那边也会自动关闭订单;主要为了防止如果用户通过别的途径支付了订单但未同步商家订单处理情况。
封装关闭订单
在epay/service类中增加关闭订单方法。
如下:
/**
* 关闭未支付微信订单
* @param $orderNo
* @return array
*/
public static function submitClose($orderNo)
{
// 创建对象
$config = Service::getConfig('wechat');
$pay = Pay::wechat($config);
$params = [
'out_trade_no' => $orderNo
];
$result = $pay->close($params);
return $result->toArray();
}
调用微信关闭订单
还是在支付trait文件中添加,orderNO:商户内容订单号,如下:
/**
* 关闭未支付订单
* @param $orderNo
* @return mixed|string
*/
public function wxClose($orderNo)
{
try {
$response = \addons\epay\library\Service::submitClose($orderNo);
if ($response['return_code'] == 'SUCCESS') {
return ['code' => 1];
}
return $response['return_msg'];
} catch (\Exception $e) {
return $e->getMessage();
}
}
总结
在Fastadmin中使用epay插件开发微信支付
1929

被折叠的 条评论
为什么被折叠?



