fix: Native扫码二维码改为HTTPS中转以支持相册识别
This commit is contained in:
1 parent
486c050c00
commit
94f7a2fba9
5 files changed
+76
-13
No files matched your search
@@ -25,12 +25,32 @@ logger = logging.getLogger(__name__)
|
||||
|
||||
CACHE_KEY_PREFIX = 'wx_native_code_'
|
||||
CACHE_TTL_SECONDS = 60 * 30
|
||||
# 相册扫码友好:二维码图编码 HTTPS 中转页(打开后再跳 weixin://),复制链接仍给官方 code_url
|
||||
BRIDGE_URL_BASE = 'https://www.abas.asia/hqhd/dingdan/wx-native-pay/'
|
||||
|
||||
|
||||
def _cache_key(dingdanid: str) -> str:
|
||||
return f'{CACHE_KEY_PREFIX}{dingdanid}'
|
||||
|
||||
|
||||
def build_native_bridge_url(dingdanid: str) -> str:
|
||||
from urllib.parse import quote
|
||||
return f'{BRIDGE_URL_BASE}?out_trade_no={quote(dingdanid, safe="")}'
|
||||
|
||||
|
||||
def _native_pay_response(dingdanid: str, code_url: str) -> dict:
|
||||
from jituan.services.alipay_pay import qr_link_to_base64
|
||||
bridge = build_native_bridge_url(dingdanid)
|
||||
return {
|
||||
# 复制支付链接:与同行一致,官方 weixin://wxpay/bizpayurl?...
|
||||
'qr_code': code_url,
|
||||
# 展示用二维码:HTTPS 中转,便于微信「扫一扫-相册」识别
|
||||
'qr_image': qr_link_to_base64(bridge),
|
||||
'bridge_url': bridge,
|
||||
'pay_method': PAY_METHOD_WECHAT_NATIVE,
|
||||
}
|
||||
|
||||
|
||||
def generate_wechat_native_pay_params(
|
||||
*,
|
||||
dingdanid,
|
||||
@@ -46,8 +66,6 @@ def generate_wechat_native_pay_params(
|
||||
同一业务单号未过期时复用 cache 中的 code_url,避免重复点支付产生双码。
|
||||
不需要 openid。第一期不走付呗。
|
||||
"""
|
||||
from jituan.services.alipay_pay import qr_link_to_base64
|
||||
|
||||
dingdanid = (dingdanid or '').strip()
|
||||
notify_url = (notify_url or '').strip()
|
||||
body = (body or '微信支付').strip() or '微信支付'
|
||||
@@ -63,11 +81,7 @@ def generate_wechat_native_pay_params(
|
||||
'[WX_NATIVE] reuse code_url dingdan=%s club=%s scene=%s',
|
||||
dingdanid, club_id, scene,
|
||||
)
|
||||
return {
|
||||
'qr_code': cached_url,
|
||||
'qr_image': qr_link_to_base64(cached_url),
|
||||
'pay_method': PAY_METHOD_WECHAT_NATIVE,
|
||||
}
|
||||
return _native_pay_response(dingdanid, cached_url)
|
||||
|
||||
pay_cfg = get_wechat_v2_config(club_id)
|
||||
log_wechat_v2_pay_diag(
|
||||
@@ -131,8 +145,4 @@ def generate_wechat_native_pay_params(
|
||||
'[WX_NATIVE] unifiedorder ok dingdan=%s club=%s mch=%s scene=%s',
|
||||
dingdanid, pay_cfg.get('club_id'), mch_id, scene,
|
||||
)
|
||||
return {
|
||||
'qr_code': code_url,
|
||||
'qr_image': qr_link_to_base64(code_url),
|
||||
'pay_method': PAY_METHOD_WECHAT_NATIVE,
|
||||
}
|
||||
return _native_pay_response(dingdanid, code_url)
|
||||
+2
-1
@@ -1,6 +1,6 @@
|
||||
from django.urls import path
|
||||
from django.views.decorators.csrf import csrf_exempt
|
||||
from .views import CreateOrderView, WechatPayNotifyView, AlipayPayNotifyView, alipay_pay_page, \
|
||||
from .views import CreateOrderView, WechatPayNotifyView, AlipayPayNotifyView, alipay_pay_page, wx_native_pay_page, \
|
||||
PaymentFailView, PaymentVerifyView, ContinuePayView, DingdanHuoquView, DingdanXiangqingView, JiedanView, \
|
||||
ShangpinLeixingView, ShangjiaPaifaView, ShangjiaDingdanHuoquView, ShangjiaJiesuanView, \
|
||||
ShangjiaDingdanXiangqingView, ShangjiaChufaShenqingView, ShangjiaTuikuanShenqingView, \
|
||||
@@ -24,6 +24,7 @@ urlpatterns = [
|
||||
path('alipay-notify/', csrf_exempt(AlipayPayNotifyView.as_view()), name='老板下单支付宝支付回调'),
|
||||
path('fubei-notify/', csrf_exempt(FubeiPayNotifyView.as_view()), name='付呗支付回调'),
|
||||
path('alipay-pay/', csrf_exempt(alipay_pay_page), name='支付宝H5中转页'),
|
||||
path('wx-native-pay/', csrf_exempt(wx_native_pay_page), name='微信Native扫码中转页'),
|
||||
path('shibai', PaymentFailView.as_view(), name='老板支付失败接口'),
|
||||
path('fucha', PaymentVerifyView.as_view(), name='老板支付成功复查接口'),
|
||||
path('dingdanhuoqu', DingdanHuoquView.as_view(), name='老板订单获取'),
|
||||
|
||||
@@ -10,6 +10,7 @@ from .payment import (
|
||||
CreateOrderView,
|
||||
ContinuePayView,
|
||||
alipay_pay_page,
|
||||
wx_native_pay_page,
|
||||
)
|
||||
from .boss_orders import (
|
||||
DingdanHuoquView,
|
||||
@@ -73,6 +74,7 @@ __all__ = [
|
||||
"PaymentFailView", "WechatPayNotifyView", "AlipayPayNotifyView", "PaymentVerifyView", "CreateOrderView",
|
||||
"ContinuePayView",
|
||||
"alipay_pay_page",
|
||||
"wx_native_pay_page",
|
||||
"DingdanHuoquView", "DingdanXiangqingView", "JiedanView",
|
||||
"DingdanXiangqingView2", "JiedanView2",
|
||||
"ShangpinLeixingView", "ShangjiaPaifaView", "ShangjiaDingdanHuoquView",
|
||||
|
||||
@@ -530,6 +530,19 @@ def alipay_pay_page(request):
|
||||
return render(request, 'alipay/pay.html', {})
|
||||
|
||||
|
||||
def wx_native_pay_page(request):
|
||||
"""微信 Native 扫码中转页:相册扫 HTTPS 码后跳转到 weixin:// 付款链接。"""
|
||||
out_trade_no = (request.GET.get('out_trade_no') or request.GET.get('dingdanid') or '').strip()
|
||||
code_url = ''
|
||||
if out_trade_no:
|
||||
cached = cache.get(f'wx_native_code_{out_trade_no}') or {}
|
||||
if isinstance(cached, dict):
|
||||
code_url = (cached.get('code_url') or '').strip()
|
||||
elif isinstance(cached, str):
|
||||
code_url = cached.strip()
|
||||
return render(request, 'wechat/native_pay.html', {'code_url': code_url, 'out_trade_no': out_trade_no})
|
||||
|
||||
|
||||
class PaymentVerifyView(APIView):
|
||||
"""
|
||||
订单支付成功复查接口 - 前端支付成功后调用,确认订单状态
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
<!DOCTYPE html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
|
||||
<title>微信支付</title>
|
||||
<style>
|
||||
* { margin: 0; padding: 0; box-sizing: border-box; }
|
||||
body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif; background: #f5f5f5; }
|
||||
.container { max-width: 420px; margin: 0 auto; padding: 48px 20px; text-align: center; }
|
||||
.icon { width: 72px; height: 72px; margin: 0 auto 20px; border: 4px solid #ddd; border-top-color: #07c160; border-radius: 50%; animation: spin 1s linear infinite; }
|
||||
.title { font-size: 18px; color: #333; margin-bottom: 12px; }
|
||||
.subtitle { font-size: 14px; color: #999; margin-bottom: 28px; line-height: 1.5; }
|
||||
.btn { display: inline-block; width: 100%; padding: 14px; font-size: 16px; border: none; border-radius: 8px; background: #07c160; color: #fff; }
|
||||
@keyframes spin { to { transform: rotate(360deg); } }
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
{% if code_url %}
|
||||
<div class="icon"></div>
|
||||
<div class="title">正在打开微信支付...</div>
|
||||
<div class="subtitle">若未自动跳转,请点击下方按钮</div>
|
||||
<a class="btn" id="payBtn" href="{{ code_url }}">立即支付</a>
|
||||
<script>
|
||||
(function () {
|
||||
var url = '{{ code_url|escapejs }}';
|
||||
setTimeout(function () { window.location.href = url; }, 80);
|
||||
})();
|
||||
</script>
|
||||
{% else %}
|
||||
<div class="title">支付链接无效或已过期</div>
|
||||
<div class="subtitle">请返回小程序重新发起支付</div>
|
||||
{% endif %}
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
||||
Reference in new issue
Block a user