taiwan-payment-skill 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/README.md +197 -0
  2. package/assets/taiwan-payment/CLAUDE.md +297 -0
  3. package/assets/taiwan-payment/EXAMPLES.md +1425 -0
  4. package/assets/taiwan-payment/README.md +306 -0
  5. package/assets/taiwan-payment/SKILL.md +857 -0
  6. package/assets/taiwan-payment/data/error-codes.csv +20 -0
  7. package/assets/taiwan-payment/data/field-mappings.csv +15 -0
  8. package/assets/taiwan-payment/data/operations.csv +8 -0
  9. package/assets/taiwan-payment/data/payment-methods.csv +24 -0
  10. package/assets/taiwan-payment/data/providers.csv +4 -0
  11. package/assets/taiwan-payment/data/reasoning.csv +32 -0
  12. package/assets/taiwan-payment/data/troubleshooting.csv +18 -0
  13. package/assets/taiwan-payment/references/ecpay-payment-api.md +880 -0
  14. package/assets/taiwan-payment/references/newebpay-payment-api.md +677 -0
  15. package/assets/taiwan-payment/references/payuni-payment-api.md +997 -0
  16. package/assets/taiwan-payment/scripts/core.py +288 -0
  17. package/assets/taiwan-payment/scripts/recommend.py +269 -0
  18. package/assets/taiwan-payment/scripts/search.py +185 -0
  19. package/assets/taiwan-payment/scripts/test_payment.py +358 -0
  20. package/assets/templates/base/quick-reference.md +370 -0
  21. package/assets/templates/base/skill-content.md +851 -0
  22. package/assets/templates/platforms/antigravity.json +25 -0
  23. package/assets/templates/platforms/claude.json +26 -0
  24. package/assets/templates/platforms/codebuddy.json +25 -0
  25. package/assets/templates/platforms/codex.json +25 -0
  26. package/assets/templates/platforms/continue.json +25 -0
  27. package/assets/templates/platforms/copilot.json +25 -0
  28. package/assets/templates/platforms/cursor.json +25 -0
  29. package/assets/templates/platforms/gemini.json +25 -0
  30. package/assets/templates/platforms/kiro.json +25 -0
  31. package/assets/templates/platforms/opencode.json +25 -0
  32. package/assets/templates/platforms/qoder.json +25 -0
  33. package/assets/templates/platforms/roocode.json +25 -0
  34. package/assets/templates/platforms/trae.json +25 -0
  35. package/assets/templates/platforms/windsurf.json +25 -0
  36. package/dist/index.js +17095 -0
  37. package/package.json +58 -0
