一份面向在泰华人的实用指南:三类可用的支付渠道、按签证细分的资格分析、NITMX 跨境二维码捷径、泰国合规要求,以及通过 Omise 和 2C2P 接入微信支付的可运行示例代码。
选择哪条支付通道,取决于你的客户群和你能提供的身份证明。现实中绝大多数商家会把"泰国本地通道"(服务泰国买家)和"中国钱包通道"(服务大陆买家)组合使用。
面向泰国本地买家,以泰铢结算。
面向中国大陆买家——这是你最自然的客群。
暂时无法开设泰国银行账户时使用。
| 方式 | 买家 | 接入难度 | 典型费率 | 结算到 | 需要泰国银行? |
|---|---|---|---|---|---|
| PromptPay 二维码(通过 Opn Payments / Omise) | 泰国居民 + 在泰中国游客(NITMX 跨境,详见下文) | 低 | 1.65%(Opn)· 0.8% Xendit · 1.0–1.5% Pay Solutions | 泰国银行,T+1 | 是 |
| 微信支付(Omise / 2C2P) | 中国大陆(App 内付款) | 中 | 实体店 1.65% / 线上 3.65%(Opn) | 泰国银行,T+2 | 是(或用 Airwallex) |
| Alipay+(Omise / 2C2P) | 中国及亚太 25 种钱包 | 中 | 实体店 1.65% / 线上 3.65%(Opn) | 泰国银行,T+2 | 是 |
| TrueMoney 钱包 | 泰国居民 | 低 | 1.5–2.0% | TrueMoney → 泰国银行 | 否(仅需泰国手机号) |
| Wise Business | 任意,电汇 | 中 | 约 0.5% 汇兑 | 多币种 Wise 账户 | 否 |
| Airwallex | 任意,含卡 / 微信 | 中 | 2.9% + 笔费 | 多币种 Airwallex | 否 |
| USDT (TRON) via NOWPayments | 能接受加密币的买家 | 低 | 0.5–1.0% | 你自己的加密钱包 | 否 |
| PayPal CN | 国际买家 | 在泰国较难 | 4.4% + 固定费 | 银联 / 中国银行 | 否 |
假设你有护照、能提供泰国居住证明,但没有泰国身份证,下表显示各方案的开户难度。
几乎所有方案最终都要求你拥有泰国银行账户或泰国营业登记,而这两者都由你的签证决定。下表说明每种常见签证对在泰华人来说真正解锁了什么。
| 签证类型 | 能开泰国银行? | 能注册公司? | 推荐通道 | 典型在泰华人画像 |
|---|---|---|---|---|
| 旅游签 / 免签 | 否(极少数:Bangkok Bank 通过中介 + 大额存款) | 否 | 仅限 Wise / Airwallex / USDT | 云南来的短期商人、跑货老板 |
| ED 学生签(语言学校 / 泰拳) | 有时——Krungsri、Bangkok Bank 凭学校信函 + ฿20k 存款 | 否(不允许工作) | 仅限个人 PromptPay,不可商用 | 清迈学语言、年纪较轻的中国学生 |
| DTV 签证(5 年目的地泰国签) | 分支行而异,部分要求工作证 | 个体可申请,但活跃经营在法律上仍属灰色 | 主用 Wise / Airwallex;条件允许时用 PromptPay 辅助 | 远程办公的中国自由职业者、数字游民 |
| O 类非移民签(泰国配偶) | 是——凭结婚证即可 | 是——配偶可共有,可办工作证 | 完整 Omise / 2C2P 方案,开通微信 + 支付宝+ | 嫁/娶泰国人的中国配偶 |
| B 类非移民签 + 工作证 | 是——最容易的路径 | 是——可在 FBA 限制内独资经营 | 完整 Omise / 2C2P 方案 | 曼谷 / EEC 的中资企业员工 |
| 泰国精英签证(Privilege / Elite) | 是——有专属服务协助开户 | 可注册,但精英签本身不带工作权——需配合工作证 | 通过泰国公司用完整方案;筹建期用 Airwallex | 富裕的中国投资人、退休族、家办成员 |
| LTR 长期居留签证 | 是——合作银行快速通道 | 是——内置数字工作证 | 完整 Omise / 2C2P,所有路径中阻力最小 | 高薪科技人才、全球高净值人群 |
| 退休签(Non-O / O-A / O-X) | 是 | 禁止工作——不可办营业登记 | 仅限个人 PromptPay,被动收款 / 家用 | 清迈、华欣等地的中国退休人士 |
| Smart 智慧签证(S / T / I / E) | 是——BoI 担保 | 是——Smart-S 含创业工作权 | 完整方案;Smart-S 创始人可直接申请 Omise | 中国科技创业者、BoI 推广投资人 |
| PR 永久居留 | 是 | 是——多数权利与泰国国民相同 | 完整方案,无任何限制 | 居住 10 年以上的资深华人 |
旅游签 → DTV(5 年),凭远程工作或"软实力"项目(泰拳、泰餐等)资格申请,在昆明或香港领事馆办理。
解锁 5 年多次入境,开户成功率提高,但法律上不可向泰国本地客户经营销售。
与泰国人结婚 → O 类签证。由配偶共同登记个体工商户,再以该营业为基础办工作证。
清迈最常见——开咖啡馆、做旅行、开工作室的中国人多走此路。
资金驱动:精英签(฿90 万–500 万换 5–20 年)或 LTR Wealthy Global Citizen(资产 100 万美元、年收入 8 万美元)。LTR 含工作权,精英签不含。
资金充足时最省事。精英签 + 泰国有限公司 = 完整经营权。
科技 / 创业路线:通过 dtsc.depa.or.th 背书的 Smart-S,或经 BoI 推广的出口型公司。
Omise 费率最低(BoI 公司常可议价),且自带工作权。
如果你的买家是来泰国旅游的中国游客(不是从大陆远程付款的居民),那你可能根本不需要单独申请微信支付或 Alipay+。NITMX(泰国国家支付清算中心)已与蚂蚁国际(Alipay+)、腾讯(微信支付)和银联建立了网络互联,中国游客可以直接用国内 App 扫描泰国标准 PromptPay 二维码付款。
展示一张普通 PromptPay 二维码即可。中国游客在国内打开支付宝或微信扫码付款——商家无需另外签约支付宝 / 微信收单。
买家以人民币按实时汇率扣款,商家以泰铢入账。结账流程里没有汇兑利差需要管理。
跨境清算指定走 Bangkok Bank 和 Krungthai Bank。在这两家开收款户路径最顺畅。
如果中国大陆买家在境内远程付款(购买时人不在泰国),NITMX 不适用——必须走 Omise / 2C2P 的微信支付或 Alipay+。NITMX 要求扫码时人在泰国境内或具备地理位置证明。
两家网关都把微信支付实现为"跳转 / QR 源"模式。你的服务端创建 charge,网关返回二维码图片(PC 端)或 weixin:// 深链(移动端),买家在微信内完成支付,服务端通过 webhook 对账。
// npm i omise express const express = require("express"); const omise = require("omise")({ publicKey: process.env.OMISE_PUBLIC_KEY, secretKey: process.env.OMISE_SECRET_KEY, }); const app = express(); app.use(express.json()); app.post("/api/checkout", async (req, res) => { const { amountTHB, orderId } = req.body; // 1. 创建 wechat_pay 类型的 source;金额单位是 satang(1 THB = 100) const source = await omise.sources.create({ type: "wechat_pay", amount: Math.round(amountTHB * 100), currency: "THB", }); // 2. 基于该 source 创建 charge const charge = await omise.charges.create({ amount: Math.round(amountTHB * 100), currency: "THB", source: source.id, return_uri: `https://yoursite.com/pay/return?order=${orderId}`, metadata: { orderId }, }); // 3. 返回二维码图片地址(PC)和深链(手机) res.json({ chargeId: charge.id, qrImageUri: charge.source.scannable_code?.image?.download_uri, deeplink: charge.authorize_uri, // 在手机上打开微信 status: charge.status, // 付款前为 "pending" }); }); app.listen(3000);
async function payWithWeChat(amountTHB, orderId) { const r = await fetch("/api/checkout", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ amountTHB, orderId }), }); const { qrImageUri, deeplink, chargeId } = await r.json(); const isMobile = /iPhone|Android/i.test(navigator.userAgent); if (isMobile) { window.location = deeplink; // → 唤起微信 } else { document.getElementById("qr").src = qrImageUri; pollChargeStatus(chargeId); // 可选:轮询付款状态 } }
app.post("/webhooks/omise", express.raw({ type: "application/json" }), async (req, res) => { const event = JSON.parse(req.body); // 不要相信 webhook body 的金额——务必重新拉取 if (event.key === "charge.complete") { const charge = await omise.charges.retrieve(event.data.id); if (charge.status === "successful" && charge.paid) { await markOrderPaid(charge.metadata.orderId, charge.amount); } } res.sendStatus(200); });
# pip install pyjwt requests flask import jwt, requests, time, uuid from flask import Flask, request, jsonify app = Flask(__name__) MERCHANT_ID = "JT01" SECRET_KEY = "YOUR_2C2P_SECRET_KEY" ENDPOINT = "https://sandbox-pgw.2c2p.com/payment/4.3/paymentToken" @app.route("/api/checkout", methods=["POST"]) def checkout(): body = request.json payload = { "merchantID": MERCHANT_ID, "invoiceNo": body["orderId"], "description": body["description"], "amount": body["amountTHB"], "currencyCode": "THB", "paymentChannel": ["WECHAT"], # 锁定为微信支付 "frontendReturnUrl": "https://yoursite.com/pay/return", "backendReturnUrl": "https://yoursite.com/webhooks/2c2p", "nonceStr": uuid.uuid4().hex, } token = jwt.encode(payload, SECRET_KEY, algorithm="HS256") r = requests.post(ENDPOINT, json={"payload": token}).json() decoded = jwt.decode(r["payload"], SECRET_KEY, algorithms=["HS256"]) # 返回托管收银台 URL —— 2C2P 在该页面展示微信二维码 return jsonify({ "redirectUrl": decoded["webPaymentUrl"], "paymentToken": decoded["paymentToken"], })
@app.route("/webhooks/2c2p", methods=["POST"]) def c2p_webhook(): token = request.json["payload"] try: data = jwt.decode(token, SECRET_KEY, algorithms=["HS256"]) except jwt.InvalidSignatureError: return ("bad sig", 400) # respCode "0000" = 成功(参见 2C2P 规范) if data["respCode"] == "0000" and data["channelCode"] == "WECHAT": mark_order_paid(data["invoiceNo"], data["amount"]) return ("", 200)
dashboard.omise.co 或 2c2p.com 注册并申请开通微信支付 + 支付宝+。下面是 Opn / 2C2P 在开通微信支付或 Alipay+ 之前会要求的文件 / 政策清单。别当成走过场——一半的拒绝都来自材料不全,而非业务本身有问题。
务必通过网关的托管页或重定向 / QR-source 模式接入,而非直接传卡 API。这一架构选择能把数千条 PCI DSS 控制项压缩为一份自评问卷(SAQ-A),网关成为敏感数据的"控制者",开通周期可缩短数月。
这个静态页面本身是一份说明,但如果它前端挂上一个本地智能体,就能回答"我是 ED 签证、客户来自昆明,应该用哪条通道?"并直接生成测试 charge。整个流程跑在你的笔记本上——不调用云端 LLM,也不会泄露商户密钥。
两个进程,同一个网络命名空间。浏览器 → 本地 FastAPI Worker → Ollama + 网关沙箱。除测试调用 Omise / 2C2P 外,没有任何数据离开你的电脑。
qwen3:8b 原生处理中文、泰语、英语——这正契合你的场景:买家说中文,网关文档是英文,银行表单是泰语。
自 v0.4 起,Ollama 的 /api/chat 支持 OpenAI 格式的 tools 数组。Agent 循环就是个普通 while 循环,无需 LangChain。
Omise 密钥、2C2P 商户号、甚至沙箱 webhook 都只在 127.0.0.1 流转。在泰国测试、外网受限时尤其有用。
用云端模型反复调试 prompt 和工具 schema 烧钱很快。本地推理让快速迭代阶段免费。
# Windows / macOS / Linux — ollama.com/download ollama pull qwen3:8b # 中文友好,约 5GB,支持工具调用 ollama pull llama3.1:8b # 仅英文场景的备选 # 验证服务在 11434 端口运行 curl http://localhost:11434/api/tags # 工具调用快速冒烟测试 curl http://localhost:11434/api/chat -d '{ "model": "qwen3:8b", "messages": [{"role":"user","content":"现在几点?"}], "tools": [{"type":"function","function":{ "name":"clock","description":"返回当前时间","parameters":{"type":"object","properties":{}} }}], "stream": false }'
from typing import Any FEES = { "promptpay": {"pct": 0.0095, "flat_thb": 2, "settles_to": "thai_bank"}, "wechat_pay": {"pct": 0.0290, "flat_thb": 0, "settles_to": "thai_bank"}, "alipay_plus": {"pct": 0.0290, "flat_thb": 0, "settles_to": "thai_bank"}, "truemoney": {"pct": 0.0175, "flat_thb": 0, "settles_to": "truemoney"}, "usdt_tron": {"pct": 0.0080, "flat_thb": 0, "settles_to": "crypto_wallet"}, } def lookup_fee(rail: str, amount_thb: float) -> dict: """计算指定通道的手续费和到账净额。""" f = FEES[rail] fee = amount_thb * f["pct"] + f["flat_thb"] return {"rail": rail, "fee_thb": round(fee, 2), "net_thb": round(amount_thb - fee, 2)} def pick_rail(visa: str, buyer_country: str, has_thai_bank: bool) -> dict: """根据商家签证和买家来源推荐通道。""" if not has_thai_bank: return {"rail": "wise_or_airwallex", "why": "无泰国银行,走多币种账户"} if visa in {"tourist", "ed", "retirement"}: return {"rail": "promptpay_personal", "why": "禁止商用——仅个人收款"} if buyer_country == "CN": return {"rail": "wechat_pay", "why": "中国买家——走 Omise 微信支付"} return {"rail": "promptpay", "why": "泰国本地默认通道"} def create_test_charge(rail: str, amount_thb: float) -> dict: # 调用 Omise 沙箱,返回二维码和 charge id(细节略) ... TOOLS: list[dict[str, Any]] = [ {"type": "function", "function": { "name": "lookup_fee", "description": "计算指定通道在某金额下的手续费和到账净额。", "parameters": {"type": "object", "properties": { "rail": {"type": "string", "enum": list(FEES.keys())}, "amount_thb": {"type": "number"} }, "required": ["rail", "amount_thb"]} }}, {"type": "function", "function": { "name": "pick_rail", "description": "根据商家签证和目标买家推荐支付通道。", "parameters": {"type": "object", "properties": { "visa": {"type": "string"}, "buyer_country": {"type": "string"}, "has_thai_bank": {"type": "boolean"} }, "required": ["visa", "buyer_country", "has_thai_bank"]} }}, {"type": "function", "function": { "name": "create_test_charge", "description": "在沙箱创建一笔 charge 并返回微信二维码用于预览。", "parameters": {"type": "object", "properties": { "rail": {"type": "string"}, "amount_thb": {"type": "number"} }, "required": ["rail", "amount_thb"]} }}, ] DISPATCH = { "lookup_fee": lookup_fee, "pick_rail": pick_rail, "create_test_charge": create_test_charge, }
import json, requests from tools import TOOLS, DISPATCH OLLAMA = "http://localhost:11434/api/chat" MODEL = "qwen3:8b" SYSTEM = ("你是一名面向在泰华人的支付顾问。" "必须使用提供的工具,而不是凭空猜测费率或通道。" "始终用用户的语言(中文、泰语或英文)回答。") def run_agent(user_msg: str, history: list[dict] | None = None) -> dict: msgs = [{"role": "system", "content": SYSTEM}, *(history or []), {"role": "user", "content": user_msg}] for _ in range(6): # 工具调用预算上限 r = requests.post(OLLAMA, json={ "model": MODEL, "messages": msgs, "tools": TOOLS, "stream": False, }, timeout=120).json() msg = r["message"] msgs.append(msg) calls = msg.get("tool_calls") or [] if not calls: return {"reply": msg["content"], "history": msgs} for call in calls: # 执行所有被请求的工具 name = call["function"]["name"] args = call["function"]["arguments"] result = DISPATCH[name](**args) msgs.append({"role": "tool", "name": name, "content": json.dumps(result, ensure_ascii=False)}) return {"reply": "(已超出工具调用预算)", "history": msgs}
# pip install fastapi uvicorn requests from fastapi import FastAPI from fastapi.middleware.cors import CORSMiddleware from pydantic import BaseModel from agent import run_agent app = FastAPI() app.add_middleware(CORSMiddleware, allow_origins=["http://localhost:8080"], allow_methods=["*"], allow_headers=["*"]) class ChatIn(BaseModel): message: str history: list[dict] = [] @app.post("/chat") def chat(body: ChatIn): return run_agent(body.message, body.history) @app.get("/health") def health(): return {"ok": True, "model": "qwen3:8b"} # 启动: uvicorn server:app --reload --port 8000
const WORKER = "http://localhost:8000/chat"; let history = []; async function ask(message) { const r = await fetch(WORKER, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ message, history }), }); const { reply, history: next } = await r.json(); history = next; // 保留 tool-call 轨迹便于追溯 render(reply); } // 智能体能通过工具回答的示例提问: // "我有 ED 签证,想给云南朋友收 500 baht,应该用哪个?" // "12000 泰铢,Omise 微信和 USDT 哪个手续费低?" // "帮我生成 99 泰铢的微信沙箱二维码"
# 终端 1 —— LLM ollama serve # 终端 2 —— Agent worker uvicorn server:app --reload --port 8000 # 终端 3 —— 提供本 HTML 页面 python -m http.server 8080 # 浏览器打开 http://localhost:8080/thailand_china_payments_zh.html # 右下角聊天小窗 → localhost:8000 → localhost:11434