better-staridc-MNBT
1<?php
2/**
3 * domain_shop 插件 - ymgm 订单结算
4 * 迁移自 MPHX/lib/pay.function.php 的 $ddxx['lx']=='ymgm' 分支
5 *
6 * 由 order.paid 钩子触发,处理:
7 * 1. 调宝塔 API 绑定域名到用户主机(所有通道都做)
8 * 2. 共享主机(type==1)改 hosts 文件 + 反向代理(所有通道都做)
9 * 3. 写 plg_domain_product.json 购买者列表(所有通道都做)
10 * 4. 根据 channel 分支:
11 * - pan(泛解析):不调 DNS API,依赖域名整体泛 A 记录到节点 IP
12 * - dnsapi:通过商品的 provider_id 调对应 DNS 服务商 API 建 A 记录指向节点 IP
13 */
14if (!defined('IN_CRONLITE')) exit;
15
16function domain_shop_settle_ymgm($order, $ctx = [])
17{
18 global $DB, $date, $conf;
19
20 if (!is_array($order)) return;
21 $out_trade_no = $order['ddh'] ?? '';
22 $ddxx_cs = json_decode($order['cs'] ?? '{}', true);
23 if (!is_array($ddxx_cs)) $ddxx_cs = [];
24
25 $ddxx_url = $ddxx_cs['url_zd'] ?? ''; // 一级域名
26 $user = $ddxx_cs['user'] ?? '';
27 $yhc = $DB->get_row_prepare("SELECT * FROM MN_zj WHERE user=? limit 1", [$user]);
28 if (!$yhc) {
29 if (function_exists('mnbt_pay_log')) {
30 mnbt_pay_log('域名购买主机不存在 用户' . $user, '处理失败', $out_trade_no);
31 }
32 return;
33 }
34 $zjid = $yhc['btid'];
35 $ssbt = $yhc['ssbt'];
36
37 // 查商品(plg_domain_product)
38 $bscx = domain_product_get_by_url($ddxx_url);
39 if (!$bscx) {
40 if (function_exists('mnbt_pay_log')) {
41 mnbt_pay_log('域名商品不存在 ' . $ddxx_url, '处理失败', $out_trade_no);
42 }
43 return;
44 }
45
46 include_once __DIR__ . "/../../user/class.php";
47 $cert = $DB->get_row_prepare("SELECT * FROM MN_bt WHERE btdh=? limit 1", [$ssbt]);
48 if (!$cert) {
49 if (function_exists('mnbt_pay_log')) {
50 mnbt_pay_log('宝塔节点不存在 ' . $ssbt, '处理失败', $out_trade_no);
51 }
52 return;
53 }
54 $btipe = ($cert['ptl'] == 'true' ? 'https' : 'http') . '://' . $cert['btip'] . ':' . $cert['btdk'];
55 $btkeye = $cert['btmy'];
56 $os_xt = $cert['btos'] == '1' ? $conf['hxi'] . '/' : $conf['hxo'] . '/';
57
58 $ul_url_ym = $ddxx_cs['url_zy'] ?? '';
59 $path = $ddxx_cs['path'] ?? '/';
60 $apie = new bt_api_set($btipe, $btkeye);
61 $api = new bt_api($btipe, $btkeye);
62
63 // 调宝塔 API 绑定域名
64 if (strpos($path, '/') !== false) {
65 $r_data = $apie->btapi_addym($zjid, $yhc['sqldz'], $ul_url_ym);
66 } else {
67 $r_data = $api->addzml($zjid, $ul_url_ym, $path, $os_xt . $yhc['sqldz']);
68 }
69 $are = $r_data['status'] ?? false;
70
71 // 失败重试:随机化前缀(与原核心逻辑一致)
72 if ($are != 'true' && $are !== true) {
73 $yr_c = true;
74 for ($yr_a = 1; $yr_c && $yr_a <= 20; $yr_a++) {
75 $hskr = mt_rand(4, 10);
76 $rqsj = md5($date . $user . $yr_a . mt_rand(100, 999));
77 $wjler = substr($rqsj, $hskr, 5);
78 $ul_url_ym = $wjler . '.' . $ddxx_cs['url_zd'];
79 if (strpos($path, '/') !== false) {
80 $r_data = $apie->btapi_addym($zjid, $yhc['sqldz'], $ul_url_ym);
81 } else {
82 $r_data = $api->addzml($zjid, $ul_url_ym, $path, $os_xt . $yhc['sqldz']);
83 }
84 $yr_c = (($r_data['status'] ?? false) == 'true' || ($r_data['status'] ?? false) === true) ? false : true;
85 }
86 if ($yr_c) {
87 if (function_exists('mnbt_pay_log')) {
88 mnbt_pay_log('域名绑定失败 ' . $ul_url_ym, '处理失败', $out_trade_no);
89 }
90 return;
91 }
92 }
93
94 // 共享主机特殊处理(原核心逻辑:改 hosts 文件 + 反向代理)
95 if (($ddxx_cs['type'] ?? '') == '1') {
96 $hhf = "\n";
97 $apic = new bt_api($btipe, $btkeye);
98 $get_host_hq = $apic->GetLogswt($ddxx_cs['hostly']);
99 $host_wjnr = ($get_host_hq['data'] ?? '') . $hhf . $ddxx_cs['yz_ip'] . ' ' . $ul_url_ym;
100 $apic->GetLogswh($host_wjnr, $ddxx_cs['hostly']);
101 $apic->fxdl_add($ul_url_ym, $yhc['sqldz']);
102 }
103
104 // 写 plg_domain_product.json 购买者列表
105 $bs_tj = json_decode($bscx['json'], true);
106 if (!is_array($bs_tj)) $bs_tj = [];
107 if (!in_array($user, $bs_tj)) array_push($bs_tj, $user);
108 $tj_jg = json_encode($bs_tj, 256);
109 if (!$DB->query_prepare("update `plg_domain_product` set `json`=? where `url`=?", [$tj_jg, $ddxx_url])) {
110 if (function_exists('mnbt_pay_log')) {
111 mnbt_pay_log('域名购买记录写入失败 用户' . $user, '处理失败', $out_trade_no);
112 }
113 return;
114 }
115
116 // 【通道分支】根据商品的 channel 决定是否调 DNS API 建 A 记录
117 // - pan(泛解析):不调 DNS API,依赖域名整体泛解析到节点 IP
118 // - dnsapi:通过商品的 provider_id 调对应 DNS 服务商 API 建 A 记录
119 $channel = $bscx['channel'] ?? 'pan';
120 $providerId = (int)($bscx['provider_id'] ?? 0);
121
122 if ($channel === 'dnsapi' && $providerId > 0) {
123 // 主机记录:购买时使用的前缀(url_qz),如果随机化了则用实际前缀
124 $prefix = explode('.', $ul_url_ym)[0];
125 $recordName = ($prefix === $ddxx_cs['url_qz']) ? $ddxx_cs['url_qz'] : $prefix;
126 $ip = $cert['btip'];
127 if ($ip) {
128 $r = dns_record_create($user, $providerId, $ddxx_url, $recordName, 'A', $ip, 600, 1);
129 if (function_exists('mnbt_pay_log') && empty($r['ok'])) {
130 mnbt_pay_log('DNS A 记录自动创建失败:' . ($r['msg'] ?? ''), '处理警告', $out_trade_no);
131 }
132 }
133 }
134
135 if (function_exists('mnbt_pay_log')) {
136 mnbt_pay_log('域名购买处理成功 用户' . $user . ' 域名' . $ul_url_ym . '(通道:' . $channel . ')', '处理成功', $out_trade_no);
137 }
138}