@@ -0,0 +1,185 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Taiwan Payment 搜索 CLI
4
+
5
+ 命令行搜索工具,支援多種輸出格式
6
+
7
+ 用法:
8
+ python search.py "信用卡" # 自動偵測域
9
+ python search.py "10100058" --domain error # 指定域
10
+ python search.py "金額" --format json # JSON 輸出
11
+ python search.py "ECPay" --domain all # 全域搜索
12
+ """
13
+
14
+ import argparse
15
+ import sys
16
+ from pathlib import Path
17
+ import json
18
+ from typing import List, Dict, Tuple
19
+
20
+ # 添加父目錄到 path
21
+ sys.path.insert(0, str(Path(__file__).parent))
22
+
23
+ from core import search, search_all, CSV_CONFIG
24
+
25
+
26
+ def format_ascii_box(title: str, content: List[str], width: int = 80, style: str = 'double') -> str:
27
+ """繪製 ASCII 邊框"""
28
+ if style == 'double':
29
+ top = '╔' + '═' * (width - 2) + '╗'
30
+ mid = '╠' + '═' * (width - 2) + '╣'
31
+ bot = '╚' + '═' * (width - 2) + '╝'
32
+ side = '║'
33
+ else:
34
+ top = '┌' + '─' * (width - 2) + '┐'
35
+ mid = '├' + '─' * (width - 2) + '┤'
36
+ bot = '└' + '─' * (width - 2) + '┘'
37
+ side = '│'
38
+
39
+ lines = [top]
40
+ lines.append(f'{side} {title.center(width - 4)} {side}')
41
+ lines.append(mid)
42
+
43
+ for line in content:
44
+ # 分割長行
45
+ if len(line) > width - 4:
46
+ words = line.split()
47
+ current_line = ''
48
+ for word in words:
49
+ if len(current_line) + len(word) + 1 < width - 4:
50
+ current_line += word + ' '
51
+ else:
52
+ lines.append(f'{side} {current_line.ljust(width - 4)} {side}')
53
+ current_line = word + ' '
54
+ if current_line:
55
+ lines.append(f'{side} {current_line.ljust(width - 4)} {side}')
56
+ else:
57
+ lines.append(f'{side} {line.ljust(width - 4)} {side}')
58
+
59
+ lines.append(bot)
60
+ return '\n'.join(lines)
61
+
62
+
63
+ def format_result_ascii(results: List[Dict], domain: str) -> str:
64
+ """ASCII 格式輸出"""
65
+ if not results:
66
+ return f'查無結果 (域: {domain})'
67
+
68
+ output = []
69
+ output.append('')
70
+ output.append(f'搜索域: {domain}')
71
+ output.append(f'找到 {len(results)} 筆結果')
72
+ output.append('=' * 80)
73
+
74
+ for i, result in enumerate(results, 1):
75
+ score = result.pop('_score', 0)
76
+ result.pop('_domain', None)
77
+
78
+ output.append(f'\n[結果 #{i}] 評分: {score}')
79
+ output.append('-' * 80)
80
+
81
+ for key, value in result.items():
82
+ if value:
83
+ key_display = key.replace('_', ' ').title()
84
+ output.append(f'{key_display:20s}: {value}')
85
+
86
+ return '\n'.join(output)
87
+
88
+
89
+ def format_all_results_ascii(all_results: Dict[str, List]) -> str:
90
+ """全域搜索 ASCII 輸出"""
91
+ if not all_results:
92
+ return '查無結果'
93
+
94
+ output = []
95
+ output.append('')
96
+ output.append(f'全域搜索 - 找到 {len(all_results)} 個域有結果')
97
+ output.append('=' * 80)
98
+
99
+ for domain, results in all_results.items():
100
+ output.append(f'\n【{domain.upper()}】 ({len(results)} 筆)')
101
+ output.append('-' * 80)
102
+
103
+ for i, result in enumerate(results, 1):
104
+ score = result.pop('_score', 0)
105
+ result.pop('_domain', None)
106
+
107
+ output.append(f' [{i}] 評分: {score}')
108
+
109
+ # 顯示關鍵欄位
110
+ if domain == 'provider':
111
+ output.append(f' 服務商: {result.get("display_name", "")}')
112
+ output.append(f' 加密: {result.get("auth_method", "")}')
113
+ elif domain == 'error':
114
+ output.append(f' 錯誤碼: {result.get("code", "")} - {result.get("message_zh", "")}')
115
+ output.append(f' 解決: {result.get("solution", "")}')
116
+ elif domain == 'payment_method':
117
+ output.append(f' 方式: {result.get("name_zh", "")}')
118
+ output.append(f' 說明: {result.get("description", "")}')
119
+ else:
120
+ # 顯示前 3 個欄位
121
+ for key, value in list(result.items())[:3]:
122
+ if value:
123
+ output.append(f' {key}: {value}')
124
+
125
+ output.append('')
126
+
127
+ return '\n'.join(output)
128
+
129
+
130
+ def main():
131
+ parser = argparse.ArgumentParser(
132
+ description='台灣金流搜索工具',
133
+ formatter_class=argparse.RawDescriptionHelpFormatter,
134
+ epilog='''
135
+ 範例:
136
+ python search.py "信用卡" # 自動偵測域
137
+ python search.py "10100058" --domain error # 搜索錯誤碼
138
+ python search.py "ECPay" --format json # JSON 輸出
139
+ python search.py "金額" --domain all # 全域搜索
140
+
141
+ 可用域:
142
+ provider, operation, error, field, payment_method, troubleshoot, reasoning, all
143
+ '''
144
+ )
145
+
146
+ parser.add_argument('query', type=str, help='搜索查詢')
147
+ parser.add_argument(
148
+ '--domain', '-d',
149
+ type=str,
150
+ choices=list(CSV_CONFIG.keys()) + ['all'],
151
+ help='搜索域 (不指定則自動偵測)'
152
+ )
153
+ parser.add_argument(
154
+ '--format', '-f',
155
+ choices=['ascii', 'json'],
156
+ default='ascii',
157
+ help='輸出格式'
158
+ )
159
+ parser.add_argument(
160
+ '--max', '-m',
161
+ type=int,
162
+ default=5,
163
+ help='最大結果數'
164
+ )
165
+
166
+ args = parser.parse_args()
167
+
168
+ # 執行搜索
169
+ if args.domain == 'all':
170
+ results = search_all(args.query, max_per_domain=args.max)
171
+ if args.format == 'json':
172
+ print(json.dumps(results, ensure_ascii=False, indent=2))
173
+ else:
174
+ print(format_all_results_ascii(results))
175
+ else:
176
+ results = search(args.query, domain=args.domain, max_results=args.max)
177
+ if args.format == 'json':
178
+ print(json.dumps(results, ensure_ascii=False, indent=2))
179
+ else:
180
+ domain = results[0]['_domain'] if results else (args.domain or 'unknown')
181
+ print(format_result_ascii(results, domain))
182
+
183
+
184
+ if __name__ == '__main__':
185
+ main()
@@ -0,0 +1,358 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ 台灣金流 API 連線測試腳本
4
+
5
+ 支援平台: ECPay, NewebPay, PayUNi
6
+
7
+ 用法:
8
+ python test_payment.py # 測試 ECPay 連線
9
+ python test_payment.py --platform newebpay # 測試 NewebPay 連線
10
+ python test_payment.py --platform payuni # 測試 PayUNi 連線
11
+ python test_payment.py --list # 列出支援平台
12
+ python test_payment.py --create # 建立測試訂單
13
+ python test_payment.py --query ORDER123 # 查詢訂單
14
+ """
15
+
16
+ import hashlib
17
+ import urllib.parse
18
+ import time
19
+ import sys
20
+ import argparse
21
+ from datetime import datetime
22
+
23
+ try:
24
+ import requests
25
+ HAS_REQUESTS = True
26
+ except ImportError:
27
+ HAS_REQUESTS = False
28
+
29
+ try:
30
+ from Crypto.Cipher import AES
31
+ from Crypto.Util.Padding import pad
32
+ HAS_CRYPTO = True
33
+ except ImportError:
34
+ HAS_CRYPTO = False
35
+
36
+
37
+ # 平台設定
38
+ PLATFORMS = {
39
+ 'ecpay': {
40
+ 'name': '綠界科技 ECPay',
41
+ 'merchant_id': '3002607',
42
+ 'hash_key': 'pwFHCqoQZGmho4w6',
43
+ 'hash_iv': 'EkRm7iFT261dpevs',
44
+ 'api_url': 'https://payment-stage.ecpay.com.tw/Cashier/AioCheckOut/V5',
45
+ 'query_url': 'https://payment-stage.ecpay.com.tw/Cashier/QueryTradeInfo/V5',
46
+ 'test_url': 'https://payment-stage.ecpay.com.tw/',
47
+ 'auth_method': 'SHA256',
48
+ 'test_card': '4311-9522-2222-2222',
49
+ },
50
+ 'newebpay': {
51
+ 'name': '藍新金流 NewebPay',
52
+ 'merchant_id': '請至後台申請',
53
+ 'hash_key': '請至後台申請',
54
+ 'hash_iv': '請至後台申請',
55
+ 'api_url': 'https://ccore.newebpay.com/MPG/mpg_gateway',
56
+ 'query_url': 'https://ccore.newebpay.com/API/QueryTradeInfo',
57
+ 'test_url': 'https://ccore.newebpay.com/',
58
+ 'auth_method': 'AES-256-CBC',
59
+ 'test_card': '4000-2211-1111-1111',
60
+ },
61
+ 'payuni': {
62
+ 'name': '統一金流 PAYUNi',
63
+ 'merchant_id': '請至後台申請',
64
+ 'hash_key': '請至後台申請',
65
+ 'hash_iv': '請至後台申請',
66
+ 'api_url': 'https://sandbox-api.payuni.com.tw/api/upp',
67
+ 'query_url': 'https://sandbox-api.payuni.com.tw/api/trade_query',
68
+ 'test_url': 'https://sandbox-api.payuni.com.tw/',
69
+ 'auth_method': 'AES-256-GCM',
70
+ 'test_card': '4000-2211-1111-1111',
71
+ },
72
+ }
73
+
74
+
75
+ def generate_ecpay_mac(params: dict, hash_key: str, hash_iv: str) -> str:
76
+ """ECPay CheckMacValue (SHA256)"""
77
+ sorted_params = sorted(params.items())
78
+ param_str = '&'.join(f'{k}={v}' for k, v in sorted_params)
79
+ raw = f'HashKey={hash_key}&{param_str}&HashIV={hash_iv}'
80
+ encoded = urllib.parse.quote_plus(raw).lower()
81
+ return hashlib.sha256(encoded.encode('utf-8')).hexdigest().upper()
82
+
83
+
84
+ def generate_newebpay_trade_info(params: dict, hash_key: str, hash_iv: str) -> str:
85
+ """NewebPay TradeInfo (AES-256-CBC)"""
86
+ if not HAS_CRYPTO:
87
+ return "需要 pycryptodome 套件"
88
+ query_string = urllib.parse.urlencode(params)
89
+ cipher = AES.new(hash_key.encode('utf-8'), AES.MODE_CBC, hash_iv.encode('utf-8'))
90
+ padded = pad(query_string.encode('utf-8'), AES.block_size)
91
+ encrypted = cipher.encrypt(padded)
92
+ return encrypted.hex()
93
+
94
+
95
+ def generate_newebpay_sha(trade_info: str, hash_key: str, hash_iv: str) -> str:
96
+ """NewebPay TradeSha (SHA256)"""
97
+ raw = f'HashKey={hash_key}&{trade_info}&HashIV={hash_iv}'
98
+ return hashlib.sha256(raw.encode('utf-8')).hexdigest().upper()
99
+
100
+
101
+ def generate_payuni_encrypt(params: dict, hash_key: str, hash_iv: str) -> str:
102
+ """PayUNi EncryptInfo (AES-256-GCM)"""
103
+ if not HAS_CRYPTO:
104
+ return "需要 pycryptodome 套件"
105
+ query_string = urllib.parse.urlencode(params)
106
+ cipher = AES.new(hash_key.encode('utf-8'), AES.MODE_GCM, nonce=hash_iv.encode('utf-8'))
107
+ encrypted, tag = cipher.encrypt_and_digest(query_string.encode('utf-8'))
108
+ return (encrypted + tag).hex()
109
+
110
+
111
+ def generate_payuni_hash(encrypt_info: str, hash_key: str, hash_iv: str) -> str:
112
+ """PayUNi HashInfo (SHA256)"""
113
+ raw = encrypt_info + hash_key + hash_iv
114
+ return hashlib.sha256(raw.encode('utf-8')).hexdigest().upper()
115
+
116
+
117
+ def test_connection(platform: str):
118
+ """測試 API 連線"""
119
+ config = PLATFORMS.get(platform)
120
+ if not config:
121
+ print(f'錯誤: 不支援的平台 "{platform}"')
122
+ print(f'支援的平台: {", ".join(PLATFORMS.keys())}')
123
+ sys.exit(1)
124
+
125
+ print('=' * 60)
126
+ print(f'{config["name"]} API 連線測試')
127
+ print('=' * 60)
128
+ print()
129
+
130
+ # 測試環境資訊
131
+ print('[測試環境]')
132
+ print(f' 平台: {config["name"]}')
133
+ print(f' 商店代號: {config["merchant_id"]}')
134
+ print(f' 加密方式: {config["auth_method"]}')
135
+ print(f' 測試網址: {config["test_url"]}')
136
+ print()
137
+
138
+ # 測試加密計算
139
+ print('[加密計算測試]')
140
+ if platform == 'ecpay':
141
+ test_params = {
142
+ 'MerchantID': config['merchant_id'],
143
+ 'MerchantTradeNo': 'TEST123456',
144
+ 'TotalAmount': 100,
145
+ }
146
+ mac = generate_ecpay_mac(test_params, config['hash_key'], config['hash_iv'])
147
+ print(f' CheckMacValue: {mac}')
148
+ print(f' 長度: {len(mac)} (應為 64)')
149
+ print(f' 格式: {"正確" if len(mac) == 64 else "錯誤"}')
150
+
151
+ elif platform == 'newebpay':
152
+ if HAS_CRYPTO and config['hash_key'] != '請至後台申請':
153
+ test_params = {
154
+ 'MerchantID': config['merchant_id'],
155
+ 'MerchantOrderNo': 'TEST123456',
156
+ 'Amt': 100,
157
+ }
158
+ trade_info = generate_newebpay_trade_info(test_params, config['hash_key'], config['hash_iv'])
159
+ trade_sha = generate_newebpay_sha(trade_info, config['hash_key'], config['hash_iv'])
160
+ print(f' TradeInfo: {trade_info[:50]}...')
161
+ print(f' TradeSha: {trade_sha}')
162
+ else:
163
+ print(' (需要設定 hash_key/hash_iv 及 pycryptodome 套件)')
164
+
165
+ elif platform == 'payuni':
166
+ if HAS_CRYPTO and config['hash_key'] != '請至後台申請':
167
+ test_params = {
168
+ 'MerID': config['merchant_id'],
169
+ 'MerTradeNo': 'TEST123456',
170
+ 'TradeAmt': 100,
171
+ }
172
+ encrypt_info = generate_payuni_encrypt(test_params, config['hash_key'], config['hash_iv'])
173
+ hash_info = generate_payuni_hash(encrypt_info, config['hash_key'], config['hash_iv'])
174
+ print(f' EncryptInfo: {encrypt_info[:50]}...')
175
+ print(f' HashInfo: {hash_info}')
176
+ else:
177
+ print(' (需要設定 hash_key/hash_iv 及 pycryptodome 套件)')
178
+ print()
179
+
180
+ # 測試網路連線
181
+ if HAS_REQUESTS:
182
+ print('[網路連線測試]')
183
+ try:
184
+ response = requests.head(config['test_url'], timeout=5)
185
+ print(f' 狀態碼: {response.status_code}')
186
+ print(f' 連線: {"成功" if response.status_code < 500 else "失敗"}')
187
+ except requests.RequestException as e:
188
+ print(f' 連線失敗: {e}')
189
+ else:
190
+ print('[網路連線測試]')
191
+ print(' (需要 requests 套件: pip install requests)')
192
+ print()
193
+
194
+ # 顯示測試信用卡
195
+ print('[測試信用卡]')
196
+ print(f' 卡號: {config["test_card"]}')
197
+ print(' 有效期: 任意未過期日期')
198
+ print(' CVV: 任意三碼')
199
+ print()
200
+
201
+ print('=' * 60)
202
+ print('測試完成')
203
+ print('=' * 60)
204
+
205
+
206
+ def create_test_order(platform: str):
207
+ """建立測試訂單"""
208
+ config = PLATFORMS.get(platform)
209
+ if not config:
210
+ print(f'錯誤: 不支援的平台 "{platform}"')
211
+ sys.exit(1)
212
+
213
+ if config['merchant_id'] == '請至後台申請':
214
+ print(f'錯誤: 請先設定 {config["name"]} 的測試帳號')
215
+ print('請編輯此腳本,填入您的測試商店資訊')
216
+ sys.exit(1)
217
+
218
+ order_id = f'TEST{int(time.time())}'
219
+ trade_date = datetime.now().strftime('%Y/%m/%d %H:%M:%S')
220
+
221
+ print('=' * 60)
222
+ print(f'建立 {config["name"]} 測試訂單')
223
+ print('=' * 60)
224
+ print()
225
+ print(f'訂單編號: {order_id}')
226
+ print(f'交易時間: {trade_date}')
227
+ print(f'金額: 100 TWD')
228
+ print()
229
+
230
+ if platform == 'ecpay':
231
+ params = {
232
+ 'MerchantID': config['merchant_id'],
233
+ 'MerchantTradeNo': order_id,
234
+ 'MerchantTradeDate': trade_date,
235
+ 'PaymentType': 'aio',
236
+ 'TotalAmount': 100,
237
+ 'TradeDesc': urllib.parse.quote('測試訂單'),
238
+ 'ItemName': '測試商品 x 1',
239
+ 'ReturnURL': 'https://example.com/callback',
240
+ 'ChoosePayment': 'Credit',
241
+ 'EncryptType': 1,
242
+ }
243
+ params['CheckMacValue'] = generate_ecpay_mac(params, config['hash_key'], config['hash_iv'])
244
+
245
+ html = f'''<!DOCTYPE html>
246
+ <html>
247
+ <head><meta charset="UTF-8"><title>ECPay 測試</title></head>
248
+ <body>
249
+ <h1>ECPay 測試訂單 {order_id}</h1>
250
+ <form method="post" action="{config['api_url']}">
251
+ '''
252
+ for k, v in params.items():
253
+ html += f'<input type="hidden" name="{k}" value="{v}">\n'
254
+ html += '<button type="submit">前往付款</button>\n</form>\n</body></html>'
255
+
256
+ filename = f'ecpay_test_{order_id}.html'
257
+ with open(filename, 'w', encoding='utf-8') as f:
258
+ f.write(html)
259
+
260
+ print(f'已產生測試頁面: {filename}')
261
+ print('請在瀏覽器中開啟此檔案進行付款測試')
262
+ print()
263
+ print(f'測試信用卡: {config["test_card"]}')
264
+
265
+ else:
266
+ print(f'{platform} 的測試訂單建立功能需要 pycryptodome 套件')
267
+ print('請執行: pip install pycryptodome')
268
+
269
+
270
+ def query_order(platform: str, order_id: str):
271
+ """查詢訂單狀態"""
272
+ if not HAS_REQUESTS:
273
+ print('錯誤: 需要 requests 套件')
274
+ sys.exit(1)
275
+
276
+ config = PLATFORMS.get(platform)
277
+ if not config:
278
+ print(f'錯誤: 不支援的平台 "{platform}"')
279
+ sys.exit(1)
280
+
281
+ print('=' * 60)
282
+ print(f'查詢 {config["name"]} 訂單: {order_id}')
283
+ print('=' * 60)
284
+ print()
285
+
286
+ if platform == 'ecpay':
287
+ params = {
288
+ 'MerchantID': config['merchant_id'],
289
+ 'MerchantTradeNo': order_id,
290
+ 'TimeStamp': int(time.time()),
291
+ }
292
+ params['CheckMacValue'] = generate_ecpay_mac(params, config['hash_key'], config['hash_iv'])
293
+
294
+ try:
295
+ response = requests.post(config['query_url'], data=params, timeout=10)
296
+ print(f'HTTP 狀態碼: {response.status_code}')
297
+ print('回應內容:')
298
+ print(response.text)
299
+ except requests.RequestException as e:
300
+ print(f'查詢失敗: {e}')
301
+ else:
302
+ print(f'{platform} 的查詢功能需要額外設定')
303
+
304
+
305
+ def list_platforms():
306
+ """列出支援的平台"""
307
+ print('=' * 60)
308
+ print('支援的金流平台')
309
+ print('=' * 60)
310
+ print()
311
+ for key, config in PLATFORMS.items():
312
+ print(f' {key:12} - {config["name"]}')
313
+ print(f' 加密: {config["auth_method"]}')
314
+ print(f' 測試: {config["test_url"]}')
315
+ print()
316
+
317
+
318
+ def main():
319
+ parser = argparse.ArgumentParser(
320
+ description='台灣金流 API 測試工具 (支援 ECPay/NewebPay/PayUNi)'
321
+ )
322
+ parser.add_argument(
323
+ '--platform', '-p',
324
+ type=str,
325
+ default='ecpay',
326
+ help='金流平台 (ecpay/newebpay/payuni)'
327
+ )
328
+ parser.add_argument(
329
+ '--list', '-l',
330
+ action='store_true',
331
+ help='列出支援的平台'
332
+ )
333
+ parser.add_argument(
334
+ '--create',
335
+ action='store_true',
336
+ help='建立測試訂單'
337
+ )
338
+ parser.add_argument(
339
+ '--query',
340
+ type=str,
341
+ metavar='ORDER_ID',
342
+ help='查詢訂單狀態'
343
+ )
344
+
345
+ args = parser.parse_args()
346
+
347
+ if args.list:
348
+ list_platforms()
349
+ elif args.create:
350
+ create_test_order(args.platform)
351
+ elif args.query:
352
+ query_order(args.platform, args.query)
353
+ else:
354
+ test_connection(args.platform)
355
+
356
+
357
+ if __name__ == '__main__':
358
+ main()