manghe/app/common/helper/WxPayHelper.php
2025-04-25 00:16:04 +08:00

207 lines
7.5 KiB
PHP
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<?php
namespace app\common\helper;
class WxPayHelper
{
/**
* 根据权重随机获取一个商户
*
* @param array $merchants 商户数组
* @return array|null 随机选择的商户信息
*/
public static function getRandomMerchant(array $merchants)
{
if (empty($merchants)) {
return null;
}
// 只有一个商户,直接返回
if (count($merchants) === 1) {
return $merchants[0];
}
// 计算总权重
$totalWeight = 0;
foreach ($merchants as $merchant) {
$totalWeight += isset($merchant['weight']) ? (int)$merchant['weight'] : 1;
}
// 生成随机数
$randomWeight = mt_rand(1, $totalWeight);
// 根据权重选择商户
$currentWeight = 0;
foreach ($merchants as $merchant) {
$weight = isset($merchant['weight']) ? (int)$merchant['weight'] : 1;
$currentWeight += $weight;
if ($randomWeight <= $currentWeight) {
return $merchant;
}
}
// 默认返回第一个商户
return $merchants[0];
}
/**
* 获取微信支付配置
*
* @return array 包含随机选择的商户信息和appid
*/
public static function getWxPayConfig()
{
// 获取当前域名对应的小程序配置
$miniprogram = \app\common\helper\MiniprogramHelper::getMiniprogramConfig();
// 选择一个商户
$merchant = null;
// 如果小程序配置了关联商户,从关联商户中随机选择一个
if (!empty($miniprogram) && !empty($miniprogram['merchants']) && is_array($miniprogram['merchants']) && count($miniprogram['merchants']) > 0) {
$weixinpay_setting = getConfig('weixinpay_setting');
if (!empty($weixinpay_setting) && !empty($weixinpay_setting['merchants'])) {
// 过滤出关联的商户
$associatedMerchants = [];
foreach ($weixinpay_setting['merchants'] as $m) {
if (in_array($m['mch_id'] ?? '', $miniprogram['merchants'])) {
$associatedMerchants[] = $m;
}
}
// 如果有关联商户,从中随机选择一个
if (!empty($associatedMerchants)) {
$merchant = self::getRandomMerchant($associatedMerchants);
}
}
}
// 如果没有关联商户或无法获取关联商户,则使用默认商户选择逻辑
if (empty($merchant)) {
$weixinpay_setting = getConfig('weixinpay_setting');
if (!empty($weixinpay_setting) && !empty($weixinpay_setting['merchants'])) {
$merchant = self::getRandomMerchant($weixinpay_setting['merchants']);
} else {
// 兼容旧配置
$old_config = getConfig('weixinpay');
if (!empty($old_config)) {
$merchant = [
'name' => '默认商户',
'mch_id' => $old_config['mch_id'],
'keys' => $old_config['keys'],
'order_prefix' => $old_config['order_prefix'] ?? 'MYH',
'weight' => 1
];
}
}
}
// 获取微信AppID - 优先使用小程序配置中的AppID
$appid = '';
if (!empty($miniprogram) && !empty($miniprogram['appid'])) {
$appid = $miniprogram['appid'];
} else {
// 兼容旧配置
$wechat_setting = getConfig('wechat_setting');
if (!empty($wechat_setting) && !empty($wechat_setting['appid'])) {
$appid = $wechat_setting['appid'];
} else if (!empty($old_config) && !empty($old_config['appid'])) {
$appid = $old_config['appid'];
}
}
return [
'merchant' => $merchant,
'appid' => $appid
];
}
/**
* 获取固定的微信支付配置(基于订单前缀)
*
* @param string $order_prefix 订单前缀,如果提供则返回对应前缀的商户信息
* @return array 包含固定商户信息和appid
*/
public static function getFixedWxPayConfig($order_prefix = '')
{
// 获取当前域名对应的小程序配置
$miniprogram = \app\common\helper\MiniprogramHelper::getMiniprogramConfig();
$weixinpay_setting = getConfig('weixinpay_setting');
// 尝试查找与订单前缀匹配的商户
$merchant = null;
if (!empty($order_prefix) && !empty($weixinpay_setting) && !empty($weixinpay_setting['merchants'])) {
foreach ($weixinpay_setting['merchants'] as $m) {
if (!empty($m['order_prefix']) && $m['order_prefix'] === $order_prefix) {
$merchant = $m;
break;
}
}
}
// 如果没有找到匹配的商户,则使用随机选择
if (empty($merchant)) {
return self::getWxPayConfig();
}
// 获取微信AppID - 优先使用小程序配置中的AppID
$appid = '';
if (!empty($miniprogram) && !empty($miniprogram['appid'])) {
$appid = $miniprogram['appid'];
} else {
// 兼容旧配置
$wechat_setting = getConfig('wechat_setting');
if (!empty($wechat_setting) && !empty($wechat_setting['appid'])) {
$appid = $wechat_setting['appid'];
} else {
$old_config = getConfig('weixinpay');
if (!empty($old_config) && !empty($old_config['appid'])) {
$appid = $old_config['appid'];
}
}
}
return [
'merchant' => $merchant,
'appid' => $appid
];
}
/**
* 从订单号中提取商户前缀
*
* @param string $order_no 订单号(格式如 MH_ABC20240529...)
* @return string|null 商户前缀如果无法提取则返回null
*/
public static function extractOrderPrefix($order_no)
{
if (strpos($order_no, 'MH_') === 0||strpos($order_no, 'FH_') === 0) {
// 尝试提取MH_后的字符作为商户前缀
// 商户前缀长度为3如果有小程序前缀则总长度为53+2
$totalPrefix = substr($order_no, 3, 5);
// 提取商户前缀前3位
$merchantPrefix = substr($totalPrefix, 0, 3);
// 如果有足够长度,可能包含小程序前缀
if (strlen($totalPrefix) >= 5) {
// 提取小程序前缀后2位
$miniprogramPrefix = substr($totalPrefix, 3, 2);
// 使用数组返回,包含商户前缀和小程序前缀
return [
'merchant_prefix' => $merchantPrefix,
'miniprogram_prefix' => $miniprogramPrefix
];
}
// 只有商户前缀,没有小程序前缀
if (!empty($merchantPrefix) && strlen($merchantPrefix) === 3) {
return ['merchant_prefix' => $merchantPrefix];
}
}
return null;
}
}