feat(avatar): route token recharge through Huihui org orders
This commit is contained in:
@@ -395,6 +395,7 @@ class TokenPaymentOrder(Base):
|
|||||||
"price": self.price_cents / 100,
|
"price": self.price_cents / 100,
|
||||||
"status": self.status,
|
"status": self.status,
|
||||||
"provider": self.provider,
|
"provider": self.provider,
|
||||||
|
"providerOrderNo": self.provider_order_no,
|
||||||
"providerStatus": self.provider_status,
|
"providerStatus": self.provider_status,
|
||||||
"payMessage": self.pay_message,
|
"payMessage": self.pay_message,
|
||||||
"failureReason": self.failure_reason,
|
"failureReason": self.failure_reason,
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ from models import (
|
|||||||
)
|
)
|
||||||
from responses import fail, ok
|
from responses import fail, ok
|
||||||
from services.huihui_payment import HuihuiPaymentClient, HuihuiPaymentError
|
from services.huihui_payment import HuihuiPaymentClient, HuihuiPaymentError
|
||||||
|
from services.huihui_org_payment import HuihuiOrgPaymentClient
|
||||||
from services.token_billing import get_or_create_account
|
from services.token_billing import get_or_create_account
|
||||||
from services.wechat_virtual_payment import (
|
from services.wechat_virtual_payment import (
|
||||||
PAYMENT_EVENTS as WECHAT_PAYMENT_EVENTS,
|
PAYMENT_EVENTS as WECHAT_PAYMENT_EVENTS,
|
||||||
@@ -270,6 +271,7 @@ def _callback_amount_cents(payload) -> int | None:
|
|||||||
"orderAmt",
|
"orderAmt",
|
||||||
"amount",
|
"amount",
|
||||||
"totalAmount",
|
"totalAmount",
|
||||||
|
"chargeAmount",
|
||||||
)
|
)
|
||||||
if value in (None, ""):
|
if value in (None, ""):
|
||||||
return None
|
return None
|
||||||
@@ -405,6 +407,47 @@ def charge(payload: dict = Body(...), authorization: str = Header(None), db: Ses
|
|||||||
return ok(_payment_payload(order, get_or_create_account(db, user.id)))
|
return ok(_payment_payload(order, get_or_create_account(db, user.id)))
|
||||||
|
|
||||||
|
|
||||||
|
@router.post("/token/charge/org")
|
||||||
|
def charge_via_huihui_org(payload: dict = Body(...), authorization: str = Header(None), db: Session = Depends(get_db)):
|
||||||
|
user = _require_user(authorization, db)
|
||||||
|
plan = db.query(TokenPlan).filter(TokenPlan.id == payload.get("planId")).first()
|
||||||
|
if not plan:
|
||||||
|
return fail("套餐不存在", 404)
|
||||||
|
method = str(payload.get("paymentMethod") or "").lower()
|
||||||
|
if method not in PAYMENT_METHODS:
|
||||||
|
return fail("支付方式不正确", 400)
|
||||||
|
scene = str(payload.get("payScene") or "APP").upper()
|
||||||
|
if scene not in PAYMENT_SCENES:
|
||||||
|
return fail("支付场景不正确", 400)
|
||||||
|
pay_type = 6 if scene == "LITE" else (1 if method == "wechat" else 2)
|
||||||
|
if scene == "LITE" and method != "wechat":
|
||||||
|
return fail("微信小程序仅支持微信支付", 400)
|
||||||
|
cents = _price_cents(plan.price)
|
||||||
|
try:
|
||||||
|
result = HuihuiOrgPaymentClient().create_order(
|
||||||
|
token=user.huihui_token, user_id=user.huihui_user_id,
|
||||||
|
name=user.nickname, phone=user.phone, avatar=user.avatar_url,
|
||||||
|
amount=f"{cents / 100:.2f}", pay_type=pay_type,
|
||||||
|
)
|
||||||
|
except HuihuiPaymentError as exc:
|
||||||
|
return fail(str(exc), 502)
|
||||||
|
provider_no = str(result.get("orderNo") or "")
|
||||||
|
if not provider_no.isdigit() or int(result.get("payStatus") or 0) != 1 or int(result.get("chargeType") or 0) != 9:
|
||||||
|
return fail("会会返回的充值订单不正确", 502)
|
||||||
|
if _callback_amount_cents({"chargeAmount": result.get("chargeAmount")}) != cents:
|
||||||
|
return fail("会会返回的充值金额不匹配", 502)
|
||||||
|
order = TokenPaymentOrder(
|
||||||
|
order_no=f"AV{datetime.utcnow().strftime('%Y%m%d%H%M%S')}{uuid.uuid4().hex[:12].upper()}",
|
||||||
|
user_id=user.id, plan_id=plan.id, payment_method=method,
|
||||||
|
pay_type=PAYMENT_METHODS[method], pay_way=scene, points_amount=plan.amount,
|
||||||
|
price_cents=cents, status="pending", provider="huihui_org",
|
||||||
|
provider_order_no=provider_no, provider_status="1",
|
||||||
|
)
|
||||||
|
db.add(order)
|
||||||
|
db.commit()
|
||||||
|
return ok(_payment_payload(order, get_or_create_account(db, user.id)))
|
||||||
|
|
||||||
|
|
||||||
@router.get("/token/payment/{order_id}")
|
@router.get("/token/payment/{order_id}")
|
||||||
def payment_status(order_id: str, authorization: str = Header(None), db: Session = Depends(get_db)):
|
def payment_status(order_id: str, authorization: str = Header(None), db: Session = Depends(get_db)):
|
||||||
user = _require_user(authorization, db)
|
user = _require_user(authorization, db)
|
||||||
@@ -414,6 +457,27 @@ def payment_status(order_id: str, authorization: str = Header(None), db: Session
|
|||||||
).first()
|
).first()
|
||||||
if not order:
|
if not order:
|
||||||
return fail("支付订单不存在", 404)
|
return fail("支付订单不存在", 404)
|
||||||
|
if order.provider == "huihui_org" and order.status == "pending":
|
||||||
|
try:
|
||||||
|
details = HuihuiOrgPaymentClient().get_order(
|
||||||
|
token=user.huihui_token, user_id=user.huihui_user_id,
|
||||||
|
order_no=order.provider_order_no,
|
||||||
|
)
|
||||||
|
status = int(details.get("payStatus") or 0)
|
||||||
|
if (str(details.get("orderNo") or "") == order.provider_order_no
|
||||||
|
and str(details.get("userId") or "") == user.huihui_user_id
|
||||||
|
and int(details.get("chargeType") or 0) == 9
|
||||||
|
and _callback_amount_cents({"chargeAmount": details.get("chargeAmount")}) == order.price_cents):
|
||||||
|
order.provider_status = str(status)
|
||||||
|
if status in (2, 3, 4):
|
||||||
|
_settle_paid_order(db, order, provider_status=f"ORG_{status}",
|
||||||
|
transaction_no=order.provider_order_no)
|
||||||
|
elif status == 5:
|
||||||
|
order.status = "closed"
|
||||||
|
db.commit()
|
||||||
|
db.refresh(order)
|
||||||
|
except (HuihuiPaymentError, TypeError, ValueError):
|
||||||
|
pass # 查询失败时保持待支付,不将未经核对的结果入账。
|
||||||
if order.provider == "wechat_virtual" and order.status == "pending" and user.wechat_mp_openid:
|
if order.provider == "wechat_virtual" and order.status == "pending" and user.wechat_mp_openid:
|
||||||
try:
|
try:
|
||||||
provider_data = query_wechat_virtual_order(
|
provider_data = query_wechat_virtual_order(
|
||||||
@@ -560,6 +624,8 @@ def admin_request_refund(
|
|||||||
return fail("订单不存在", 404)
|
return fail("订单不存在", 404)
|
||||||
if order.status != "paid" or order.refund_status not in {"", "none", "failed"}:
|
if order.status != "paid" or order.refund_status not in {"", "none", "failed"}:
|
||||||
return fail("该订单当前不可退款", 409)
|
return fail("该订单当前不可退款", 409)
|
||||||
|
if order.provider == "huihui_org":
|
||||||
|
return fail("会会组织订单的原路退款接口尚未接入,请先在会会后台处理", 409)
|
||||||
account = get_or_create_account(db, order.user_id)
|
account = get_or_create_account(db, order.user_id)
|
||||||
if int(account.balance or 0) < int(order.points_amount or 0):
|
if int(account.balance or 0) < int(order.points_amount or 0):
|
||||||
return fail("该订单发放的积分已使用,不能执行全额退款", 409)
|
return fail("该订单发放的积分已使用,不能执行全额退款", 409)
|
||||||
|
|||||||
@@ -0,0 +1,48 @@
|
|||||||
|
"""Huihui organization token-recharge order API."""
|
||||||
|
import os
|
||||||
|
|
||||||
|
import httpx
|
||||||
|
|
||||||
|
from services.huihui_payment import HuihuiPaymentClient, HuihuiPaymentError
|
||||||
|
|
||||||
|
|
||||||
|
class HuihuiOrgPaymentClient(HuihuiPaymentClient):
|
||||||
|
def __init__(self):
|
||||||
|
super().__init__({
|
||||||
|
"HUIHUI_PAYMENT_BASE_URL": os.getenv("HUIHUI_ORG_BASE_URL", ""),
|
||||||
|
"HUIHUI_APP_ID": os.getenv("HUIHUI_APP_ID", ""),
|
||||||
|
"HUIHUI_ACCESS_ID": os.getenv("HUIHUI_ACCESS_ID", ""),
|
||||||
|
"HUIHUI_ACCESS_SECRET": os.getenv("HUIHUI_ACCESS_SECRET", ""),
|
||||||
|
})
|
||||||
|
|
||||||
|
def _request(self, method: str, path: str, *, token: str, user_id: str, body=None) -> dict:
|
||||||
|
if not self.configured or not token or not user_id:
|
||||||
|
raise HuihuiPaymentError("会会订单服务或登录凭证未配置")
|
||||||
|
try:
|
||||||
|
response = httpx.request(
|
||||||
|
method, f"{self.base_url}{path}",
|
||||||
|
headers={"Authorization": f"Bearer {token}", "appId": self.app_id},
|
||||||
|
params=self._signed_params(user_id), json=body,
|
||||||
|
timeout=self.timeout, follow_redirects=True,
|
||||||
|
)
|
||||||
|
except httpx.HTTPError as exc:
|
||||||
|
raise HuihuiPaymentError("会会订单服务连接失败") from exc
|
||||||
|
payload = self._json(response)
|
||||||
|
if response.status_code >= 400 or payload.get("code") not in (0, 200, "0", "200"):
|
||||||
|
raise HuihuiPaymentError(str(payload.get("message") or "会会订单请求失败"))
|
||||||
|
data = payload.get("data")
|
||||||
|
if not isinstance(data, dict):
|
||||||
|
raise HuihuiPaymentError("会会订单信息缺失")
|
||||||
|
return data
|
||||||
|
|
||||||
|
def create_order(self, *, token: str, user_id: str, name: str, phone: str,
|
||||||
|
avatar: str, amount: str, pay_type: int) -> dict:
|
||||||
|
body = {"chargeAmount": float(amount), "payType": pay_type,
|
||||||
|
"commodityName": "数字分身积分充值", "userId": user_id,
|
||||||
|
"name": name or "", "phoneNumber": phone or "", "avatar": avatar or ""}
|
||||||
|
return self._request("POST", "/order/tokenRecharge", token=token, user_id=user_id, body=body)
|
||||||
|
|
||||||
|
def get_order(self, *, token: str, user_id: str, order_no: str) -> dict:
|
||||||
|
if not order_no.isdigit():
|
||||||
|
raise HuihuiPaymentError("会会订单号格式不正确")
|
||||||
|
return self._request("GET", f"/order/get/{order_no}", token=token, user_id=user_id)
|
||||||
@@ -100,6 +100,37 @@ def test_charge_creates_huihui_order_without_early_points(authorization_context)
|
|||||||
assert "test-callback-secret-123456" not in callback_url
|
assert "test-callback-secret-123456" not in callback_url
|
||||||
|
|
||||||
|
|
||||||
|
def test_org_recharge_only_credits_after_verified_provider_order(authorization_context):
|
||||||
|
seed()
|
||||||
|
context = authorization_context
|
||||||
|
_enable_huihui_payment_login(context)
|
||||||
|
provider_no = "261016111200090123456"
|
||||||
|
created_data = {"orderNo": provider_no, "chargeType": 9,
|
||||||
|
"chargeAmount": 10, "payStatus": 1}
|
||||||
|
with patch("routers.tokens.HuihuiOrgPaymentClient") as client_factory:
|
||||||
|
provider = client_factory.return_value
|
||||||
|
provider.create_order.return_value = created_data
|
||||||
|
created = client.post(
|
||||||
|
"/api/token/charge/org", headers=context["owner_headers"],
|
||||||
|
json={"planId": "1", "paymentMethod": "wechat", "payScene": "APP"},
|
||||||
|
).json()["data"]
|
||||||
|
assert created["providerOrderNo"] == provider_no
|
||||||
|
assert created["status"] == "pending"
|
||||||
|
assert created["balance"] == DEFAULT_TOKEN_GRANT
|
||||||
|
assert provider.create_order.call_args.kwargs["pay_type"] == 1
|
||||||
|
|
||||||
|
details = {**created_data, "payStatus": 2,
|
||||||
|
"userId": context["owner"].huihui_user_id}
|
||||||
|
provider.get_order.return_value = {**details, "chargeAmount": 9}
|
||||||
|
assert client.get(f"/api/token/payment/{created['id']}", headers=context["owner_headers"]).json()["data"]["status"] == "pending"
|
||||||
|
provider.get_order.return_value = details
|
||||||
|
paid = client.get(f"/api/token/payment/{created['id']}", headers=context["owner_headers"]).json()["data"]
|
||||||
|
assert paid["status"] == "paid"
|
||||||
|
assert paid["balance"] == DEFAULT_TOKEN_GRANT + 2_000_000
|
||||||
|
duplicate = client.get(f"/api/token/payment/{created['id']}", headers=context["owner_headers"]).json()["data"]
|
||||||
|
assert duplicate["balance"] == paid["balance"]
|
||||||
|
|
||||||
|
|
||||||
def test_success_callback_credits_once_and_status_is_user_scoped(authorization_context):
|
def test_success_callback_credits_once_and_status_is_user_scoped(authorization_context):
|
||||||
context = authorization_context
|
context = authorization_context
|
||||||
_enable_huihui_payment_login(context)
|
_enable_huihui_payment_login(context)
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
# 数字分身 H5 生产接入与部署
|
# 数字分身 H5 生产接入与部署
|
||||||
|
|
||||||
|
测试环境入口为 `https://fat-digital.99hui.com/`;测试支付收银台使用 `https://fat-open.99hui.com/huihui-h5/`,生产支付收银台使用 `https://99hui.com/huihui-h5/`。两套环境的订单和验签配置必须隔离,密钥只保存在各自后端配置中,不写入前端或仓库。
|
||||||
|
|
||||||
## 1. 接入方式
|
## 1. 接入方式
|
||||||
|
|
||||||
生产会会在用户已登录后打开以下地址:
|
生产会会在用户已登录后打开以下地址:
|
||||||
|
|||||||
@@ -156,7 +156,8 @@ export interface TokenPaymentOrder {
|
|||||||
pointsAmount: number
|
pointsAmount: number
|
||||||
price: number
|
price: number
|
||||||
status: 'pending' | 'paid' | 'failed' | 'closed' | 'refunded'
|
status: 'pending' | 'paid' | 'failed' | 'closed' | 'refunded'
|
||||||
provider: 'huihui' | 'wechat_virtual'
|
provider: 'huihui' | 'wechat_virtual' | 'huihui_org'
|
||||||
|
providerOrderNo?: string
|
||||||
providerStatus: string
|
providerStatus: string
|
||||||
payMessage: string
|
payMessage: string
|
||||||
failureReason: string
|
failureReason: string
|
||||||
@@ -196,6 +197,12 @@ export const chargeToken = (
|
|||||||
payScene: 'APP' | 'H5' | 'LITE' | 'JSAPI'
|
payScene: 'APP' | 'H5' | 'LITE' | 'JSAPI'
|
||||||
) => request.post<TokenPaymentOrder>('/token/charge', { planId, paymentMethod, payScene })
|
) => request.post<TokenPaymentOrder>('/token/charge', { planId, paymentMethod, payScene })
|
||||||
|
|
||||||
|
export const chargeTokenOrg = (
|
||||||
|
planId: string,
|
||||||
|
paymentMethod: 'wechat' | 'alipay',
|
||||||
|
payScene: 'APP' | 'H5' | 'LITE' | 'JSAPI'
|
||||||
|
) => request.post<TokenPaymentOrder>('/token/charge/org', { planId, paymentMethod, payScene })
|
||||||
|
|
||||||
export const getTokenPaymentStatus = (orderId: string) =>
|
export const getTokenPaymentStatus = (orderId: string) =>
|
||||||
request.get<TokenPaymentOrder>(`/token/payment/${orderId}`)
|
request.get<TokenPaymentOrder>(`/token/payment/${orderId}`)
|
||||||
|
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ app.use(pinia)
|
|||||||
|
|
||||||
// —— 混合架构:在挂载前注入 uniapp 壳传入的认证与会会资料 ——
|
// —— 混合架构:在挂载前注入 uniapp 壳传入的认证与会会资料 ——
|
||||||
const params = getLaunchParams()
|
const params = getLaunchParams()
|
||||||
|
if (params.evn !== undefined) sessionStorage.setItem('hh_launch_evn', params.evn)
|
||||||
const avatarStore = useAvatarStore(pinia)
|
const avatarStore = useAvatarStore(pinia)
|
||||||
const userStore = useUserStore(pinia)
|
const userStore = useUserStore(pinia)
|
||||||
|
|
||||||
|
|||||||
@@ -12,15 +12,16 @@ export interface UniLaunchParams {
|
|||||||
nickname?: string
|
nickname?: string
|
||||||
avatar?: string
|
avatar?: string
|
||||||
ts?: string
|
ts?: string
|
||||||
|
evn?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const PARAM_KEYS: (keyof UniLaunchParams)[] = ['token', 'userId', 'nickname', 'avatar', 'ts']
|
const PARAM_KEYS: (keyof UniLaunchParams)[] = ['token', 'userId', 'nickname', 'avatar', 'ts', 'evn']
|
||||||
|
|
||||||
function readParams(search: string, target: UniLaunchParams): void {
|
function readParams(search: string, target: UniLaunchParams): void {
|
||||||
const sp = new URLSearchParams(search)
|
const sp = new URLSearchParams(search)
|
||||||
for (const key of PARAM_KEYS) {
|
for (const key of PARAM_KEYS) {
|
||||||
const value = sp.get(key)
|
const value = sp.get(key)
|
||||||
if (value) target[key] = value
|
if (value || (key === 'evn' && sp.has(key))) target[key] = value ?? ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -110,7 +110,7 @@
|
|||||||
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
import { computed, onMounted, onUnmounted, ref } from 'vue'
|
||||||
import { useRouter } from 'vue-router'
|
import { useRouter } from 'vue-router'
|
||||||
import {
|
import {
|
||||||
chargeToken,
|
chargeTokenOrg,
|
||||||
applyTokenInvoice,
|
applyTokenInvoice,
|
||||||
getRechargePlans,
|
getRechargePlans,
|
||||||
getTokenBalance,
|
getTokenBalance,
|
||||||
@@ -118,7 +118,7 @@ import {
|
|||||||
getTokenPaymentStatus,
|
getTokenPaymentStatus,
|
||||||
type TokenPaymentOrder
|
type TokenPaymentOrder
|
||||||
} from '@/api'
|
} from '@/api'
|
||||||
import { isInUniWebView, onNativeMessage, UniEvents } from '@/utils/uniapp-bridge'
|
import { isInUniWebView, onNativeMessage } from '@/utils/uniapp-bridge'
|
||||||
import wechatPayIcon from '@/assets/wechat-pay.svg'
|
import wechatPayIcon from '@/assets/wechat-pay.svg'
|
||||||
import alipayIcon from '@/assets/alipay.svg'
|
import alipayIcon from '@/assets/alipay.svg'
|
||||||
|
|
||||||
@@ -235,71 +235,12 @@ const checkoutLabel = computed(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
const payScene = () => {
|
const payScene = () => {
|
||||||
|
if (paymentMethod.value === 'wechat' && /miniProgram/i.test(navigator.userAgent)) return 'LITE' as const
|
||||||
if (isInUniWebView()) return 'APP' as const
|
if (isInUniWebView()) return 'APP' as const
|
||||||
if (paymentMethod.value === 'wechat' && /MicroMessenger/i.test(navigator.userAgent)) return 'JSAPI' as const
|
if (paymentMethod.value === 'wechat' && /MicroMessenger/i.test(navigator.userAgent)) return 'JSAPI' as const
|
||||||
return 'H5' as const
|
return 'H5' as const
|
||||||
}
|
}
|
||||||
|
|
||||||
const parsePayMessage = (message: string) => {
|
|
||||||
const text = (message || '').trim()
|
|
||||||
if (!text) return null
|
|
||||||
try {
|
|
||||||
return JSON.parse(text)
|
|
||||||
} catch {
|
|
||||||
return text
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const findPaymentUrl = (value: any): string => {
|
|
||||||
if (typeof value === 'string' && /^https?:\/\//i.test(value)) return value
|
|
||||||
if (!value || typeof value !== 'object') return ''
|
|
||||||
for (const key of ['url', 'payUrl', 'mwebUrl', 'mweb_url', 'redirectUrl']) {
|
|
||||||
if (typeof value[key] === 'string' && /^https?:\/\//i.test(value[key])) return value[key]
|
|
||||||
}
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
|
|
||||||
const invokeWechatJsapi = (params: Record<string, any>) => new Promise<void>((resolve, reject) => {
|
|
||||||
const invoke = () => {
|
|
||||||
const bridge = (window as any).WeixinJSBridge
|
|
||||||
if (!bridge?.invoke) {
|
|
||||||
reject(new Error('当前微信环境无法拉起支付'))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
bridge.invoke('getBrandWCPayRequest', params, (result: any) => {
|
|
||||||
const message = String(result?.err_msg || result?.errMsg || '')
|
|
||||||
if (/\bok\b/i.test(message)) resolve()
|
|
||||||
else reject(new Error(/cancel/i.test(message) ? '支付已取消' : '微信支付未完成'))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
if ((window as any).WeixinJSBridge) invoke()
|
|
||||||
else document.addEventListener('WeixinJSBridgeReady', invoke, { once: true })
|
|
||||||
})
|
|
||||||
|
|
||||||
const launchPayment = async (order: TokenPaymentOrder) => {
|
|
||||||
const parsed = parsePayMessage(order.payMessage)
|
|
||||||
if (order.payWay === 'JSAPI' && order.paymentMethod === 'wechat' && parsed && typeof parsed === 'object') {
|
|
||||||
await invokeWechatJsapi(parsed)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if (isInUniWebView() && UniEvents.payment({
|
|
||||||
orderId: order.id,
|
|
||||||
orderNo: order.orderNo,
|
|
||||||
paymentMethod: order.paymentMethod,
|
|
||||||
payType: order.payType,
|
|
||||||
payWay: order.payWay,
|
|
||||||
payMessage: order.payMessage,
|
|
||||||
paymentParams: parsed
|
|
||||||
})) return
|
|
||||||
|
|
||||||
const paymentUrl = findPaymentUrl(parsed)
|
|
||||||
if (paymentUrl) {
|
|
||||||
window.location.assign(paymentUrl)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
throw new Error('请在会会 App 内完成支付')
|
|
||||||
}
|
|
||||||
|
|
||||||
const clearPendingOrder = () => {
|
const clearPendingOrder = () => {
|
||||||
pendingOrderId.value = ''
|
pendingOrderId.value = ''
|
||||||
sessionStorage.removeItem('hh_pending_payment_order')
|
sessionStorage.removeItem('hh_pending_payment_order')
|
||||||
@@ -349,12 +290,18 @@ const doCharge = async () => {
|
|||||||
charging.value = true
|
charging.value = true
|
||||||
paymentNotice.value = ''
|
paymentNotice.value = ''
|
||||||
try {
|
try {
|
||||||
const order = await chargeToken(selectedPlan.value.id, paymentMethod.value, payScene())
|
const order = await chargeTokenOrg(selectedPlan.value.id, paymentMethod.value, payScene())
|
||||||
if (order.status === 'failed') throw new Error(order.failureReason || '支付订单创建失败')
|
if (order.status === 'failed') throw new Error(order.failureReason || '支付订单创建失败')
|
||||||
|
if (!order.providerOrderNo || !/^\d+$/.test(order.providerOrderNo)) throw new Error('会会充值订单号缺失')
|
||||||
paymentNoticeTone.value = 'pending'
|
paymentNoticeTone.value = 'pending'
|
||||||
paymentNotice.value = '支付订单已创建,正在等待付款结果'
|
paymentNotice.value = '支付订单已创建,正在等待付款结果'
|
||||||
startPolling(order.id)
|
startPolling(order.id)
|
||||||
await launchPayment(order)
|
const checkoutBase = window.location.hostname === 'digital.99hui.com'
|
||||||
|
? 'https://99hui.com/huihui-h5/'
|
||||||
|
: 'https://fat-open.99hui.com/huihui-h5/'
|
||||||
|
const evn = sessionStorage.getItem('hh_launch_evn')
|
||||||
|
const evnPart = evn ? `&evn=${encodeURIComponent(evn)}` : '&evn'
|
||||||
|
window.location.assign(`${checkoutBase}#/payOrder?orderNo=${encodeURIComponent(order.providerOrderNo)}&isOrg=true${evnPart}`)
|
||||||
} catch (error: any) {
|
} catch (error: any) {
|
||||||
paymentNoticeTone.value = 'error'
|
paymentNoticeTone.value = 'error'
|
||||||
paymentNotice.value = error?.message || '充值失败,请重试'
|
paymentNotice.value = error?.message || '充值失败,请重试'
|
||||||
|
|||||||
Reference in New Issue
Block a user